Maine

纵有疾风起,人生不言弃

Makefile 学习

1. make

make 是 Linux 自带的构建器,构建规则依赖于 makefile

2. makefile

2.1 命名

Makefile / makefile

2.2 规则

  1. 目标、依赖、命令

    目标:依赖

    (tab)命令

    app:main.c a.c b.c
     gcc main.c a.c b.c -o app
  2. makefile 由一条或多条规则组成

2.3 书写makefile

  1. Version 1.0
app:main.c a.c b.c
    gcc main.c a.c b.c -o app
  • 执行效率低下,每次更改代码需要重新编译整个项目
  1. Version 2.0
app:main.o a.o b.o
    gcc main.o a.o b.o -o app
a.o:a.c
    gcc -c ./a.c
b.o:b.c
    gcc -c ./b.c
b.o:b.c
    gcc -c ./b.c
  • 冗余,稍后解决

2.4 工作原理

  1. 检测依赖是否存在

    • 如果不存在,向下找规则,如果规则是用来生成依赖的,则执行相应命令
  2. 依赖存在

    • 判断是否需要更新,以便重新生成依赖

      原则:目标时间需要大于依赖的时间

2.4 变量

  1. 自定义定义变量
name=app
  1. 使用自定义变量
gcc ./*.c -o $(name)
  1. makefile 自带变量 – 大写
CPPFLAGS
CC
...
  1. 自动变量(只能在命令中使用)
[email protected] : 规则中的目标
$< : 规则中的第一个依赖
$^ : 规则中的所有依赖
  1. 模式匹配 %,相当于通配符

Version 3.0

obj = main.o a.o b.o
target = app
$(target):$(obj)
    gcc $^ -o [email protected]
*.o:*.c
    gcc -c $^ -o [email protected]
  • 可移植性比较差

2.5 函数

  1. Makefile 所有函数都有返回值,调用时需要用 ${} 包裹
  2. 查找指定目录下指定类型的文件
src = ${wildcard ./*.c}
  1. 匹配替换
obj = ${patsubst %.c, %.o, ${src}}

Version 4.0

src = ${wildcard ./*.c}
obj = ${patsubst %.c, %.o, ${src}}
target = app
$(target):$(obj)
    gcc $^ -o [email protected]
*.o:*.c
    gcc -c $^ -o [email protected]
  • 不能清理项目

2.6 补充内容

version 5.0

src = ${wildcard ./*.c}
obj = ${patsubst %.c, %.o, ${src}}
target = app
$(target):$(obj)
    gcc $^ -o [email protected]
*.o:*.c
    gcc -c $^ -o [email protected]

.PHONY:clean
clean:
    -rm -f ${target} ${obj}
  1. make 指定目标,可以使用如下命令
make target
  1. 创建一个伪目标(不进行更新检测)
.PHONY:clean
  1. 忽略执行错误(命令前加 -

2.7 测试 makefile

# 创建一些基本变量
src_dir = ./src/
build_dir = ./build/
target = demo
include_path = ./include/

# 自动读取 src 目录下的 .c 文件,创建依赖变量
src = ${wildcard ${src_dir}*.c}
obj = ${patsubst ${src_dir}%.c, ${build_dir}%.o, ${src}}

# 主要规则
${target}:init ${obj}
    gcc ${obj} -o [email protected]

# 依赖生成规则
${build_dir}%.o:${src_dir}%.c
    gcc -I ${include_path} -c $< -o [email protected]

# 创建 build 目录
.PHONY:init
init:
    -mkdir ${build_dir}

# 自动清理
.PHONY:clean
clean:
    rm -rf ${target} ${obj} ${build_dir}
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注