有没有办法让 gmake 从不并行运行一组目标中的两个目标?
我不想使用 .NOTPARALLEL,因为它强制整个 Makefile 按顺序运行,而不仅仅是所需的部分。
我还可以添加依赖项,以便一个依赖于另一个,但是(除了丑陋之外)我需要构建所有依赖项才能构建最后一个,这不是必需的。
我需要这个的原因是我的 Makefile 的(只有一部分)调用了 ghc --make
,它自己处理它的依赖关系。并且不可能在两个不同的目标上并行运行它,因为如果两个目标共享一些依赖关系,它们可以重写彼此的.o
文件。 (但 ghc
可以按顺序调用。)
更新:举一个具体的例子。假设我需要在 Makefile 中编译两个程序:
prog1
取决于 prog1.hs
和 mylib.hs
; prog2
取决于 prog2.hs
和 mylib.hs
. 现在,如果我调用
ghc --make prog1.hs
,它检查它的依赖关系,编译prog1.hs
和 mylib.hs
进入它们各自的目标和接口(interface)文件,并链接prog1
.当我调用 ghc --make prog2.hs
时也会发生同样的情况.因此,如果两个命令并行运行,其中一个将覆盖 mylib.o
另一个,导致它严重失败。但是,我不需要
prog1
取决于 prog2
反之亦然,因为它们应该可以单独编译。 (实际上它们非常大,有很多模块,并且需要编译它们都大大减慢了开发速度。)
最佳答案
嗯,可以提供更多信息,所以这只是在黑暗中刺伤。
Make 并不真正支持这一点,但您可以通过几种方式对两个目标进行序列化。首先,递归make的真正用途:
targ1: ; recipe1...
targ2: ; recipe2...
both-targets:
${MAKE} targ1
${MAKE} targ2
所以在这里你可以
make -j both-targets
一切都很好。虽然很脆弱,因为 make -j targ1 targ2
仍然并行运行。您可以改用依赖项:targ1: ; recipe1...
targ2: | targ1 ; recipe2...
现在
make -j targ1 targ2
做你想做的事。坏处? make targ2
将始终尝试构建 targ1
首先(依次)。这可能(或可能不会)对您来说是一个阻碍。编辑
另一个不满意的策略是明确查看
$MAKECMDGOALS
,其中列出了您在命令行中指定的目标。仍然是一个脆弱的解决方案,因为当有人使用 Makefile 中的依赖项来构建东西时它会被破坏(不是不合理的行为)。假设您的 makefile 包含两个独立的目标
targ1
和 targ2
.基本上它们保持独立,直到有人在命令行上指定它们都必须被构建。在这种特殊情况下,您打破了这种独立性。考虑这个片段:$(and $(filter targ1,${MAKECMDGOALS)),$(filter targ2,${MAKECMDGOALS}),$(eval targ1: | targ2))
呃!这里发生了什么?
$(and)
$(filter targ1,${MAKECMDGOALS})
targ1
已指定,它继续扩展 $(filter targ2,${MAKECMDGOALS})
targ2
也被指定,它继续扩展 $(eval)
, 强制序列化 targ1
和 targ2
.$(eval)
扩展为空(它的所有工作都是作为副作用完成的),所以原来的 $(and)
总是扩展到什么都没有,不会导致语法错误。 啊!
[现在我已经把它打出来了,更简单的
prog2: | $(filter prog1,${MAKECMDGOALS})
发生在我身上。那好吧。]YMMV 等等。
我对 ghc 不熟悉,但正确的解决方案是让 ghc 的两次运行使用不同的构建文件夹,然后它们可以愉快地并行运行。
关于parallel-processing - 如何强制某组目标始终按顺序运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21832023/