这些Makefile结构意味着什么?

时间:2009-01-29 20:24:38

标签: gcc makefile

有人可以帮我弄清楚下面的make文件吗?

BINS=file1 file2 file3

all: $(BINS)

clean: 
        rm -f $(BINS) *~ 

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

以下是我的问题:

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

5 个答案:

答案 0 :(得分:5)

来自gccmake文档:

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

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

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

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

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

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

答案 1 :(得分:3)

  

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

生成调试信息

  

2。)什么是$ *和$ @

$*是规则的主干。当您制定像

这样的规则时
%.ext: %.otherext
    ext2otherext --input $? --output $@ --logfile $*.log

,规则尝试从file.ext发出file.otherext,然后登录到file.log

$@是目标文件名(在上述情况下为file.ext)。

  

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

这是一个谜。

$*用于中间档案:例如,当您尝试从%.so中制作%.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 $@ $?

答案 2 :(得分:1)

答案 3 :(得分:1)

第一行就是通过查看它所期望的 - 它创建一个名称列表并将其分配给BIN。接下来,定义了一个名为all的make目标,该目标取决于$BIN中列出的目标(all中的每个目标构建之前无法构建$BIN) 。 all是一个特殊的构建目标;如果您只是运行make而不是make clean,则all目标会自动生成。没有与all相关联的实际命令 - 它只是确保构建所有依赖项。最后一个相当简单的命令定义了一个名为clean的构建目标,它删除了$BIN中列出的每个文件(注意$BIN正被用作构建目标列表和文件列表在这个makefile中)和所有备份。

接下来,我们得到一条基本上是魔术的线。 $*是一个特殊的构建目标,意思是“任何未明确定义的东西”。当make尝试构建all时,它会找到目标并开始处理其依赖项。但是当它尝试构建file1时,没有定义明确的目标。相反,它使用$*来构建file1。类似地,$@被替换为构建目标的名称,而$?被其依赖项替换(排序;您最好查看手册)。当make构建file1时,$*规则会使其行为就像定义了以下规则一样:

file1: file1.c
        gcc -g -o file1 file1.c

最后,-g选项只是允许编译调试信息。

答案 4 :(得分:0)

第一季度和第二季度已经得到了广泛的回答,所以仅对Q3进行简要解释:

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