Makefile文件用于管理和组织代码工程的编译和链接,需要被make工具解析并完成相关的动作。
1、文件包含:
·语法:include 文件名
·作用:将其它makefile文件包含进来,组成一个更大的makefile文件,这样有利于makefile模块化编程。通常我们将一些配置选项分开成一个独立的makefile文件,这样有利于makefile文件的管理;或将模块代码的依赖关系和需要编译的文件信息独自写到一个 makefile文件中,最终通过include命令形成一个顶层makefile文件来完成整个工程代码的编译和链接。
2、变量定义:
·语法:变量名 := 变量值
·在makefile中,经常需先定义一个变量,然后往该变量中追加新的值(通过+=符号)。
·例如:先定义一个C_SRCS变量(该值可以为空),然后将代码文件test1.c和test2.c添加到C_SRCS中
C_SRCS :=
C_SRCS += test1.c test2.c
·在makefile中有一类特殊的变量,其名称为自动变量,自动变量的值会依据规则中的target(目标) 和 prerequisites(前提)自动计算其值,自动变量一般以开头$为起始,下面将列出一些常见的自动变量:
$@为规则中的target名称
<
为规则中第一个
p
r
e
r
e
q
u
i
s
i
t
e
s
名称
3
、内置命令:
⋅
M
a
k
e
f
i
l
e
中内置了一些常用的命令,有字符串处理函数
s
u
b
s
t
、
p
a
t
s
u
b
s
t
、
s
t
r
i
p
、
f
i
n
d
s
t
r
i
n
g
、
f
i
l
t
e
r
、
f
i
l
t
e
r
−
o
u
t
、
s
o
r
t
、
w
o
r
d
、
w
o
r
d
l
i
s
t
、
w
o
r
d
s
、
f
i
r
s
t
w
o
r
d
、
l
a
s
t
w
o
r
d
;文件名处理函数
d
i
r
、
n
o
t
d
i
r
、
s
u
f
f
i
x
、
b
a
s
e
n
a
m
e
、
a
d
d
s
u
f
f
i
x
、
a
d
d
p
r
e
f
i
x
、
j
o
i
n
、
w
i
l
d
c
a
r
d
、
r
e
a
l
p
a
t
h
、
a
b
s
p
a
t
h
;条件处理函数
i
f
;循环处理函数
f
o
r
e
a
c
h
等。
⋅
常见的函数:
w
i
l
d
c
a
r
d
函数:其语法为
<为规则中第一个prerequisites名称 3、内置命令: · Makefile中内置了一些常用的命令,有字符串处理函数subst、patsubst、strip、findstring、filter、filter-out、sort、word、wordlist、words、firstword、lastword;文件名处理函数dir、notdir、suffix、basename、addsuffix、addprefix、join、wildcard、realpath、abspath;条件处理函数if;循环处理函数foreach等。 ·常见的函数: wildcard 函数:其语法为
<为规则中第一个prerequisites名称3、内置命令:⋅Makefile中内置了一些常用的命令,有字符串处理函数subst、patsubst、strip、findstring、filter、filter−out、sort、word、wordlist、words、firstword、lastword;文件名处理函数dir、notdir、suffix、basename、addsuffix、addprefix、join、wildcard、realpath、abspath;条件处理函数if;循环处理函数foreach等。⋅常见的函数:wildcard函数:其语法为(wildcard pattern),pattern为匹配的模式,比如
(
w
i
l
d
c
a
r
d
f
o
r
e
a
c
h
函数:其语法为
(wildcard %.c) 为查找当前路径下面文件名以.c结尾的文件。 foreach 函数:其语法为
(wildcardforeach函数:其语法为(foreach var,list,text),每循环一次var从list中按顺序取值一个,然后执行一次text代码并记录结果,最终返回所用text代码运行的结果。
dirs := C_DIR S_DIR
file :=
(
f
o
r
e
a
c
h
d
i
r
,
(foreach dir,
(foreachdir,(dirs),$(wildcard
(
d
i
r
)
/
∗
)
)
将
C
D
I
R
和
S
D
I
R
文件夹下面的所有文件添加到
f
i
l
e
变量中。
d
i
r
函数:其语法为
(dir)/*)) 将C_DIR和S_DIR文件夹下面的所有文件添加到file变量中。 dir 函数:其语法为
(dir)/∗))将CDIR和SDIR文件夹下面的所有文件添加到file变量中。dir函数:其语法为(dir names…),用于获取names中文件夹路径,比
(
d
i
r
s
r
c
/
f
o
o
.
c
h
a
c
k
s
)
将获得文件夹路径
s
r
c
/
.
/
n
o
t
d
i
r
函数:其语法为
(dir src/foo.c hacks) 将获得文件夹路径 src/ ./ notdir 函数:其语法为
(dirsrc/foo.chacks)将获得文件夹路径src/./notdir函数:其语法为(notdir names…),用于获取names中除去路径的信息
(
n
o
t
d
i
r
s
r
c
/
f
o
o
.
c
h
a
c
k
s
)
将获得文件信息
f
o
o
.
c
h
a
c
k
s
b
a
s
e
n
a
m
e
函数:其语法为
(notdir src/foo.c hacks) 将获得文件信息 foo.c hacks basename 函数:其语法为
(notdirsrc/foo.chacks)将获得文件信息foo.chacks basename函数:其语法为(basename names…),用于获取names中除去后缀信息
(
b
a
s
e
n
a
m
e
s
r
c
/
f
o
o
.
c
s
r
c
−
1.0
/
b
a
r
h
a
c
k
s
)
将获得信息
s
r
c
/
f
o
o
s
r
c
−
1.0
/
b
a
r
h
a
c
k
s
a
d
d
s
u
f
f
i
x
函数:其语法为
(basename src/foo.c src-1.0/bar hacks) 将获得信息 src/foo src-1.0/bar hacks addsuffix 函数:其语法为
(basenamesrc/foo.csrc−1.0/barhacks)将获得信息src/foosrc−1.0/barhacksaddsuffix函数:其语法为(addsuffix suffix,names…),用于往names中添加后缀信息suffix
(
a
d
d
s
u
f
f
i
x
.
c
,
f
o
o
b
a
r
)
将获得文件信息
f
o
o
.
c
b
a
r
.
c
a
d
d
p
r
e
f
i
x
函数:其语法为
(addsuffix .c,foo bar) 将获得文件信息 foo.c bar.c addprefix 函数:其语法为
(addsuffix.c,foobar)将获得文件信息foo.cbar.caddprefix函数:其语法为(addprefix prefix,names…),用于往names中添加前缀信息prefix
(
a
d
d
p
r
e
f
i
x
s
r
c
/
,
f
o
o
b
a
r
)
将获得信息
s
r
c
/
f
o
o
s
r
c
/
b
a
r
p
a
t
s
u
b
s
t
函数:其语法为
(addprefix src/,foo bar) 将获得信息src/foo src/bar patsubst 函数:其语法为
(addprefixsrc/,foobar)将获得信息src/foosrc/bar patsubst函数:其语法为(patsubst pattern,replacement,text),根据 pattern信息将text替换成replacement
objects = foo.o bar.o baz.o
files =
(
p
a
t
s
u
b
s
t
(patsubst %.o,%.c,
(patsubst( objects))
将获得信息 foo.c bar.c baz.c
其可以简单写成
objects = foo.o bar.o baz.o
files = $(objects:.o=.c)
4、规则定义:
·规则是makefile中最重要的概念,其告诉make 目标文件的依赖关系,以及如何生成及更新这些目标文件。在makefile文件规则有2种,一种是显式规则,另一种是隐式规则。
·显式规则用于说明 何时及如何重新生成目标,其列出了目标依赖的文件信息,并通过调用命令来创建或更新目标,其语法一般为:
targets : prerequisites
recipe
…
targets为要生成或更新的目标,prerequisites为目标依赖的关系,recipe为生成目标的命令,一个规则可以有多条recipe;
foo.o : foo.c defs.h
cc -c -g foo.c
其中foo.o为target,foo.c defs.h 为prerequisites,cc -c -g foo.c为recipe。
·隐式规则用于说明 何时及如何根据其名称来重新生成一类目标文件,其描述了目标是如何依赖于名称相似的文件(一般来说除去后缀信息,其目标与依赖文件的名称是一样的),并调用命令来创建或更新目标;
%.o : %.c
$(CC) -c $(CFLAGS) $< -o
@
这个隐式规则说明了
.
o
的目标文件依赖于同名的
.
c
文件,其中
@ 这个隐式规则说明了.o的目标文件依赖于同名的.c文件,其中
@这个隐式规则说明了.o的目标文件依赖于同名的.c文件,其中< 及
@
为自动变量,
@为自动变量,
@为自动变量,<为第一个prerequisites条件,也就是 目标名称.c,$@为目标,也就是 目标名称.o。 $(CC) -c $(CFLAGS) %.c -o %.o
·在makefile中,我们通常要编写3种隐式规则,第1种为代码链接规则,第2种为源代码编译规则,第3种为汇编代码编译规则。
5、文件搜索路径设置:
·Make命令默认会在当前路径中搜索prerequisites中的文件,比如头文件,但我们在写程序时,经常将头文件和源文件隔开放在不同的文件夹下,这种该怎么处理呢?1、我们可以通过VPATH变量来解决,2、我们可以通过vpath指令来解决。
·VPATH变量:VPATH变量为所有的prerequisites指定文件路径,路径之间可以通过 : 或 空格 隔开
VPATH = src:…/headers
其代表在src文件或者上层的headers文件中查找。
·vpath指令:vpath指令的作用与变量VPATH的作用差不多,但vpath有更多的灵活性,其语法为:vpath pattern directories
pattern为需要查找的文件匹配模式信息,directories为要查找的文件路径;
vpath %.h …/headers
其代表在上一层文件夹headers中查找 .h头文件信息。
6、依赖关系生成:
在编写c文件代码时,我们经常通过#include 语句来包含其它文件信息,比如头文件,该c文件被编译时需要依赖于其#include包含进来的文件,在规则编写中,就需要指出这个依赖关系,这样当头文件信息改变后,make程序就知道如何更新目标文件了,而不是整个进行重编译,但这个操作可以看出是非常消耗时间及傻瓜式的,作为解决方案我们可以通过使用 编译器命令 –M选项来自动完成该工作,比如在main.c中#include “defs.h”,通过 cc –M main.c将产生输出 main.o:main.c defs.h,我们可以将输出结果写到 .d文件中,然后通过include指令包含到makefile文件中。
7、编译器常用命令选项:
编译器通常进行预处理、编译、汇编和链接处理,预处理包含了宏定义、文件包含、条件编译,编译则直接将代码翻译成机器码,汇编则将汇编代码翻译成机器码,链接则按照内存地址分配文件将各个文件的机器码统一形成一个可执行文件,对编译命令(比如gcc)而言该如何区别这些操作呢?即通过命令选项。下面将介绍一些常见的命令选项:
-o file 输出生成的 file文件
-c 编译或汇编程序文件,但不会执行链接操作
-mcpu=name 规定目标处理器的型号
-Wall 使能所有警告调试信息输出
-glevel 要求带调试信息的等级,-g0代表不产生调试信息,-g1代表产生最小的调试信息用来跟踪程序的运行,但不包括本地变量,-g3包含了一些额外的调试信息比如程序的宏定义等。
-I dir 增加头文件的搜索路径,比如 –I…/header
-D name 预先定义一个宏定义
04-01
1030
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
07-16
2277
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
09-23
2557
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
04-18
527
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
05-14
1万+
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
03-21
3053
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)
03-19
574
![](https://csdnimg.cn/release/blogv2/dist/pc/img/readCountWhite.png)