赞
踩
目录
Linux中自动化构建项目最简单的方式:make/Makefile
make:是一个命令
Makefile:是一个在当前目录下存在的一个具有特定格式的文本文件。
(Makefile首字母可以小写,但建议使用大写)Makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取Makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。
touch Makefile
vim Makefile
make
make clean
Makefile 中包括依赖关系(目标、依赖)和依赖方法(命令)。
下面是 Makefile 中一些要素的基本语法规则:
第一行不要空行
原因:第一行通常是一个目标,例如 all: 或者 clean:。在 Makefile 中,空行被视为分隔符,用于区分不同的规则或目标。
当 Make 工具解析 Makefile 文件时,它会忽略空行,并将第一行之后的非空行视为第一个规则或目标。如果第一行是一个空行,可能会导致 Make 工具不正确地解释 Makefile,从而产生意外的行为或错误。
目标:指定了要生成的文件或要执行的操作名。
例如:上面的mybin就是要生成的目标文件名。
依赖:指定了目标所依赖的文件或其他目标。
例如:上面的test.c 是目标文件依赖的文件。一个目标文件可以有多个依赖文件,用空格分开。
目标和依赖构成了依赖关系。
命令(依赖方法):包含了生成目标所需的具体操作步骤,通常是一条或多条 Shell 命令。
第二行必须以Tab开头,不能是空格,紧接着是生成目标文件的命令。
例如:上面的gcc test.c -o mybin -std=c99
(gcc test.c -o mybin 与gcc -o mybin test.c 相同,-o后面跟目标文件名即可)
伪目标:伪目标是指在 Makefile 中.PHONY定义的不对应实际文件的目标,通常用于执行一些特定的操作,比如清理临时文件。
例如:上面的clean目标用于执行清理操作,删除mybin文件。
注:make默认执行的是第一行的命令,一般把清理工作放在最后面。
注释:使用 # 符号来添加注释,注释从 # 开始一直到该行的末尾。
变量:可以使用变量来存储命令选项、编译器名称等信息,然后在规则中引用这些变量。
语法格式:VAR_NAME = value条件判断:可以使用条件判断(ifeq、ifdef 等)来根据不同的条件执行不同的命令。
函数:Makefile 支持一些内置函数,可以用于字符串处理、文件查找等操作。
使用make和make clean,就可以方便地完成项目自动化构建和清理。
make命令不是每次都会重新编译,只有更改过的文件才会重新编译。(提高编译效率)
若源代码没有更改也重新编译,那么每次预处理编译汇编链接的时间比较长,成本高。
make/Makefile是如何知道文件更改过的?
答:通过源文件的修改时间和形成的可执行程序(也是文件)的修改时间做对比。
重新编译的本质:重新写入一个二进制的可执行文件(bin文件),文件的修改时间会跟着更改。
大部分情况下重新编译都没问题,问题的产生不仅仅是修改新文件就能解决的。有些历史问题需要重新清理项目才可以解决。
文件 = 内容 + 属性,所以文件的ACM时间肯定与内容或属性有关。
Access(最近访问时间):普通文本文件打开:cat、vim,或者对目录进入、ls显示等
Modify (对内容修改):当文件内容发生变化时,修改时间(mtime)会被更新。
Change(对属性修改):当文件的权限、所有者、链接数或文件名发生变化时,更改时间(ctime)会被更新。
注:
- 三种时间会出现联动,例如对内容修改,Access和Change时间也会更改。
- Access时间不是每次访问时都更改,读取查看文件操作最频繁,如果每次都改的话,比较浪费时间,因为文件一般都在磁盘存放,更改时间的本质就是访问磁盘。但是访问磁盘的速度比较慢(相对cpu而言),读取查看文件操作又是很频繁,如果每次都更改Access time的话,系统效率就会降低很多,所以就会隔一段时间更改一次。
(具体间隔时间和是否间隔,由内核版本决定)- 使用touch命令可以修改ACM时间。
-a 选项 修改Access时间,但同时也修改了change时间,因为access时间也是属性。
-m 选项 修改Modify时间,但是Change时间也会跟着改。
综上,make 是通过对比源文件和bin文件的Modify时间确定文件新旧的。
通过时间对比,可以做到不让有些代码进行重新编译(不让某些操作进行)。
总是被执行就是:不考虑其他任何问题,总是执行依赖方法,不会被任何情况拦截。
(make/makefile不再依靠时间对比了,直接执行对应的命令)
例如:mybin被.PHONY修饰,则多次make时,都会执行gcc命令,把可执行程序重新形成。
上一节讲到gcc编译生成一个可执行程序需要经过预处理、编译、汇编和连接,中间会产生.i,.o,.s文件。但是在上面的操作中都没有生成中间文件。
但是我们知道一件事:生成bin文件,就需要对应的.o文件。
以Makefile的推导过程如下:(类似一个栈结构)
生成了临时文件 code.o code.s code.i
以上写法只是为了了解编译推导的过程,实际上不推荐使用。
建议直接用gcc形成可执行!
- include path/to/another_makefile.mk
-
- target: dependency
- command
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。