Linux开发工具——make/makefile

📝前言:
这篇文章我们来讲讲Linux开发工具——make/makefile

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏


目录

  • 一,make/makefile基础介绍
    • make
    • Makefile
  • 二,具体示例
    • 1. 基础示例
      • 1.1 时间戳
      • 1.2 是否重新编译判断
    • 2. 进阶1——依赖链
    • 3. 进阶2——变量替换
    • 4. 进阶3——多文件
      • 4.1 获取当前目录下的所有文件
        • 执行的命令不回显
      • 4.2 %<
      • 4.3 模式规则

一,make/makefile基础介绍

make/Makefile用于自动化构建和管理项目。

make

  • 功能make是一个命令工具,它根据Makefile定义的规则来自动构建和管理项目。它可以自动检测源文件的修改情况,并仅重新编译那些需要更新的目标文件,从而大大提高了编译效率。
  • 工作原理make通过读取Makefile中的规则,分析目标文件和依赖文件之间的关系(简称依赖关系)。然后,它根据文件的时间戳modify时间)来判断哪些文件需要重新编译。如果一个依赖文件的修改时间晚于目标文件,或者目标文件不存在,make就会执行相应的命令来更新目标文件。
  • 使用方法:在项目目录中,只需在命令行中输入make命令,它就会自动查找当前目录下的Makefile,并按照其中的规则进行构建。如果Makefile中有多个目标,make默认构建第一个规则,后面的要指定要构建的特定目标,例如make target_name

Makefile

  • 作用Makefile是一个文本文件,它包含了一系列规则,用于告诉make工具如何构建项目。它定义了项目中的目标文件、依赖文件以及构建目标所需的命令(方法)。
  • 基本结构Makefile由一系列规则组成,每个规则通常包含以下部分:
    • 目标:通常是要构建的文件,如可执行文件、目标文件或库文件。也可以是一个抽象的目标,如clean用于清理生成的文件。
    • 依赖:目标所依赖的文件列表。
    • 命令:用于构建目标的命令。命令必须以Tab键开头。

