【Linux必备工具】自动化构建工具makefile的使用详解

news2024/11/25 4:19:11

目录

引言

Makefile 简介

依赖关系与依赖方法

make运行规则

依赖关系示例

依赖方法

Makefile 工作原理

示例代码

清理项目与伪目标

清理示例

.PHONY总是被执行

文章手稿:


文章手稿见文末~

引言

项目构建时遇到的各种挑战如文件编译顺序、库链接、依赖文件的管理等,在不同开发环境中会有不同的解决方案。

在 Visual Studio (VS) 环境中,这些问题往往被自动处理,运行直接 Ctrl + F5 就可以了,编译个项目真的轻轻松松。 那是因为 VS 帮你自动维护了对应的项目结构!

那如果需要手动实现呢:多文件   我们先编译哪一个程序?链接需要哪些库?整个项目结构,该如何维护......在 Linux 环境中,我们需要更手动、细致地管理这些方面。为了解决这个问题,Linux 提供了自动化构建工具 Makefile

Makefile 简介

Makefile 是 Linux 下用于管理文件依赖和编译顺序的一个重要工具。它用于定义项目中的各个源文件如何编译链接,可以极大地提高开发效率。

Makefile 文件中定义了一系列规则,指定文件编译顺序、文件依赖关系及各文件的编译方法。make 命令是一个解释 Makefile 文件的命令工具,可以完成项目的自动化构建。

依赖关系与依赖方法

在一个大项目中例如一不小心写反gcc的执行,可执行程序就覆盖掉了原文件,最后导致你的源代码都没了……由此可见,在命令行操作时如果出现误操作,就会翻车。正是因为这些悲剧的存在,使得 Makefile 的光芒愈发温暖!

我们先做一些准备工作,touch makefile ,然后vim 输入以下指令

可以将依赖关系和依赖方法类比为生活中的要钱例子:打电话告诉爸爸"我是你儿子"表示依赖关系,而要求给你打钱表明了依赖方法。只有同时满足依赖关系和依赖方法,才能成功达到目的,即完成编译和链接。

在 Makefile 中,最核心的概念是依赖关系和依赖方法。依赖关系用于指定某个目标文件依赖哪些源文件,当这些源文件发生变化时,需要重新生成目标文件。依赖方法则是生成目标文件所执行的具体命令。

效果:

以后我们在 Linux 下编译代码就不需要敲 gcc 命令了,直接 make 就可以了,尤其是在大项目中会特别的方便

make运行规则

❓ 思考:为什么 make 的时候它总是执行第一个呢?

 makefile 在形成文件时会自顶而下扫描,默认只会形式第一个目标文件,执行该依赖关系的依赖方法。 

我们这里有两个目标文件,一个是 mytest 一个是 clean,凭什么我 make 执行的是 mytest 而不是 clean?答案很简单,就凭 mytest 是在前面写的

 如果我们把它们两的顺序换一下:

因为上下位置的调换,修改了make的默认操作

依赖关系示例

假设我们有以下文件依赖关系:

hello: hello.o
hello.o: hello.s
hello.s: hello.i
hello.i: hello.c

依赖方法

使用 gcc 命令编译不同中间文件:

hello: hello.o
	gcc hello.o -o hello

hello.o: hello.s
	gcc -c hello.s -o hello.o

hello.s: hello.i
	gcc -S hello.i -o hello.s

hello.i: hello.c
	gcc -E hello.c -o hello.i

在上述例子中,hello 是最终目标文件,它依赖于目标文件 hello.o,而后者又进一步依赖于 hello.s,如此递归下去直到源文件 hello.c

Makefile 工作原理

  1. make 命令查找名为 Makefile 或 makefile 的文件。
  2. 读取文件并找到第一个目标文件,在本例中是 hello
  3. 如果 hello 不存在,或其依赖文件中任何一个文件比 hello 更新,则生成 hello 文件。
  4. 递归检查每个依赖文件,按顺序进行必要的编译步骤。
  5. 如果出现错误,make 退出并报错。
  6. 如果依赖文件仍然不在,make 也将退出。

示例代码

这是一个简单的 C 代码示例和相应的 Makefile 文件:

// hello.c
#include <stdio.h>
int main() {
    printf("hello Makefile!\n");
    return 0;
}
# Makefile
hello: hello.o
	gcc hello.o -o hello

