前言
Makefiles是Linux系统中的一个构建自动化工具,用于管理大型项目的编译、安装等过程,通过定义一系列源文件、目标文件和规则,可以自动的构建和安装程序。
一、Makefile介绍
Makefile是一种文本文件,其中包含了一系列的规则和指令,指定了如何生成目标文件。
Makefile中的规则通常由目标、依赖项和命令组成。
目标/依赖:表示程序编译以及链接的源文件和目标文件
命令:用于生成目标文件的指令
二、使用场景
Makefile通常用于大管理大型、复杂的软件项目,特别是需要编译多个源文件的程序。通过Makefile可以自动地构建和安装程序,简化程序的编译过程,提高程序的可维护性。
大型程序中通常有很多文件,在更新时如果全部重新编译会非常浪费时间,而Makefile则用于决定大型程序中的哪些部分需要重新编译,即保留其他文件的编译只更新更改部分的文件。
1、语言
大多情况下Makefile都用于C或C++文件,一些代码编辑器(如Microsoft Visual Studio)有自己的内置构建工具,其他语言也有自己的对应工具,其作用与Make类似。
而像Python和Javascript这样的解释语言则不需要这类东西。
Makefiles的目标是根据已更改的文件编译任何需要编译的文件。
解释语言中的文件改变后,程序运行使用的是文件最新版本,因此不需要重新编译。
2、系统
Makefile通常在Linux环境下使用。然而,由于Makefile是是一种文本文件,所以可以在任何操作系统中编辑与使用。
例如在Windows系统下,虽然不能直接运行Makefile,但可以借助GNU Make等软件,将Makefile转换成Windows系统可识别的格式。通过在Windows环境中构建Makefile,可以将程序编译成适用于不同的平台和设备的二进制文件。
3、优缺点
优点:
(1)、简化程序的编译过程,可以有效的提高程序开发的效率
(2)、能够自动判断程序源文件是否发生变化,只对修改的过的文件进行编译,从而节约编译时间
(3)、Makefile可以自动生成依赖关系,在编译过程中能够自动解决依赖关系,避免出现编译错误
(4)、如果目标文件以及是最新的,Makefile不会重新编译和链接源文件,从而避免浪费时间
缺点:
(1)、Makefile语法相对于其他自动化构建工具来说比较复杂,学习成本过高
(2)、Makefile只适用于Linux系统,无法应用于其他操作系统(其他系统编译方法见上)
(3)、Makefile对于大型软件项目的管理可能存在一定缺陷,无法充分满足复杂项目的配置和构建需求
三、补充内容
1、编译和链接
Windows的集成开发环境(integrated development environment,IDE)一般都默认做了这项工作。
大型工程中的源文件不计其数,并且按功能类型分别放在不同目录下,而
makefile则定义了一系列的规则来指定文件编译的先后顺序,是否有修改需要重新编译,甚至可以执行操作系统的命令类似于shell脚本。
(1)、编译
一般情况下,C/C++首先要把源文件编译成中间代码文件(目标文件),也就是将.c和.cpp文件转换成在UNIX下的 .o 文件或Windows下的 .obj 文件,每个源文件(.c/.cpp)对应一个中间目标文件(.o/.obj文件)。
编译器时,主要检查的是语法,函数与变量的声明是否正确。
(2)、链接
链接时,主要是链接函数和全局变量,将众多的目标文件(.o/.obj文件)合成可执行文件。
链接时需要明确指出中间目标文件名,如果文件过多,一般会给中间目标文件打个包,在Windows下这种包被称为“库文件”(lib),也就是 .lib文件,在UNIX下被称为“存档文件”,也就是 .a文件(Archive File)。
(3)、总结
源文件(.c/.cpp)→中间目标文件(.o.obj)→可执行文件(.exe/.out||无后缀)
编译阶段,编译器只检测程序语法和函数、变量是否被声明,如果函数未被声明,编译器会给出一个警告,但可以生成目标文件。
链接阶段,链接器会在所有的目标文件中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),例如VC下链接器未能找到函数的实现,需要指定函数的目标文件(error LINK2001:无法解析的外部符号)。