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