Makefile中*.c与$(wildcard *.c)的差异疑问及实验验证
Makefile中
*.c与$(wildcard *.c)的差异分析 实验1
CC = gcc src = *.c#$(wildcard *.c) obj = $(src:.c=.o) target = $(src:.c=.exe) $(target) : $(obj) %.exe : $(obj) $(CC) $< -o $@ %.o : $(src) $(CC) -c $< -o $@ clean: rm *.exe *.o
实验2
src = *.c src1 = $(wildcard *.c) p : @echo $(src) p1 : @echo $(src1)
实验结果对比
实验1:差异显著
当src赋值为*.c时,编译报错:
gcc -c test1.c -o *.o Assembler messages: Fatal error: can't create *.o: Invalid argument makefile:25: recipe for target '*.o' failed make: *** [*.o] Error 1
将src改为$(wildcard *.c)后,编译流程正常执行。
实验2:输出无差异
执行make p,输出内容为file1.c file2.c file3.c;
执行make p1,输出内容同样为file1.c file2.c file3.c。
补充说明:测试环境包含3个C文件。
差异本质
$(wildcard *.c)是Make的内置函数,在Make解析Makefile的阶段就会将通配符扩展为当前目录下所有匹配的.c文件名列表,生成的是具体文件名集合。- 直接使用
*.c时,扩展时机取决于所在场景:- 若出现在Shell命令中(如实验2的
echo),会由Shell在执行命令时完成通配符扩展,最终输出具体文件名; - 若出现在Make的变量替换、规则目标或依赖定义中(如实验1的
obj = $(src:.c=.o)),*.c会被当作普通字符串处理。此时obj会被替换为*.o,而gcc无法识别文件名中的通配符,无法创建名为*.o的文件,因此触发报错。
- 若出现在Shell命令中(如实验2的
内容的提问来源于stack exchange,提问作者atlasxi
相关产品推荐
相关产品推荐

