【问题标题】:build multiple targets in make command line在 make 命令行中构建多个目标
【发布时间】:2020-05-26 02:17:16
【问题描述】:

假设我有一个 make 文件,并且我有很多目标 MyTarget1,MyTarget2,MyTarget3,...,MyTarget100

如果我想使用 12 线程编译所有目标,我可以简单地使用 make -j12 all

现在我想编译所有目标的子集,假设 MyTarget1, MyTarget2, MyTarget3, MyTarget4

我知道必须逐个编译每个目标。这样,12个线程在MyTarget1上工作,等待,在MyTarget2上工作,等待,...如果MyTarget的并行度不高,比如是helloworld这样的小目标,一些线程的时间是浪费了。我不喜欢它的低平行度。

我想要一个高并行度的解决方案,比如make -j12 all,12个线程可以同时在不同的目标上工作。

我该如何实现?

我想要类似的东西

make -j12 MyTarget1,MyTarget2,MyTarget3,MyTarget4

参考

follow link已经给出了CMake的解决方案,现在我想知道它是否可以直接使用make来实现。

感谢您的宝贵时间。

【问题讨论】:

  • make -j12 MyTarget1 MyTarget2 MyTarget3 MyTarget4 不符合您的需求?
  • @ymonad 在您的建议中,make do 遵循:使用 12 线程编译 MyTarget1,等待它完成。然后使用 12 线程编译 MyTarget2,等待,... 这样,12 线程在某个时刻在同一个目标上工作。它就像一个一个的解决方案。它没有make -j12 all 那样的高并行性。在make -j12 all 中,12 个线程可以在某个时刻作用于不同的目标。
  • 我认为@ymonad 是正确的。我做了一个简单的实验来证实它(至少使用 GNU Make 3.81)。
  • 我相信这是一个 CMake 限制。当我使用 CMake 时,其中一些生成的 Makefile 确实包含显式的 .NOPARALLEL 选项。
  • 我真的不这么认为。 CMake 生成的 Makefile 非常复杂,据我所知,Makefile 将调用CMakeFiles/Makefile2。您可能幸运地直接调用此Makefile2,但最好定义自定义目标来调用其他目标的预定义子集(如果它可以预定义而不是完全随机的)。

标签: makefile


【解决方案1】:

这是CMake 的限制。生成的Makefile 被明确列出为不并行运行。例如:

$ cat CMakeLists.txt
project(foo C)

add_custom_target(target1 ALL
  COMMAND python3 -c "import time; time.sleep(5)"
  VERBATIM
  )

add_custom_target(target2 ALL
  COMMAND python3 -c "import time; time.sleep(5)"
  VERBATIM
  )

生成的Makefile 的相关部分是:

$ cat Makefile
...
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:
...
# The main all target
all: cmake_check_build_system
        $(CMAKE_COMMAND) -E cmake_progress_start /home/raspy/so-62013595/CMakeFiles /home/raspy/so-62013595/CMakeFiles/progress.marks
        $(MAKE) -f CMakeFiles/Makefile2 all
        $(CMAKE_COMMAND) -E cmake_progress_start /home/raspy/so-62013595/CMakeFiles 0
.PHONY : all
...
# Build rule for target.
target2: cmake_check_build_system
        $(MAKE) -f CMakeFiles/Makefile2 target2
.PHONY : target2
...
# Build rule for target.
target1: cmake_check_build_system
        $(MAKE) -f CMakeFiles/Makefile2 target1
.PHONY : target1

所以你可以看到每个目标都传播到一个子makefile,但是由于这个顶部Makefile 被列为不并行,它不允许同时构建多个目标。

$ make -j8 target1 target2 | ts
May 26 15:45:06 Built target target1
May 26 15:45:13 Built target target2    # <--- Built after target1 completed

对于任意目标,直接调用 sub-makefile 可能会成功:

$ make -j8 -f CMakeFiles/Makefile2 target1 target2 | ts
May 26 15:45:42 Built target target2
May 26 15:45:42 Built target target1    # <--- Built simultaneously with target2

YMMV。

【讨论】:

  • AFAICT the issue 导致当前实现也是为什么直接调用 Sub-Makefile 对我不起作用(在构建目标的公共依赖项时竞争)。如果可以,请使用忍者生成器。使用 CMake 生成的 ninja 项目,多个目标的并行构建对我来说完美无缺。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 2021-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多