在makefile脚本中:*.c和$(通配符*.c)是不同的?我对我的实验感到困惑

问题描述 投票:0回答:2

实验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中,

*.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文件用于测试。

makefile gnu-make
2个回答
1
投票

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 $@

他们说“每个单独的目标文件都依赖于所有源文件”,这不是你想要的。


0
投票

您已告诉 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
以及其他功能。

© www.soinside.com 2019 - 2024. All rights reserved.