Linux make/Makefile详解

会不会写makefile,从侧面说明了一个人是否具备完成大型工程的能力。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的 规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂 的功能操作。(虽然目前还没有接触过大型项目,但其实这段话是可以理解的。)

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编 译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命 令

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。


好了好了,不CV了


 起初存在这些文件,下面的makefile的作用是自动化构建项目。 main.c test.c test.h 构建出test可执行程序。  yzl.c 构建出yzl可执行程序

  1 test: test.o main.o
  2     gcc test.o main.o -o test
  3 yzl: yzl.o
  4     gcc yzl.o -o yzl
  5 test.o: test.c
  6     gcc -c test.c -o test.o
  7 main.o: main.s
  8     gcc -c main.s -o main.o
  9 main.s: main.i
 10     gcc -S main.i -o main.s
 11 main.i: main.c
 12     gcc -E main.c -o main.i
 13 yzl.o: yzl.c
 14     gcc -c yzl.c -o yzl.o
 15                                                                                                                                                                                                              
 16 .PHONY: clean
 17 clean:
 18     rm -f main.i main.s main.o test.o test
 19 
 20 .PHONY: ll
 21 ll:
 22     ls
 23 
 24 .PHONY: cleanyzl
 25 cleanyzl:
 26     rm -f yzl yzl.o

依赖关系,依赖方法

编写makefile。两个核心是依赖关系和依赖方法

依赖关系:为了生成某个目标文件,此目标文件依赖于其他文件。比如上图makefile中的生成test依赖于test.o main.o 而test.o又依赖于test.c  依赖方法:生成test目标可执行文件,依赖关系是依赖于test.o 和main.o 而依赖方法就是下面的命令行,表示执行此命令(方法)之后即可生成目标文件。

在makefile中,依赖关系是层层依赖的,比如test依赖于test.o main.o ,如下test.o 依赖于test.c main.o依赖于main.s main.s 依赖于main.i   make处理makefile时,默认进行第一个依赖关系和依赖方法。 也就是只有main.o 和 test.o不存在时,才会往下查找是否有某个依赖关系的目标文件是main.o 和 test.o 。所以编写makefile时,一定要从后往前,以程序形成的逆序来编写makefile。
所以,第二个依赖关系yzl : yzl.o  不主动执行的情况下,是无法自动自动进行的,因为第一个依赖关系中不依赖于yzl文件。所以,如果想生成yzl,比如主动执行make :  make yzl

我们现在知道了make指令默认从makefile的第一个依赖关系开始,而重复进行make时,

make失效时,依据的是什么。

就会出现如上情况,make: 'test' is up to date  意思是此时的目标文件test已经是最新的了,再次构建项目是没有意义的,那么,make是如何知道此时test是最新的呢?其实是依据目标文件test和其依赖的文件的修改时间,来判断是否需要进行此次make。 当所有的依赖文件的修改时间都比test的时间早时,表示test目标文件是最新的,也就没有必要进行make操作。一旦修改其中任何一个依赖文件,下一次的make就会生效。

make clean

工程是需要被清理的,我们可以设定一个clean,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行, 不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

但是一般clean这种的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被 执行的。

总是被执行:每次make clean时,不会按照文件的修改时间来判断此时make clean是否执行,而是每次make clean都生效,这就是总是被执行。

再比如上方的yzl目标文件,因为它不是第一个依赖关系依赖的文件,所以它不会自动执行,我们可以make yzl 而执行这个依赖关系。 make cleanyzl即执行清理yzl相关文件的工作。

.PHONY

1. 如上的clean声明为.PHONY 除了让其总是被执行,还有一个原因是.PHONY是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突。也就是如果工作目录下存在clean文件,那么make就会不执行此依赖关系。而.PHONY声明clean后可以理解为clean并不是一个目标文件,只是一个操作。

2. 目标确实是一个文件,但是目标文件的构建很复杂,其构建是通过其他方式完成的,在当前makefile中没有包含其完整的依赖关系和构建方式。默认方式下makefile检查依赖后可能不执行目标的构建命令。这时使用.PHONY表示目标不是当前makefile直接构建的,不要通过检查依赖来决定是否执行命令,必须执行其构建命令来完成构建。

需要注意的是虽然.PHONY目标不通过依赖来决定目标是否要执行命令,但是还是会检查依赖的,依赖的文件不存在时仍然会尝试构建或报错。

总结一下:.PHONY目标一定会执行构建命令。一般用于目标非实体文件,或目标文件不受makefile管理、依赖关系不完整的情况。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值