make工具简介
在Linux C/C++的开发过程中,当源代码文件较少时,我们可以手动使用gcc或g++进行编译链接,但是当源代码文件较多且依赖变得复杂时,我们就需要一种简单好用的工具来帮助我们管理。于是,make应运而生。
make主要用来管理C/C++项目,通过Makefile书写的规则来对项目中的源代码文件进行编译,生成可执行的程序。
make流程
make执行的主要过程如下:当在shell中使用make命令时,make会寻找当前目录下的Makefile文件,根据该文件中的规则来确定依赖关系,如果一个文件所依赖的文件比这个文件要新,或者说修改时间更晚,那么make会根据Makefile中指明的命令来重新编译生成该文件。
另外,make除了自动寻找定义了编译规则的Makefile文件外,还可以手动指明定义了规则的文件。比如:
$ make -f rule.txt # rule.txt中为make规则
Makefile的写法
规则
Makefile由一系列的规则构成,一条规则的基本格式如下:
目标 : 条件
[tab] 命令
其中,需要在命令之前加一个Tab制表符,并且条件和命令都是可以省略的,但是只能省略其一,条件省略时一般做一些编译以外的其他工作,当命令省略时其实也可以对目标进行编译生成,这涉及到了Makefile中的隐式规则,这里不过多赘述,我们只讨论显式规则。
如make流程所述,当条件中的文件比目标要新时,会执行tab后的命令。
Makefile中有很多规则时,当在shell中执行make命令,默认会将第一条规则的目标作为最终生成的目标。
比如下面这个Makefile例子:
main: main.o sub.o
gcc -o main main.o sub.o
sub.o: sub.c sub.h
gcc -c -o sub.o sub.c
main.o: main.c sub.h
gcc -c -o main.o main.c
clean:
rm sub.o main.o
.PHONY: clean
当我们在shell中执行make时,会最终生成main这个最终目标。
但是如果我们只想生成某个中间的目标也是可以的,比如只生成sub.o,只需要采用make 最终目标的形式就可以了,即make sub.o
注意到示例中省略了条件的那条规则(目标为clean的那条规则),正规上把它叫做伪目标,用来执行一些其他的任务,如本例中清除编译中生成的.o文件。当然,伪目标下的命令可以是多种多样的,比如将clean下的命令改为ls,当执行make clean时,会列出当前目录下的所有文件。但是有一点需要注意的是,如果我们的目录下已经有了一个叫做clean的文件,当我们执行make clean时,make就分不清这个clean到底是那个了,为了避免这种情况,需要用.PHONY: 伪目标1,伪目标2..的方式来显式的声明伪目标。
变量
当我们Makefile中的规则变得非常多时,为了方便,也为了可维护性,我们一般使用变量来代替某些信息。
Makefile中定义变量的格式如下:
变量名 := 变量值
其中:=也该以使用=,依个人喜好。用$(变量名)的形式来使用变量。
先前示例中便可精简如下:
CC := gcc
LD := gcc
CFLAGS := -c
OBJS := main.o \
sub.o
main: $(OBJS)
$(LD) -o main $(OBJS)
sub.o: sub.c sub.h
$(CC) $(CFLAGS) -o sub.o sub.c
main.o: main.c sub.h
$(CC) $(CFLAGS) -o main.o main.c
clean:
rm $(OBJS)
.PHONY: clean
Tip: 有时候我们的规则可能太长,写在一行又不好看,可以使用
\来进行换行。
内置变量
Makefile中还提供了一些内置变量,比如$(CC)代表默认的C编译器,$(CXX)代表默认的C++编译器。更多内置变量请参考这里
自动变量
Makefile中还提供了一些特殊的变量,不用定义且会根据所在的规则而改变,减少一些目标文件名和条件文件名的输入。以下是六个常用的自动变量:
| 变量名 | 作用 |
|---|---|
$@ |
目标的文件名 |
$< |
第一个条件的文件名 |
$? |
时间戳在目标之后的所有条件,并以空格隔开这些条件 |
$^ |
所有条件的文件名,并以空格隔开,且排除了重复的条件 |
$+ |
与$^类似,只是没有排除重复条件 |
$* |
目标的主文件名,不包含扩展名 |
根据以上自动变量,我们可以将上面的示例改成更简便的形式:
CC := gcc
LD := gcc
CFLAGS := -c
OBJS := main.o \
sub.o
main: $(OBJS)
$(LD) -o $@ $^
sub.o: sub.c sub.h
$(CC) $(CFLAGS) -o $@ $<
main.o: main.c sub.h
$(CC) $(CFLAGS) -o $@ $<
clean:
rm $(OBJS)
.PHONY: clean
后记
另外,尽管make工具常常用来管理C/C++项目,但是用来管理其他项目也是可以的,比如汇编项目,Pascal项目,甚至是node.js的项目,make就是一个工具,来帮我们管理一些构建的规则,只要规则写的得当,怎么用就随你了。
最后,make虽然可以很好来管理项目了,但是还是不够方便。试想一下,当Makefile中的规则越来越多,又臭又长的时候,make就又显得很难用了,这也就是为什么cmake诞生的原因。通过编写Cmakelist,来指导cmake生成各种Makefile文件和project文件,从而减轻管理Makefile的负担。
参考:
make工具简介的更多相关文章
- sysbench压力测试工具简介和使用(一)
sysbench压力测试工具安装和参数介绍 一.sysbench压力测试工具简介: sysbench是一个开源的.模块化的.跨平台的多线程性能测试工具,可以用来进行CPU.内存.磁盘I/O.线程.数据 ...
- JS内存泄漏 和Chrome 内存分析工具简介(摘)
原文地址:http://web.jobbole.com/88463/ JavaScript 中 4 种常见的内存泄露陷阱 原文:Sebastián Peyrott 译文:伯乐在线专栏作者 - AR ...
- SQL Profiler工具简介
一.SQL Profiler工具简介 SQL Profiler是一个图形界面和一组系统存储过程,其作用如下: 图形化监视SQL Server查询: 在后台收集查询信息: 分析性能: 诊断像死锁之类的问 ...
- sed 工具简介
sed 工具简介sed 可以分析 Standard Input (STDIN) 的数据, 然后将数据经过处理后,再将他输出到 standrad out (STDOUT) 的一个工具. 至于处理呢?可以 ...
- redis redis常用命令及内存分析总结(附RedisClient工具简介
redis常用命令及内存分析总结(附RedisClient工具简介 by:授客 QQ:1033553122 redis-cli工具 查看帮助 连接redis数据库 常用命令 exists key se ...
- openssl命令行工具简介 - 指令x509
原文链接: http://blog.csdn.net/allwtg/article/details/4982507 openssl命令行工具简介 - 指令x509 用法: open ...
- 004-restful应用构建、分布式会话、测试工具简介
一.概述 什么是rest(表述性状态转移,Representational State Transfer)是一种架构风格.他定义了创建可扩展Web服务的最佳实践. 1.Richardson成熟度模型 ...
- golang学习笔记5 用bee工具创建项目 bee工具简介
golang学习笔记5 用bee工具创建项目 bee工具简介 Bee 工具的使用 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/instal ...
- Python 性能分析工具简介
Table of Contents 1. 性能分析和调优工具简介 1.1. Context Manager 1.2. Decorator 1.3. 系统自带的time命令 1.4. python ti ...
- (转)Synopsys工具简介
DC Ultra--Design Compiler的最高版本 在Synopsys软件中完整的综合方案的核心是DC UltraTM,对所有设计而言它也是最好级别的综合平台.DC Ultra添加了全面的数 ...
随机推荐
- js或者jq的string类型或者number类型的相互转换及json对象与字符串的转换
1.将值乘以1,将string类型转为number类型 //算合计价值function summoney(money) { var zijin = $("#main_xm_dam09&quo ...
- Java学习笔记(十一)面向对象---多态
多态的体现 父类的引用指向了自己的子类对象. 父类的引用也可以接受自己的子类对象. 代码体现 abstract class Animal { public abstract void eat(); } ...
- clippingNode 裁剪
let stencil = new cc.Sprite(fileName); let clippingNode = new cc.ClippingNode();this.addChild(clippi ...
- Apache Kafka(二)- Kakfa 安装与启动
安装并启动Kafka 1.下载最新版Kafka(当前为kafka_2.12-2.3.0)并解压: > wget http://mirror.bit.edu.cn/apache/kafka/2.3 ...
- 使用命令行生成动态库dll
1.安装开发工具,比如visual studio或者mingw等等.下面以visual studio编译器cl作为讲解. 2.导出dll中的函数基本使用两种方式,可以使用关键字__declspec(d ...
- ffmpeg 音频常用命令
ffmpeg的使用方式: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... Stream ...
- HTML学习(8)超链接
<a href="url">链接文本或图片</a> 可以使用id属性来访问标记的地方,例: <a id="tip">被访问的 ...
- 期货、期权tick数据接收
功能: 1.开启之后,7*24自动运行. 2.在共享内存中存放当个交易日的tick数据,方便随时取用. 3.支持多行情源取数据.经过测试一个行情源峰值带宽要求为20M,所以使用时要配合带宽限制. 4. ...
- Jarvis OJ - DD-Hello -Writeup
Jarvis OJ - DD-Hello -Writeup 转载请注明出处http://www.cnblogs.com/WangAoBo/p/7239216.html 题目: 分析: 第一次做这道题时 ...
- 安装Oracle进行先决条件检查时显示 Environment variable:"PATH" 失败”
问题已解决:安装时exe可执行文件的目录也不能有中文,安装时注意目录一定要按oracle的格式.运行安装程序时,要用右键--> 要以管理员方式启动. 原文: 用到oracle数据库,由于电脑装的 ...