首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
数据库
›
SQL-Server
›
初识Linux —— make和makefile主动化构建工具 ...
返回列表
发新帖
初识Linux —— make和makefile主动化构建工具
[复制链接]
发表于 2025-11-23 17:52:54
|
显示全部楼层
|
阅读模式
什么是make/makefile
本篇文章对于图片即内容详解,已同步到博主gitee:根本工具利用/make和makefile.png - 积极学习的小廉
在之前写
代码
的过程中,我们都是对一个文件举行编译链接(gcc编译),但是如果一个项目中,源
代码
文件非常的多,我们总不能一个一个的举行编译链接,这也太贫苦了;以是现在就来学习make/makefile实现主动化构建
make是一个下令工具,是一个表明makefile在指令的下令工具,大多数的IDE都存在这个下令。
makefile成为一种在工程方面的编译方法。
makefile是一个文件,make是一个下令;二者搭配利用来完成项目的主动化构建
makefile的长处就是主动化构建,写好makefile文件以后就只需make下令就可以完成项目工程的主动化构建,提点高了软件开辟的服从
实在会不会写makefile文件,也侧面反映了其是否具备完成大型工程的本领
在一个工程中源
代码
文件,按照范例、
功能
、模块分别放到了多少个目次下,makefile界说一系列的规则来指定哪些文件须要先编译、哪些文件须要后编译,哪些文件须要重新编译,乃至举行更加复杂的利用。
makefile根本利用
起首先来看一个makefile怎样利用(以及怎样编写)
现在有一个已经写好的makefile文件(这里简单利用一下)
我们在当前目次下编写一个code.c文件,而且写上一个简单的代码
现在就来利用make下令
我们看到,利用make下令就主动编译code.c文件形成code可实行步调了。
现在就来看一下makefile中内容有和寄义呢?
code:code.c
gcc code.c -o code
.PHONY:clean
clean:
rm -f code
复制代码
1. 依靠关系和依靠方法
对于上述makefile文件,在先容之前我们先来想要个题目,就是依靠关系和依靠方法
依靠关系:所谓依靠关系就表明两个事物(这里指目的文件和依靠文件)之间关系(就像实际生存中两个人之间的关系一样)
依靠方法:有了依靠关系,那应该做什么呢?,依靠方法就表明(这里表现要怎样天生目的文件);(就像实际生存中,你须要向朋侪寻求资助,有了你们是朋侪这一关系,接下来就要表明你要做什么了)
相识了依靠关系和依靠方法,接下来看目的文件和依靠文件
目的文件和依靠文件,实在就是两个有着依靠关系的文件(依靠文件可以有多个),如上图就表现code依靠code.c文件
而依靠关系就表明白,怎样由依靠文件列表天生目的文件。
如许我们就很好明白了,上述makefile文件中,code作为目的文件、code.c作为依靠文件、通过依靠关系gcc code.c -o code来天生目的文件。
2. 伪目的.PHONY
对于上述makefile,我们连续实行多次make就会发现,不能实行
但是我们如果连续指向多次make clean,它并没有堕落
到这里一个大概想到是.PHONY的作用了;那这到底是什么呢?又为什么被称为伪目的呢?
伪目的:.PHONY修饰,伪目的它总是被实行的;像clean这种的目的文件,一样平常都设置成伪目的
对于这个,可以表明为:
伪目的clean不依靠于任何文件,实行make clean天生clean目的文件就会实行依靠方法rm -f code;但是依靠方法并没有天生clean文件,而是删除code文件,做清算工作。
这里固然说clean是一个目的文件,但在依靠方法中并没有天生clean文件。(大概是由于没有天生clean目的文件,才称为伪目的)
3. ACM时间
对于上述的伪目的可以或许不绝被实行,而其他就不可以或许连续实行;又是怎样实现的呢?
先来相识什么是ACM时间
Access :文件迩来访问的时间
Modify :文件内容迩来修改的时间
Change :文件属性迩来修改的时间
那我们如果想要看一个文件的ACM时间,就要用到新的指令stat了。
那又是根据哪个时间来判定是否实行呢?
答案是Modify文件内容修改时间
我们可以看到上图中目的文件的Modify时间是晚于依靠文件的,以是就不能为实行。
细致观察可以看出来,上图Change时间目的文件也晚于依靠文件啊,如许不能分析比力的是Modify时间啊
现在接着来看
我们可以看到,依靠文件code.c的Change时间晚于目的文件code的Change时间照旧不可以或许实行;
那现在我们就可以或许得出结论,只有当依靠文件的Modify时间晚于目的文件的Modify时间时(在编译事后,依靠文件内容有所修改),才气够被实行。
这里.PHONY之以是能不绝被实行,其缘故因由就是它忽视了对比时间。
4. 推导过程
在上述过程中,我们写的依靠文件都是在当前目次中直接存在的;拿如果依靠文件并没有直接存在,而是依靠于其他依靠文件呢?
这里就根据编译过程,天生编译过程中全部的暂时文件,来写makefile
code:code.o
gcc code.o -o code
code.o:code.s
gcc -c code.s -o code.o
code.s:code.i
gcc -S code.i -o code.s
code.i:code.c
gcc -E code.c -o code.i
.PHONY:clean
clean:
rm -f *.i *.s *.o code
复制代码
如上述,code依靠于code.o、code.o依靠于code.s、code.s依靠于code.i、code.i依靠于code.c。这些除了code.c以为的文件都没有直接存在于当前目次下。
如许依然可以运行,而且都天生了这些文件;这足以分析应该存在可以推导的过程。
扩展语法——更加通用的makefile
上面所形貌的makefile它只能实用于一个文件,拿对于多个文件也是无济于事(还要重新写makefile)
这就一点太贫苦了,现在就来学习更多makefile语法,让makefile变得更加实用。
1. 创建变量
在makefile中也可以创建变量,和C语言中指针那样
BI
N=code
SRC=cpde.c
OBJ=code.o
CC=gcc
RM=rm -f
$(
BI
N):$(OBJ)
gcc $(OBJ) -o $(
BI
N)
$(OBJ):$(SRC)
gcc -c $(SRC) -o $(OBJ)
.PHONY:clean
clean:
$(RM) $(OBJ) $(BIN)
复制代码
上述中比方BIN=code、SRC=code.c
如许的就是创建了变量,(它们就像`C语言中的指针);
在须要访问这些变量的值的时间须要用到$()(就比如$(BIN)访问BIN变量的值)
这里尚有优化一下,利用$^和$@
$^:在依靠方法中利用,指依靠关系中的依靠文件
$@:在依靠方法中利用,指依靠关系在的目的文件
全部就可以如许来写:
BIN=code
SRC=cpde.c
OBJ=code.o
CC=gcc
RM=rm -f
$(BIN):$(OBJ)
gcc $^ -o $@
$(OBJ):$(SRC)
gcc -c $^ -o $@
.PHONY:clean
clean:
$(RM) $(OBJ) $(BIN)
复制代码
2. 编译当前目次下的多个文件
说了这么多,这照旧只能编译一个文件,现在就来看怎样编译当前目次下的多个文件
要想编译多个文件,那我们就不能给变量如许赋值了
SRC=code.c
复制代码
如许就写死了,只能利用一个文件;现在我们须要的是,辨认到当前目次下以是的.c文件
获取当前目次下全部的.c文件
方法有两种:
$(shell ls *.c) :在makefile中实行shell下令,获取当前目次全部的.c文件。
$(wildcard *.c) :利用wildcard函数,获取全部的.c文件。
将全部的.c修改成.o
这里,我们并不是直接天生code可实行步调的,而是天生对应的.o文件,再链接形成的可实行步调;以是我们就须要获取全部.c文件对于的.o文件名;(利用makefile语法即可)
OBJ=$(SRC:.c=.o)
复制代码
这个语法就是将SRC(获取当前目次下全部.c文件)中的.c更换成.o;如许我们就获取到了全部.c文件对应的.o文件名。
通配符%和逐个实行$<
上面经常写到*.c,它就表现全部以.c末端的文件;那在写makefile的利用,偶然候也要用到通配符,但是我们没有利用*,而是利用%。
我们想要让它编译多个文件就不能像之前那样写了,(由于这里我们要天生全部.c文件对应的.o文件。
如许我们在写由.c天生.o文件时,就能直接利用通配符%,如许就可以主动匹配
在匹配竣事之后,目的文件依靠多个文件;就不能利用$^直接取依靠文件列表了,而是利用%<将依靠文件列表中多个文件一个一个实行。
到这里,我们就能根本完成编译当前目次下全部.c文件的makefile了。
BIN= codeSRC=$(shell ls *.c)OBJ=$(SRC:.c=.o)
CC=gccRM=rm -f$(BIN):$(OBJ) gcc $^ -o $@$(OBJ):$(SRC) gcc -c $^ -o $@.PHONY:cleanclean: $(RM) $(OBJ) $(BIN)
复制代码
3. 测试和优化makefile
对于上述的makefile,我们举行一些优化
BIN= codeSRC=$(shell ls *.c)OBJ=$(SRC:.c=.o)
CC=gccRM=rm -fCOM=-cLINK=-o$(BIN):$(OBJ) $(CC) $^ $(LINK) $@%.o:%.c $(CC) $(COM) $<.PHONY:cleanclean: $(RM) $(OBJ) $(BIN)
复制代码
这里优化,新增了COM编译选项、LINK链接选项;而且都利用变量,更将通用。
在举行测试之前,我们要先让当前目次有多个文件,这里先容应该语法
touch code{1..20}.c
复制代码
该指令作用是创建code1.c、code2.c、code3.c......code20.c(20个文件)。
现在该目次下新建了20个文件,运行一试
可以看到,它会表现出来编译的过程,如果不想要看到可以在语句前加上@。
BIN= codeSRC=$(shell ls *.c)OBJ=$(SRC:.c=.o)
CC=gccRM=rm -fCOM=-cLINK=-o$(BIN):$(OBJ) @$(CC) $^ $(LINK) $@%.o:%.c @$(CC) $(COM) $<.PHONY:cleanclean: $(RM) $(OBJ) $(BIN)
复制代码
如许我们不知道它编译的进度了,我们就可以手动回显一些内容(在依靠关系中直接添加输出到表现器文件的语句即可)
BIN= codeSRC=$(shell ls *.c)OBJ=$(SRC:.c=.o)
CC=gccRM=rm -fCOM=-cLINK=-o$(BIN):$(OBJ) @$(CC) $^ $(LINK) $@ @echo "link...$^"%.o:%.c @$(CC) $(COM) $< @echo "compile...$^".PHONY:cleanclean: $(RM) $(OBJ) $(BIN)
复制代码
留意:这里在echo语句前也要加@不让它回显,否则就会回显出来echo语句的内容。
实行效果展示
到这里makefile部分就竣事了,后续有要深入相识的语法知识,在后续过程在继承学习。
我的博客即将同步至腾讯云开辟者社区,约请各人一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2oul0hvapjsws
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
回复
使用道具
举报
返回列表
何小豆儿在此
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表