makefile

规则
变量
函数
条件执行
文件,文件名处理函数
文件包含
注释

解析阶段:

  • 解析makefile,建立依赖关系树
  • 控制解析过程:引入makefile,变量展开,条件执行
  • 生成关系树

编译阶段:根据依赖关系树和时间戳编译

  • 载入关系树
  • 根据关系树和时间戳,执行操作

规则

作用:
目的:生成依赖关系树
目标:依赖
操作

  • 规则可以无依赖,仅仅实现某种操作
  • 规则可以无命令,仅仅描述依赖关系
  • 规则必须有一个目标,可以有多个目标

隐式规则

make预定义了一些规则,如将.c编译成.o

hello:hello.o
  gcc -o hello hello.o

上面没有定义 hello.o的规则,但是可以生成make,
因为make以定义了%.o的规则,
所以上面的makefile相当于

hello:hello.o
  gcc -o hello hello.o
hello.o:hello.c
  gcc -o hello.o -c hello.c

目标

默认目标
第一个目标为默认目标

合并目标
多个目标,具有相同规则,相同依赖,会被合并为一个目标
all:a1 a2

a1:a3
echo "1111"

a2:a3
echo "1111"
被合并为
all:a1 a2
a1 a2:a3
echo "1111"

合并依赖
目标相同,依赖不同,合并依赖,注意,目标不能有规则
all:a1
all:a2

a1:
echo "1111"
a2:
echo "2222"

合并为
all:a1 a2
a1:
echo "1111"
a2:
echo "2222"

伪目标
不比较是否重新执行,可无条件执行

依赖

更新
非伪目标时,依赖文件时间戳新于目标文件时间戳,执行操作

隐式依赖
%.o:%.c

模式匹配

命令

shell命令组成,tab开头

每条命令,make开一个进程
进程执行完,make检查返回码,
成功则继续执行,失败则退出

变量

定义
CC=gcc

赋值
追加赋值 +=
条件赋值 ?= ,若没有赋值,则赋值

引用
$(CC) ${CC}

立即展开变量
使用:=,在解析阶段直接赋值常量字符串
延迟展开
使用=,在运行阶段 使用 运行时值赋值

注意:
通常,目标,依赖 使用立即展开变量,命令 中使用延迟展开

作用域
一般变量:全局变量
目标变量:规则作用域

N=0
all:a1 a2
a1:N=1
a1:
  echo "a1 N=${N}"
a2:
  echo "a2 N=${N}"

模式变量

N=0
all:a1 a2
a%:N=1
b%:N=2
%:
  echo "$@ N=${N}"

自动变量
为局部变量
目标:$@
所有依赖:$^
第一个依赖 : $<

环境变量
所有makefile可以直接引用,
若makefile定义了同名变量,则覆盖

变量传递

  • 递归make
    make -C subdir
    相当于
    cd subdir && make
  • 通过export传递变量
  • 通过命令行传递变量

条件执行

  • 关键字
    ifeq else endif ifneq
ifeq($(DEBUG), true)
CC=gcc -g
else
CC=gcc
endif

函数

函数名,参数,返回值
返回值为字符串
$(函数名 参数1, 参数2, 参数3)

posted on 2021-12-30 11:50  开心种树  阅读(157)  评论(0编辑  收藏  举报