目录
Makefile
什么是Makefile
Makefile 可以简单的认为是一个工程文件的编译规则,描述了整个工程的编译和链接等规则。其中包含了那些文件需要编译,那些文件不需要编译,那些文件需要先编译,那些文件需要后编译,那些文件需要重建等等。
Makefile 可以使得我们的项目工程的编译变得自动化,不需要每次都手动输入一堆源文件和参数。
这个在windows平台下的IDE大多都内置了Makefile。linux上则需要自己编写。
想一想学会了是不是惬意呢。
Makefile规则
Makefile 描述的是文件编译的相关规则,它的规则主要是两个部分组成,分别是依赖的关系和执行的命令,其结构如下所示:
targets : prerequisites
command
targets:规则的目标,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标签;
prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;
command:make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。
Makefile所使用的命令是由 shell 命令行组成,他们是一条一条执行的。多个命令之间要使用分号隔开,Makefile 中的任何命令都要以tab
键开始。多个命令行之间可以有空行和注释行,在执行规则时空行会被自动忽略。而且命令中出现的字符“#”到行末的内容被认为是注释。 当然了“#”可以不在此行的行首,此时“#”之前的内容不会被作为注释处理。
如以下的一个例子:
test:test.c
gcc -o test test.c
通配符规则
使用示例:
.PHONY:clean
clean:
rm -rf *.o test
变量赋值规则
Makefile 文件中定义变量的基本语法如下:
变量的名称=值列表
变量的名称可以由大小写字母、阿拉伯数字和下划线构成。等号左右的空白符没有明确的要求,因为在执行 make 的时候多余的空白符会被自动的删除。至于值列表,既可以是零项,又可以是一项或者是多项。
VALUE_LIST = one two three
调用变量的时候可以用 “(VALUE_LIST)” 或者是 “{VALUE_LIST}” 来替换,这就是变量的引用。
变量赋值的四种方式
简单赋值 ( := ) 编程语言中常规理解的赋值方式,只对当前语句的变量有效。
递归赋值 ( = ) 赋值语句可能影响多个变量,所有目标变量相关的其他变量都受影响。
条件赋值 ( ?= ) 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。
追加赋值 ( += ) 原变量用空格隔开的方式追加一个新值。
自动化变量规则
关于自动化变量可以理解为由 Makefile 自动产生的变量。 在模式规则中,规则的目标和依赖的文件名代表了一类的文件。
那么模式规则命令中该如何表示文件呢?就需要使用“自动化变量”,自动化变量的取值根据执行的规则来决定,取决于执行规则的目标文件和依赖文件。
看以下实例:
test:test.o test1.o test2.o
gcc -o $@ $^
test.o:test.c test.h
gcc -o $@ $<
test1.o:test1.c test1.h
gcc -o $@ $<
test2.o:test2.c test2.h
gcc -o $@ $<
这个规则模式中用到了 “ @ " 、 " @" 、" @"、"<” 和 “ " 这 三 个 自 动 化 变 量 , 对 比 之 前 写 的 M a k e f i l e 中 的 命 令 , 我 们 可 以 发 现 " ^" 这三个自动化变量,对比之前写的 Makefile 中的命令,我们可以发现 " "这三个自动化变量,对比之前写的Makefile中的命令,我们可以发现"@” 代表的是目标文件test,“ ” 代 表 的 是 依 赖 的 文 件 , “ ^”代表的是依赖的文件,“ ”代表的是依赖的文件,“<”代表的是依赖文件中的第一个。我们在执行 make 的时候,make 会自动识别命令中的自动化变量,并自动实现自动化变量中的值的替换。
环境变量规则与修改
Makefile中常见的搜索的方法的主要有两种:一般搜索VPATH
和选择搜索vpath
。乍一看只是大小写的区别,其实两者在本质上也是不同的。
VPATH 和 vpath 的区别
VPATH 是变量,更具体的说是环境变量,Makefile 中的一种特殊变量,使用时需要指定文件的路径;vpath 是关键字,按照模式搜索,也可以说成是选择搜索。搜索的时候不仅需要加上文件的路径,还需要加上相应限制的条件。
VPATH的使用
单个路径:VPATH := 路径
多个路径:VPATH := 路径1:路径2
无论你定义了多少路径,make 执行的时候会先搜索当前路径下的文件,当前目录下没有我们要找的文件,才去 VPATH 的路径中去寻找。 如果当前目录下有我们要使用的文件,那么 make 就会使用我们当前目录下的文件。
vpath因为用的不多在这里就不介绍了。
条件判断规则
条件语句的作用:条件语句可以根据一个变量的值来控制 make 执行或者时忽略 Makefile 的特定部分,条件语句可以是两个不同的变量或者是常量和变量之间的比较。
使用示例:
ifeq (ARG1, ARG2)
ifeq 'ARG1' 'ARG2'
ifeq "ARG1" "ARG2"
ifeq "ARG1" 'ARG2'
ifeq 'ARG1' "ARG2"
libs_for_gcc= -lgnu
normal_libs=
foo:$(objects)
ifeq($(CC),gcc)
$(CC) -o foo $(objects) $(libs_for_gcc)
else
$(CC) -o foo $(objects) $(noemal_libs)
endif
包含规则
当 make 读取到 “include” 关键字的时候,会暂停 读取当前的 Makefile,而是去读 “include” 包含的文件,读取结束后再继读取当前的 Makefile 文件。
include <文件名>
大致更新这么多,以后用到再更。
话说我也用不到,VS真香。
参考文献
[1] Makefile教程.C语言中文网.http://c.biancheng.net/makefile/