Linux make与makefile 项目自动化构建工具
本文章将对make与makefile进行一些基础的讲解。
假设我们要建造一座房子,建造过程涉及很多步骤,比如打地基、砌墙、安装门窗、粉刷墙壁等。每个步骤都有先后顺序,并且有些步骤可能依赖于其他步骤的完成。比如,你必须先打好地基才能砌墙,必须先砌好墙才能安装门窗。这时候,你需要一个详细的施工流程表,告诉工人每一步该做什么,以及在什么条件下可以进行下一步。make 和 makefile 就像是这个施工流程表。
一、什么是 make 和 makefile
-
makefile:是一个文本文件,里面包含了一系列的规则,这些规则定义了如何从源文件生成目标文件,以及各个目标文件之间的依赖关系。 -
make:是一个构建自动化工具,它会读取makefile中的规则,并根据这些规则来决定哪些文件需要重新编译或构建。
二、makefile 的基本结构
一个典型的 makefile 包含以下几个部分:
- 目标(Target):你想要生成的东西,比如一个可执行文件或一个目标文件。
- 依赖(Dependency):生成目标所需要的文件。
- 命令(Command):为了生成目标需要执行的命令。
一个简单的 makefile 示例:
# 目标:生成可执行文件 main
main: main.o add.o sub.ogcc main.o add.o sub.o -o main# 目标:生成 main.o
main.o: main.cgcc -c main.c# 目标:生成 add.o
add.o: add.cgcc -c add.c# 目标:生成 sub.o
sub.o: sub.cgcc -c sub.c# 清理生成的文件
clean:rm -f main main.o add.o sub.o
解释
-
目标
main:- 依赖:
main.o、add.o和sub.o。 - 命令:
gcc main.o add.o sub.o -o main。这个命令表示将main.o、add.o和sub.o链接成一个可执行文件main。
- 依赖:
-
目标
main.o:- 依赖:
main.c。 - 命令:
gcc -c main.c。这个命令表示将main.c编译成目标文件main.o。
- 依赖:
-
目标
add.o和sub.o:- 类似于
main.o,分别将add.c和sub.c编译成目标文件。
- 类似于
-
目标
clean:- 命令:
rm -f main main.o add.o sub.o。这个命令用于清理生成的可执行文件和目标文件。
- 命令:
三、make 的工作原理
当你运行 make 命令时,make 会读取 makefile 文件,并按照以下步骤工作:
- 读取
makefile:make会解析makefile中的规则,构建一个依赖图。 - 确定目标:默认情况下,
make会尝试生成makefile中第一个目标(在这个例子中是main)。 - 检查依赖:
make会检查目标的依赖文件是否存在,以及这些依赖文件是否有更新。如果依赖文件不存在或比目标文件新,make会执行相应的命令来更新目标文件。(如何检查的呢?) - 执行命令:
make会按照依赖图的顺序执行命令,生成最终的目标。
四、示例运行
假设你有以下文件:
main.cadd.csub.c
运行 make 命令:
make 会根据 makefile 中的规则,依次编译 main.c、add.c 和 sub.c,然后将它们链接成可执行文件 main。
如果你修改了 add.c 文件,再次运行 make:
make 会检测到 add.c 文件有更新,只重新编译 add.c 成 add.o,然后重新链接生成 main。
如果你想清理生成的文件,可以运行:
make clean
make 会执行 clean 目标中的命令,删除 main、main.o、add.o 和 sub.o 文件。
五、 .PHONY
在 makefile 中,.PHONY 是一个特殊的目标,用于声明某些目标是“伪目标”。伪目标不是实际的文件,而是用于执行特定的命令或任务。使用 .PHONY 可以避免与同名文件冲突,并且可以提高 make 的执行效率。
1.为什么需要 .PHONY
- 避免与文件名冲突:如果有一个目标名与文件名相同,
make会误认为该目标是文件,而不是一个任务。使用.PHONY可以避免这种冲突。 - 提高执行效率:
make会检查文件的时间戳来决定是否需要重新生成目标文件。对于伪目标,make不需要检查时间戳,可以直接执行相应的命令,从而提高执行效率。 - 明确意图:使用
.PHONY可以明确告诉其他开发者,这个目标是一个虚拟的任务,而不是一个实际的文件。
2.如何使用 .PHONY
以下是一个简单的 makefile 示例,展示了如何使用 .PHONY:
# 声明伪目标
.PHONY: clean test# 默认目标
all: main# 生成可执行文件 main
main: main.o add.o sub.ogcc main.o add.o sub.o -o main# 生成 main.o
main.o: main.cgcc -c main.c# 生成 add.o
add.o: add.cgcc -c add.c# 生成 sub.o
sub.o: sub.cgcc -c sub.c# 清理生成的文件
clean:rm -f main main.o add.o sub.o# 运行测试
test:./mainecho "All tests passed!"
在这个示例中:
.PHONY: clean test声明了clean和test是伪目标。clean目标用于清理生成的文件,它不生成任何实际的文件。test目标用于运行测试,它也不生成任何实际的文件。
示例解释
1.声明伪目标
.PHONY: clean test
这行代码告诉 make,clean 和 test 是伪目标,而不是实际的文件。即使当前目录下存在名为 clean 或 test 的文件,make 也会执行相应的命令。
2. 使用伪目标
-
清理文件:
make clean这条命令会执行
clean目标中的命令,删除main、main.o、add.o和sub.o文件。 -
运行测试:
make test这条命令会执行
test目标中的命令,运行main可执行文件,并输出 "All tests passed!"。
3. 避免冲突
假设当前目录下有一个名为 clean 的文件,如果没有使用 .PHONY 声明 clean 为伪目标,make 会认为 clean 是一个文件,而不是一个任务。此时,运行 make clean 不会执行任何命令,因为 clean 文件已经存在,且没有依赖关系需要更新。
通过使用 .PHONY,可以避免这种冲突,确保 make clean 总是执行清理命令。
.PHONY 不仅可以用于常见的清理和测试任务,还可以用于其他任何不需要生成实际文件的任务。
-
.PHONY的作用:声明伪目标,避免与文件名冲突,提高执行效率,明确意图。 - 如何使用:在
makefile中使用.PHONY关键字,后跟伪目标的名称列表。 - 常见用途:清理文件、运行测试、生成文档、打包发布、代码风格检查等。
- 伪目标总是会被执行,不会被拦截。(比如我们重复make会提示已经make了不让我们make,但是如果我们把他搞成伪目标,那么就不会受此限制了)。
六、优点
- 自动化:
make可以自动处理文件之间的依赖关系,只重新编译需要更新的文件,节省时间和资源。 - 可维护性:通过
makefile,你可以清晰地定义项目的构建流程,方便团队协作和项目管理。 - 灵活性:
makefile支持复杂的规则和条件判断,可以适应各种构建需求。
七、缺点
- 维护成本:随着项目规模的增大,
makefile可能会变得非常复杂,维护起来比较困难。
八、总结
-
makefile:是一个包含构建规则的文本文件,定义了如何从源文件生成目标文件以及各个目标文件之间的依赖关系。 -
make:是一个构建自动化工具,读取makefile中的规则,并根据这些规则决定哪些文件需要重新编译或构建。
通过 make 和 makefile,你可以高效地管理和构建项目,确保每次构建都是基于最新的文件状态。
相关文章:
Linux make与makefile 项目自动化构建工具
本文章将对make与makefile进行一些基础的讲解。 假设我们要建造一座房子,建造过程涉及很多步骤,比如打地基、砌墙、安装门窗、粉刷墙壁等。每个步骤都有先后顺序,并且有些步骤可能依赖于其他步骤的完成。比如,你必须先打好地基才…...
leetcode51-N皇后
leetcode 51 思路 本题可以使用回溯算法来解决。回溯算法通过尝试所有可能的解决方案来找到问题的解的算法,当发现当前的选择无法得到有效的解决方案时,就回溯到上一步,尝试其他的选择。对于 N 皇后问题,我们可以逐行放置皇后&…...
linux 命令 awk
awk 是 Linux/Unix 系统中一个强大的文本处理工具,尤其擅长处理结构化文本数据(如日志、表格数据)。它不仅是命令行工具,还是一种脚本语言,支持变量、条件、循环等编程特性 1. 基本语法 awk [选项] 模式 {动作} 文件名…...
接口自动化学习四:全量字段校验
什么是全量字段校验: 校验接口返回响应结果的全部字段(更进一步的断言)。 校验内容: 1.字段值 2.字段名或者字段类型 校验流程: 1.定义 校验规则(json语法,只能针对json对象校验,如…...
R语言——获取数据1
参考资料:学习R 数据的来源可以由很多。R内置有许多数据集,而在其他的附件包中能找到更多的数据。R能从各式各样的来源中读取,且支持大量的文件格式。 1、内置的数据集 R的基本分发包有一个datasets,里面全是示例数据集。很多其他…...
自编码器(AutoEncoder)概念解析与用法实例:压缩数字图像
目录 1. 前言 2. 自编码器的基本概念 2.1 自编码器的结构 2.2 损失函数 3. 使用 PyTorch 构建自编码器:压缩数字图像 3.1 导入必要的库 3.2 定义自编码器模型 3.3 准备数据集 3.4 训练模型 3.5 可视化重建结果 3.6 完整代码 4. 自编码器的应用场景 5. …...
从零开始打造HTML5拼图游戏:一个Canvas实战项目
从零开始打造HTML5拼图游戏:一个Canvas实战项目 先看效果: 你是否曾经被那些精美的网页拼图游戏所吸引?用 HTML5 的 Canvas 技术,从零开始,教你怎么画图、处理鼠标事件,还有游戏的核心逻辑,…...
每日一题洛谷P8649 [蓝桥杯 2017 省 B] k 倍区间c++
P8649 [蓝桥杯 2017 省 B] k 倍区间 - 洛谷 (luogu.com.cn) #include <iostream> #include <vector> using namespace std; #define int long long signed main() {int n, k;cin >> n >> k;vector<int> a(n 1);vector<int> sum(n 1);vec…...
在uniapp中,video比普通的标签层级高解决问题
<view style"position: relative;"><video style"position: absolute;z-index:-1"></video><view style"position: absolute;z-index:999"></view> </view> 上面代码并没有解决view的层级比video高的问题&…...
《探索边缘计算:重塑未来智能物联网的关键技术》
最近研学过程中发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...
Linux(十二)信号
今天我们就要来一起学习信号啦!!!还记得小编在之前的文章中说过的ctrlc吗?之前小编没有详细介绍过,现在我们就要来学习啦!!! 一、信号的基本介绍 首先,小编带领大家先一…...
LeetCode算法题(Go语言实现)_30
题目 给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。 第一个节点的索引被认为是 奇数 , 第二个节点的索引为 偶数 ,以此类推。 请注意,偶数组和奇数组内…...
无线通信技术(三):5G NR通信频带划分与应用场景
目录 一.5G NR频带划分概述 二.全球运营商5G频带分配对比 三.5G频带的应用场景 5G网络的发展离不开频谱资源的合理分配。不同的频段决定了5G的覆盖范围、传输速率和应用场景。本文将系统介绍5G NR频带划分,并结合实际应用场景,理解不同频段的特性及其适用环境。 …...
【读书笔记·VLSI电路设计方法解密】问题61:扫描插入的目的是什么
如问题60所述,要构建可测试电路,必须确保电路中每个节点都具有可控性和可观测性。但对于包含时序元件(如触发器、锁存器等存储元件)的电路,若不采取特殊设计则难以实现这两项特性。这是因为时序元件关联节点的逻辑状态不仅取决于当前输入,还受其先前存储状态影响——它们…...
VirtualBox安装FnOS
1.下载FnOS镜像 下载网址: https://www.fnnas.com/2.创建虚拟机 虚拟机配置如图所示(注意操作系统类型和网卡配置) (注意启动顺序) 3.启动虚拟机 网卡类型选择桥接的Virtual Adapter 如果没有IP地址或者IP地址无法…...
Pycharm(十二)列表练习题
一、门和钥匙 小X在一片大陆上探险,有一天他发现了一个洞穴,洞穴里面有n道门, 打开每道门都需要对应的钥匙,编号为i的钥匙能用于打开第i道门, 而且只有在打开了第i(i>1)道门之后,才能打开第i1道门&#…...
集合与容器:List、HashMap(II)
一、ArrayList 是集合框架中最核心的动态数组实现,高频使用的容器之一。 1. 核心数据结构 基于数组实现,维护elementData数组存储元素: transient修饰的elementData不会被默认序列化(通过自定义序列化逻辑优化存储)…...
Eclipse 视图(View)
Eclipse 视图(View) Eclipse 视图(View)是 Eclipse 界面的重要组成部分,它提供了用户交互的平台,使得用户可以通过图形界面来编辑、调试、分析代码等。在本文中,我们将深入探讨 Eclipse 视图的功能、使用方法以及它们在软件开发中的作用。 1. 视图的功能 Eclipse 视图具…...
《AI大模型应知应会100篇》第3篇:大模型的能力边界:它能做什么,不能做什么
第3篇:大模型的能力边界:它能做什么,不能做什么 摘要 在人工智能飞速发展的今天,大语言模型(LLM)已经成为许多领域的核心技术。然而,尽管它们展现出了惊人的能力,但也有明显的局限性…...
Springboot----@Role注解的作用
Role(BeanDefinition.ROLE_INFRASTRUCTURE) 是 Spring 框架中的一个注解,用于显式标记 Bean 的角色,表明该 Bean 是 Spring 容器内部的基础设施组件(如后置处理器、工具类等),而非用户直接使用的业务 Bean。其核心作用…...
小程序API —— 58 自定义组件 - 创建 - 注册 - 使用组件
目录 1. 基本介绍2. 全局组件3. 页面组件 1. 基本介绍 小程序目前已经支持组件化开发,可以将页面中的功能模块抽取成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护࿱…...
前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标节流处理、throttle、限制触发频率(setTimeout、clearInterval)
文章目录 使用lodashjs库手动实现节流(通过判断之前设定的定时器setTimeout是否存在) 使用lodashjs库 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Com…...
在 Android Studio 中运行安卓应用到 MuMu 模拟器
一、准备工作 1、确保 MuMu 模拟器已正确安装并启动 从官网下载安装最新版 MuMu 模拟器。启动后,建议在设置中调整性能参数(如 CPU 核心数和内存分配),以保证流畅运行。 2、配置 Android Studio 环境(按…...
从文本到多模态:如何将RAG扩展为支持图像+文本检索的增强生成系统?
目录 从文本到多模态:如何将RAG扩展为支持图像文本检索的增强生成系统? 一、为什么需要扩展到多模态? 二、多模态 RAG 系统的基本架构 三、关键技术点详解 (一)多模态嵌入(Embedding)技术 …...
【JavaEE】网络原理详解
1.❤️❤️前言~🥳🎉🎉🎉 Hello, Hello~ 亲爱的朋友们👋👋,这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章,请别吝啬你的点赞❤️❤️和收藏📖📖。如果你对我的…...
Python项目-基于Flask的个人博客系统设计与实现(2)
源代码 续 {% extends base.html %}{% block title %}评论管理{% endblock %}{% block content %} <div class"container py-4"><div class"row"><div class"col-md-3"><div class"list-group mb-4"><a h…...
洛谷题单3-P1720 月落乌啼算钱(斐波那契数列)-python-流程图重构
题目描述 给定一个整数 N N N,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例 2)。 输入格式 一个整数 N N N。 …...
NOIP2013提高组.华容道
题目 509. 华容道 算法标签: 搜索, b f s bfs bfs, s p f a spfa spfa 思路 不难发现, 在人移动的过程中, 箱子是不动的, 从当前位置到下一个箱子旁边的位置不会移动箱子, 可以预处理出人在每个位置到其他位置的距离预处理, 从某一个状态出发, 走到另一个状态的最短路使…...
政安晨【超级AI工作流】—— 基于COZE探索有趣的主题互动问答工作流(同宇宙儿童提问机)
政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正! 本例,我们将从零展示如何创建一款专门针对儿童对某项主题进行问答的对话流智能体…...
Derivatives and Differentiation (导数和微分)
Derivatives and Differentiation {导数和微分} 1. Derivatives and Differentiation (导数和微分)1.1. Visualization Utilities 2. Chain Rule (链式法则)3. DiscussionReferences For a long time, how to calculate the area of a circle remained a mystery. Then, in Anc…...
