无后缀的两种模式,任一字母大小写错误即错误
# 在makefile文件同级目录
# linux下
# Built for x86_64-pc-linux-gnu
make
# windows下
# Built for x86_64-w64-mingw32
mingw32-make
# 执行指定规则
make 完整规则名
下面列出示例文件目录。
众所周知,头文件不属于源文件,因此下文不会涉及。
.
├── add.c
├── head.h
├── main.c
├── makefile
└── sub.c
main.c
#include
#include "head.h"
int main() {
printf("1 + 2 = %d\n", add(1, 2));
printf("1 - 2 = %d\n", sub(1, 2));
}
head.h
#ifndef HH
#define HH
int add(int, int);
int sub(int, int);
#endif
add.c
int add(int x, int y) {
return x + y;
}
sub.c
int sub(int x, int y) {
return x - y;
}
以目标(s) : 依赖(s)
的规则形式
然后作用域内是以tab
开头。
一个makefile的第一个规则是主规则,后续规则是在主规则有需要时才执行。
# 目标(s) : 依赖(s)
# 此处的目标由下方规则生成
my_target.out : main.o add.o sub.o
gcc main.o add.o sub.o -o my_target.out
# 为第一条规则服务
main.o add.o sub.o : main.c add.c sub.c
gcc -c main.c -o main.o
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
变量分为三类
具体使用将在下文的例子中展示。
自定义变量必须有值,自动变量根据目标和依赖而定。
自动变量
自动变量 | 含 义 |
---|---|
$* | 目标文件的名称,不包含目标文件的扩展名 |
$@ | 目标文件的名称,包含文件扩展名 |
$^ | 所有不重复的依赖文件,这些文件之间以空格分开 |
$< | 依赖项中第一个依赖文件的名称 |
$? | 依赖项中,所有比目标文件时间戳晚的依赖文件,依赖文件之间以空格分开 |
$+ | 所有的依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能 包含重复的依赖文件 |
# 使用自动变量
my_target.out : main.o add.o sub.o
gcc $^ -o $@
# 模式匹配
# %是makefile中的通配符
%.o : %.c
gcc $< -c
my_obj += main.o
my_obj += sub.o
my_obj += add.o
my_target = my_target.out
# 使用自定义变量
# $() 或 ${}
$(my_target) : $(my_obj)
gcc $(my_obj) -o $(my_target)
%.o : %.c
gcc $< -c
为了展示函数效果,这里把目录结构变一下
.
├── head.h
├── main.c
├── makefile
└── src
├── add.c
└── sub.c
变量名 = $(wildcard 路径1 路径2)
变量名 = $(patsubst 原后缀, 新后缀, 源)
# 根据路径搜索文件
my_file = $(wildcard *.c ./src/*.c)
# 后缀名的替换
my_obj = $(patsubst %.c, %.o, $(my_file))
my_target = my_target.out
${my_target} : ${my_obj}
gcc ${my_obj} -o ${my_target}
# 不写-o $@ 默认生成当前目录下
%.o : %.c
gcc -c $< -o $@
效果
.
├── head.h
├── main.c
├── main.o
├── makefile
├── my_target.out
└── src
├── add.c
├── add.o
├── sub.c
└── sub.o
从上面的效果看到,我们会获得很多的.o文件和一个.out文件。
当我们需要清除的时候,除了写shell还能用makefile。
添加.PHONY : clear
这样在同路径下若有clear同名文件也能执行这个规则。
# 根据路径搜索文件
my_file = $(wildcard *.c ./src/*.c)
# 后缀名的替换
my_obj = $(patsubst %.c, %.o, $(my_file))
my_target = my_target.out
${my_target} : ${my_obj}
gcc ${my_obj} -o ${my_target}
%.o : %.c
gcc -c $< -o $@
# 用于删除的脚本
# 伪目标,不比较依赖和目标的时间戳
.PHONY : clear
clear :
rm $(my_obj) $(my_target)
参考:Makefile | 爱编程的大丙 (subingwen.cn)