Makefile仅执行第一个前置条件,后续任务停滞求助
问题:Make处理第一个文件后重复执行同一任务,未处理后续文件
运行make命令时,程序仅处理第一个.m4a文件,之后重复执行该文件的处理命令,未推进到后续文件。检查确认$(OBJ)变量已包含所有目标.txt文件,但无法定位问题根源。
相关Makefile代码
.SUFFIXES : .txt .m4a SOURCES := $(wildcard *.m4a) OBJ := $(subst m4a,txt,$(SOURCES)) WS = whisper WG = wordgrinder FLAGS = --device cuda:1 --model small .PHONY: test clean imported all : $(OBJ) $(OBJ): $(SOURCES) @echo $(WS) $(FLAGS) ./$< @echo $(WG) --convert $(subst m4a,txt, $< ) $(subst m4a,wg, $< ) clean : rm *~ *.json *.srt *.tsv *.vtt imported: mv odt/*.odt odt/imported/ test: $(SOURCES) @echo $(OBJ) @echo PREREQUISITES: $^
命令输出
make执行结果
make whisper --device cuda:1 --model small ./Nigel_00001.m4a wordgrinder --convert Nigel_00001.txt Nigel_00001.wg whisper --device cuda:1 --model small ./Nigel_00001.m4a wordgrinder --convert Nigel_00001.txt Nigel_00001.wg
make test执行结果
make test Nigel_00001.txt Olivier_00001.txt PREREQUISITES: Nigel_00001.m4a Olivier_00001.m4a
问题原因
核心问题出在规则$(OBJ): $(SOURCES)的定义:
- 该规则表示所有.txt目标文件都依赖于全部.m4a源文件,而非一对一绑定
- 规则中的
$<代表第一个依赖文件,因此无论构建哪个.txt目标,都会仅调用第一个.m4a文件(Nigel_00001.m4a)执行命令 - 当前命令仅用
echo打印操作,未实际生成目标.txt文件,Make会判定目标始终未完成,陷入重复执行同一任务的循环
解决方案
需要将目标与源文件一对一绑定,同时确保实际生成目标文件,让Make能正确判断任务状态:
推荐方案:使用模式规则
替换原有的$(OBJ): $(SOURCES)规则为:
%.txt: %.m4a $(WS) $(FLAGS) ./$< $(WG) --convert $@ $(subst m4a,wg, $< )
%.txt: %.m4a:定义任意.txt目标依赖同名的.m4a源文件,实现一对一绑定$<:指代当前目标对应的.m4a源文件$@:指代当前要构建的.txt目标文件- 去掉
@echo,直接执行实际命令,确保生成目标文件,避免Make重复执行
备选方案:静态模式规则
如果需要明确绑定OBJ列表中的目标,可使用静态模式:
$(OBJ): %.txt: %.m4a $(WS) $(FLAGS) ./$< $(WG) --convert $@ $(subst m4a,wg, $< )
内容的提问来源于stack exchange,提问作者Rick Dearman
相关产品推荐
相关产品推荐

