概念
makefile是Linux下常用的工程管理工具,通过编写makefile文件可以轻松编译、链接我们的整个工程文件,下面来总结一下最常用到的知识点。
首先是makefile文件的命名问题:
默认的情况下,
make
会在工作目录(执行
make
的目录)下按照文件名顺序寻找makefile
文件读取并执行,查找的文件名顺序为:“
GNUmakefile
”、“
makefile
”、
“
Makefile
”
然后是makefile最常见的描述规则:
target : prerequisites
command
target:目标。要么是最终生成的文件,通常是.o文件或者是可执行的二进制文件或者是库文件;要么是一个动作,动作没有依赖
prerequisites:依赖。是生成目标文件所需要的文件列表,通常是.c文件、.o文件或是库文件
conmmand:命令。是要执行的命令语句。通常是shell命令
我们make的过程就是一个执行规则的过程
然后makefile通常就是多个规则组合在一起,首先会指出最终的目标文件,然后通过规则来生成所需要的目标文件,而依赖文件有时不一定存在,那么同理,将不存在的依赖文件通过别的规则来生成,以此类推,直到找到存在的依赖文件
注:
1.一个规则可以有多个命令,一个命令占一行,每个命令行必须以Tab字符开始
2.如果是简单的一个.c文件生成一个.o文件,可以省去命令和所需.c,给出所需的.h即可
3.如果一行太长,可以用 \ 来分解成多行,但是注意 \ 之后不能有空格
然后是clean的解释及使用:
下面先给出两种常见的clean语句
clean :
rm edit $(objects)
.PHONY : clean
clean :
-rm edit $(objects)
两句的意思一样,前面说到目标可以是一个动作,这里的clean就是一个动作,因为clean不存在于终极目标的依赖文件中,且目录下也确实没这个文件,所以只有当使用make clean,明确指定这个目标时,才会执行下面的命令,删除指定文件
然后来说一下两者的差别:
1.
通过“
.PHONY
”特殊目标将“
clean
”目标声明为伪目标。避免当磁盘上存在一个名为“
clean
”文件时,目标“
clean
”所在规则的命令无
法执行,因为如果clean文件是最新的,没有改变,makefile就不会执行下述命令。所以声明为伪命令不仅提高了效率还更安全
2.
在命令行之前使用“-
”,意思是忽略命令
“
rm
”的执行错误
然后是关于通配符的解释:
Maekfile
中表示文件名时可使用通配符。可使用的通配符有:“*
”、“
?
”和“
[…]
”。
在
Makefile
中通配符的用法和含义和
Linux
(
unix
)的
Bourne shell
完全相同。例如,
“
*.c
”代表了当前工作目录下所有的以“
.c
”结尾的文件等。但是在
Makefile
中这些
统配符并不是可以用在任何地方,
Makefile
中统配符可以出现在以下两种场合:
1.
可以用在规则的目标、依赖中,
make
在读取
Makefile
时会自动对其进行匹配处理(通配符展开);
2.
可出现在规则的命令中,通配符的通配处理是在
shell
在执行此命令时完成的。除这两种情况之外的其它上下文中,不能直接使用通配符。而是需要通过函数“
wildcard
”
来实现。
然后是makefile中的变量:
概念
在
Makefile
中,变量是一个名字(更像是
C
语言中的宏),代表一个文本字符串(变量的值)。在
Makefile
的目标、依赖、命令中引用变量的地方,变量会被它的值所取代
注:
1.使用的时候用$即可展开变量
。例如:“
$(foo)
”或者“
${foo}
”就是取变量“
foo
”的值
2.
变量的展开过程和
c
语言中的宏展开的过程相同,是一个严格的文
本替换过程
3.变量对大小写敏感
赋值方式 := += ?= 的差别
:=
变量值中对其他量或者函数的引用在定义变量时被展开,且是对变量进行替换
+= 直接在变量追加上这个值
?=
只有此变量在之前没有赋值的情况下才会对这个变量进行赋值
隐含变量
内嵌隐含规则的命令中,所使用的变量都是预定义的变量。我们将这些变量称为“隐含变量”。这些变量允许对它进行修改。隐含变量分为两类:
1.
代表一个程序的名字(例如:“
CC
”代表了编译器这个可执行程序)。
2.
代表执行这个程序使用的参数(例如:变
量“
CFLAGS
”)
下面列举常见的变量:
AR:
函数库打包程序,可创建静态库
.a
文档。默认是“
ar
”
CC
:C
编译程序。默认是“
cc
”。注:cc默认指向gcc
CXX:
C++
编译程序。默认是“
g++
”
ARFLAGES:
执行“
AR
”命令的命令行参数。默认值是“
rv
”
CFLAGES:
执行“
CC
”编译器的命令行参数(编译
.c
源文件的选项)
CXXFLAGES:
执行“
g++
”编译器的命令行参数(编译
.cc
源文件的选项)
LDFLAGES:
链接器(如:“
ld
”)参数
RM:
删除命令。默认是“
rm -f
”
自动化变量:
自动化变量的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名,下面列举两个比较常用的:
$@:规则的目标文件名
$^:所有依赖文件列表
$<:第一个依赖文件的文件名
export和override
export的作用:
可以让上层
make
过程将所执行的
Makefile
中的变量传递
给子
make
。当一个变量使用“export
”进行声明后,变量和它的值将被加入到当前工作的环境变量
中,以后在
make
执行的所有规则的命令都可以使用这个变量
override:
举个例子比较好理解
override CFLAGS += -g
在执行
make
时无论在命令行中指定了那些编译选项(“指定
CFLAGS
”的值),
编译时“
-g”参数始终存在,例如 make CFLAGS = -O2,执行结果依旧会加上-g
最后讲一下常用的骚操作
wildcard:把指定目录的指定文件名全部展开
notdir:把文件名去掉路径信息
patsubst:文件名按照某种规则进行改变
![](https://img-blog.csdnimg.cn/d9dda9eed8dd4e4981c1fd6646f52e8a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YeO54yq6LWW55qu,size_20,color_FFFFFF,t_70,g_se,x_16)