【问题标题】:Parallelization of recursive jobs in GNU makeGNU make 中递归作业的并行化
【发布时间】:2009-11-05 14:46:04
【问题描述】:

我正在寻找一种优雅的方式来在 GNU make 中并行化作业。这是我到目前为止所做的示例。 Make 以串行方式处理目录 dir-1、dir-2 和 dir-3,这是合乎逻辑的,但不是我的意图:

SUBDIRS=dir-1 dir-2 dir-3

default: all

all:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE)); done

.PHONY: clean

clean:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) clean); done

有没有办法支持使用“-j”选项并行处理这些目录而不为每个目录指定特定目标?

【问题讨论】:

    标签: makefile parallel-processing


    【解决方案1】:
    SUBDIRS = a b c
    
    default: all
    
    $(SUBDIRS)::
        $(MAKE) -C $@ $(MAKECMDGOALS)
    
    all clean : $(SUBDIRS)
    

    【讨论】:

    【解决方案2】:

    这可能不会直接回答您的问题,但除了其他答案的建议外,我建议您研究非递归 make 技术。这确实是一种并行构建的优雅方式,尽管取决于现有的 Makefile,可能需要付出很大的努力。非递归 make 的优点不仅限于简单的并行化:它可以看到完整的依赖关系图,因此不需要构建太少或太多,这意味着构建时间更快(有时更快)。

    一些资源:

    【讨论】:

    • 感谢这些资源。我会努力了解 make 的工作原理。其实我不是很熟悉。
    • 设计 url 是 404'ing
    • sites.e-advies.nl/nonrecursive-make.html 可能是更新后的网址
    • 是的 - 看起来它是正确的更新 URL,我已经更新了答案
    【解决方案3】:

    我发现在使用 ::(双冒号规则)时,如果 applibdoc 之间存在任何依赖关系,我找不到强制排序的方法。在阅读了 GNU Make 手册的大部分内容之后,我想出了以下规则来强制执行依赖项,同时拥有一个通用的递归 make。请注意,即使目录已经存在,.PHONY 规则也会强制 make 进入目录。

    SUBDIRS = app lib doc
    
    default: all
    
    app: lib
    
    .PHONY: $(SUBDIRS)
    
    $(SUBDIRS):
        $(MAKE) -C $@ $(MAKECMDGOALS)
    
    all clean install: $(SUBDIRS)
    

    【讨论】:

      【解决方案4】:

      dir-1、dir-2 和 dir-3 是相互依赖还是独立?

      我有类似的结构,但子目录之间存在依赖关系,因此我更喜欢在每个子目录使用并行构建。你可以通过

      ## default to four parallel runs
      MAKEFLAGS += -j 4  
      
      all:
        @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) ); done
      

      但另一个技巧是阅读 make 手册中的 SUBDIRS —— 你不需要 for 循环,因为 make 可以为你展开它。尝试类似

      ## default to four parallel runs
      MAKEFLAGS += -j 4  
      
      SUBDIRS =    dir-1 dir-2 dir-3
      
      $(SUBDIRS):  #whatever your depends here
                   $(MAKE) -C $@
      

      【讨论】:

      • 最好不要在 Makefile 中硬编码'-j 4'。如果用户在命令行上指定了“-j n”,则在使用 $(MAKE) 调用时,它将通过 MAKEFLAGS 传递给子 make。
      • 原则上同意,实际上这是来自一个真正的 Makefile,我懒得总是输入 'make -j 4' 但想要并行构建 - 并且还看到我关于 sub 之间相互依赖的注释-目录。
      • 试试这个 - 设置一个默认值但不会破坏命令行:MAKEFLAGS += -j 4
      • 你知道make如何处理这些$(MAKEFLAGS)吗?我认为在这种情况下,同时作业的数量是处理目录的数量乘以 4,或者类似的东西。因此,我不会将“工作”的论点转发给 child-makes。你怎么看?
      • 这不是我的印象。我修改了一个包含五个 SUBDIRS 的现有项目以使用“MAKEFLAGS += -j 4”,并且我进行了多达四个编译。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-03
      • 2017-05-27
      相关资源
      最近更新 更多