如何强制某些目标组始终按顺序运行?

Pet*_*lák 14 parallel-processing makefile gnu-make ghc

有没有办法让gmake永远不会从一组并行运行两个目标?

我不想使用.NOTPARALLEL,因为它强制整个Makefile按顺序运行,而不仅仅是所需的部分.

我还可以添加依赖项,以便一个依赖于另一个,但是然后(除了uglu)我需要构建所有它们以构建最后一个,这是不必要的.


我需要这个的原因是我的Makefile的一部分(只有一部分)调用ghc --make,它自己处理它的依赖.并且不可能在两个不同的目标上并行运行它,因为如果两个目标共享一些依赖关系,它们可以重写彼此的.o文件.(但ghc顺序调用很好.)

更新:举一个具体的例子.假设我需要在Makefile中编译两个程序:

  • prog1取决于prog1.hsmylib.hs;
  • prog2取决于prog2.hsmylib.hs.

现在,如果我调用ghc --make prog1.hs,它会检查它的依赖,既编译prog1.hsmylib.hs到各自的目标和接口文件和链接prog1.我打电话时也是如此ghc --make prog2.hs.因此,如果两个命令并行运行,则会覆盖mylib.o另一个命令,从而导致其严重失败.

但是,我需要它既不prog1依赖prog2也不反过来,因为它们应该单独编译.(实际上它们非常庞大,有很多模块,需要编译它们都会大大减慢开发速度.)

bob*_*ogo 7

嗯,可以做更多的信息,所以这只是在黑暗中刺伤.

Make并不真正支持这一点,但你可以通过几种方式顺序实现两个目标.首先,真正用于递归制作:

targ1: ; recipe1...
targ2: ; recipe2...

both-targets:
    ${MAKE} targ1
    ${MAKE} targ2
Run Code Online (Sandbox Code Playgroud)

所以在这里你可以make -j both-targets一切都很好.虽然脆弱,因为make -j targ1 targ2仍然并行运行.您可以使用依赖项:

targ1: ; recipe1...
targ2: | targ1 ; recipe2...
Run Code Online (Sandbox Code Playgroud)

现在make -j targ1 targ2做你想要的.坏处?make targ2将始终尝试先建立targ1(顺序).这可能(或可能不是)对你来说是一个阻碍.

编辑

另一个令人不满意的策略是明确查看$MAKECMDGOALS,其中列出了您在命令行中指定的目标.仍然是一个脆弱的解决方案,因为当有人在Makefile中使用依赖项来构建内容时(这不是不合理的操作),它会被破坏.

假设你的makefile包含两个独立的目标targ1targ2.基本上它们保持独立,直到某人在命令行上指定必须同时构建它们.在这种特殊情况下,你打破了这种独立性 请考虑以下代码段:

$(and $(filter targ1,${MAKECMDGOALS)),$(filter targ2,${MAKECMDGOALS}),$(eval targ1: | targ2))
Run Code Online (Sandbox Code Playgroud)

乌尔克!这里发生了什么?

  • 制作评估 $(and)
  • 它首先必须扩大 $(filter targ1,${MAKECMDGOALS})
  • Iff targ1 指定,它继续扩展$(filter targ2,${MAKECMDGOALS})
  • Iff targ2被指定,它继续扩展,强制序列化和. $(eval)targ1targ2
    • 请注意,$(eval)扩展为空(所有工作都是作为副作用完成),因此原始文件$(and)总是扩展为空,不会导致语法错误.

啊!

[现在我输入了这个,prog2: | $(filter prog1,${MAKECMDGOALS}) 对我来说简单得多了.那好吧.]

YMMV等等.

我不熟悉ghc,但正确的解决方案是让ghc的两次运行使用不同的构建文件夹,然后他们可以愉快地并行运行.