Makefile自动变量


原文链接: Makefile自动变量

.c.o : It's an old-fashioned suffix rule. The more up-to-date way to do it is to use a pattern rule: =>
%.o : %.c

3.7 自动变量(Automatic Variables)

Make命令还提供一些自动变量,它们的值与当前规则有关。主要有以下几个。

(1)$@

$@ 指代当前目标,就是Make命令当前构建的那个目标。比如,make foo的 $@ 就指代foo。

a.txt b.txt: 
    touch $@

等同于下面的写法。

a.txt:
    touch a.txt
b.txt:
    touch b.txt

(2)$<

$< 指代第一个前置条件。比如,规则为 t: p1 p2,那么$< 就指代p1。

a.txt: b.txt c.txt
    cp $< $@

等同于下面的写法。

a.txt: b.txt c.txt
    cp b.txt a.txt

(3)$?

$? 指代比目标更新的所有前置条件,之间以空格分隔。比如,规则为 t: p1 p2,其中 p2 的时间戳比 t 新,$?就指代p2。

(4)$^

$^ 指代所有前置条件,之间以空格分隔。比如,规则为 t: p1 p2,那么 $^ 就指代 p1 p2 。

(5)$*

$* 指代匹配符 % 匹配的部分, 比如% 匹配 f1.txt 中的f1 ,$* 就表示 f1。

(6)$(@D) 和 $(@F)

$(@D) 和 $(@F) 分别指向 $@ 的目录名和文件名。比如,$@是 src/input.c,那么$(@D) 的值为 src ,$(@F) 的值为 input.c。

(7)$(<D) 和 $(<F)

$(<D) 和 $(<F) 分别指向 $< 的目录名和文件名。

所有的自动变量清单,请看手册。下面是自动变量的一个例子。

dest/%.txt: src/%.txt
    @[ -d dest ] || mkdir dest
    cp $< $@

上面代码将 src 目录下的 txt 文件,拷贝到 dest 目录下。首先判断 dest 目录是否存在,如果不存在就新建,然后,$< 指代前置文件(src/%.txt), $@ 指代目标文件(dest/%.txt)。

在Makefile中也#开始的行都是注释行.Makefile中最重要的是描述文件的依赖关系的说明。一般的格式是:

target:components

TAB rule

第一行表示的是依赖关系。第二行是规则。

比如说我们上面的那个Makefile文件的第二行。

main:main.o mytool1.o mytool2.o

表示我们的目标(target)main的依赖对象(components)是main.o mytool1.omytool2.o 当倚赖的对象在目标修改后修改的话,就要去执行规则一行所指定的命令。就象我们的上面那个Makefile第三行所说的一样要执行 gcc-o main main.o mytool1.o mytool2.o 注意规则一行中的TAB表示那里是一个TAB键

Makefile有三个非常有用的变量。分别是$@,$^,$<代表的意义分别是:

$@ --目标文件,$^--所有的依赖文件,$< --第一个依赖文件。

如果我们使用上面三个变量,那么我们可以简化我们的Makefile文件为:

这是简化后的Makefile

main:main.o mytool1.o mytool2.o

gcc -o $@ $^

main.o:main.c mytool1.h mytool2.h

gcc -c $<

mytool1.o:mytool1.c mytool1.h

gcc -c $<

mytool2.o:mytool2.c mytool2.h

gcc -c $<

经过简化后,我们的Makefile是简单了一点,不过人们有时候还想简单一点。这里我们学习一个 Makefile的缺省规则

.c.o:

gcc -c $<

这个规则表示所有的 .o文件都是依赖与相应的.c文件的。例如mytool.o依赖于mytool.c这样Makefile还可以变为:

这是再一次简化后的Makefile

main:main.o mytool1.o mytool2.o

gcc -o $@ $^

.c.o:

gcc -c $<

.c.o:

$(CC) $(CFLAGS) -c $< $(INCS) -o $@

%.o : %.c

$(CC) $(CFLAGS) -c $< -o $@

好了,我们的Makefile 也差不多了,如果想知道更多的关于Makefile的规则,可以查看相应的文档
————————————————
版权声明:本文为CSDN博主「dongzhongshu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dongzhongshu/article/details/5628459

这个静态模式就是一种自动编译模式,在这种模式下,我们可以容易的定义“多目标”规则,让我们的规则变得更加有弹性和灵活。它的语法如下:

< targets ....> : < target-pattern > : < prereq-patterns ...>

<commands>
.....

其中:

targets定义了一些列的目标文件,也就是多目标,可以有通配符,是目标的一个集合。

 target-pattern 是targets的模式,也就是目标集模式

prereq-patterns 则是目标的“依赖”元素,

这么去说,可能还是比较拗口,不容易理解,我们还是把理论落地,举例一下吧:

 我们把target-pattern 定义成  %.o  意思是我们的target集合都是以.o结尾。当然这里也可以使用通配符*,只不过%多用于Makefile,他们两个的区别,我们后面再讲。而我们的prereq-patterns则定义为%.c,这意思就是对 target-pattern中所形成的目标集进行二次定义,其计算方法是取target-pattern模式中的%代表部分(其实就是去掉.o后的文件名),并为其加上[.c]结尾,形成新的集合。代码如下:

$(OBJS) : %.o : %.c

gcc -c $< -o $@

   这两条命令的功能就是,大目标是OBJS,这个OBJS就是各种.o文件,然后%.o就是具体的解释,而%.c就是对应同样名字的.c文件,而下面的命令,结合了2个自动化变量,$< 表示依赖对象集中的第一个,$@ 则代表了目标集。所以这个功能就是要遍历所有的.c文件,对所有的.c文件进行编译,然后编译生成对应的.o文件。我们在实际编写程序时,targets是不需要的,可以简写如下:

%.o : %.c

gcc -c $< -o $@

 
————————————————
版权声明:本文为CSDN博主「猪哥-嵌入式」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012351051/article/details/88600562

`