make的使用
关于make与makefile
make工具通过makefile文件描述的规则对工程中的源文件进行自动编译。
makefile规则
target: prerequisite
command
其中,target为目标文件(.o)或可执行文件(也可为伪目标);prerequisite为target的先决条件;command为命令(command需另起一行且前有tab)。由target、prerequisite和command组成的makefile描述的规则如下:
- target的生成依赖于prerequisite,而通过prerequisite生成target的方法由command确定
- makefile中第一个target被视为最终生成的文件
- 若某个target不存在,或prerequisite中任一文件新于target,则command被执行
- 若某个target不存在且prerequisite中某文件亦不存在,则在makefile中找到此文件的依赖关系并生成该文件(逐层深入最终生成首个taget所依赖的全部文件,亦即所有与首个target相关的命令均会被执行)
- makefile使用\作为换行符(换行符后不能有空格),使用#作为注释符
makefile示例
main: main.o safe.o sound.o g++ main.o safe.o sound.o -o main main.o: main.cpp g++ -c main.cpp safe.o: safe.cpp g++ -c safe.cpp sound.o: sound.cpp g++ -c sound.cpp clean: rm main.o safe.o sound.o
*注:
clean不与main有直接或间接的依赖关系,因此不会被自动执行,需要通过make clean命令手动清除目标文件;
由于.o文件的生成仅依赖于.cpp文件,因此当某些.h文件发生变化后,不会重新编译,因此clean目标文件十分必要;
与g++编译命令的只需要对源文件(.cpp)执行操作(不需要包含头文件,头文件已在源文件中使用include预处理指令包含)不同,makefile的依赖文件中需包含头文件。
在makefile中使用变量
通过“=”在makefile中声明变量(类似于C++中的宏),并通过“$()”使用变量:
- 声明变量
argname = filename1 filename2
- 使用变量
main: $(argname)
g++ -o main $(argname)
使用变量的makefile示例:
obj = main.o safe.o sound.o xx = g++ main: $(obj) $(xx) $(obj) -o main main.o: main.cpp $(xx) -c main.cpp safe.o: safe.cpp safe.h $(xx) -c safe.cpp sound.o: sound.cpp sound.h $(xx) -c sound.cpp clean: rm main.o safe.o sound.o
makefile隐晦规则
make可以自动推导taget所需的prerequisite及要执行的command,即由目标文件(.o)可以推导出所需的源文件(.c),并进一步推导出要执行的命令g++ -c,由此,上面的makefile示例可简化为:
obj = main.o safe.o sound.o xx = g++ main: $(obj) $(xx) $(obj) -o main .PHONY: clean clean: rm main.o safe.o sound.o
其中的.PHONY显示指出clean是一个伪目标,可防止clean后若有除rm外的其他command而引发错误。
makefile中的通配符
- *:任意一个或多个字符
- ?:任意一个字符
- [...]:[]内任意一个字符;[^...]:除[]内的字符;[0-9]:0至9中任意一个数字
- ~:用户的home目录
其他
- 在command前加上“-”前缀可忽略错误继续执行,如:
clean: -rm main.o safe.o sound.o
使用g++的-MM选项可以显示源文件(.cpp)的依赖关系,此依赖关系可用于指导编写makefile文件:
g++ -MM main.cpp
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)