linux之makefile
lipiwang 2024-11-27 17:15 10 浏览 0 评论
作为软件开发者,相信大家对集成开发环境并不陌生,而如果你从事linux这种类Unix系统软件的开发,也许对make工具也就应该不会陌生了。
make工具是什么呢?如果我们熟悉集成开发环境,也许就会对某个工程的增量编译不会陌生,而make就类似于管理整个工程,并实现增量编译。换句话说它是一种转化文件形式的工具。当执行它时,它会根据文件的依赖关系检查所依赖文件的修改时间来确定该目标文件是否需要重新编译。
我们知道make命令相当智能,但光靠其自身还是无法获取到该如何去构建用户的应用程序,因此你必须给它提供一个能引导它如何构建用户应用程序的文件,这个文件叫做makefile。
值得注意的是,尽管我们多数时候是用make工具来编译我们的源代码,并生成可执行代码或库文件的,但它的用处远不止于此,当我们需要将多个输入文件来生成输出文件时,当我们需要进行文档处理时,我们都可以用它来完成任务。
下面将具体讲解重要文件makefile的编写及make工具的使用。
语法
makefile文件到底是什么呢?说到底它就是由一组规则构成。而每个规则则是由一个或多个目标和一组该目标所依赖的先决条件所组成。因此每个规则的语法为:
目标:依赖(先决条件)
命令
当执行make命令时,它会去读取makefile的内容,首先确定目标文件,然后比较该目标所依赖的源文件(先决条件)的日期和时间以决定该采用如何来构造这个目标。通常若先决条件也是目标时,在生成最终的目标文件之前,它会先生成先决条件等一些中间目标。在执行make命令时,它会根据makefile文件来自行确定各目标文件的构造顺序以及采用正确的规则调用顺序。
需要注意的是,在编写makefile文件时,空格和制表符tab是有区别的。语法中命令所在的行必须以制表符tab开头,而不能用空格。此外,如果文件中某一行以空格结尾,那么它也可能会导致make命令执行失败。因此编写makefile文件必须小心,小心。
下面我们上一个例子来实操一下makefile文件,编写一个如下的makefile文件:
终端输入make命令运行如下:
上面的运行结果不知道友友们发现什么了呢?下面来一一解答makefile运行特点:
- 从makefile源文件可以看出,我们在文件中定义了两个目标:all和test,但当我们只输入make命令时,它其实指检测了运行了第一个目标;
- Makefile语法中的依赖(先决条件)是可选项,如图中的test目标;
- 当运行make指令时,它运行all目标,发现了其存在先决条件,故它确实是先运行了先决条件的目标后,再运行的最后目标的,从最后的输出可以看到;
- 当运行make命令时,若在语法中的命令前不加@,它既会输出命令本身,还会输出命令执行结果,但若在命令前加@,它将不输出命令本身,只输出命令执行结果。
以上特点都可以对照上面的例子加深理解。
变量
尽管make工具并非-门编程语言,但它却具有像编程语言那样处理变量的能力,这就大大方便了我们对makefile文件的修改和维护。
Makefile文件默认的变量分两类:自动变量和预定义变量。
- 自动变量
常见的自动变量的如下表所示。
变量名 | 含义 |
$@ | 表示当前规则中的目标。若当前规则存在多目标,则表示其中任何造成命令被执行的那个目标 |
$* | 表示当前规则中不含后缀的目标 |
$^ | 表示当前规则中所有的依赖(先决条件) |
lt; | 表示当前规则中第一个依赖(先决条件) |
$% | 表示目标是归档成员的名称 |
$? | 所有时间戳比目标晚的依赖(先决条件) |
- 预定义变量
Makefile常见的预定义变量如下。
变量名 | 含义 |
CC | C编译器名称,默认cc |
CPP | C预编译器名称,默认$(CC) -E |
CXX | C++编译器名称,默认g++ |
AR | 库文件维护程序名称,默认ar |
AS | 汇编器名称,默认as |
RM | 文件删除命令名称,默认 rm -f |
CFLAGS | C编译选项,无默认 |
CPPFLAGS | C预编译选项,无默认 |
CXXFLAGS | C++编译选项,无默认 |
ARFLAGS | 库文件维护选项,无默认 |
ASFLAGS | 汇编选项,无默认 |
- 变量的定义和引用
变量定义及赋值,如:CC=gcc,表示变量CC被赋值为gcc编译器。当然变量的值也可设为空值,如CC= ,即可
引用方法:$(变量名) 或 ${变量名}
说明:
变量通常是在makefile文件中定义,但你也可以在输入make命令时,在命令行上给出变量定义。
命令行上的变量将覆盖在makefile文件中的同名变量。
当在makefile文件之外命令行使用变量定义时,需注意变量定义必须以单参数形式传递,即是应避免在变量定义中使用空格或应给变量定义加上双引号,例如,make "CC = gcc" 。
函数
本文仅列出一些在makefile日常编写中需要用到的常用函数,具体如下:
函数名 | 作用及用法 |
addprefix | 给字符串中每个子串添加一个前缀,形式为:$(addprefix prefix,names…) |
filter | 从一个字符串中,筛选满足格式的字符串,形式为$(filter pattern…,text) |
Filter-out | 从一个字符串中,滤除满足格式的字符串,形式为$(filter-out pattern…,text) |
wildcard | 通配符函数,即通配所有满足格式文件,形式为$(wildcard pattern) |
patsubst | 字符串替换,其形式为$(patsubst pattern,replacement,text) |
注释
Makefile文件的注释很简单,就是在行前加入#号即可。
make指令
make指令常用选项如下表所示。
选项 | 含义 |
-C dir | 读取dir下的makefile进行处理 |
-f filename | 执行当前目录下的名为filename的文件,默认选项。 |
-i | 忽略所有命令执行错误 |
-k | 发现错误时仍继续执行 |
-n | 只打印规则中的命令,但不执行命令 |
-p | 显示make的变量数据库及隐含规则 |
-w | 若在执行过程中改变目录,则打印当前目录 |
-s | 执行命令时不显示命令 |
通常情况下,我们在终端只输入make后,未加入任何选项,则标准版的make命令会首先在当前目录下查找文件名为makefile的文件,若不存在,它就再找文件名Makefile的文件。但对于GNU Make版本,它则在搜索makefile文件和Makefile文件之前,会首先搜索名为GNUmakefile的文件。
同时需要注意的是为防止文件被make指令误处理,需警惕make指令执行的假目标。从上表可知当我们仅输入make指令时,实际隐式执行 make –f makefile,所以当我们如果指定要make某个目标时,而此目标又在当前目录下有个同名文件,此时就会出现问题。下面还是以开头的一个makefile文件为例进行讲解说明。
开头的一个makefile有个名为test的目标,而我们在当前目录下新建了一个名为test的文件,此时运行make test命令,可以发现它根本就没有如我们所愿去打开makefile中的test目标执行,而是执行了当前目录下的test,整个过程如下图所示。
为了解决这个问题,也为了避开这个坑,我们可以在makefile文件中,将目标采用.PHONY关键字定义一下就好。如上面的例子,我们可以在文件开头定义.PHONY test,此时在运行就没有问题了。
友友们觉得需要补充的或者说需要探讨的欢迎评论区留言!大家一起学习进步
相关推荐
- 怀孕生孩子那些事 之 小剂量阿司匹林为什么是81mg?
-
作者:段涛无论是在内科还是妇产科,阿司匹林都是常用药物。在看国外文献以及药物说明书的时候,或者是在海外代购药物的时候,大家都会有一些小小的疑问,就是为什么这些国外阿司匹林的剂量经常不是整数?阿司匹林剂...
- 国际临床试验发现 将三种心脏病药物组合成一粒药丸更有效果
-
一项大型国际临床试验发现,与分别服用每种药物相比,将三种常见的心脏病药物组合成一粒药丸在预防心血管事件和死亡方面明显更有效。在新试验中测试的治疗方法称之为Trinomia,使用由3种药物混合而成...
- 如何看懂医生写的处方字?
-
解码处方:从“天书”到清晰指引当我们拿到医生开具的处方,面对那密密麻麻、看似潦草的字迹,往往会感到困惑。医生的处方字似乎自成一体,宛如神秘的“天书”,但这背后其实是有迹可循的,只要掌握了正确的方法,...
- 当归全身都是宝!一碗黄芪当归补血汤,打造红润好气色,收藏备用
-
当归别名秦归、云归,外形类似人参,是伞形科植物当归的干燥根,《本草纲目》提到,“古人娶妻为嗣续也,当归调血为女人要药,为思夫之意,故有当归之名。”从当归鸭、当归羊肉到中药四物汤、生化汤,当归食药两...
- 14张菌落图"撞脸"他人文献!贵州某三甲医院研究成果遭质疑
-
2019年5月,贵州省人民医院在TranslationalCancerResearch(IF1.4999/4区)期刊上发表了一篇论文。在发表6年后,因图片与早期论文图片重复在pubpeer上被读者...
- 阿司匹林的各种剂型,有什么区别吗?听医生说说看
-
无论是在内科还是妇产科,阿司匹林都是常用药物。为什么这些国外阿司匹林的剂量经常不是整数?在看国外文献以及药物说明书的时候,或者是在海外代购药物的时候,大家都会有一些小小的疑问,就是为什么这些国外阿司匹...
- 医生讲解如何正确应用阿司匹林,控制冠心病的发展进程,改善症状
-
谈及冠心病的临床控制和干预,永远绕不开阿司匹林,它是冠心病患者最熟悉的药物,绝大多数病人都吃过阿司匹林,可以说是控制冠心病的基石,贯穿了患者的前中后期,需要特别慎重。阿司匹林是什么?阿司匹林(Aspi...
- 测绘专业!EI会议选刊口诀必看!
-
推荐EI会议会议名称:IEEE国际地理信息与遥感技术研讨会(IGIRS)截稿时间:即日起至11月30日时间地点:次年3月15-17日·新加坡论文集上线:会后2个月内提交至IEEEXplore版...
- 解码运营诉求:一对一直播源码如何实现"用户增长到付费转化"?
-
在竞争激烈的一对一直播交友赛道,用户增长和付费转化是决定产品成败的两大核心指标。然而,许多团队面临一个共同困境:用户进来了,但留不住、难付费。问题的根源往往在于源码架构是否深度适配运营需求。山东布谷科...
- 计算机EI源刊论文投稿秘籍|审稿周期解析
-
期刊推荐:《IEEETransactionsonComputers》-刊号:ISSN0018-9340-影响因子:3.7(最新数据)-分区:中科院2区,JCRQ1-版面费:非开源免...
- 学习人工智能AI所需的数学基础
-
人工智能(AI)的快速发展离不开数学理论的有力支撑。不管是构建神经网络模型,亦或是优化算法性能,乃至处理高维数据的不确定性,数学皆充当着核心要角。此文将自核心数学领域起始,详尽剖析其与AI的关联所...
- 化学工程亲测!EI会议高通过率
-
高录用率EI会议推荐会议名称:InternationalConferenceonChemicalEngineeringandApplications(CCEA)会议编号:CCF-C...
- DDD编程入门指南
-
什么是DDD编程?领域驱动设计(Domain-DrivenDesign,简称DDD)是一种软件开发方法论,由EricEvans在其2003年的著作《领域驱动设计:软件核心复杂性应对之道》中提出。D...
- 软件工程?EI会议录用潜规则!
-
【推荐会议】ICSEA2025(会议号:61205)截稿时间:2025年4月10日召开时间与地点:2025年8月22-24日·美国波士顿论文集上线:会后3个月内提交至SpringerLN...
- 安全漏洞之经典上传漏洞
-
0x01概要说明文件上传漏洞可以说是日常渗透测试用得最多的一个漏洞,因为用它获得服务器权限最快最直接。但是想真正把这个漏洞利用好却不那么容易,其中有很多技巧,也有很多需要掌握的知识。俗话说,知己知彼...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)