Makefile中能否为不同目标设置不同任务数以配合distcc使用?
Makefile分阶段指定并行数解决方案
结论
该需求完全可以实现,以下是两种常用的落地方式:
方案1:递归调用Make(兼容性最优)
核心逻辑是将构建拆分为「代码生成」「编译链接」两个独立阶段,在顶层规则中分别调用两次make,各自指定匹配的并行参数,不受Make版本限制。
示例Makefile如下:
# 定义所有生成的cpp文件列表 GENERATED_SRCS := generated/module_a.cpp generated/module_b.cpp # 编译所需的所有目标文件 OBJS := $(GENERATED_SRCS:.cpp=.o) normal_src.o utils.o # 顶层默认构建目标 all: # 第一阶段:代码生成,指定本地并行数为4,适配本地算力 $(MAKE) -j4 generate_code # 第二阶段:全量编译,指定30并行走分布式编译集群 $(MAKE) -j30 build # 代码生成聚合目标 generate_code: $(GENERATED_SRCS) # 单个代码生成规则示例 generated/%.cpp: code_generator.py python3 $< $@ # 编译聚合目标 build: $(OBJS) $(CXX) $(LDFLAGS) $(OBJS) -o output_binary # 通用cpp编译规则 %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@
方案2:高版本GNU Make目标级并行限制
如果使用GNU Make 4.3及以上版本,可以通过.NOTPARALLEL伪目标单独限制代码生成目标的并行行为,全局保留-j30配置给编译环节,使用更简便。
示例Makefile如下:
# 仅限制generate_code及其依赖不并行,其余目标使用全局-j参数 .NOTPARALLEL: generate_code GENERATED_SRCS := generated/module_a.cpp generated/module_b.cpp OBJS := $(GENERATED_SRCS:.cpp=.o) normal_src.o utils.o all: output_binary # 代码生成聚合目标 generate_code: $(GENERATED_SRCS) generated/%.cpp: code_generator.py python3 $< $@ # 所有编译目标依赖代码生成完成,避免提前编译 $(OBJS): generate_code output_binary: $(OBJS) $(CXX) $(LDFLAGS) $(OBJS) -o $@
使用该方案时直接执行make -j30即可,代码生成阶段不会占满本地资源,编译阶段自动跑满30并行分发到集群。
注意事项
- 必须确保所有编译目标的依赖链包含代码生成目标,避免编译阶段提前启动读取不存在的生成文件
- 低版本Make(4.3以下)不支持
.NOTPARALLEL指定特定目标,优先选择递归调用方案 - 如果代码生成任务本身支持少量并行(比如本地能扛8个并行),递归方案可以直接修改第一阶段的
-j参数为对应数值,灵活度更高
内容的提问来源于stack exchange,提问作者ArAmIuS
相关产品推荐
相关产品推荐