hello.o: hello.c
	gcc -c hello.c -o hello.o

.PHONY: clean
clean:
	rm -f hello.o hello

在这个示例中,hello 目标文件依赖于 hello.o 文件,而 hello.o 则由 hello.c 编译生成。clean 是一个伪目标,无论何时执行 make cleanclean 中的命令都会被执行,达到清理文件目的。

清理项目与伪目标

工程经常需要清理生成的中间文件和目标文件,Makefile 提供了方便的清理机制。通过定义伪目标,可以确保 make clean 总能执行对应的清理命令。

清理示例

代码:

.PHONY: clean
clean:
	rm -f hello.o hello

 clean  没有依赖文件,也是存在依赖关系的,只不过这个  clean  没有依赖列表。

.PHONY 用于标记 clean 为伪目标,无论当前目录下是否有 clean 文件或目标,make clean 命令都会执行。

效果:

.PHONY总是被执行

我们刚才看了 "总是不被执行" 的现象,我们试试给我们的 mytest 也用 ​{\color{Red} .PHONY},让它从默认的 "总是不被执行" 变成 "总是被执行" 看看

但为了提高效率,我们一般不建议这样

实际上是make一次,如果未发生改变就不会再执行了

详细解释如下:

我们打开文件修改,Access 应不应该改变呢?我们读取 Access 变不变?

要变的!但是现在不会变!因为访问文件的频率是最高的,Modify 和 Change 是不得不变的,不变的化文件就不对了。但是我们大多数情况修改文件属性和修改文件内容是很低频的事情,但打开文件是非常高平的事情,Linux 后期内核对 Access 进行了优化,将文件打开访问,打开时间不会变化,累计一段时间后他才会变化。如果不这样,打开文件这种高频率的事情,一旦更新 Access 时间,就要将数据刷新到磁盘上,这实际上一个很没效率的事情。

具体 Access 的调整策略取决于 Linux 的版本。

让我们再来回答一下最初的怎么做到的?

通过对比你的源文件和可执行程序的更改时间 (modify time) 识别的新旧。 根据原文件和可执行程序的最近修改时间,评估要不要重新生成

文章手稿:

 

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

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

相关文章

深入理解Java并发锁

在Java中&#xff0c;并发锁是用来控制多个线程对共享资源的访问&#xff0c;确保数据的一致性和完整性。Java提供了多种并发锁机制&#xff0c;包括内置锁&#xff08;synchronized&#xff09;、显示锁&#xff08;如ReentrantLock&#xff09;、原子变量、并发容器以及一些高…

【系统设计】如何权衡范式与反范式设计

一、什么是范式设计与反范式设计 1.1、范式设计&#xff08;Normalization&#xff09; 定义&#xff1a; 范式设计是数据库设计中最基础的设计原则之一&#xff0c;它主要通过规范化数据模型&#xff0c;减少数据冗余和数据不一致的问题。 常用的范式&#xff1a; 第一范式…

Nginx 负载均衡实现上游服务健康检查

Nginx 负载均衡实现上游服务健康检查 Author&#xff1a;Arsen Date&#xff1a;2024/06/20 目录 Nginx 负载均衡实现上游服务健康检查 前言一、Nginx 部署并新增模块二、健康检查配置2.1 准备 nodeJS 应用程序2.2 Nginx 配置负载均衡健康检查 小结 前言 如果你使用云负载均衡…

js中的window和Window

示例&#xff1a; window.name name; console.log(window.name) // name console.log(Window.name) // Window由此可见Window和window是有区别的。 console.log(Object.prototype.toString.call(Window)); // [object Function] console.log(Object.prototype.toString.c…

论文:R语言数据分析之机器学习论文

欢迎大家关注全网生信学习者系列&#xff1a; WX公zhong号&#xff1a;生信学习者Xiao hong书&#xff1a;生信学习者知hu&#xff1a;生信学习者CDSN&#xff1a;生信学习者2 一、研究背景 全球范围内&#xff0c;乳腺癌是导致癌症发病率和死亡率的主要疾病之一。根据2018年…

微软 Florence-2:多功能视觉模型

微软开发的 Florence-2 系列模型&#xff0c;使用提示&#xff08;prompt-based approach&#xff09;来处理不同的视觉任务。 通过改变提示&#xff0c;模型可以执行不同的任务&#xff0c;例如&#xff1a; 描述&#xff08;Caption&#xff09;详细描述&#xff08;Detail…

