Makefile

什么是Makefile

  • 一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为Makefile文件就像一个shell脚本一样,也可以执行操作系统的命令。
  • Makefile带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大提高了软件开发效率。make是一个命令工具,是一个解释Makefile文件中指令的命令工具,一般来说,大多数IDE都有这个命令,比如Delphi的make,Visual C++的nmake,Linux下GNU的make。

Makefile文件命名和规则

  • 文件命名
    makefile 或者 Makefile

  • Makefile规则
    一个Makefile文件中可以有一个或者多个规则

目标…:依赖…
(Tab)命令(shell命令)
(Tab)…

目标:最终要生成的文件(伪目标除外)
依赖:生成目标所需要的文件或是目标
命令:通过执行命令对依赖操作生成目标(命令前必须Tab缩进)

Makefile中的其他规则一般都是为第一条规则服务的。

例1:

app:sub.c add.c multi.c div.c main.c
	gcc sub.c add.c multi.c div.c main.c -o app

工作原理

  • 命令在执行之前,需要先检查规则中的依赖是否存在

如果存在,执行命令
如果不存在,向下检查其他规则,检查有没有一个规则是用来生成这个依赖的,如果找到了,则执行改规则中的命令

  • 检查更新,在执行规则中的命令时,会比较目标和依赖文件的时间

如果依赖的时间比目标的时间晚,需要重新生成目标
如果依赖的时间比目标时间早,目标不需要更新,对应规则中的命令不需要被执行

例2:

app:sub.o add.o multi.o div.o main.o
	gcc sub.o add.o multi.o div.o main.o -o app
sub.o:sub.c
	gcc -c sub.c -o sub.o
...
main.o:main.c
	gcc -c main.c -o main.o

当main.c发生改变时,例2的写法只需要重新编译生成main.o和app,而例1需要全部重新编译。

变量

  • 自定义变量

变量名 = 变量值 var = hello

  • 预定义变量

AR:归档维护程序的名称,默认值为ar
CC:C编译器的名称,默认值为cc
CXX:C++编译器的名称,默认值为g++
$@:目标的完整名称
$<:第一个依赖文件的名称
$^:所有的依赖文件

  • 获取变量的值

$(变量名)

模式匹配

%.o : %.c
(%:通配符,匹配一个字符串,
两个%匹配的是同一个字符串)

例3:

# 定义变量
src = sub.o add.o multi.o div.o main.o
target = app
$(target):$(src)
	$(CC) $(src) -o $(target)
	
# 模式匹配
%.o:%.c
	$(CC) -c $< -o $@

函数

  • $(wildcard PATTERN…)

功能:获取指定目录下指定类型的文件列表
参数:PATTERN 指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
返回:得到的若干个文件的文件列表,文件名之间使用空格间隔
示例:
$(wildcard .c ./sub/.c)
返回值格式:a.c b.c c.c d.c e.c f.c

  • $(patsubst <pattern>, <replacement>, <text>)

功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符合模式<pattern>,如果匹配的话,则以<replacement>替换;
<pattern>可以包括通配符‘%’,表示任意长度的字符串。如果<replacement>中也包含‘%’,那么,<replacement>中的这个‘%’将是<pattern>中的那个‘%’所代表的字符串;
返回:函数返回被替换过后的字符串。
示例:
$(patsubst %.c, %.o, x.c bar.c)
返回值格式:x.o bar.o

例4:

# 定义变量
# add.c sub.c main.c multi,c div.c 
src = $(wildcard ./*.c)
objs = $(patsubst %.c, %.o, $(src))
target = app
$(target):$(objs)
	$(CC) $(objs) -o $(target)
	
# 模式匹配
%.o:%.c
	$(CC) -c $< -o $@
	

# 删除生成的 ".o" 文件,clean为伪目标
.PHONY:clean
clean:
	rm $(objs) -f
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值