Makefile一般为Linux环境下的工程项目构建工具,描述了整个工程的编译和链接情况
规则的目标:依赖的文件
执行的命令
其中,规则的目标可以为:中间文件/可执行文件/标签;
依赖的文件可以为:生成规则的目标所需要的文件或者目标或者是没有;
执行的命令可以为:任意的shell命令
注意:命令的开始用Tab隔开
//Makefile 文件
test:test.cpp
g++ -o test test.cpp
//test.cpp文件
#include
using namespace std;
int main()
{
cout<<"hello makefile."<
在当前目录中执行:make(自动寻找Makefile 文件);即可得到执行文件test。
以下面的Makefile 文件为例
//Makefile 文件
test:test.o
g++ -o test test.o
test.o:test.cpp
g++ -o test.o -c test.cpp
这里有两个规则和两个命令,以第一个目标为终极目标,第一个目标的执行依赖test.o文件,而执行生成test.o文件需要第二个目标作为前提,执行过程是,假如test.o文件没有变化,则直接运行第一个目标结束,这样可以提高效率;假如test.o文件有变化继续执行下面的命令。
当执行新的make命令的之前,可能想删除之前生成的test.o和test可执行文件,其Makefile 文件编写如下:
//Makefile 文件
test:test.o
g++ -o test test.o
test.o:test.cpp
g++ -o test.o -c test.cpp
.PHONY:clean
clean:
rm -rf *.o test
其中,目标 clean 是一个伪目标(伪目标不会创建目标文件,但是会执行下面的命令);将一个目标声明称伪目标的方法是将它作为特殊的目标.PHONY的依赖。如上所示,clean是.PHONY的依赖,目标 clean的依赖为空(依赖的文件可以为:生成规则的目标所需要的文件或者目标或者是没有)。
由于clean是一个伪目标,不是一个具体的文件,与最终的目标test没有依赖的关联,因此执行make命令时候,不会执行它的命令。最后的效果为:(1)执行make命令会生成test和test.o,不会执行clean下的命令(2)执行make clean命令的时候,执行clean下的命令,删除之前生成的test.o和test可执行文件。
与shell支持的通配符一致,有:
(1)*:0或任意个字符
(2)?:匹配任意一个字符
(3)[]:将指定匹配的字符放在 “[]” 中
一共有文件:main.cpp 、 test01.cpp 、 test01.h 、 test02.cpp 、 test02.h
//main.cpp ==========================
#include"test01.h"
#include"test02.h"
#include
using namespace std;
int main()
{
print01();
print02();
cout<<"hello makefile."<
using namespace std;
void print01()
{
cout<<"I am test01!"<
using namespace std;
void print02()
{
cout<<"I am test02!"<
Makefile 文件编辑如下:
//Makefile
main:*.cpp
g++ -o $@ $^
其中,通配符出现在规则中;$@
为自动化变量,表示规则的目标文件名(即main);$^
也为自动化变量,表示所有依赖文件列表(即*.cpp,这里是main.cpp、test01.cpp、test02.cpp)
格式:
变量的名称=值列表
其中,值列表可以0项或1项或多项
变量的使用:
$(VALUE_LIST)
或 ${VALUE_LIST}
例子:
//Makefile
OBJ = main.cpp test01.cpp test02.cpp
main:$(OBJ)
g++ -o $@ $(OBJ)
:=
只对当前语句的变量有效
例子:
//Makefile
x:=foo
y:=$(x)b
x:=new
test:
@echo "y=>$(y)"
@echo "x=>$(x)"
输出:
y=>foob
x=>new
第2行变量x已经赋值y,但是简单赋值只对当前语句的变量有效,因此执行x:=new
后y的值不变
=
与目标变量相关的变量都会受到影响
例子:
//Makefile
x:=foo
y=$(x)b
x=new
test:
@echo "y=>$(y)"
@echo "x=>$(x)"
输出:
y=>newb
x=>new
注意: y=$(x)b
中不能是:=
,否则无法影响y
?=
如果变量未定义,则使用符号中的值去定义变量;如果该变量已经赋值,则赋值语句无效。
例子:
x:=foo
y:=$(x)b
x?=new
test:
@echo "y=>$(y)"
@echo "x=>$(x)"
输出:
y=>foob
x=>foo
可以看出x?=new
赋值无效,因为变量x
已经赋值
+=
追加的结果为:原来的值+空格+新值
VPATH是一个环境变量,与小写的vpath是有区别的,搜索的过程为:当前目录=》VPATH设置的目录
格式:
VPATH:=path1 path2 ...
或者
VPATH:=path1:path2:...
举例:
//Makefile
VPATH:=src
main:main.cpp test01.cpp test02.cpp
g++ -o $@ $^
其中,Makefile文件与src目录在同一级目录中,所有的代码文件在子目录src目录中,执行make,则在当前目录生成main可执行文件
vpath 是关键字,按照模式搜索,给出了搜索的条件
格式:
(1) vpath PATTERN DIRECTORIES
vpath test.cpp src // 在目录src中搜索test.cpp
(2 vpath PATTERN
//除符合文件PATTERN 的搜索目录
(3) vpath
//除所有已被设置的文件搜索路径
嵌套执行make的作用在于可以将不同模块编写一个Makefile文件,然后做最外层写总的Makefile文件控制所有的Makefile文件执行
格式:
subsystem:
cd subdir && $(MAKE)
或者
subsystem:
$(MAKE) -C subdir
其中,subdir目录是一个子目录,里面也有个Makefile文件;上面的执行步骤即为进入到子目录subdir执行Makefile文件。
参考:http://c.biancheng.net/view/7097.html