Makefile详解

Makefile 简介

  • Makefile作用:记录依赖关系和编译规则;
  • Makefile三要素:目标、依赖、命令
  • Makefile基本格式:
    目标:依赖的文件或者其他目标
    <tab>命令1
    <tab>命令2
  • 设置伪目标:.PHONY: clean
  • 指定Makefile文件:make -f Makefile2

Makefile变量及模式规则

  • 自定义变量
符号 含义
= 延时赋值(调用时赋值)
:= 立即赋值
?= 空赋值(变量为空时赋值)
+= 追加赋值(不覆盖原值,在后面追加)
  • 自动化变量

    1. $< 第一个依赖文件
    2. $^ 所有的依赖文件
    3. $@ 目标文件
  • 模式匹配:%匹配任意多个非空字符

  • 默认规则:.o文件默认.c文件编译

Makefile条件分支

1
2
3
4
5
ifeq(var1,var2)       |         ifneq(var1,var2)
... | ...
else | else
... | ...
endif | endif

Makefile常用函数

  • patsubst(模式替换函数): ${patsubst pattern, replace_pattern, text} %作通配符
  • notdir(取文件名函数): ${notdir .../.../name}去掉目录部分只取文件名
  • wildcard(取匹配文件名函数):${wildcard pattern}取当前目录下所有符合pattern模式的文件名,*作通配符
  • foreach(遍历函数):${foreach var, list, text}将list中每一个单词赋值给var,然后在text中使用var

编写Makefile

  • 创建目录用于存储编译过程中生成的文件:BUILD_DIR
  • 源文件目录(存放.c及.s后缀文件):SRC_DIR
  • 头文件目录(存放.h文件):INC_DIR
  • 搜索路径关键字:VPATH
  • 编译器头文件路径:CFLAGS -I + 头文件路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
ifeq (${ARCH},x86)   //判断当前编译环境 win上编译命令:make ARCH=x86
CC = gcc
else
CC = arm-linux-gnuenbihf-gcc
endif

TARGET = output //输出可执行文件名
BUILD_DIR = build //生成文件储存目录
SRC_DIR = . //源文件存储于当前面目录
INC_DIR = . //头文件存储与当前目录

SOURCES_C = ${foreach dir,${SRC_DIR},${wildcard ${dir}/*.c}} //所有.c文件路径
SOURCES_S = ${foreach dir,${SRC_DIR},${wildcard ${dir}/*.s}} //所有.s文件路径
INCLUDES = ${foreach dir,${INC_DIR},${wildcard ${dir}/*.h}} //所有头文件路径
OBJS = ${patsubst %.c,${BUILD_DIR}/%.o,${notdir ${SOURCES_C}}} //.c文件生成的.o文件名
OBJS += ${patsubst %.s,${BUILD_DIR}/%.o,${notdir ${SOURCES_C}}} //.s文件生成的.o文件名
VPATH = ${SRC_DIR} //编译器搜索路径为源文件路径
CFLAGS = ${patsubst %,-I%,${INC_DIR}} //编译器头文件路径

${BUILD_DIR}/${TARGET}:${OBJS}
${CC} $^ -o $@ ${CFLAGS}

${BUILD_DIR}/%.o:%.c ${INCLUDES} | create_build
${CC} -c $< -o $@ ${CFLAGS}

.PHONY:clean create_build //伪目标

clean: //make clean时执行清除rm命令
rm -r ${BUILD_DIR}


create_build: //创建build目录
mkdir -p ${BUILD_DIR}


Makefile详解
http://example.com/2022/09/21/Makefile/
作者
Hector
发布于
2022年9月21日
许可协议