我正试图编写一个规则,将一组.c文件替换为变量的.o文件。
为了确保它有效,我呼应了他们的价值观。.c文件是通过shell通配符从当前工作目录中获得的
sources := *.c
然而,对于.o文件,没有任何内容被打印出来,因为"源"似乎没有为此进行扩展,无论我是使用patsubst还是handier$(src:%.c=%.o(。
另一方面,如果我设置"手动"的值,一切都会按预期进行,例如
sources := source1.c source2.c source3.c
生成文件:
sources := *.c
srcs = one.c two.c
objects := $(sources:.c=.o)
objs := $(patsubst %.c, %.o, $(srcs))
prints:
@echo sources
@echo $(sources)
@echo objects
@echo $(objects)
@echo $(objs)
输出:
sources
source1.c source2.c source3.c source4.c
objects
*.o
one.o two.o
正如您所看到的,"objects"(基于使用"sources"的通配符(是不可行的,但"objs"(基于管理集"srcs"(可以正常工作。
我错过了什么。我知道这一定与扩张的时间或方式有关。
Make不是shell。此行:
sources := *.c
将生成变量CCD_ 1设置为文字字符串CCD_。然后这行:
objects := $(sources:.c=.o)
将CCD_ 3设置为文字字符串CCD_。
然后这行:
@echo $(sources)
将echo *.c
发送到shell,然后shell将*.c
扩展到与该glob匹配的文件列表中。
然后这行:
@echo $(objects)
将echo *.o
发送到shell,由于没有与*.o
glob匹配的文件,它只打印glob本身*.o
。
如果您想在make中获得文件的列表,您必须使用sources
0函数:
sources := $(wildcard *.c)
此外,当人们试图调试makefile时,您会遇到两个不同的常见错误:
首先,您不应该在配方行中使用@
来隐藏命令。这就像戴着眼罩调试你的makefile。看到make发送到shell的内容会给你提供关于这里发生的事情的绝对重要的信息。即使在我的makefile工作后,我个人也不会使用@
,除了一些琐碎的操作,而且我在调试时绝对不会使用它。
其次,如果你想在食谱中查看make变量的内容,你应该始终在它们周围使用单引号。如果你不加引号或使用双引号,那么shell就会出现并破坏这些值(取决于值是什么(,你将无法看到它们的真实内容。要么在它们周围使用''
,要么使用像$(info ...)
这样的make函数来查看它们的值,而不是像echo
这样的shell程序。
如果你写了这样的测试makefile:
prints:
echo sources
echo '$(sources)'
echo objects
echo '$(objects)'
echo '$(objs)'
问题出在哪里会更为明显。