linux下的makefile简略介绍

makefile介绍

  • makefile有点类似于windows中的vs一下,它定义了一些规则来指定,哪些文件需要先编译哪些文件需要后编译,甚至一些更复杂的操作,makefile也可以写shell脚本一样的命令。makefile相比于在shell下一直使用gcc去写方便的是只需要一个make命令就可以搞定,比如在当前目录使用make
  • makefile中会使用gcc去对源代码进行编译,生成.o或者可执行文件。
  • makefile的命名规则:makefile或Makefile。

makefile的基本规则

makefile由一组规则组成,规则如下:

目标:依赖
(tab)命令

①目标:要生成的目标文件,比如main
②依赖:目标文件由哪些文件生成比如main.c
③命令:通过执行这条命令由依赖生成目标例如gcc -o main main.c
下面举个例子来更清楚的了解下如何使用makefile:
当前目录下,有一个main.c fun1.c fun2.c sum.c,根据这个依赖生成可执行文件main。
(1)第一次

#在当前文件夹下 vi makefile
#然后在makefile里面输入
main:main.c fun1.c fun2.c sum.c
	gcc -o main main.c fun1.c fun2.c sum.c -I./

不过这明显可以看出效率很低,如果文件很多,我们就要疯狂输入。
通过这个我们来说明下makefile的原理:
若想生成目标文件,就要检查规则的依赖是否存在。依赖存在与否,又可以分为下面两种情况:
依赖存在:检查规则中是否需要更新,比如你main是之前生成的,main.c的内容后面经过了修改,它会对比这个时间,判断你修改时间先后,再去进行重新生成。
依赖不存在:如果依赖不存在,那么往下面找,如果下面能找到这个依赖生成,那么先执行下面那条,再回过来执行上面的。如果到结束都没找到生成这个依赖的,那么就报错。
(2)第二次

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

这里我们可以发现,它其实从main.o到sum.o这里,代码出现了冗余,就是很多重复的,这样编写起来还挺麻烦的。所以我们引入了makefile的变量来进行改善。

makefile中的变量

makefile中的变量有点类似于C语言的宏定义,相当于替换一样,使用变量可以使makefile方便维护,修改起来更加简单。
makefie有三种类型的变量:
①普通变量
变量定义直接用“=”符号
使用变量值用“$(变量名)”。举个例子

hello = world //定义变量并赋值
hi = $(hello)  //使用变量

上面定义了两个变量hello和hi,其中hi的值士hello值的引用。
②自带变量
除了使用用户自定义的变量,makefile中也提供了一些变量供用户直接使用,我们可以直接对其进行赋值。

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

③自动变量

$@:表示规则中的目标
$<:表示规则中的第一个条件
$^:表示规则中的所有条件,组成一个list,以空格隔开,如果有重复选项则消除重复项。
注意:自动变量只能再规则的命令中使用

还有一个“%”的使用,如果目标中有“%”,在依赖条件中同样可以使用“%”,依赖条件中的“%”取决于其目标:
比如第二次中有好多次的.o和.c,他们都是xx.o:xx.c,我们我们就可以用%来代替xx,这样通过%和我们的变量就形成了我们的第三次
(3)第三次

target=main
object main.o fun1.o fun2.o sum.o
CC=gcc
CPPFLAGS=-I./

$(target):$(object)
	$(CC) -o $@ $^
%.o:%.c
	$(CC) -o $@ -c $< $(CPPFLAGS)

这样是不是比第二次简洁多了。
下面我们引入makefile的函数来进行第四次操作。

makefile函数

makefile中函数有很多,基本只要知道最常用的就行,wildcard和patsubst是最常用的,下面对他们进行介绍。

1.wildcard —— 查找指定目录下的指定类型的文件
	src=$(wildcard *c) //找到当前目录下所有后缀为.c的文件,并赋值给src
2.patsubst——匹配替换
	obj=$(patsubst %.c,%.o,$(src))//把src变量里所有后缀为.c的文件变成.o的文件

通过上面两个函数,我们就出现了第四次的版本

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

$(target):$(object)
	$(CC) -o $@ $^
%.o:%.c
	$(CC) -o $@ -c $< $(CPPFLAGS)

这次可以说基本都涉及了,而且都不用怎么修改,不过还存在的一个就是,它每次生成的.o文件和目标文件在每次编译前都需要进行手动rm。下面就介绍怎么清理。

makefile的清理操作

用途:用来清理生成的.o和目标文件
使用方法:make clean,如果当前目录下有同名clean文件,则不执行clean对应的命令,解决方案:
伪目标声明:
.PHONY:clean
声明目标为伪目标之后,makefile将不会检查该目标是否存在或该目标是否需要更新。

  • clean命令中的特殊符号:
    • “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
    • rm -f:强制执行,比如若要删除的文件不存在使用-f不会报错。
    • “@”不显示命令本身,只显示结果。如果“@echo clean done”
  • 其它
    • make 默认执行第一个出现的目标,可通过make dest指定要执行的目标
    • make -f:-f执行一个makefile文件名称,使用make执行执行的makefile:make -f mainmak
      通过清理就出现了第五个版本
target=main
object main.o fun1.o fun2.o sum.o
CC=gcc
CPPFLAGS=-I./

$(target):$(object)
	$(CC) -o $@ $^
%.o:%.c
	$(CC) -o $@ -c $< $(CPPFLAGS)
.PHONY:clean
clean:
	-rm -f $(target) $(object)

这也是使用比较多的,综合了变量、函数、模式规则和清理命令。
参考资料:
某机构的学习笔记

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值