makefile简述

makefile 基本语法

目标文件:依赖文件
[Tab] 命令

上述makefile语法被称为一组规则

  • 目标文件是此规则想要生成的文件
  • 依赖文件指生成目标文件所用到的其他文件,是一个文件列表
  • 命令指此规则中要执行的shell命令。一个命令独占一行,行首必须以Tab键开头。

make程序通过比较依赖文件和目标文件的mtime属性,判断是否执行命令。

当test2的mtime比test1新时,将执行相应的命令

test1:test2
    echo "test1"
maketest.png

当我门修改test1,此时test1的mtime比test2新,则不再执行命令


test1.png

伪目标

当makefile中有多个规则时,通过make <指定目标名> 的方式,可以单独执行目标名处的规则如:

jmp.png

ps:@可以在输出中屏蔽命令显示

然而,当target2的mtime比test1新时,make target2 将不执行对应命令,有时候我们希望有些命令不管在什么情况下都能执行,这时候就需要用到伪目标了。

当规则中不存在依赖文件时,这个目标文件名就被称为伪目标。它的作用就是为了纯粹的执行命令。为避免伪目标与真实目标同名,可以用.PHONY关键字来修饰它。

如:

all.png

一些约定的伪目标

phonytarget.png

递归式推导目标

现在有如下两个C文件和对应的makefile文件:

test1.c:

void my_print(char*);
void main(){
    my_print("hello world\n");
}

test2.c:

#include 

void my_print(char* str){
    printf(str);
}

makefile:

test2.o:test2.c
    gcc -w -c -o test2.o test2.c
test1.o:test1.c
    gcc -w -c -o test1.o test1.c
test.bin:test1.o test2.o
    gcc -w -o test.bin test1.o test2.o
all:test.bin
    @echo "done"

执行make all命令的流程如下:

  1. make 发现all的依赖文件test.bin不存在,就去寻址以test.bin为目标文件的规则
  2. 找到对应规则后,发现test.bin的依赖文件test1.o不存在,于是去找test1.o为目标文件的规则。
  3. 找到test1.o对应的规则后,执行gcc -w -c -o test1.o test1.c
  4. 回到test.bin对应规则,发现依赖文件test2.o不存在,于是去找test2.o为目标文件的规则。
  5. 找到test2.o对应的规则后,执行gcc -w -c -o test2.o test2.c
  6. 回到test.bin对应规则,执行gcc -w -o test.bin test1.o test2.o
  7. 回到all对应的规则,执行@echo "done"
makefiletest.png

自定义变量和系统变量

自定义变量

定义变量格式:变量名=值(字符串),多个值之间用空格分开

变量引用:$(变量名)

如上节中的makefile可以改为:

test2.o:test2.c
    gcc -w -c -o test2.o test2.c
test1.o:test1.c
    gcc -w -c -o test1.o test1.c
objfiles = test1.o test2.o
test.bin:$(objfiles)
    gcc -w -o test.bin test1.o test2.o
all:test.bin
    @echo "done"

系统变量

sys_var.png

自动化变量

自动化变量可以代表一组文件名。

以下为一些自动化:

$@ 表示规则中的目标文件名集合
$< 表示规则中依赖文件的第1个文件
$^ 表示规则中所有依赖文件的集合
$? 表示规则中,所以比目标文件mtime新的依赖文件集合

用自动化变量修改前面的makefile文件:

test2.o:test2.c
    gcc -w -c -o test2.o test2.c
test1.o:test1.c
    gcc -w -c -o test1.o test1.c
objfiles = test1.o test2.o
test.bin:$(objfiles)
    gcc -w -o $@ $^
all:test.bin
    @echo "done"

$@ 表示规则中的目标文件:test.bin

$^ 表示规则中的所以依赖文件:test1.o test2.o

规则模式

make支持字符串正则匹配

% 匹配多个非空字符

前面的mkefile可用匹配模式修改为:

%.o:%.c
    gcc -w -c -o $@ $^
objfiles = test1.o test2.o
test.bin:$(objfiles)
    gcc -w -o $@ $^
all:test.bin
    @echo "done"

你可能感兴趣的:(makefile简述)