是一系列规则,每个规则由目标、依赖、要执行的命令组成
目录如下:
├── main.c
├── makefile
├── test.c
└── test.h
makefile 如下:
hello: main.c test.c
gcc main.c test.c -o main
在执行make时,首先会去看依赖文件是否发生更新,如果更新了则重新编译。
目标:把链接和编译分成两个步骤进行
hello: main.o test.o
gcc main.o test.o -o hello
main.o:main.c
gcc -c main.c
test.o:test.c
gcc -c test.c
先进行编译,然后再链接
.PHONY: 伪目标名
.PHONY: clean all
all:hello hello2
echo "ok"
hello: main.o test.o
gcc main.o test.o -o hello
hello2: main.o test.o
gcc main.o test.o -o hello
main.o:main.c
gcc -c main.c
test.o:test.c
gcc -c test.c
clean:
rm -f *.o hello
自动变量 | 含义说明 | 示例结果(假设目标是 main.o ) |
---|---|---|
$@ |
目标文件名(target) | main.o |
$< |
第一个依赖文件(prerequisite) | main.c |
$^ |
所有的依赖文件,去重 | main.c utils.c |
$+ |
所有的依赖文件,不去重 | main.c utils.c main.c |
$* |
不包含扩展名的目标文件名 | main |
$? |
所有比目标更新的依赖文件 | main.c (如果它比 main.o 新) |
$$ |
在 makefile 中表示一个字面意义的 $ 符号 |
$ |
注意:这些自动变量一般只在规则的命令中使用有效,即
target: prerequisites
后跟
通配符 | 含义说明 | 示例匹配结果(假设目录中有多个 .c 文件) |
---|---|---|
* |
匹配任意长度的任意字符(不含 / ) |
*.c → 匹配所有 .c 文件如 main.c 、util.c |
? |
匹配任意一个字符 | ?.c → 匹配如 a.c 、b.c (只匹配一个字符) |
[...] |
匹配指定范围内的任意单个字符 | [mu]ain.c → 匹配 main.c 和 uain.c |
% |
模式规则中的通配符,匹配目标和依赖中的相同部分 | %.o : %.c → main.o : main.c |
✅
*
、?
、[...]
是 shell 通配符,用于文件查找(如$(wildcard *.c)
)
✅%
是 模式规则中的通配符,用于简化规则定义
示例:
.PHONY: clean all
CFLAGS = -Wall -g
targets = hello hello2
sources = main.c test.c
objects = main.o test.o
all: $(targets)
@echo "ok"
$(targets): $(objects)
gcc $(CFLAGS) $(objects) -o $@
%.o:%.c
gcc $(CFLAGS) -c $< -o $@
# main.o: main.c
# gcc $(CFLAGS) -c $< -o $@
# test.o:test.c
# gcc $(CFLAGS) -c $< -o $@
clean:
rm -f *.o hello hello2
是一个构建系统生成器。
它本身不直接构建你的软件,而是根据你编写的配置文件(通常名为 CMakeLists.txt)来生成本地构建系统所需的文件,例如 Unix 系统上的 Makefiles。
├── CMakeLists.txt
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── Makefile
│ ├── cmake_install.cmake
│ └── hello
├── main.c
├── makefile
├── test.c
└── test.h
其中CMakeList.txt:
cmake_minimum_required(VERSION 3.10)
# 限制CMake 最低版本
project(TEST)
# Project名
set(SOURCES main.c test.c)
# 设定好源文件
add_executable(hello ${SOURCES})
# 添加可执行程序