Makefile 简单入门教程

一、简介

make 命令执行时,需要一个 Makefile 文件,以告诉 make 命令需要怎么样的去编译和链接程序(简单将: 管理工程的文件,决定先编译哪些文件,编译顺序)。

二、编写规则

目标 1: 目标依赖 (然后回车+tab 键)
命令

目标 2: 目标依赖 (然后回车+tab 键)
命令

目标 n: 目标依赖 (然后回车+tab 键)
命令

注意: 命令必须是 tab 键开头的, 不能是多个空格替代的 tab.

三、Makefile 演进

1、Makefile 常规思路

一个项目有 main.c/a.c/a.h/b.c/b.h 五个文件;main.c 包含 a.h 和 b.h 并使用相关函数;然后建立一个新的 Makefile 文件,内容如下:

1
2
3
4
5
6
main: a.o b.o
gcc -o main a.o b.o
a.o: a.c
gcc -c a.c -o a.o
b.o: b.c
gcc -c b.c -o b.o

2、Makefile 升级 1

采用 makefile 变量: 想用就用,没有类型,不需要定义(引用变量使用$(obj)来包含更多.o 文件)
方法: obj:=a.o b.o
那么上面的 Makefile 程序升级如下:

1
2
3
4
5
6
7
obj:=a.o b.o
main: $(obj)
gcc -o main a.o b.o
a.o: a.c
gcc -c a.c -o a.o
b.o: b.c
gcc -c b.c -o b.o

3、Makefile 升级 2

经过以上两个 makefile 的编译,项目执行是成功的,但是如果 main.c 需要引用更多文件中的函数时,是否要填写那么多的编译命令吗?显然这个方法不可取。
改进: makefile 特殊变量和自动推导功能
知识点说明:

  • $@ 代表目标名,
  • $^ 代表依赖文件
  • % 代表任意字符
  • %.o 代表任意.o 文件
  • %.c 代表任意.c 文件

以上 Makefile 升级如下:

1
2
3
4
5
6
7
obj:=a.o b.o
main: $(obj)
gcc -o main $(obj)
%.o: %c #注释: 模式通配,自动将.c文件编译成.o文件
gcc -o $@ -c $^ #注释: 通配符
clean:
rm -rf *.o main

4、Makefile 升级 3

1
2
3
4
5
6
7
8
exe=main      #注释: 最后的编译结果名字
obj:=main.o a.o b.o c.o #注释: 依赖文件
all: $(obj)
gcc -o $(exe) $(obj)
%.o:%.c
gcc -c $^ -o $@
clean:
rm -rf $(obj) $(exe)

以上程序看似没有什么问题的,但是 clean 有点瑕疵,要是也有一个文件叫 clean 那怎么办?如果 make clean 就没办法执行这条命令。

5、Makefile 升级 4

使用伪目标.PHONY 来解决 clean 瑕疵问题,升级 Makefile 如下:

1
2
3
4
5
6
7
8
9
exe:=main
obj:=main.o a.o b.o c.o
all: $(obj)
gcc -o $(exe) $(obj)
%.o:%.c
gcc -c $^ -o $@
.PHONY: clean #注释: 声明clean是伪目标
clean:
rm -rf $(obj) $(exe)

注释#.PHONY:clean 声明伪目标,避免当前目录存在名字为 clean 文件的时候命令不能执行的情况

6、Makefile 升级 5

有时使用的编译器可能是 g++、gcc 甚至是 arm-linux-gcc。为了方便统一管理,最好开头定义一个变量来代表编辑器,然后在 gcc 命令上变成$(CC):
Makefile 升级如下:

1
2
3
4
5
6
7
8
9
10
CC:=gcc    #注释: 定义一个变量,表示当前编辑器为gcc
exe:=main
obj:=main.o a.o b.o c.o
all: $(obj)
$(CC) -o $(exe) $(obj)
%.o: %.c
$(CC) -c $^ -o $@
.PHONY: clean
clean:
rm -rf $(obj) $(exe)

基本上现在的 Makefie 可以编辑很多普通的程序了。秩序要对 Makefile 的文件名适当稍加修改即可。如果在比较大型的程序里面写 Makefile 会相对知识点多一点,比如添加静态库、动态库、线程等等;后续再做升级。

本文章非原创, 来源: https://www.linuxidc.com/Linux/2017-06/145306.htm

Donate - Support to make this site better.
捐助 - 支持我让我做得更好.