You need to enable JavaScript to run this app. GNU Make能否实现部分目标并行、其余目标串行执行?
优惠活动
大模型
产品
解决方案
定价
更多

GNU Make能否实现部分目标并行、其余目标串行执行?

核心结论

GNU Make 完全支持「部分目标并行执行、其余目标固定串行」的执行模式,不需要完全关闭-j带来的并行编译能力。你提供的两个示例本身存在规则方向颠倒的问题,且没有用到Make针对单类目标的串行控制能力,无法满足需求。

现有示例的问题点
  • 规则依赖方向完全颠倒:无论显式规则还是模式规则,正常编译逻辑是「由源文件生成目标文件」,即依赖关系应该是目标文件(.o)依赖对应的源文件(.c/.s)。你当前写的$(c_sources) : $(c_objs)、%.c : %.o的逻辑,是让Make基于已有的.o文件反向生成.c/.s源文件,完全不符合正常编译流程,哪怕不开并行也无法正确执行编译动作。
  • 没有用到分目标串行的控制机制:之前尝试的全局.NOTPARALLEL写在Makefile顶层时,会让整个Make流程全部串行,和你的需求相反;之前查阅到的顺序编排方案,只是用.ORDER这类目标保证依赖的先后执行顺序,无法阻止多个目标同时并行运行。
正确实现方案

核心思路是利用GNU Make 3.82及以上版本支持的作用域化的.NOTPARALLEL特性:当.NOTPARALLEL作为某一个聚合目标的前置依赖时,Make在构建这个聚合目标的整个依赖子图时,会临时关闭并行执行模式,子图内所有目标严格串行执行;这个子图之外的其他目标不受影响,可以正常利用-j参数并行运行。

很多用户之前尝试这个特性失败,是因为将.NOTPARALLEL直接写在Makefile全局最前端,这种写法会让整个Make构建流程全部关闭并行,完全达不到分目标控制的效果。只有将.NOTPARALLEL作为专门聚合串行组的目标的依赖写入,才能实现作用域隔离。

显式声明源文件规则的正确写法

# 可被并行执行的C编译目标
c_sources := a.c b.c c.c
c_objs := a.o b.o c.o

# 必须串行执行的汇编目标
assembly_sources := d.s e.s f.s
assembly_objs := d.o e.o f.o

# 全局总目标
all: $(c_objs) assembly_phase

# 专门聚合所有汇编目标的阶段目标,通过前置.NOTPARALLEL标记
# 该目标下的所有依赖会强制串行执行
assembly_phase: .NOTPARALLEL $(assembly_objs)

# C文件编译规则:不在串行子图内,可正常并行
$(c_objs): %.o: %.c
	@echo 'Command used to compile .c files.'

# 汇编文件编译规则:被assembly_phase覆盖,强制串行
$(assembly_objs): %.o: %.s
	@echo 'Command used to assemble assembly files (.s files).'

执行时哪怕携带-j8参数:

  • 所有a.o/b.o/c.o的C编译动作,会共享并行槽位同时运行
  • 所有d.o/e.o/f.o的汇编动作,哪怕并行槽位充足,也会严格一个接一个串行执行,不会同时启动多个汇编进程

模式规则实现的正确写法

逻辑和显式规则完全一致,只需要通过变量标识哪些汇编目标属于串行组即可:

# 标记需要串行的汇编目标列表
assembly_objs := d.o e.o f.o
# 可并行的C编译目标
c_objs := a.o b.o c.o

all: $(c_objs) assembly_phase

# 给汇编阶段加作用域化的NOTPARALLEL标记
assembly_phase: .NOTPARALLEL $(assembly_objs)

# C编译模式规则:正常并行
%.o: %.c
	@echo 'Command used to compile .c files.'

# 汇编编译模式规则:被assembly_phase覆盖后强制串行
%.o: %.s
	@echo 'Command used to assemble assembly files (.s files).'
老版本GNU Make的兼容方案

如果使用的Make版本低于3.82,不支持作用域化的.NOTPARALLEL,可以通过递归Make的方式实现等价效果:

  • 把C文件的并行编译放在独立的递归Make调用里,携带-j8参数执行
  • 把汇编部分的编译作为单独的Make调用,不携带-j参数,强制串行
  • 主Makefile只负责编排两个阶段的先后顺序,不需要自己处理并行逻辑

内容的提问来源于stack exchange,提问作者mAshraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 08:36:04