linux下自动构建工具make:makefile

news2025/2/28 15:22:49

文章目录

      • make/makefile介绍
      • makefile的核心规则
      • makefile的寻找规则
      • makefile的伪目标

什么是makefile?大多数人都应该是不太清楚的,因为现在人们基本都用着非常好的适合自己的IDE,而IDE为人们做了makefile该做的,从而导致大多数人并不了解makefile。如果是在Linux下编译程序,那么makefile是必须要掌握的!

很多linux新手经常是直接用gcc/g++命令来编译程序的,因为对于linux新手,他们的源文件数目少得可怜,他们仅仅用gcc/g++也是可以的,但通常一个项目是拥有非常多的源文件的,而这些源文件直接也有着复杂的关系(编译的先后顺序等),如果此时仍然用gcc/g++命令来直接编译的话,那将会是一个极其痛苦的事情。

make/makefile介绍

make是一条命令,makefile是一个文件。

执行make命令时,makefile会告诉make命令以什么样的规则来编译程序。

而makfile文件里的内容(也就是编译规则),是需要我们自己来写的!

来一个简单的例子:

image-20221120203333125

这里有四个文件:makefile、add.h、add.c、main.c

makefile里编写了编译add.c、main.c的规则

接下来,我们只需要执行一条命令make,即可完成makefile里的编译规则。

image-20221120203538207

现在我们再回想一下,如果不用make/makefile的话,我们是如何编译这两个源文件的呢?

我们应该是用gcc -o main main.c add.c 这一条命令来编译的。如果我们想要编译十次,我们就需要输入十次这样的命令,但如果有了make/makefile,我们只需要十次make。如果来一百个源文件,并且编译十次,我们直接用gcc会极其的麻烦,但是make仍然只需要十次就ok。

看到这里,想必大家已经认识到了make/makefile的重要性!

makefile的核心规则

target ...:prerequisites ...
	command
	...
	...

target是一个目标文件,prerequisites是生成target所需要的文件,commmand是make所需要执行的命令(shell命令)。

而这就是一种依赖关系:target依赖于prerequisites,而生成target的规则(命令)定义在command中。

值得注意的是:如果prerequisites中如果存在一个文件的时间要比target新,则command才能够执行。

看下面例子:

image-20221120205059317

当main已存在,并且main比main.c、add.c时间都要新的话,makefile中的command是无效的。

那么我们如何证实呢?

截屏2022-11-20 20.55.04

可以看到,main的modify时间是要比main.c、add.c的modify时间要新的,然后执行make的时候出现提示。

那么我们现在改一下main.c的modify时间(需要对main.c里的文本内容作修改),看看会发生什么。

截屏2022-11-20 21.00.16

我们打开文件,在里面添加了若干行空格,就改变了main.c的modify时间,导致main.c的modify时间比main的要新,所以后续执行make命令时能够执行成功。

这里有一个疑问,那就是要比较target和prerequisites的日期新旧,为什么只比较modify时间?

因为modify时间只有修改了文件里的内容时,才会跟着改变。

makefile的寻找规则

执行make时,会默认执行makefile里的第一个target。当第一个target成功生成(执行)之后,则停止下面的规则。如果当生成第一个target时发现所需的依赖文件不存在,则按从上到下的顺序依次执行规则直到找到依赖文件使得第一个target生成成功。

image-20221120220738353

直接执行make时,会为了makefile里的第一个target而从上往下寻找依赖文件。那么如果我们不想生成第一个target呢?假设我们这里只想生成add.o,该怎么办?这时我们需要make加上我们要生成(执行的)那个target。

image-20221120221217078

看上图,我们只想生成main.o,所以我们make main.o,而main.o的依赖文件是不存在的,所以向下寻找,直到生成main.o停止,所以也并没有执行makefile里面的add.o add.s add.i等操作。

makefile的伪目标

上面我们说过target和prerequisites会根据modify的时间新旧来决定是否执行command。

那么为什么要这样做呢?

这是因为,根据prerequisites而生成的target没必要再次编译生成,并且大型项目编译的时间是很长的,只有当prerequisites发生变化时target才需要再次编译生成最新的。

