makefile编写规则


一、makefile编写规则

makefile由一组规则组成 :

目标 : 依赖

tab )命令

注意:命令前面的是 tab 键!

二、makefile工作原理

工作原理:

若想生成目标 , 检查规则中的所有的依赖文件是否都存在:如果有的依赖文件不存在, 则向下搜索规则 , 看是否有生成该依赖文件的规则,如果有规则用来生成该依赖文件, 则执行规则中的命令生成依赖文件 ;如果没有规则用来生成该依赖文件 , 则报错。

更新:

如果所有依赖都存在,检查规则中的目标是否需要更新,必须先检查它的所有依赖,依赖中有任何一个被更新,则目标必须更新。( 检查的规则是哪个时间大哪个最新)

三、实例

例:目录下有 main.c、task1.c、task2.c ,根据这个基本规则编写一个简单的 makefile 文件 ,生成可执行文件 main.

第一个版本的 makefile:

main:main.c fun1.c fun2.c sum.c
(tab)gcc main.c fun1.c fun2.c sum.c -o main -I./

缺点 :效率低 ,修改一个文件,所有的文件会全部重新编译。

第二个版本的makefile :

main:main.o fun1.o fun2.o sum.o
	gcc main.o fun1.o fun2.o sum.o-o main
	
main.o:main.c
	gcc -c main.c -o main.o-I./
fun1.o:fun1.c
	gcc -c fun1.c-o fun1.o
fun2.o:fun2.c
	gcc -c fun2.c-o fun2.o
sum.o:sum.c
	gcc -c sum.c-o sum.o

缺点: 冗余,若 .c文件数量很多,编写起来比较麻烦。

在makefile 中使用变量有点类似于 C 语言中的宏定义,使用该变量相当于内容替换,使用变量可以使makefile 易于维护,修改起来变得简单。
makefile有三种类型的变量:
普通变量
自带变量
自动变量

普通变量
变量定义: 直接用 =
使用变量值: 用 $( 变量名 )

如: 下面是变量的定义和使用

foo = abc // 定义变量并赋值
bar = $(foo) // 使用变量, $(变量名)

自带变量

除了使用用户自定义变量, makefile中也提供了一些变量(变量名大写)供用户直接使用 ,我们可以直接对其进行赋值:

CC = gcc #arm-linux-gcc
CPPFLAGS : C预处理的选项 -I
CFLAGS: C编译器的选项 -Wall -g -c
LDFLAGS : 链接器选项 -L -l

自动变量

$@ 表示规则中的目标
$^ 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项消除重复项
$\< 表示规则中的第一个条件
$? 第一变化的依赖

特别注意:自动变量只能在规则的命令中使用.

makefile的第三个版本 :

target=main
object=main.o fun1.o fun2.o sum.o
CC=gcc
CPPFLAGS=-I./
$(target):$(object)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) -c $\< -o $@ $(CPPFLAGS)

四、 makefile 函数

wildcard

wildcard – 查找指定目录下的指定类型的文件
src=$(wildcard \*.c) //找到当前目录下所有后缀为.c的文件,赋值给src

Patsubst

patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o

makefile的第四个版本 :

src=$(wildcard ./\*.c)
object=$(patsubst %.c,%.o,$(src))
target=main
CC=gcc
CPPFLAGS=-I./
$(target):$(object)
	$(CC) $^ -o $@
%.o:%.c
	$(CC) -c $\< -o $@ $(CPPFLAGS)

缺点: 每次重新编译都需要手工清理中间 .o文件和最终目标文件

makefile的清理操作

伪目标声明:

.PHONY:clean

声明目标为伪目标之后,makefile 将不会检查该目标是否存在或者该目标是否需要更新

clean 命令中的特殊符号:

此条命令出错 ,make也会继续执行后续的命令。如 :-rm main.o

rm -f: 强制执行 , 比如若要删除的文件不存在使用 -f 不会报错

makefile的第5个版本:

src=$(wildcard ./\*.c) #等价于src=main.c fun1.c fun2.c sum.c,其中wildcard - 查找指定目录下的指定类型的文件
object=$(patsubst %.c,%.o,$(src)) #等价于obj=main.o fun1.o fun2.o sum.o,其中,patsubst – 匹配替换
target=main
CC=gcc
CPPFLAGS=-I./

$(target):$(object)
	$(CC) -o $@ $^

%.o:%.c
	$(CC) -o $@ -c $\< $(CPPFLAGS)

.PHONY:clean
clean:
	-rm -f $(target) $(object)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值