有人可以帮我找出以下make文件吗?
BINS=file1 file2 file3
all: $(BINS)
clean:
rm -f $(BINS) *~
$*: $@.c
gcc -g -o $@ $?
以下是我的问题:
- gcc的-g选项是什么?
- 什么是 $* 和 $@
- 它怎么知道执行最后一个目标?
谢谢!
从gcc
和make
文档:
“-g 以操作系统的本机格式生成调试信息”。
一种。"$* 与隐式规则匹配的词干(请参阅模式匹配方式)。如果目标是 dir/a.foo.b 并且目标模式是 a.%.b,那么词干就是 dir/foo。词干是用于构造相关文件的名称。在静态模式规则中,词干是与目标模式中的 '%' 匹配的文件名的一部分。
湾。"$@ 规则目标的文件名。如果目标是归档成员,则 '$@' 是归档文件的名称。在具有多个目标的模式规则中(请参阅模式规则简介), '$@' 是导致规则命令运行的目标的名称。”
C。“$?所有比目标新的先决条件的名称,它们之间有空格。” (没有问,但值得添加。)
"'all' 编译整个程序。这应该是默认目标。"
这个示例 makefile 有点受限,因为它似乎只构建 C 程序。GNU make有几个更广泛的示例,可用于学习如何编写 makefile。
1.) gcc 的 -g 选项是什么?
生成调试信息
2.) 什么是 $* 和 $@
$*
是规则的主干。当你制定规则时
%.ext: %.otherext
ext2otherext --input $? --output $@ --logfile $*.log
, 并且规则尝试file.ext
从file.otherext
, 然后到 log 去file.log
$@
是目标文件名(file.ext
在上面的例子中)。
3.) 它如何知道执行最后一个目标?
这是一个谜。
$*
用于中间文件:例如,当您尝试制作%.so
out of 时%.c
,您需要一个%.o
既不是目标也不是源的中间人。你把:
%.so: %.c
gcc -fPIC -g -c -o $*.o $?
ld -shared -o $@ $*.o
换句话说,在%.extension
规则中,$*
除了.extension
.
作为一个目标,$*
没有任何意义。
你确定这条规则实际上是在某处执行的吗?当我尝试使用您的 Makefile 复制它时,它会应用默认规则 ( cc -o
) 而不是gcc -g -o
您需要的规则似乎是:
%: %.c
gcc -g -o $@ $?
第一行正如你所期望的那样——它创建了一个名称列表并将其分配给BIN
. 接下来,定义了一个名为 make 的目标all
,它依赖于列出的目标$BIN
(all
只有在构建每个目标之后才能$BIN
构建)。 all
是一个特殊的构建目标;如果你只是运行make
而不是,例如,make clean
目标all
是自动构建的。没有相关的实际命令all
——它只是确保构建其所有依赖项。最后一个相当简单的命令定义了一个名为 的构建目标clean
,它删除列出的每个文件$BIN
(注意,$BIN
它同时用作构建目标列表和此 makefile 中的文件列表)和所有备份。
接下来,我们到达一条基本上是魔法的线。 $*
是一个特殊的构建目标,意思是“任何没有明确定义的东西”。当make
尝试构建all
时,它会找到目标并开始处理其依赖项。但是当它尝试构建时file1
,没有明确定义目标。相反,它用于$*
构建file1
. 同样,$@
被构建目标的名称和$?
它的依赖项替换(有点;你最好检查手册)。然后,当make
转到 buildfile1
时,该$*
规则使其表现得好像定义了以下规则:
file1: file1.c
gcc -g -o file1 file1.c
最后,该-g
选项仅允许编译调试信息。
Q1 和 Q2 已经得到了广泛的回答,因此仅对 Q3 进行简要说明:
除非您指定了不同的目标,否则 Make 始终执行第一个目标。这也称为默认目标。通常默认目标称为“全部”。