那么如果我们就是想要每次重新编译生成target而不受时间新旧的约束,这时该怎么做呢?我们可以给target前面修饰一个.PHONY,经过.PHONY修饰的名词就变为来伪目标,该目标下的command每次都可以执行而不受时间约束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

同花顺_代码解析_技术指标_O

本文通过对同花顺中现成代码进行解析,用以了解同花顺相关策略设计的思想 目录 OBOS OBV OBVFS OI指标 OSC OBOS 超买超卖指标 大盘指标。 输出超买超卖指标:上涨家数-下跌家数的N日异同移动平均 输出MAOBOS:OBOS的M日简单移动平均 1.指标上升至80时为超买&…

第2章 数据结构中栈与队列的概念

文章目录文档配套视频讲解链接地址第02 章 栈与队列2.1 栈与队列的框图2.2 栈1. 栈的概念2. 顺序栈3. 实例11 顺序栈4. 实例12 链式栈2.3 队列1. 队列的概念2. 顺序队列3. 实例13 顺序队列4. 链式队列5. 实例14 链式队列2.4 实例15 球钟问题2.5 队列与栈的转换1. 实例16 顺序的…

基于Labview的图像傅里叶变换研究-含Labview程序

⭕⭕ 目 录 ⭕⭕一、说明二、基于Labview的图像傅里叶变换研究三、Labview源程序下载一、说明 订阅该专栏后,可获取该专栏内的任意一份代码,请及时私信博主获取下载链接。 从该专栏获取的程序,博主有责任并将保证该程序能在您电脑上完整运行…

初识Spring框架~控制反转IoC、依赖注入DI以及Spring项目的创建方式

目录 Spring框架初识 Spring IoC IoC(控制反转) DI(依赖注入) Spring项目的创建 创建一个maven项目 配置XML文件 添加启动类 简单了解Bean对象的存储与获取 创建一个Spring IoC容器 注册Bean对象 获取并使用Bean对象 Spring框架初识 通常所说的Spring是指Spri…

java知识梳理 第十五章 I/O流

一、文件 1.1 文件流 值得一提的是,这里的流的概念是围绕java程序展开的 1.2 常用的文件操作 1.2.1 创建文件对象相关构造器和方法 代码演示如上,读者可自行实验 1.2.2 获取文件的相关信息 代码演示如上,读者可自行实验 1.2.3 目录的操作和删…

NodeJs实战-待办列表(6)-前端绘制表格显示待办事项详情

NodeJs实战-待办列表6-前端绘制表格显示待办事项详情定义服务器返回的 json 数据前端绘制动态表格后端返回列表数据验证执行添加查看数据库中的数据是否与页面一致使用浏览器debug表格绘制过程项目地址前面几节显示的列表,看不到事项创建时间,完成时间&a…

springmvc-day03

springmvc-day03 第一章 拦截器 1.概念 1.1 使用场景 1.1.1 生活中坐地铁的场景 为了提高乘车效率,在乘客进入站台前统一检票: 1.1.2 程序中的校验登录场景 在程序中,使用拦截器在请求到达具体 handler 方法前,统一执行检…

基于stm32单片机的智能恒温自动加氧换水鱼缸

资料编号:105 下面是相关功能视频演示: 105-基于stm32单片机的智能恒温自动加氧换水鱼缸Proteus仿真(源码仿真全套资料)功能讲解:采用stm32单片机,ds18b20测量温度,LCD1602显示温度&#xff0c…

C语言第十一课(上):编写扫雷游戏(综合练习2)

目录 前言: 一、文件建立: 1.头文件game.h: 2.函数定义文件game.c: 3.工程测试文件test.c: 二、编写井字棋游戏: 1.程序整体执行思路: 2.menu菜单: 3.game游戏函数逻辑&#xff…

【Detectron2】代码库学习-5.标注格式- 矩形框, 旋转框,关键点, mask, 实例标注,IOU计算, 旋转框IOU计算,

文章目录Detectron2 内置的标注格式BoxMode 表示方式实用APIRotatedBoxesInstances 实例标注KeypointsMasks结语Detectron2 内置的标注格式 BoxesRotatedBoxesBitMasksPolygonMasksROIMasksKeypointsInstancesImageList BoxMode 表示方式 XYXY_ABSXYWH_ABSXYXY_REL # 相对模…

