如何使用 GNU make 部分序列化

sch*_*ily 5 make gnu gnu-make sunpro

当我有一个需要在另一个目标之前制作特定目标的 make 任务时,在并行模式下,使用 SunPro Make (dmake) 时这很简单。以下生成文件:

install:  dir dir/file

dir:
    mkdir dir

dir/file:
    cp source dir/file
Run Code Online (Sandbox Code Playgroud)

通过将第一行更改为:

install: dir .WAIT dir/file
Run Code Online (Sandbox Code Playgroud)

或通过使用:

.NO_PARALLEL: install
Run Code Online (Sandbox Code Playgroud)

makefile 的其余部分仍将在并行模式下处理,即使是左侧或右侧的目标列表.WAIT也将以并行模式处理。

参见:http : //schlytools.sourceforge.net/man/man1/make.1s.htmlhttp://schlytools.sourceforge.net/man/man1/dmake.1.html

但是 GNU make 似乎没有类似的选项。真的没有办法用 GNU make 做到这一点吗?

更具体地说,该解决方案需要以允许使用其他 make 实现处理 makefile 的方式编写。

特殊目标 .WAIT 可以例如在称为 $(WAIT) 的 make 程序相关宏中

请注意,有一个明显的解决方案无济于事:

从理论上讲一个可以使dir的依赖dir/file,以实施创建dir试图复制之前dir/file,,但如果以后另一个文件复制到dir,这使得dir比新dir/file。因此,make多次调用会dir/file一次又一次地复制,而没有预期的结果,make只有在源变得更新的情况下才进行复制dir/file.

这提出了另一个问题,是否可能存在强制在复制之前make创建的依赖关系拓扑而不依赖于dirdir/filedirdir/file.

fil*_*den 7

在 GNU make 中,您可以使用order-only-prerequisites来确保dir在要创建的规则dir/file运行之前已创建。

有关更多详细信息,请参阅此页面

您可以从 GNU make 手册中的示例中看到,它确实是为在创建目录之前添加对正在创建的目录的依赖而量身定制的。

在您的具体示例的情况下,应该这样做:

dir/file: | dir
        cp source dir/file
Run Code Online (Sandbox Code Playgroud)

尽管您不需要修改现有规则,但您可以在 Makefile 的其他位置添加该依赖项...

更具体地说,该解决方案需要以允许使用其他 make 实现处理 makefile 的方式编写。

我不认为这会在其它品牌实现工作...一个可能的解决方案是创建一个GNUmakefileinclude实际Makefile并添加GNU做出具体的扩展。

您也可以让 GNU make 忽略规则,例如.WAIT将其定义为GNUmakefile.

我希望这些指针有帮助!


fil*_*den 6

您需要添加依赖项,以便在目录下的文件之前创建目录。

可以使用“标记”文件来实现对目录的依赖,这样在其下创建文件就不会触及目录的时间戳。这也不需要任何 GNU make 的特定功能。

在你的例子中:

install: dir/file

dir/.marker:
        mkdir -p dir
        touch dir/.marker

dir/file: dir/.marker
        cp source dir/file
Run Code Online (Sandbox Code Playgroud)

您可以使用类似.directory.dir或 的内容.folder作为标记文件...


sch*_*ily 1

这是我自己的答案,它源自 Filipe Brandenburger 提出的想法以及 Schily Makefile 系统中使用的通用方法:

makefile 系统确保以make macros这种方式设置以下内容:

WAIT=       # empty with GNU make
WAIT= .WAIT # .WAIT special target with SunPro Make

MAKEPROG= <name of the make program> # This is from: smake, gmake, sunpro

_UNIQ= .XxZzy-
Run Code Online (Sandbox Code Playgroud)

现在使用上面的宏定义的 makefile:

_NORULE=    $(_UNIQ)$(MAKEPROG)
__NORULE=   $(_NORULE:$(_UNIQ)gmake=)
NORULE=     $(__NORULE:$(_UNIQ)%=%)

install: dir $(WAIT) dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

$(NORULE)dir/file: | dir
Run Code Online (Sandbox Code Playgroud)

$(NORULE)使用 gmake 可以扩展为空,而sunpro使用 SunPro Make 则可以扩展为空。

对于 gmake,整个 makefile 扩展为:

install: dir dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

dir/file: | dir
Run Code Online (Sandbox Code Playgroud)

对于 SunPro Make,整个 makefile 扩展为:

install: dir .WAIT dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

sunprodir/file: | dir
Run Code Online (Sandbox Code Playgroud)

最后一行被视为没有相关性的垃圾规则。