You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makefile中仅对指定模式目标使用.NOTPARALLEL?

解决Makefile中特定目标串行、其余目标并行的问题

刚好碰到过类似的场景,要让批量生成的fast_target/%串行构建,同时让slow_target/%这类目标并行跑,其实有两种挺实用的方案,看你环境选就行:

方案一:用文件锁强制串行(类Unix系统首选)

这种方法最简单,利用系统的文件锁机制,让同一时间只有一个fast_target/%的构建命令在执行,其他目标不受影响可以并行。

修改你的Makefile如下:

# 定义锁文件(可以随便取个名字,放在当前目录)
FAST_LOCK := .fast_target_build_lock

slow_target/%: fast_target/%
	python $< # 这里主Make会并行启动多个Python进程,没问题

fast_target/%:
	# 用flock获取锁,只有拿到锁才会执行后面的构建命令
	flock $(FAST_LOCK) bash -c './your_optimized_program $* > $@'
	# 替换上面的./your_optimized_program为你的实际多核程序命令

# 清理时顺便删掉锁文件
.PHONY: clean
clean:
	rm -rf fast_target/ slow_target/ $(FAST_LOCK)

原理说明:

flock会给指定的锁文件加排他锁,只有当前命令执行完释放锁后,下一个fast_target/%的构建才能获取锁开始执行,完美实现所有fast_target/%串行。而slow_target/%的构建因为不需要抢锁,主Make可以并行启动多个Python脚本,完全符合你的需求。

方案二:递归Make实现串行(跨平台通用)

如果你的环境不支持flock(比如Windows),可以用Make的递归调用特性,把fast_target/%的构建放到子Make进程中,并强制子Make串行执行,主Make保持并行能力。

修改后的Makefile示例:

# 全局目标:先构建所有fast_target(串行),再并行构建slow_target
.PHONY: all fast_targets slow_targets
all: slow_targets

# 调用子Make构建fast_targets,强制串行
fast_targets:
	$(MAKE) -f $(MAKEFILE_LIST) build_fast_targets .NOTPARALLEL

# 实际的fast_target构建规则,这里可以用变量或通配符生成目标列表
build_fast_targets: $(wildcard fast_target/*) # 或者用$(FAST_TARGETS)变量定义所有目标

fast_target/%:
	# 这里写你的多核程序执行命令
	./your_optimized_program $* > $@

# 并行构建slow_targets,依赖已串行构建完成的fast_targets
slow_targets: fast_targets
	$(MAKE) -j $(shell nproc) build_slow_targets

# 生成所有slow_target的目标列表
build_slow_targets: $(patsubst fast_target/%,slow_target/%,$(wildcard fast_target/*))

slow_target/%: fast_target/%
	python $<

原理说明:

  1. 主Make先启动一个子Make进程,子Make通过.NOTPARALLEL特殊目标强制所有fast_target/%串行构建;
  2. 等所有fast_target都构建完成后,主Make再启动另一个子Make(或者直接并行构建),用-j $(shell nproc)充分利用CPU核心,并行执行所有Python脚本。

这个方案完全基于Make的原生特性,跨平台兼容性更好,适合需要在不同系统上运行的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:42:56