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
src = *.c
src1 = $(wildcard *.c)
p :
@echo $(src)
p1 :
@echo $(src1)
在实验1中,
*.c
和$(wildcard *.c)
有很大的区别。
如果 src
(变量)= *.c
,gcc 会给我一个错误,如下所示:
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
如果我将
*.c
替换为 $(wildcard *.c)
,一切都会顺利。
在实验2中,
*.c
和$(wildcard *.c)
的结果没有差异。
if @echo $(src)
echo file1.c file2.c file3.c
if @echo $(src1)
echo file1.c file2.c file3.c
补充:有3个c文件用于测试。
wildcard
函数在展开时由make
求值。
对于 make 来说,字符串
*.c
只是一个字符串。所以这一行:
obj = $(src:.c=.o)
如果
src
是 $(wildcard *.c)
,则 make 首先将 src
扩展为 foo.c bar.c baz.c
,然后用 .c
替换 .o
,得到 foo.o bar.o baz.o
。
如果
src
是 *.c
,那么 make 会扩展 src
,但它只是简单的字符串 *.c
,所以不需要扩展,然后用 .c
替换 .o
,得到 *.o
。
这条规则也是错误的:
%.o : $(src)
$(CC) -c $< -o $@
他们说“每个单独的目标文件都依赖于所有源文件”,这不是你想要的。
您已告诉 Make,任何以
.exe
结尾的文件都取决于 $(obj)
。如果 src = *.c
,则 obj = *.o
所以 Make 会尝试编译它。
任何以
.o
结尾的文件都取决于 $(src)
,即 *.c
,因此尝试编译 *.c
并生成一个名为 *.o
的文件 - 这就是它回显的命令:
gcc -c *.c -o *.o
由于某种原因(可能是非常有限的文件系统类型),GCC 无法写入
*.o
文件。
当您在 Make 中使用
$(wildcard)
函数时,它会扩展到多个标记。
顺便说一句,你可能是说
%.o: %.c
但是您应该避免编写与内置规则重复(严重)的规则。只要相信 Make 就知道如何使用
CC
、CFLAGS
以及其他功能。