Makefile入门

文章目录

  • 一、Makefile文件介绍
  • 二、Makefile文件的hello world编写
    • 1、编写格式
    • 2、实例
  • 二、Makefile的工作流程
    • 1、工作流程
    • 2、清除过程文件
  • 三、通配符的使用
    • 1、通配符
    • 2、实例
  • 四、Makefile变量的定义和赋值
    • 1、变量的定义与使用
    • 2、变量的赋值
      • (1)简单赋值`:=`
      • (2)递归赋值`=`
      • (3)条件赋值`?=`
      • (3)追加赋值`+=`
  • 五、目标文件的搜索(VPATH和vpath)
    • 1、VPATH
    • 2、vpath
  • 六、嵌套执行make

一、Makefile文件介绍

Makefile一般为Linux环境下的工程项目构建工具,描述了整个工程的编译和链接情况

二、Makefile文件的hello world编写

1、编写格式

规则的目标:依赖的文件
	执行的命令

其中,规则的目标可以为:中间文件/可执行文件/标签;
依赖的文件可以为:生成规则的目标所需要的文件或者目标或者是没有;
执行的命令可以为:任意的shell命令
注意:命令的开始用Tab隔开

2、实例

//Makefile 文件

test:test.cpp
        g++ -o test test.cpp

//test.cpp文件

#include
using namespace std;
int main()
{
    cout<<"hello makefile."<

在当前目录中执行:make(自动寻找Makefile 文件);即可得到执行文件test。

二、Makefile的工作流程

1、工作流程

以下面的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文件有变化继续执行下面的命令。

2、清除过程文件

当执行新的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可执行文件。

三、通配符的使用

1、通配符

与shell支持的通配符一致,有:
(1)*:0或任意个字符
(2)?:匹配任意一个字符
(3)[]:将指定匹配的字符放在 “[]” 中

2、实例

一共有文件: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)

四、Makefile变量的定义和赋值

1、变量的定义与使用

格式:

变量的名称=值列表

其中,值列表可以0项或1项或多项

变量的使用:
$(VALUE_LIST)${VALUE_LIST}

例子:
//Makefile

OBJ = main.cpp test01.cpp test02.cpp
main:$(OBJ)
        g++ -o $@ $(OBJ)

2、变量的赋值

(1)简单赋值:=

只对当前语句的变量有效
例子:
//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的值不变

(2)递归赋值=

与目标变量相关的变量都会受到影响
例子:
//Makefile

x:=foo
y=$(x)b
x=new
test:
        @echo "y=>$(y)"
        @echo "x=>$(x)"

输出:

y=>newb
x=>new

注意: y=$(x)b中不能是:=,否则无法影响y

(3)条件赋值?=

如果变量未定义,则使用符号中的值去定义变量;如果该变量已经赋值,则赋值语句无效。
例子:

x:=foo
y:=$(x)b
x?=new
test:
        @echo "y=>$(y)"
        @echo "x=>$(x)"

输出:

y=>foob
x=>foo

可以看出x?=new赋值无效,因为变量x已经赋值

(3)追加赋值+=

追加的结果为:原来的值+空格+新值

五、目标文件的搜索(VPATH和vpath)

1、VPATH

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可执行文件

2、vpath

vpath 是关键字,按照模式搜索,给出了搜索的条件
格式:

(1) vpath PATTERN DIRECTORIES 
vpath test.cpp src // 在目录src中搜索test.cpp
(2  vpath PATTERN
//除符合文件PATTERN 的搜索目录
(3)  vpath
//除所有已被设置的文件搜索路径

六、嵌套执行make

嵌套执行make的作用在于可以将不同模块编写一个Makefile文件,然后做最外层写总的Makefile文件控制所有的Makefile文件执行
格式:

subsystem:
    cd subdir && $(MAKE)

或者

subsystem:
    $(MAKE) -C subdir

其中,subdir目录是一个子目录,里面也有个Makefile文件;上面的执行步骤即为进入到子目录subdir执行Makefile文件。

参考:http://c.biancheng.net/view/7097.html

你可能感兴趣的:(c-c++,linux)