Makefile通配符目标异常:执行make *.exe提示‘Nothing to be done’
解决Makefile中
make xxx.exe提示"Nothing to be done"的问题 问题分析
你遇到的问题有两个核心原因:
.PHONY未覆盖动态的.exe目标:你的ALL_EXES是通过ls *.exe获取当前已有的.exe文件,但当你执行make some-program.exe时,这个文件并不存在,所以它不会被加入到.PHONY列表中。Make会默认把它当作一个普通文件目标,检查依赖some-program是否比目标新——但因为目标文件不存在,理论上应该执行规则,不过第二个问题导致了异常。- 规则命令错误使用
$(shell):在Make规则的命令行中,$(shell ...)是在Make解析规则时就执行的,而不是在执行目标时。这不仅会导致命令提前执行(甚至可能出错),还会让Make误以为目标已经被处理,最终出现"Nothing to be done"的提示。另外,你命令中试图运行$@(即some-program.exe),但实际生成的可执行文件是some-program,这里路径也错了。
修正后的Makefile
ALL_EXES=$(shell ls *.exe 2>/dev/null) .PHONY: all clean $(ALL_EXES) foo %.exe # 新增%.exe到PHONY,标记所有.exe模式目标为伪目标 CC=gcc CFLAGS=-g -Wall GTKFLAGS=$(shell pkg-config --cflags gtk+-3.0) GTKLIBS=$(shell pkg-config --libs gtk+-3.0) PWD=$(shell pwd) clean: @echo cleaning rm -f *.exe 2>/dev/null # 简化clean命令,无需嵌套shell %: %.c $(CC) $(GTKFLAGS) -o $@ $< $(GTKLIBS) $(CFLAGS) %.exe: % @echo running $< # 改为指向实际可执行文件$< $(PWD)/$< # 直接执行命令,移除多余的$(shell)
关键修改说明
- 标记
%.exe为伪目标:将%.exe加入.PHONY列表后,Make会将所有以.exe结尾的目标视为伪目标,不会检查对应文件是否存在,每次执行都会触发规则命令。 - 移除
$(shell)嵌套:Make规则的命令本身就是在shell环境中执行的,嵌套$(shell)会导致命令在Make解析阶段提前运行,破坏预期的执行逻辑。 - 修正程序运行路径:用
$<(规则的第一个依赖,即编译生成的some-program)代替$@(目标some-program.exe),确保运行的是正确的可执行文件。 - 简化clean命令:直接使用
rm -f命令删除文件,无需通过sh -c嵌套,更简洁高效。
现在执行make some-program.exe时,Make会先确保some-program已编译(若未编译则自动触发编译规则),然后正常运行程序,不会再出现"Nothing to be done"的提示。
内容的提问来源于stack exchange,提问作者Donghua Liu
相关产品推荐
相关产品推荐

