Makefile入门
Make
- 编译、链接、构建:
- 把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)
- 然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。
- 编译和链接程序的安排,叫做构建(build)。
- Make是一个根据指定的Shell命令进行构建的工具,是最常用的构建工具,诞生于1977年,主要用于C语言的项目。它的规则很简单,你规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。
- Make命令执行时,需要一个Makefile文件,以告诉Make命令需要怎么样的去编译和链接程序。很多大型项目的编译都是通过 Makefile 来组织的。
Makefile
- Windows 下的集成开发环境(IDE)已经内置了 Makefile,或者说会自动生成 Makefile,我们不用去手动编写。
Linux 中却不能这样,需要我们去手动的完成这项工作。不懂 Makefile,就操作不了多文件编程,就完成不了相对于大的工程项目的操作。如果你想在 Linux(Unix) 环境下做开发的话,Makefile 是必须掌握的一项技能。
Makefile 可以简单的认为是一个工程文件的编译规则,描述了整个工程的编译和链接等规则。其中包含了那些文件需要编译,那些文件不需要编译,那些文件需要先编译,那些文件需要后编译,那些文件需要重建等等。编译整个工程需要涉及到的,在 Makefile 中都可以进行描述。换句话说,Makefile 可以使得我们的项目工程的编译变得自动化,不需要每次都手动输入一堆源文件和参数。
在Linux下开发如果要编译的源文件很多的情况下,会遇到下列问题:
- 编译的时候需要链接库的的问题。拿C语言来说,编译的时候 gcc 只会默认链接一些基本的C语言标准库,很多源文件依赖的标准库都需要我们手动链接。
- 编译大的工程会花费很长的时间。工程项目的源文件每次修改后都要去重新编译。
- 工程文件中的源文件的类型很多,需要选择编译器进行编译。
- 文件可能会分布在不同的目录中,使用时需要调节路径。
对于上面的这些以及等等很多问题都可以使用Makefile很好的解决。
Makefile结构:Makefile里主要包含了五个东西:
- 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
- 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。 刚才写的疑似shell脚本的Makefile全部都是显示规则。
- 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
- 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样。
- 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符。
Makefile文件格式
Makefile文件由一系列规则(rules)构成。Makefile的规则主要是两个部分组成,分别是依赖的关系和执行的命令,也就是构建目标的前置条件,以及如何构建。每条规则形式如下:
targets : prerequisites [tab]command
或者是
targets : prerequisites; command [tab]command
- targets:规则的目标,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标签;
- prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;
- command:make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行,必须由一个tab键起首。
- "目标"是必需的,不可省略;"前置条件"和"命令"都是可选的,但是两者之中必须至少存在一个。
注意:目标和依赖文件之间要使用冒号分隔开,命令的开始一定要使用Tab键,不能用空格代替。
例:
test:test.c gcc -o test test.c
#编译 test.c 文件。其中 test 是目标文件,也是我们的最终生成的可执行文件,依赖文件就是 test.c 源文件。
Makefile工作流程
当我们在执行 make 条命令的时候,make 就会去当前文件下找要执行的编译规则,也就是 Makefile 文件。我们编写 Makefile 的时可以使用的文件的名称 "GNUmakefile" 、"makefile" 、"Makefile" ,make 执行时回去寻找 Makefile 文件,找文件的顺序也是这样的。
推荐使用 Makefile。如果文件不存在,make 就会给我们报错,提示:
make:*** 没有明确目标并且找不到 makefile。停止
当在 shell 提示符下输入 make 命令以后。 make 读取当前目录下的 Makefile 文件并开始处理第一个规则。
GNU make的工作方式
1.读入主Makefile (主Makefile中可以引用其他Makefile) 2.读入被include的其他Makefile 3.初始化文件中的变量 4.推导隐晦规则, 并分析所有规则 5.为所有的目标文件创建依赖关系链 6.根据依赖关系, 决定哪些目标要重新生成 7.执行生成命令