如何使用 GNU make 部分序列化

如何使用 GNU make 部分序列化

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

install:  dir dir/file

dir:
    mkdir dir

dir/file:
    cp source dir/file

可以通过将第一行更改为并行使安全:

install: dir .WAIT dir/file

或通过使用:

.NO_PARALLEL: install

makefile 的其余部分仍将以并行模式处理,甚至如果左侧或右侧的目标列表也.WAIT将以并行模式处理。

看:http://schilytools.sourceforge.net/man/man1/make.1s.htmlhttp://schilytools.sourceforge.net/man/man1/dmake.1.html

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

更具体地说,解决方案的编写方式需要允许 makefile 与其他 make 实现一起处理。

特殊目标 .WAIT 可以位于 make 程序相关的宏中,该宏被称为 $(WAIT)

请注意,有一个明显的解决方案没有帮助:

理论上,可以在尝试复制到之前建立dir依赖关系dir/file,以便强制创建,但是如果您稍后将另一个文件复制到其中,则这会比.因此,多次调用会一次又一次地复制,而只有在源变得较新的情况下才进行复制不会达到预期的结果dirdir/file,dir,dirdir/filemakedir/filemakedir/file.

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

答案1

在 GNU make 中,您可以使用仅订购先决条件确保在运行dir要创建的规则之前创建dir/file

这一页更多细节。

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

对于您的具体示例,应该执行类似的操作:

dir/file: | dir
        cp source dir/file

虽然您不需要修改现有规则,但您可以将该依赖项添加到 Makefile 中的其他位置...

更具体地说,解决方案的编写方式需要允许 makefile 与其他 make 实现一起处理。

我认为这在其他 make 实现中不起作用...一种可能的解决方案是创建GNUmakefile一个include实际中Makefile还添加了 GNU 做出的特定扩展。

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

我希望这些指示有帮助!

答案2

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

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

在你的例子中:

install: dir/file

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

dir/file: dir/.marker
        cp source dir/file

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

答案3

这是我自己的答案,它源自 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-

现在使用上面的宏定义的 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

$(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

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

install: dir .WAIT dir/file

dir/file: source
        cp source dir/file

dir:
        mkdir -p dir

sunprodir/file: | dir

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

相关内容