(也可以认为:规则 = 依赖关系 + 依赖方法


二,具体示例

1. 基础示例

先对前面介绍到的基础的概念和用法做演示。

步骤:

  1. 现在当前目录下创建Makefile文件:touch ./Makefile
  2. 根据需求,编写Makefile
    在这里插入图片描述

解释:

  1. code.exe是目标文件,code.c是源文件(这是一组依赖关系,code.exe依赖code.c
  2. Tab开头,后面写依赖方法(构造目标用的命令)
  3. 一个抽象的目标clean,可以没有所依赖的文件列表
  4. 依赖方法

调用示例:
在这里插入图片描述

  1. make默认调用第一个规则,即code.exe:code.c这一个
  2. make clean,调用clean对应的规则
  3. 为什么连续调用make会失败呢?

因为:make根据文件modify时间戳来判断哪些文件需要重新编译。


1.1 时间戳

那什么是modify时间戳,?
stat查看文件时间属性
在这里插入图片描述

  • Access:访问时间,当文件被查看,如cat的时候会被修改(但有一些系统会优化,即:多次查看后才修改,为了减少磁盘I/O操作)
  • Modify:修改时间,代表文件最后一次被修改的时间,即内容有所改动,Modify就会改变
  • Change:变更时间,当文件属性有变化的时候会改变
  • Birth:诞生时间,创建时的时间

1.2 是否重新编译判断

当源文件的modify时间相比目标文件“旧”,代表没有源文件没有修改,则不重新编译
当源文件的modify时间相比目标文件“新”,代表源文件修改了,则重新编译

在这里插入图片描述
如图:我们在没有执行make之前,只有源文件1,执行完后,有了目标文件1,时间关系如上。此时再执行make就不会再重新编译

如果我们更改了源文件:
在这里插入图片描述
这时候,代表有新内容,目标文件就需要重新编译

那有没有办法让make无视时间戳,让依赖方法总是被执行呢?
有的兄弟,有的。那就是特殊目标声明:.PHONY,将目标标记为伪目标。
在这里插入图片描述

此时,make 不用去检查伪目标对应的文件是否存在、是否更新,而是直接执行命令
在这里插入图片描述


2. 进阶1——依赖链

在这里插入图片描述
在这里插入图片描述
依赖链的结构就像一个栈:

  1. 检查其依赖code.o,发现 code.o 不存在,则依赖方法入栈
  2. 检查 code.o 的依赖 code.s,发现 code.s 不存在,则依赖方法也入栈
  3. 检查 code.i 的依赖 code.c,发现 code.c 存在,则执行code.i的依赖方法
  4. 将栈中依赖方法依次执行

3. 进阶2——变量替换

定义变量
=:递归展开变量(不会在定义变量时立即对右侧的表达式进行求值,而是在使用该变量时才进行求值。这意味着变量的值可能会因为其他变量的改变而改变)
:=:简单展开变量(在定义变量时就对右侧的表达式进行求值,变量的值在定义时就已经确定,后续不会因为其他变量的改变而改变)

引用变量
$(变量名)

示例:
在这里插入图片描述
$@$^
$@指代目标文件,$^指代依赖文件列表
即上面的内容可以改成:
在这里插入图片描述
这里$^会自动对应这个方法的依赖关系中的$(SRC)$@对应$(BIN)


4. 进阶3——多文件

4.1 获取当前目录下的所有文件

在Makefile中执行命令:$(shell 命令)
使用函数:$(函数名 参数1,参数2…)

获取当前目录下所有.c文件后缀的方法:

  1. $(shell ls *.c),回顾:ls这个命令只列出名称
  2. $(wildcard *.c)

在这里插入图片描述输入make运行结果:
在这里插入图片描述

执行的命令不回显

在命令前加:@
在这里插入图片描述
效果:
在这里插入图片描述

4.2 %<

当有多个源文件需要编译成目标文件,且每个源文件的编译命令基本相同时,使用 $< 能避免重复书写源文件名称。

$<被自动替换为当前规则中列出的第一个依赖文件的名称。例如,对于规则 target: dep1 dep2 dep3,在其对应的命令里使用 $<,它就代表 dep1

4.3 模式规则

%:通配符,如%.c:所有以.c结尾的文件

%.o: %.c :这个规则中,%所匹配的内容在目标和依赖中是相同的。(同名)
当 make工具处理这个规则时,会针对每个 .o 文件的构建分别执行一次规则里的命令

错误写法:
在这里插入图片描述
报错:

make: *** No targets.  Stop.

因为:%.o: %.c只是一个模式规则,并没有具体构建目标。具体的构建目标是指在 Makefile 中明确指定要构建的文件,文件名需要是完整且能明确指向一个具体文件的。

正确使用示例:
在这里插入图片描述

额外语法:

  • 命令可以多行,但是也要Tab开头
  • 注释用#符号

理解执行过程:

  1. 具体构建目标:code.exe,依赖所有.o文件,没有.o文件,于是到下一个规则%.o:%.c
  2. %.o:%.c规则中,make会针对每个.o文件分别执行一次命令,此时,每个.o文件变成了这个规则里的具体构建目标

运行结果:
在这里插入图片描述


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

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

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

相关文章

python加载训练好的模型并进行叶片实例分割预测

要基于“GMT: Guided Mask Transformer for Leaf Instance Segmentation”进行代码复现&#xff0c;可按照以下步骤利用Python实现&#xff1a; 环境配置 克隆仓库&#xff1a;在终端中使用git clone https://github.com/vios-s/gmt-leaf-ins-seg.git命令&#xff0c;将项目代…

AI平台初步规划实现和想法

要实现一个类似Coze的工作流搭建引擎&#xff0c;可以结合SmartEngine作为后端工作流引擎&#xff0c;ReactFlow作为前端流程图渲染工具&#xff0c;以及Ant Design作为UI组件库。以下是实现的步骤和关键点&#xff1a; ### 1. 后端工作流引擎&#xff08;SmartEngine&#xf…

Pycharm 启动时候一直扫描索引/更新索引 Update index/Scanning files to index

多个项目共用一个虚拟环境&#xff0c;有助于加快PyCharm 启动吗 chatgpt 4o认为很有帮助&#xff0c;gemini 2.5pro认为没鸟用&#xff0c;我更认可gemini的观点。不知道他们谁在一本正经胡说八道。 -------- 打开pycharm的时候&#xff0c;下方的进度条一直显示在扫描文件…

dify新版本1.1.3的一些问题

本人使用window版本上构建dify&#xff0c;采用docker方法启动 1、拉取镜像问题 windows上更改拉取镜像仓库地址 优化加速参考&#xff1a;青春不留白/Docker-hub 如果还是拉取比较慢的话&#xff0c;建议科学上网解决。 2、启动问题 发生报错Dify:failed to init dify plu…

4.2-3 fiddler抓取手机接口

安卓&#xff1a; 长按手机连接的WiFi&#xff0c;点击修改网络 把代理改成手动&#xff0c;服务器主机选择自己电脑的IP地址&#xff0c;端口号为8888&#xff08;在dos窗口输入ipconfig查询IP地址&#xff0c;为ipv4&#xff09; 打开手机浏览器&#xff0c;输入http://自己…

Spring Boot中自定义注解的创建与使用

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

2024第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

记录刷题的过程、感悟、题解。 希望能帮到&#xff0c;那些与我一同前行的&#xff0c;来自远方的朋友&#x1f609; 大纲&#xff1a; 1、握手问题-&#xff08;解析&#xff09;-简单组合问题&#xff08;别人叫她 鸽巢定理&#xff09;&#x1f607;&#xff0c;感觉叫高级了…

HTML应用指南:利用POST请求获取三大运营商5G基站位置信息(一)

在当前信息技术迅猛发展的背景下,第五代移动通信(5G)技术作为新一代的无线通信标准,正逐步成为推动社会进步和产业升级的关键驱动力。三大电信运营商(中国移动、中国联通、中国电信)在全国范围内的5G基站部署,不仅极大地提升了网络性能,也为智能城市、物联网、自动驾驶…

C++学习之线程

目录 1.进程和线程的概念 2.线程内核三级映射 3.线程优缺点 4.创建线程和获取线程ID的函数 5.创建子线程 6.循环创建N个子线程 7.子线程传参地址错误演示分析 8.主、子线程共享全局变量、堆空间 9.线程退出 10.pthread join回收线程退出值 11.pthread_cancel 12.杀死…

element-plus中,表单校验的使用

目录 一.案例1&#xff1a;给下面的表单添加校验 1.目的要求 2.步骤 ①给需要校验的el-form-item项&#xff0c;添加prop属性 ②定义一个表单校验对象&#xff0c;里面存放了每一个prop的检验规则 ③给el-form组件&#xff0c;添加:rules属性 ④给el-form组件&#xff0…

团体设计程序天梯赛L2-025 # 分而治之

文章目录 题目解读输入格式输出格式 思路Ac Code参考 题目解读 在战争中&#xff0c;我们希望首先攻下敌方的部分城市&#xff0c;使其剩余的城市变成孤立无援&#xff0c;然后再分头各个击破。为此参谋部提供了若干打击方案。本题就请你编写程序&#xff0c;判断每个方案的可…

Arduino示例代码讲解:Knock Sensor 敲击感知器

Arduino示例代码讲解:Knock Sensor 敲击感知器 Knock Sensor 敲击感知器功能概述硬件部分:软件部分:代码逐行解释定义常量定义变量`setup()` 函数`loop()` 函数工作原理Knock Sensor 敲击感知器 这段代码是一个Arduino示例程序,用于检测敲击声。它通过读取一个压电元件(p…

【百日精通JAVA | SQL篇 | 第三篇】 MYSQL增删改查

SQL得最核心就是增删改查 一个后端开发&#xff0c;在工作中&#xff0c;最常见的场景就是CRUD。 插入数据 insert into student values (1,zhangsan); 指定列插入数据 同时多个列明之间使用逗号&#xff0c;来分割 insert into student (name) values (zhaoliu); 这个黑框…

ggscitable包通过曲线拟合深度挖掘一个陌生数据库非线性关系

很多新手刚才是总是觉得自己没什么可以写的&#xff0c;自己不知道选什么题材进行分析&#xff0c;使用scitable包ggscitable包后这个完全不用担心&#xff0c;选题多到你只会担心你写不完&#xff0c;写得不够快。 既往咱们使用scitable包交互效应深度挖掘一个陌生数据库&…

ctfshow VIP题目限免 版本控制泄露源码2

根据题目提示是版本控制泄露源码 版本控制&#xff08;Version Control&#xff09;是一种在软件开发和其他领域中广泛使用的技术&#xff0c;用于管理文件或项目的变更历史。 主流的版本控制工具&#xff1a; ‌Git‌&#xff1a;目前最流行的分布式版本控制系统。‌SVN‌&am…

2025-04-05 吴恩达机器学习5——逻辑回归(2):过拟合与正则化

文章目录 1 过拟合1.1 过拟合问题1.2 解决过拟合 2 正则化2.1 正则化代价函数2.2 线性回归的正则化2.3 逻辑回归的正则化 1 过拟合 1.1 过拟合问题 欠拟合&#xff08;Underfitting&#xff09; 模型过于简单&#xff0c;无法捕捉数据中的模式&#xff0c;导致训练误差和测试误…

如何用人工智能大模型,进行作业批改?

今天我们学习人工智能大模型如何进行作业批改。手把手学习视频请访问https://edu.csdn.net/learn/40402/666452 第一步&#xff0c;进入讯飞星火。打开google浏览器&#xff0c;输入百度地址后&#xff0c;搜索”讯飞星火”&#xff0c;在搜索的结果中&#xff0c;点第一个讯飞…

C++学习笔记之 模板|函数模板|类模板

函数模板 类模板 定义&#xff1a;函数模板是建立一个通用函数&#xff0c;它所用到的数据的类型&#xff08;包括返回值类型、形参类型、局部变量类型 &#xff09;可以不具体指定&#xff0c;而是用一个虚拟的类型来代替&#xff08;用标识符占位&#xff09;&#xff0c;在…

正则入门到精通

​ 一、正则表达式入门​ 正则表达式本质上是一串字符序列&#xff0c;用于定义一个文本模式。通过这个模式&#xff0c;我们可以指定要匹配的文本特征。例如&#xff0c;如果你想匹配一个以 “abc” 开头的字符串&#xff0c;正则表达式可以写作 “^abc”&#xff0c;其中 …

对备忘录模式的理解

对备忘录模式的理解 一、场景1、题目【[来源](https://kamacoder.com/problempage.php?pid1095)】1.1 题目描述1.2 输入描述1.3 输出描述1.4 输入示例1.5 输出示例 2、理解需求 二、不采用备忘录设计模式1、代码2、问题3、错误的备忘录模式 三、采用备忘录设计模式1、代码1.1 …