makefile小结

makefile心得

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

 

target:components 

 

TAB rule 

 

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

 

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

 

main:main.o mytool1.omytool2.o 

 

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

 

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

 

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

 

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

 

# 这是简化后的Makefile 

 

main:main.o mytool1.omytool2.o 

 

gcc -o $@ $^ 

 

main.o:main.c mytool1.hmytool2.h 

 

gcc -c $< 

 

mytool1.o:mytool1.cmytool1.h 

 

gcc -c $< 

 

mytool2.o:mytool2.cmytool2.h 

 

gcc -c $< 

 

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

 

.c.o: 

 

gcc -c $< 

 

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

 

# 这是再一次简化后的Makefile 

 

main:main.o mytool1.omytool2.o 

 

gcc -o $@ $^ 

 

.c.o: 

 

gcc -c$< 

1)makefile路径

在编写大型项目的时候,有时候文件分布在不同的文件夹下,这时需要在makefile文件中对各个文件的路径进行设置。

同时,路径也有两种,一种是针对Makefile来说在执行make命令的时候,要寻找目标文件和依赖文件的路径

 

另一个就是源文件所要包含的头文件等相关文件的路径。

 

对于第一种来说,Makefile提供了两种方式,一种是设置全局访问路径VAPTH:即在执行make命令时可以从该路径中查询目标和依赖make可识别一个特殊变量“VPATH”。通过变量“VPATH”可以指定依赖文件的搜索路径,在规则的依赖文件在当前目录不存在时,make会在此变量所指定的目录下去寻找这些依赖文件。

一般我们都是用此变量来说明规则中的依赖文件的搜索路径。首先说明一下makefile的执行步骤:

 

1、读入所有的Makefile。

2、读入被include的其它Makefile。

3、初始化文件中的变量。

4、推导隐晦规则,并分析所有规则。

5、为所有的目标文件创建依赖关系链。

6、根据依赖关系,决定哪些目标要重新生成。

7、执行生成命令

 

Makefile中所有文件的搜索路径,包括依赖文件和目标文件。

变量“VPATH”的定义中,使用空格或者冒号(:)将多个目录分开。make搜索的目录顺序按照变量“VPATH”定义中顺序进行(当前目录永远是第一搜索目录)。

 

例如:

 

VPATH= src:../headers

 

它指定了两个搜索目录,“src”和“../headers”。对于规则“foo:foo.c”如果“foo.c”在“src”

目录下,此时此规则等价于“foo:src:/foo.c”

 

对于第二种来说:当需要为不类型的文件指定

不同的搜索目录时需要这种方式

 

vpath:关键字

 

它所实现的功能和上一小节提到的“VPATH”变量很类似,但是

它更为灵活。它可以为不同类型的文件(由文件名区分)指定不同的搜索目录。它的使用方法有三

 

1、vpath PATTERN DIRECTORIES

为符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES”。多个目录使用空格或者

冒号(:)分开。类似上一小节的“VPATH”

2、vpath PATTERN

清除之前为符合模式“PATTERN”的文件设置的搜索路径

 

3、vpath

 

清除所有已被设置的文件搜索路径。

 

对于vpath的详细说明待续。

 

在执行make命令的时候,根据makefile执行步骤,首先读入所有的makefile文件,那么

 

VPATH = include:src       //指定了makefile的搜索路径

 

或者

 

vpath %.h include    //指定.h类型文件的搜索路径是include

 

vpath %.cpp src      //指定.cpp类型文件的搜索路径是src

 

这仅仅是对于makefile来说搜索目标和依赖文件的路径,但是对于命令行来说是无效的,也就是说

 

在执行g++或者gcc时不会自动从VPATH或者vpath中自动搜索要包含的头文件等信息文件

 

此时要用到了 -I 或者--incude +路径

 

例如依赖是:

 

main.o:main.cpphello.h

 

g++ -c  $< -Iinclude,这时候,g++会自动从include目录中搜索要包含的hello.h头文件

2makefile变量定义

VARIABLE = value //递归赋值,赋值后并不马上生效,等到用时才真正的赋值

 VARIABLE ?=value//如果变量没有赋值就对其赋值

 VARIABLE := value//直接赋值,一赋值马上有效

 VARIABLE += value//在变量后追加字符

3自动化变量

模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这

一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去

意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。

假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写

正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时

源文件名都是不一样的。为了解决这个问题,就需要使用“自动变量”,自动化变量

的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。

下面对所有的自动化变量进行说明:

$@

表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为

文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式

规则中,它代表的是哪个触发规则被执行的目标文件名。

$%

当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则

的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@”的值为“foo.a”。

如果目标不是静态库文件,其值为空。

$<

规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表

由隐含规则加入的第一个依赖文件。

$?

所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代

表的是库成员(.o 文件)。

$^

规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的

只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量

“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。

$+

类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库

的交叉引用场合。

$*

在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的

部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考  10.5.4

模式的匹配 一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,

“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值