GNU Make组间并行、组内串行执行的实现方案问询
问题:Make并行构建中分组串行与跨组并行的实现
我习惯用make -j进行并行构建,需要实现以下场景:
- 不同目标组(如grp_t0、grp_t1_t2)之间允许并行执行
- 包含多个子目标的组(如grp_t1_t2)内部子目标必须串行执行
此前尝试的方案无效,以下是我的示例Makefile和当前执行结果,期望达到t0与t1并行、t2在t1完成后执行的效果,求可行解决办法。
示例Makefile
== Makefile == t0: echo t0_start `date` sleep 5 echo t0_end `date` t1: echo t1_start `date` sleep 5 echo t1_end `date` t2: echo t2_start `date` sleep 5 echo t2_end `date` # The above were delivered from another team grp_t0 : t0 grp_t1_t2: t1 t2 all: grp_t0 | grp_t1_t2
当前执行结果
== t0_start Sun Apr 7 08:31:59 PDT 2024 t2_start Sun Apr 7 08:31:59 PDT 2024 t1_start Sun Apr 7 08:31:59 PDT 2024 t0_end Sun Apr 7 08:32:04 PDT 2024 t2_end Sun Apr 7 08:32:04 PDT 2024 t1_end Sun Apr 7 08:32:04 PDT 2024
解决方案
修改Makefile的依赖关系,核心是让组内子目标形成串行依赖,同时保证跨组目标可以并行启动:
# 原有目标(来自其他团队) t0: echo t0_start `date` sleep 5 echo t0_end `date` t1: echo t1_start `date` sleep 5 echo t1_end `date` t2: t1 # 新增依赖:t2必须在t1完成后执行 echo t2_start `date` sleep 5 echo t2_end `date` # 分组目标 grp_t0 : t0 grp_t1_t2: t2 # 组目标仅依赖最终子目标,通过t2的依赖保证组内串行 all: grp_t0 grp_t1_t2 # 移除管道符,允许两个组并行执行
原理说明
- 组内串行实现:给
t2添加t1作为依赖,Make会强制等待t1执行完成后才启动t2,确保grp_t1_t2内部串行。 - 跨组并行实现:原
all目标中的管道符(|)是order-only依赖,会让grp_t0执行完才启动grp_t1_t2,不符合并行需求。移除管道符后,grp_t0和grp_t1_t2会被Make同时调度,实现跨组并行。
预期执行效果
执行make -j后,输出会类似:
t0_start Sun Apr 7 08:XX:XX PDT 2024 t1_start Sun Apr 7 08:XX:XX PDT 2024 t0_end Sun Apr 7 08:XX:05 PDT 2024 t1_end Sun Apr 7 08:XX:05 PDT 2024 t2_start Sun Apr 7 08:XX:05 PDT 2024 t2_end Sun Apr 7 08:XX:10 PDT 2024
内容的提问来源于stack exchange,提问作者Kannan Ramaswamy
相关产品推荐
相关产品推荐