代码随想录算法训练营第二十八天

题目&#xff1a;134. 加油站 暴力方法 暴力的方法很明显就是O(n^2)的&#xff0c;遍历每一个加油站为起点的情况&#xff0c;模拟一圈。 如果跑了一圈&#xff0c;中途没有断油&#xff0c;而且最后油量大于等于0&#xff0c;说明这个起点是ok的。 暴力的方法思路比较简单…

NGINX_十六 nginx 错误页面配置

十六 nginx 错误页面配置 nginx错误页面包括404 403 500 502 503 504等页面&#xff0c;只需要在server中增加以下配置即可&#xff1a; #error_page 404 403 500 502 503 504 /404.html;location /404.html {root /usr/local/nginx/html;}注意&#xff1a; /usr/local…

PostgreSQL性能优化之分区表 #PG培训

在处理大规模数据时&#xff0c;PostgreSQL的性能优化是一个非常重要的话题&#xff0c;其中分区表&#xff08;Partitioned Tables&#xff09;是提高查询和数据管理效率的重要手段。本文将详细介绍PostgreSQL分区表的概念、优势、创建与管理方法以及一些常见的优化策略。 #P…

qml:一个基础的界面设计

文章目录 文章说明效果图重要代码说明组件矩形卡片窗口最大化后组件全部居中菜单栏Repeater实现重复8行图片加载直接加载图片文本转图片FluentUI中可供选择的图标 文章说明 qt6.5.3 qml写的一个界面配置设计软件&#xff0c;目前不含任何c代码&#xff0c;纯qml。windoms风格的…

【Java】已解决java.net.HttpRetryException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例 已解决java.net.HttpRetryException异常 在Java的网络编程中&#xff0c;尤其是使用Apache HttpClient或其他类似的HTTP客户端库时&#xff0c;可能会遇到java.net.HttpRetryException异常。这个…

华为200人园区网有线和无线

实验描述&#xff1a; 1 内网有有线业务、内部无线、外部无线三种业误。 2 内网服务器配置静态IP&#xff0c;网关192.168.108.1。 3 sW1和R1之间使用v1an200 192.168.200.9/30 互联。 4 R2向运营商申请企业宽带并获得了1个固定公网IP&#xff1a; 200.1.1.1 子网掩码 255.255.…

VMware虚拟机下载安装Windows Server 2016

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

Docker常用操作和命令

文章目录 1、卸载旧版本 2、yum安装Docker CE&#xff08;社区版&#xff09; 3、添加镜像加速器 4、docker --version 查看docker版本 5、docker info 或 docker system info 显示 Docker 系统的详细信息&#xff0c;包括容器、镜像、网络等 6、docker search 搜索镜像 …

MEMS环境传感器生产测试的挑战与未来趋势

微机电系统 (MEMS) 环境传感器无处不在&#xff0c;默默地支撑着我们日常生活中众多设备的功能。从智能手机和可穿戴设备到智能家居和工业自动化&#xff0c;这些微型产品可以测量温度、压力、湿度和大量其他环境参数。 由于环境监测需求不断增长以及空气质量严格法规的实施&am…

一站式家装服务管理系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;装修风格管理&#xff0c;主材管理&#xff0c;用户管理&#xff0c;基础数据管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;装修风格&#xff0…

极狐GitLab落户香港科学园并成功发布AI产品驭码CodeRider国际版

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

189.二叉树:将有序数组转换为二叉搜索树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

canvas绘制红绿灯路口(二)

系列文章 canvas绘制红绿灯路口&#xff08;一&#xff09; 无图不欢&#xff0c;先上图 优化项&#xff1a; 一&#xff1a;加入人行道红绿信号 二&#xff1a;加入专用车道标识&#xff08;无方向标识时采用专用车道标识&#xff09; 三&#xff1a;东南西北四项路口优化绘…

汇凯金业:现货黄金投资平仓策略有哪些

现货黄金作为全球投资者广泛关注与参与的财富增值途径&#xff0c;其双向交易制度为市场参与者在不同行情下提供了盈利的可能。然而&#xff0c;如何在波动的市场中把握最佳的平仓时机&#xff0c;从而最大化收益&#xff0c;是所有投资者心中的疑问。正确的平仓策略可以说是现…