Makefile
在没整理的文件里翻出来一篇很久以前写的关于makefile的知识, 整理一下放出来
前置知识: c++的编译过程
makefile文件是什么
Makefile最大的作用是实现对工程的自动编译
Makefile 可以简单的认为是一个工程文件的编译规则,描述了整个工程的编译和链接等规则
一个大型工程往往是由许源文件组成的,这些源文件按照其功能,类型,模块放在了若干个文件,这些文件有编译的先后顺序,这些规则都必须通过Makefile来实现
makefile文件怎么用
写完Makefile后,只需要用命令行工具(windows用cmd)进入到Makefile的同级目录,输入make即可开始编译
一般来说, 会有makefile和Makefile两个文件, 如果不指定, 默认执行 makefile, 一般Makefile由工程师编写, makefile由客户编写
makefile文件工作原理
运行规则
如果这个工程没有编译过,那么我们的所有 C 文件都要编译并被链接。
如果这个工程的某几个 C 文件被修改,那么我们只编译被修改的 C 文件,并链接目标程序
如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的 C 文件,并链接目标程序
工作流程
创建程序(make程序)首先读取makefile文件,然后再激活编译器,汇编器,资源编译器和连接器以便产生最后的输出,最后输出并生成的通常是可执行文件
make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
如果找到,它会找文件中的第一个目标文件 ( target ),并把这个文件作为最终的目标文件。
如果 target 文件不存在,或是 target 所依赖的后面的 .o 文件的文件修改时间要比 target 这个文件新,那么,他就会执行后面所定义的命令来生成 target 这个文件。
如果 target 所依赖的.o 文件也存在,那么 make 会在当前文件中找目标为.o 文件的依赖性,如果找到则再根据那一个规则生成.o 文件
当然,你的 C 文件和 H 文件是存在的啦,于是 make 会生成 .o 文件,然后再用 .o 文 件声明 make 的终极任务,也就是执行文件 target 了
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
makefile文件编写
makefile文件里有什么
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2、隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
3、变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根 据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲 述。
5、注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“#”。
最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。
1 | |
Target: 目标
Prerequisites: 目标依赖
Command: 规则的命令行
eg:
有以下文件
main.c tool1.c tool1.h tool2.c tool2.h
makefile文件写这样
1 | |
关于变量
1 | |
1 | |
$^代指上一句中的target
$@代指目标文件
1 | |
1 | |
代表一个函数, %表示通配
补充:
有一些函数
1 | |
关于make clean命令:
实际上是指定执行了clean命令, 他没有依赖项, 执行的是shell命令
假设在当前路径下有一个文件叫clean, 那么运行make clean时总是会显示已是最新
解决方案: 把clean设为伪目标
1 | |