Windows安装mysql并且配置odbc

文章目录 mysql下载ODBC驱动下载安装mysql使用测试安装ODBC驱动添加ODBC数据源配置完成了用户不能远程访问的问题mysql下载 https://dev.mysql.com/downloads/installer/ ODBC驱动下载 https://dev.mysql.com/downloads/connector/odbc/ 安装mysql 点击mysql安装包,选择…

【25-业务开发-基础业务-品牌管理-图片管理-图片上传方式的三种实现方式-第三方公共服务模块集成到项目中-服务端生成签名实战】

一.知识回顾 【0.三高商城系统的专题专栏都帮你整理好了,请点击这里!】 【1-系统架构演进过程】 【2-微服务系统架构需求】 【3-高性能、高并发、高可用的三高商城系统项目介绍】 【4-Linux云服务器上安装Docker】 【5-Docker安装部署MySQL和Redis服务】…

【第三部分 | 移动端开发】1:移动端基础概要

目录 | 概述 | 手机端调试 | 视口 ViewPort 三种视口 meta标签 设置视口 代码适配PE端的要点 | 二倍图 物理像素和物理像素比 利用二倍图解决图片在PE端默认放大失真 背景缩放 background-size | 移动端的开发选择 | 移动端的相关开发注意点 | 概述 | 手机端调试 打…

【操作系统习题】假定某多道程序设计系统供用户使用的主存空间为100 KB ,磁带机2台,打印机1台

4.假定某多道程序设计系统供用户使用的主存空间为100 KB ,磁带机2台,打印机1台。采用可变分区方式管理主存,采用静态分配方式分配磁带机和打印机,忽略用户作业I/O时间。现有如下作业序列,见表2-8。 采用先来…

Linux磁盘分区中物理卷(PV)、卷组(VG)、逻辑卷(LV)创建和(LVM)管理

文章目录一 基础定义二 创建逻辑卷2-1 准备物理设备2-2 创建物理卷2-3 创建卷组2-4 创建逻辑卷2-5 创建文件系统并挂载文件三 扩展卷组和缩减卷组3-1 准备物理设备3-2 创建物理卷3-3 扩展卷组3-4 查看卷组的详细信息以验证3-5 缩减卷组四 扩展逻辑卷4-1 检查卷组是否有可用的空…

Python实现全自动输入文本

文章目录1. 效果图2. 示例代码3. 代码解释1. 效果图 该Python脚本可以实现自动用Notepad打开文本文件,然后自动输入文本,最后保存并关闭文件,从而实现全面自动化处理文本。 2. 示例代码 Python脚本源码如下,主要使用了win32gui、…

Modern Radar for Automotive Applications(用于汽车应用的现代雷达)

目录 1 引言 2 汽车雷达系统的工作原理 2.1 基本雷达功能 2.2 汽车雷达架构 2.2.1 发射机 2.2.2 接收机 2.2.3 天线和天线阵 2.3 信号模型 2.3.1 振幅模型 2.3.2 噪声模型 2.4 雷达波形和信号处理 2.4.1 距离处理 2.4.2 多普勒处理 2.4.3 FMCW汽车雷达应用的典型波形参数…

[Unity好插件之PlayMaker]PlayMaker如何扩展额外创建更多的脚本

学习目标: 如果你正在学习使用PlayMaker的话,那么本篇文章将非常的适用。关于如何连线则是你自己的想法。本篇侧重于扩展适用更多的PlayMaker行为Action,那么什么是PlayMaker行为Action呢? 就是这个列表。当我们要给PlayMaker行为…

CSS的元素显示模式和CSS的背景

🍓个人主页:bit.. 🍒系列专栏:Linux(Ubuntu)入门必看 C语言刷题 数据结构与算法 HTML和CSS3 目录 一.CSS的元素显示模式 1.1什么是元素的显示模式 1.2块元素 1.3行内元素 1.4 行内块元素 1.5元素显示模式总结 1.6…

JavaEE——HttpServletRequest

HttpServletRequest 核心方法 方法功能String getProtocol()返回请求协议的名称和版本。String getMethod()返回请求的 HTTP 方法的名称String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。String getContextPath…