制作平行完井障碍

时间:2016-11-02 18:32:20

标签: makefile gnu-make

我有一个带有目标的Makefile,其中有几个正在运行的作业与-j选项并行。

all: header
    mkdir -p $(STAGEDIR)
    @echo STAGEDIR = $(STAGEDIR)
    [ -z "$(dir_1_y)" ] || $(MAKE) -j$(HOST_NCPU) $(sort $(dir_1_y)) || exit $$?
    [ -z "$(dir_1_y)" ] || $(SET_STAGEDIR)
    [ -z "$(dir_2_y)" ] || $(MAKE) -j$(HOST_NCPU) $(sort $(dir_2_y)) || exit $$?
    [ -z "$(dir_2_y)" ] || $(SET_STAGEDIR)

这些工作可能需要不同的时间才能完成。在进入构建过程的下一个阶段之前,有什么方法可以确保所有这些完成

2 个答案:

答案 0 :(得分:0)

使用您当前的配方,所有作业都在下一行开始之前完成。是否使用-j完全无关紧要。

另外,我不知道你是否知道,你所拥有的,不是一个makefile。它实际上是一个伪装成makefile的shell脚本,没有使用Make的优点。没有理由保持这种方式。

忘记“makefile”并使用shell脚本:

mkdir -p $STAGEDIR
echo STAGEDIR = $(STAGEDIR)
[ -z "$(dir_1_y)" ] || make -j$HOST_NCPU $(sort $dir_1_y) || exit $?
[ -z "$(dir_1_y)" ] || $(SET_STAGEDIR) 
[ -z "$(dir_2_y)" ] || $(MAKE) -j$HOST_NCPU $(sort $dir_2_y) || exit $?
[ -z "$(dir_2_y)" ] || $(SET_STAGEDIR)

当您这样做时,一切都将更容易管理,包括原始问题中的问题。 Make为您提供了特定的优势,与shell脚本相比,增加了难度。如果你根本不使用这些优点,那么应对这些困难毫无意义。

答案 1 :(得分:0)

你可能会想得太高了。 Make 更喜欢你给它真正的基于文件的依赖项, 它会准确地做出被要求的事情。

因此,举例来说,您可能会想到这样的构建:

  • 构建库
  • 编译应用对象
  • 通过链接app对象和lib来创建可执行文件

Simples。 事实上,这里的障碍是人为的。 没有理由你不能编译其中一个lib对象, 而同时编译其中一个app对象。 或者在创建库时编译一些app对象。

细粒度的依赖关系是你的朋友。

${objects}: %.o: %.c ; Recipe for creating $@ from $<
lib1.a: l1.o l2.o ; Recipe for creating lib out of objects
lib2.a: l3.o l4.o ; Recipe for creating lib out of objects
executable: lib1.a lib2.a o5.o ; Recipe for linking

这里我们将实际文件作为依赖项和目标。 最大并行度,错误检查和剔除工作。 这是一个例子, 但考虑一个更大的系统,其中构建包括运行测试。 当您进行更改时,您只想重新运行一小部分测试。 您还希望在编译其他代码时运行一些测试。

是的,你必须让你的依赖关系正确, 但这就是 make 的重点。 如果你不能这样做,那么是的,每次使用批处理文件并从头开始构建。