Makefile是啥
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mokefile 定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。
Make与Mokefile 的关系
mke是一个命令工具,它解释Mokefile中的指令。在Mokefle文件中描述了整个工程所有文件的编译顺序、编译规则。
Makefile命名规则
Mefile或makefile -般使用Mokefile
Makefile基本语法
目标:依赖
Tab 命令
目标: 一般是指要编译的目标,也可以是一个动作
依赖:指执行当前目标所要依赖的先项,包括其它目标,某个具体文件或库等一个目标可以有多个依赖
命令:该目标下要执行的具体命令,可以没有,也可以有多条,多条时,每条命令一行
make常用选项
make [-f file] [options] [target]
Make默认在当前目录中寻找GUNmakefile, makefile, Makefile 的文件作为make的输入文件
-f可以指定除上述文件名之外的文件作为输人文件
-v显示版本号
-n只输出命令,但并不执行,一般用来测试
-s只执行命令,但不显示具体命令,此处可在命令中用@符抑制命令输出
-w显示执行前执行后的路径
-C dir指定makefile所在的目录
没有指定目标时,默认使用第一个目标如果指定,则执行对应的命令。
gcc/g++编译流程
预处理gcc -E [文件].cpp>[文件名].i
编译gcc -S [文件].ii得到名[文件名].s 的汇编文件
汇编gcc -C [文件].s得到名为[文件名].o(.obj) 的进制文件
链接gcc -lstdc++ [文件名].o得到名为a.out 的可执行文件
Makefile中的变量
系统变量
*不包括扩展名的目标文件名称
+所有的依赖文件,以空格分隔
<表示规则中的第一个条件
?所有时间戳比目标文件晚的依赖文件,以空格分隔@目标文件的完整名称
^所有不重复的依赖文件,以空格分隔
%如果目标是归档成员,则该变量表示目标的归档成员名称
系统常量(可用make-p查看)
AS 汇编程序的名称,默认为 as
CC C编译器名称默认cc
CPP C预编译器名称默认Cc-E
CXX C++编译器名称默认 g++
RM 文件删除程序别名默认rm-f
自定义变量
定义:变量名=变量值
使用: $(变量名)/${变量名}
Makefile中的伪目标和模式匹配
伪目标.PHONY:clean
声明目标为伪目标之后,makefile 将不会判断目标是否存在或该目标是否需要更新
%.0:%.cpp .0 依赖于对应的.cpp
wildcard $(wildcard ./* .cpp)获取当前目录下所有的.cpp文件
patsubst $(patsubst %.cpp, %.o, ./*.cpp) 将对应的Cpp文件名替换成.0文件名
Makefile运行流程
保证目标是用最新的依赖生成的
第一次全完编译,后面只编译最新的代码(部份编译)
Makefile中编译动态链接库
动态链接库:不会把代码编译到二进制文件中,而是在运行时才去加载,所以只需要维护一个地址-fPIC产生位置无关的代码
-shared共享
-l(小L)指定动态库
-I(大i)指定头文件目录,默认当前目录
-L手动指定库文件搜索目录,默认只链接共享目录
动态链接库好处是程序可以和库文件分离,可以分别发版,然后库文件可以被多处共享
动态 运行时才去加载动态加载
链接 指库文件和二进制程序分离,用某种特殊手段维护两者之间的关系库
库 库文件.dll .so
make工具自动完成编译工作。这些工作包括:如果仅修改了某几个源文件,则只重新编译这几个源文件;如果某个头文件被修改了,则重新编译所有包含该头文件的源文件。利用这种自动编译可大大简化开发工作,避免不必要的重新编译。
make工具通过一个称为makefile的文件来完成并自动维护编译工作。makefile需要按照某种语法进行编写,其中说明了如何编译各个源文件并连接生成可执行文件,并定义了源文件之间的依赖关系。当修改了其中某个源文件时,如果其他源文件依赖于该文件,则也要重新编译所有依赖该文件的源文件。
目标(TARGET) 程序产生的文件,如可执行文件和目标文件;目标也可以是要执行的动作,如“clean'
依赖(DEPENDENCIES)是用来产生日标的输入文件,一个目标通常依赖于多个文件。
命令(COMMAND)是make执行的动作,一个可以有多个命令,每个占一行。注意:每个命令行的起始字符必须为TAB字符!
如果DEPENDENCIES中有一个或多个文件更新的话,COMMAND就要执行,这就是Makefile最核心的内容
make是如何工作的
make会在当前目录下找名字叫Makefile或makefile
如果找到,它会找文件中的第一个目标文件(target),