makefile从入门到入门
makefile文件是用来帮助编译和管理C++项目代码的,需要配合make命令使用。makefile里也可以执行shell操作,具备一部分.sh脚本的功能。
makefile格式
makefile内容的编写按照如下规则
目标1:依赖1
命令1
目标2:依赖2
命令2
目标3:依赖3
命令3
.........................
目标N:依赖N
命令N
命令可以是任意的shell语句。多数情况下,命令都是起到了从依赖生成目标的功能。例如从.cpp文件生成.o文件,那么命令一定包括g++和一些编译参数的完整的编译命令。
目标1 2 3可以是嵌套依赖的,如果依赖1里包含目标2 目标3,那就是一种嵌套的依赖。也可以是独立的,例如目标1 2 3就是三个独立的可执行文件,或者三个动态库,那么他们之间是可以完全没有依赖关系的,写在一个makefile文件里只是便于统一管理。
命令前要以一个tab开头 。如果使用空格代替tab,执行make命令时会报
[root@localhost makefiletest]# make
makefile:5: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
举个例子
以下面简单的C++代码为例,说明makefile的具体使用。
源代码文件test.cpp
#include <string>
#include <iostream>
#include<iomanip>
int main(int argc, char** argv)
{
using namespace std;
int i =1 ;
int j = 2;
j += 3;
cout << j<<endl;
}
makefile文件,文件就是makefile
CC=g++
all = test.o
test: $(all)
$(CC) -o test $(all)
test.o: ./test.cpp
$(CC) -c test.cpp
clear:
rm -f *.o test
执行make命令
[root@localhost makefiletest]# make
g++ -c test.cpp
g++ -o test test.o
[root@localhost makefiletest]# ls -lrt
total 24
-rw-r--r--. 1 root root 196 Aug 6 11:00 test.cpp
-rw-r--r--. 1 root root 120 Aug 6 11:04 makefile
-rw-r--r--. 1 root root 2328 Aug 6 11:04 test.o
-rwxr-xr-x. 1 root root 8840 Aug 6 11:04 test
正确生成了test和test.o
例子讲解
makefile中的“目标1”test是个可执行文件,也是最终我们需要的东西。test依赖$(all)这个变量,文件开头定义了all = test.o,所以test依赖的是test.o,生成test的命令是$(CC) -o test $(all),进行变量替换后就是g++ -o test test.o,是一个我们熟知最基础的编译命令。
同理,“目标2”test.o依赖的是test.cpp,生成目标的命令是g++ -c test.cpp。
上面两个规则完成了从源代码到可执行文件的编译。
大型工程必须用makefile
其实我们直接执行g++ -o test test.cpp就可以生成test了,但这种直接敲命令只适用于代码文件很少的情况。
即使项目只有5个文件,每次代码更新都要敲5个编译命令也是很麻烦的。我们只要编写一次makefile,之后每次代码更新,或者代码文件有增减,都只需要修改makefile对应的一小部分内容,然后执行make就行了。
例如test依赖是100个.o文件,在上面的makefile中我们只要写一次all = test.o test1.o test2.o ..... test99.o,就把目标test的生成规则表达清楚了。当然下面要写上100个.o文件的生成规则。
上面说的是按最原始的写法,实际makefile的编写有很多技巧使得编写量大大减少,
- 编译命令的各种参数选项统一都写在变量中
- 模式匹配
- 特殊符号代码依赖集
- 目标集
- shell指令在makefile里完成自动查找生成所有文件名,然后替换.cpp为.o的玩法
这些都可以大大减少makefile的篇幅。如果打开一个开源C++项目的makefile,会觉得完全看不懂,就是因为里面大量使用各种技巧。但即使我们用最原始办法也就是第一次编写麻烦一些,之后维护是很简单的,因为一个C++项目不会频繁的大变样。
makefile文件名
make默认支持makefile和Makefile两种文件名,所以我们直接执行make等价于执行make Makefile。如果我们写make规则的文件叫test20200806,需要执行的命令是make -f test20200806。
并行编译
并行make的命令是make -j。可以加快工程编译速度,对于大规模工程适用。
自动推导
make会自动推导各个目标的依赖关系,按照依赖关系的顺序生成目标文件。
伪目标
本文makefile里的“目标3”clear是个伪目标,伪目标后面无文件依赖,make不自动找文件依赖,无法执行后面的命令。要执行伪目标,就要make+为目标名。执行make clear,会执行下面的rm命令,这种命令用来清理项目之前编译的.o等文件,在需要彻底重新编译项目时都会执行这个命令。
[root@bogon makefiletest]# make clear
rm -f *.o test
如果不执行make clear清理之前的.o文件,make会比较.o和.cpp谁更新,如果依赖文件cpp更新,重新编译这个.o,否则不重新编译。
makefile从入门到入门的更多相关文章
- babel从入门到入门
babel从入门到入门 来源 http://www.cnblogs.com/gg1234/p/7168750.html 博客讲解内容如下: 1.babel是什么 2.javascript制作规范 3. ...
- Android视频录制从不入门到入门系列教程(一)————简介
一.WHY Android SDK提供了MediaRecorder帮助开发者进行视频的录制,不过这个类很鸡肋,实际项目中应该很少用到它,最大的原因我觉得莫过于其输出的视频分辨率太有限了,满足不了项目的 ...
- Android视频录制从不入门到入门系列教程(三)————视频方向
运行Android视频录制从不入门到入门系列教程(二)————显示视频图像中的Demo后,我们应该能发现视频的方向是错误的. 由于Android中,Camera给我们的视频图片的原始方向是下图这个样子 ...
- springboot + kafka 入门实例 入门demo
springboot + kafka 入门实例 入门demo 版本说明 springboot版本:2.3.3.RELEASE kakfa服务端版本:kafka_2.12-2.6.0.tgz zooke ...
- springboot + mybatisPlus 入门实例 入门demo
springboot + mybatisPlus 入门实例 入门demo 使用mybatisPlus的优势 集成mybatisplus后,简单的CRUD就不用写了,如果没有特别的sql,就可以不用ma ...
- spring入门--spring入门案例
spring是一个框架,这个框架可以干很多很多的事情.感觉特别吊.但是,对于初学者来说,很难理解spring到底是干什么的.我刚开始的时候也不懂,后来就跟着敲,在后来虽然懂了,但是依然说不明白它到底是 ...
- 《图说VR入门》——入门汇总
本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/53818922 作者:car ...
- 09Vue.js快速入门-Vue入门之Vuex实战
9.1. 引言 Vue组件化做的确实非常彻底,它独有的vue单文件组件也是做的非常有特色.组件化的同时带来的是:组件之间的数据共享和通信的难题. 尤其Vue组件设计的就是,父组件通过子组件的prop进 ...
- Python该怎么入门?Python入门教程(非常详细)
Python要学多久可以学会,达到精通呢? 任何知识都是基础入门比较快,达到通晓的程序是需求时日的,这是一个逐渐激烈的进程. 通晓任何一门编程语言,都需求通过大量的实践来积累经验,解决遇到的各种疑难问 ...
随机推荐
- 2020.08.23 瞎扯周记之论短暂假期(QAQ)内要不要睡午觉
蒟蒻的假期都是很短暂的嘛 作为一只合格的蒟蒻 假期自然是很短暂的QAQ 只有短短的26h93360s(手动微笑) 总体来讲 假期只有两件事要干: 1.满足人体自身需求 2.满足作业需求 2.5.摸鱼 ...
- Visual Studio Installer闪退问题解决方法
Visual Studio 2019安装推荐的方式是通过官方给的Installer进行的(2017也是同样方法),但是有时会出现在”即将完成…一切即将准备就绪“这个界面闪退的问题,导致软件的安装.卸载 ...
- C++ —— 输出100以内的质数
代码如下: #include<iostream> #include<math.h> using namespace std; int main() { int i; for(i ...
- 取得min和max之间包括端点的随机整数
产生随机数的函数用处不少,写一个放博客里备用,函数如下: /** * get a random integer between min and max * @param min * @param ma ...
- composer 国内镜像
本文列举一些最常用的国内镜像,配置国内镜像后可以提高composer包的下载速度.使用阿里云镜像的开发者较多,我也一直在使用这个镜像. 1. composer 中文网提供的中国全量镜像 https:/ ...
- Win10 在VM里面装Centos7.4后使用桥接模式连接外网,并用MobaXterm远程虚拟机详细教程
1.首先登陆虚拟机如图 2.执行ping命令看虚拟机里面的centos7是否可以连网 ping www.baiducom 此时会报错:name or service not known 3.设置一个文 ...
- css常用属性之绝对定位、相对定位、滚动条属性、背景图属性、字体、鼠标、超链接跳转页面
1.绝对定位position: fixed(比如广告页面向下滑动的时候,页面最上方有个标题不能随之滑动,就需要用到position: fixed,同时还需要用到一个标签(标签高度很高才会出现滚动的情况 ...
- swift基本体验
Swift初体验 1. 导入框架 2. 定义标识符: let/var 3. 语句结束时;可以省略 4. print() 5. let/var 6. 逻辑分支 7. 循环使用 // 1.Swift中如何 ...
- ASP.NET Core 3.x启动时运行异步任务(一)
这是一个大的题目,需要用几篇文章来说清楚.这是第一篇. 一.前言 在我们的项目中,有时候我们需要在应用程序启动前执行一些一次性的逻辑.比方说:验证配置的正确性.填充缓存.或者运行数据库清理/迁移等 ...
- Linux实战(7):centos7安装xrdp
系统环境:最小化安装,无安装桌面化 操作 yum更新 yum -y update 安装依赖. tigervnc-server.xrdp .GNOME Desktop yum -y install ep ...