Makefile
Makefile工程管理
- 通过输入命令"make"启动Make工程管理对程序进行编译,Make启动后根据makefile文件中的编译规则命令自动对源文件进行编译链接,最终生成可执行文件。
- 为了提高编译程序效率,Make检查每个源文件的修改时间。只有在上次编译之后被修改的源文件才会在接下来的编译过程中被编译和链接。
Makefile语法
Makefile文件由三相基本内容组成。
- 需要生成的目标文件(target file)
- 生成目标文件所需要的依赖文件(dependency file)
- 生成目标文件的编译规则命令(command)
target file : dependency file
<Tab>Command
- 1
- 2
伪目标
- 伪目标不是真正的目标文件
- 通过伪目标执行规则命令,不用创建实际的目标文件
- 伪目标最好写在 .PHONY后面声明一下,否则如果当前文件夹下存在和伪目标相同的文件,则伪目标将失效
.PHONY : clean
clean:
rm -rf *.o
- 1
- 2
- 3
- 4
Makefile的进化之一
hello:main.c
gcc main.c -o hello
.PHONY : clean
clean:
rm -rf *hello
- 1
- 2
- 3
- 4
- 5
- 6
翻译过来就是,生成hello的目标文件依赖于main.c文件
通过gcc main.c -o hello命令方式生成hello目标文件
Makefile的进化之二——使用变量
- makefile中变量不需要类型,例如:定义变量 src=abc
- 取变量的值用 $(变量),例如:使用变量 $(src) ===> abc
target := a.out
obj := main.c
(
t
a
r
g
e
t
)
:
(target):
(target):(obj)
gcc $(obj) -o $(target)
.PHONY : clean
clean:
rm -rf $(target)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Makefile的进化之三——使用函数
和变量一样,函数也用符号 进 行 标 识 ‘ 进 行 标 识 ‘ 进 行 标 识 ‘ 进行标识‘进行标识‘ 进行标识 ` 进行标识‘进行标识‘进行标识‘进行标识‘(函数名 参数, 参数, 参数…)`
常见函数
函数名 | 用法 | 功能 |
---|---|---|
wildcard | $(wildcard *.c) | 匹配当前目录下所有.c 文件 |
patsubst | $(patsubst %.c, %.o, $(src)) | 把符合%.c模式参数,替换成%.o |
#使用“wildcard”函数获取工作目录下的.c文件列表
src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))
target = a.out
$(target) : $(obj)
gcc $(obj) -o $(target)
.PHONY : clean
clean:
-rm -rf $(target) $(obj)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
Makefile的进化之四——多文件make
src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))
target=a.out
all:$(target)
(
t
a
r
g
e
t
)
:
(target):
(target):(obj)
gcc $(obj) -o a.out
main.o:main.c
gcc -c main.c -o main.o
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
mul.o:mul.c
gcc -c mul.c -o mul.o
.PHONY : clean
clean:
-rm -rf $(target) $(obj) *.o
- 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
Makefile的进化之五——自动变量&模式匹配
自动变量 | 匹配 |
---|---|
$(@) | 代表规则中的目标文件 |
$(^) | 代表规则中的所有依赖文件 |
$(<) | 代表规则中的第一个依赖文件 |
模式匹配:
%.o:%.c
src = $(wildcard ./src/*.c)
obj = $(patsubst %.c, %.o, $(src))
target=a.out
all:$(target)
(
t
a
r
g
e
t
)
:
(target):
(target):(obj)
gcc $(^) -o $(@)
%.o:%.c
gcc -c $(^) -o $(@)
.PHONY:clean all
clean:
-rm -rf $(target) $(obj)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
Makefile的进化之六——工程模板
将src文件生成的目标文件.o放置obj目录下
产生的可执行文件a.out放置bin目录下
编译所需要的头文件包含在include目录下
├── bin
│ └── a.out
├── Makefile
├── obj
│ ├── add.o
│ ├── main.o
│ ├── mul.o
│ └── sub.o
|__ include
└── src
├── add.c
├── main.c
├── mul.c
└── sub.c
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
src = $(wildcard ./src/*.c)
obj = $(patsubst ./src/%.c, ./obj/%.o, $(src))
target=./bin/a.out
all:$(target)
(
t
a
r
g
e
t
)
:
(target):
(target):(obj)
gcc $(^) -o $(@)
$(obj):./obj/%.o:./src/%.c
gcc -c $(^) -I ./include -o $(@)
.PHONY:clean all
clean:
-rm -rf $(target) $(obj)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-095d4a0b23.css" rel="stylesheet">
</div>