4

有人可以帮我找出以下make文件吗?

BINS=file1 file2 file3

all: $(BINS)

clean: 
        rm -f $(BINS) *~ 

$*: $@.c
        gcc -g -o $@ $?

以下是我的问题:

  1. gcc的-g选项是什么?
  2. 什么是 $* 和 $@
  3. 它怎么知道执行最后一个目标?

谢谢!

4

5 回答 5

5

gccmake文档:

  1. “-g 以操作系统的本机格式生成调试信息”。

  2. 一种。"$* 与隐式规则匹配的词干(请参阅模式匹配方式)。如果目标是 dir/a.foo.b 并且目标模式是 a.%.b,那么词干就是 dir/foo。词干是用于构造相关文件的名称。在静态模式规则中,词干是与目标模式中的 '%' 匹配的文件名的一部分。

    湾。"$@ 规则目标的文件名。如果目标是归档成员,则 '$@' 是归档文件的名称。在具有多个目标的模式规则中(请参阅模式规则简介), '$@' 是导致规则命令运行的目标的名称。”

    C。“$?所有比目标新的先决条件的名称,它们之间有空格。” (没有问,但值得添加。)

  3. "'all' 编译整个程序。这应该是默认目标。"

这个示例 makefile 有点受限,因为它似乎只构建 C 程序。GNU make有几个更广泛的示例,可用于学习如何编写 makefile。

于 2009-01-29T20:36:07.420 回答
3

1.) gcc 的 -g 选项是什么?

生成调试信息

2.) 什么是 $* 和 $@

$*是规则的主干。当你制定规则时

%.ext: %.otherext
    ext2otherext --input $? --output $@ --logfile $*.log

, 并且规则尝试file.extfile.otherext, 然后到 log 去file.log

$@是目标文件名(file.ext在上面的例子中)。

3.) 它如何知道执行最后一个目标?

这是一个谜。

$*用于中间文件:例如,当您尝试制作%.soout 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 $@ $?
于 2009-01-29T20:39:02.780 回答
1

GNU Make 手册

GCC 在线文档

于 2009-01-29T20:28:40.837 回答
1

第一行正如你所期望的那样——它创建了一个名称列表并将其分配给BIN. 接下来,定义了一个名为 make 的目标all,它依赖于列出的目标$BINall只有在构建每个目标之后才能$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选项仅允许编译调试信息。

于 2009-01-29T20:41:20.513 回答
0

Q1 和 Q2 已经得到了广泛的回答,因此仅对 Q3 进行简要说明:

除非您指定了不同的目标,否则 Make 始终执行第一个目标。这也称为默认目标。通常默认目标称为“全部”。

于 2009-01-29T20:40:50.297 回答