事先声明:本文的适合读者为,有一定的linux下编程基础。
一、Makefile是什么
Makefile文件 Makefile 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令(摘自百度百科)。按照以上定义,就是说明Makefile是用来管理源代码进行编译链接的。平时写一些规模较小的代码,也就那么一两个两三个文件就搞定了,用gcc一个一个来编译是米有任何问题地,说不定你用Makefile还慢呢;但是当某个问题大道一定的程度的时候,假如有好几十个文件,你也得一个一个的编译?链接?那就只能说明您out了!当你读完了本文,你就会发现有一枚很好的方法在等着您呢!
二、Makefile的组成
TARGET... : DEPENDEDS...
COMMAND
...............
.................
TARGET:规则所定义的目标。通常规则是最后生成的可执行文件的名或者为了生成可执行文件而依赖的目标文件的文件名,也可以是一个动作,称之为“伪目标”。
DEPENDEDS:执行次规则所必须的依赖条件,例如生成可执行文件的目标文件。DEPENDEDS也可以是某个TARGET,这样就形成了TARGET之间的嵌套。
COMMAND:规则随执行的命令,即规则的动作,例如编译文件、生成库文件等等。。。
一个Makefile文件有许多个规则组成;那么Makefile在执行的时候会怎么做呢!答案是依据文件的时间戳!而且还是ctime这个时间戳!会比较TARGET文件的时间戳和后面的DEPENDEDS的时间戳。如果TARGET的ctime新于后面的DEPENDEDS那么好了,这就说命名TARGET的存在时间要比后面的DEPENDEDS文件时间短,换句话说:这个时候的TARGET就是由后面的DEPENDEDS文件生成的。这个时候,这条规则下面的COMMAND就不用在执行了。然后会一直遍历n遍这个Makefile文件,直到所有的TARGET的ctime新于右面的DEPENDEDS文件(仅仅是本规则当中的有效,你不能将第一条的TARGET和第二个规则的DEPENDEDS来比较)。关于这个稍候会分析! 执行一个规则的过程是这样的:对于一个存在的规则(明确规则和隐含规则)首先,make程序将比较目标文件和所有的依赖文件的时间戳。如果目标的时间戳比所有依赖文件的时间戳更新(依赖文件在上一次执行make之后没有被修改),那么什么也不做。否则(依赖文件中的某一个或者全部在上一次执行make后已经被修改过),规则所定义的重建目标的命令将会被执行。这就是make工作的基础,也是其执行规制所定义命令的依据。
三、Makefile变量
什么是用户自定义变量?就是你自己定义的变量,只能够你自己在哪儿用。
定义规则:变量名 = 变量表达式
引用规则:$(变量名)
CC = gcc
CFLAGS = -Isub -Iadd
TARGET = cacu
RM = rm -f
上面的是几个变量的定义,向变量CC、CFLAGS等等... 引用的时候呢就$(CC) 这个就等价于gcc。
在Makefile中有一些已经定义的变量,用户可以直接使用这些变量,而不必再次定义。
常用的预定义变量
变量名 含义 默认值
AR 生成静态库库的程序名称 ar
AS 汇编编译器的名称 as
CC C语言编译器名称 cc
CPP C语言预编译器名称 $(CC)-E
CXX C++语言编译器的名称 g++
RM 删除文件程序的名称 rm -f
ARFLAGS 生成静态库库文件程序的选项 无默认值
CFLAGS C语言编译器编译选项 无默认值
CPPFLAGS C语言预编译器的选项 无默认值
CXXFLAGS C++语言预编译其的编译选项 无默认值
那么啥是编译器选项、预编译器选项等等、不在本文的讨论范围之内!
常见自动变量
变量 含义
$* 表示目标文件名称,不包含目标文件的拓展明
$+ 表示所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先 后为顺序,其中可能包含重复的依赖文件
$< 表示依赖项中第一个依赖文件的名称
$? 依赖项中,所有目标文件的时间戳晚的依赖文件,依赖文件之间用空 格分开
$@ 目标项中目标文件的名称
$^ 依赖选项中,所有不重复的依赖文件,这些文件之间以空格分开
阅读(2808) | 评论(0) | 转发(0) |