【LInux学习】Linux项目自动化构建工具-make/Makefile

news2024/12/23 2:25:56

在这里插入图片描述

文章目录

    • 🌂背景
    • 🌂make/Makefile的使用
    • 🌂make/Makefile原理
    • 🌂项目清理
    • 🌂make/Makefile的语法补充


🌂背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

🌂make/Makefile的使用

先看一个简单的使用示例:使用步骤:

  1. 先创建一个文件,文件名必须是makefile/Makefile,不能是其他名字。
  2. vim打开该makefile文件,增加第一行:依赖关系 第二行:依赖方法(后面会讲解到)
  3. 然后退出,输入命令
    # make
  1. 结果,就会生成自己指定的文件
    结果:
    在这里插入图片描述

以上的例子来讲:Makefile文件里面的第一行:
依赖关系:code:test.c意思就是形成code文件,需要依赖test.c
依赖方法:[TAB]gcc -o code test.c 就是应该怎么依赖test.c文件形成code文件,这里就是利用gcc编译test.c文件,形成code文件。

下面通过这样的例子帮助我们更好的理解:(如下图)
在这里插入图片描述
🌂解析:
这里是上一章讲的翻译的过程,不知道的可以去看看: link

🌂依赖关系
依赖关系必须用冒号(:)作为分隔符,冒号左边为需要形成的目标文件,右侧是依赖文件列表(可以有多个,空格分开)。
上面的code文件,依赖test.o文件
test.o文件,依赖test.s文件
test.s文件,依赖test.i文件
test.i文件,依赖test.c文件

🌂 依赖方法
拿一行说明:就比如最后一行的依赖关系下面的依赖方法:

# gcc -E -o test.i test.c

就是需要依赖test.c文件,将他预处理后形成test.i文件。

最后指令make后的效果:
在这里插入图片描述
我们可以看到,这里执行的顺序和我们写的顺序是相反的,这就要看看make与Makefile的原理了。

🌂make/Makefile原理

make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“code”这个文件,并把这个文件作为最终的目标文件。
  3. 如果code文件不存在,或是code所依赖的后面的code.o文件的文件修改时间要比code这个文件新,那么,他就会执行后面所定义的命令来生成code这个文件。
  4. 如果code所依赖的code.o文件不存在,那么make会在当前文件中找目标为code.o文件的依赖文件,如果找到则再根据上面的规则生成code.o文件。(这有点像一个堆栈的过程)
  5. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  6. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  7. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

在这里插入图片描述
🌂大白话解析:
make指令后,会进入到Makefile文件中去找到第一个目标文件,也就是code文件,然后发要生成code文件,但是code文件依赖的test.o文件不存在或则,那么就会向下寻找test.o文件,发现要生成的test.o文件的test.s文件也不存在,就会向下找test.s文件,又发现生成test.s文件的test.i文件不存在,向下找test.i文件,这时,生成test.i文件依赖的test.c文件存在,就会执行下面的指令,生成test.i文件,然后一直向上执行,直到最后生成code目标文件。

🌂注意:
再执行make指令的时候,如果源文件在上次执行后到现在,内容没有发生实质性的变化,那么就make就不会执行。
在这里插入图片描述

🌂扩展知识:
思考:make和Makefile怎么知道生成的code文件是不是最新的呢?
这里是通过对比时间知道的。 (对比<Modify的时间)

一个文件有三个时间,可以通过指令查看:

# stat 文件

在这里插入图片描述
🌂注意:

  1. 在我们更改内容的时候,往往Modify与Change会发生联动变化,因为内容更改可能会影响文件属性(文件大小)的变化。
  2. 当我们每次去访问一个文件,该文件的Access时间可能不会改变,取决于Linux系统自己的评判标准,那为什么呢?这个就要谈谈Linux历史了,Linux最开始是每次访问过后,文件的Access时间都会改变,但是后面人们发现,在使用Linux的时候,有时候会经常去查看文件,文件属性(时间)也是数据,如果每次都要对时间进行更新的话,那就意味着每次都会涉及到让操作系统向对应的磁盘文件当中的文件属性Access时间进行更改,就会降低效率。

🌂怎么更新这3个时间;

使用命令:

 # touch 文件名   //如果该文件存在就会更新时间,不存在就会创建

在这里插入图片描述

🌂项目清理

工程是需要被清理的,可以使用在makefile文件中添加clean,或则自己命名。

像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰(后面会再次提到),伪目标的特性是,总是被执行的。
在这里插入图片描述

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

🌂make/Makefile的语法补充

🌂语法一:.PHNOY 文件名
示例:
在这里插入图片描述
运行测试:
在这里插入图片描述

但是我们一般不会将目标文件设置为伪目标,一般建议将clean设置为伪目标。
在这里插入图片描述
🌂不将源文件设置为伪目标的原因:
如果源文件里面很多的源文件,那么如果将该源文件设置为伪目标后,每次make执行编译的时候,都会将所有文件,不管改没改变,都重新编译一遍,会导致效率低下的问题。

🌂语法二:$@ 与 $^
在这里插入图片描述
测试:结果:与之前的效果一样。
在这里插入图片描述

🌂语法三:makefile里面可以定义变量
例如:
在这里插入图片描述

测试:
在这里插入图片描述


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

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

相关文章

C++模版初阶----函数模版、类模版

C模版初阶 1. 泛型编程2. 函数模板2.1 函数模板概念2.2函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 函数模版的匹配原则 3. 类模板3.1 类模板的定义格式3.2 类模板的实例化 总结 1. 泛型编程 泛型编程 : 编写与类型无关的通用代码&#xff0c;是代码复用的一种手段…

模电期末复习(三)放大电路的频率响应

放大电路的频率响应 3.1 频率响应的一般概念3.1.1 幅频特性和相频特性3.1.2 下限频率、上限频率和通频带3.1.3 频率失真3.1.4 波特图3.1.5高通电路和低通电路 3.2 三极管的频率参数3.2.1 共射截止频率3.2.2 特征频率3.2.3 共基截止频率 3.3 单管共射放大电路的频率响应3.3.1 三…

Chrome 侧边栏开发示例

前言 最近做项目&#xff0c;需要开发浏览器扩展&#xff0c;但是考虑页面布局兼容性问题&#xff0c;使用了Chrome114开始的侧边栏&#xff0c;浏览器自带的能力毕竟不会出现兼容性问题&#xff0c;不过Chrome123开始&#xff0c;侧边栏居然又可以选择固定右侧扩展栏了&#…

IDEA中Vue开发环境搭建

1. IDEA安装Vue.js 文件>设置>插件>搜索Vue.js并安装。 2. 安装Node.js 官网地址&#xff1a;https://nodejs.org 安装包下载地址&#xff1a;https://nodejs.org/en/download 下载并安装&#xff0c;安装时&#xff0c;勾选添加系统变量选项。 # 如果正确安装…

Spring AI Summary

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Spring AI is a project that aims to streamline the development of AI applications by providing abstractions and reusable components that can be easily integrate…

Jmeter-非GUI模式下运行jmeter脚本-适用于服务器上持续集成测试

背景 大部分Jmeter脚本都是部署在Linux上运行&#xff0c;利用Jenkins做接口自动化&#xff0c;定时巡检任务。 执行命令 1.进入jmeter的目录&#xff0c;bin文件夹 cd C:\path\to\jmeter\bin2.运行脚本文件 jmeter -n -t D:\{脚本文件目录}\xxx.jmx -l D:\{脚本文件目录}…

Java代码基础算法练习-逆序输出-2024.04.22

任务描述&#xff1a; 输入10个数字&#xff08;数字取值范围&#xff1a;0~1000&#xff09;&#xff0c;然后逆序输出。 任务要求&#xff1a; 代码示例&#xff1a; package April_2024;import java.util.Scanner;/*** 输入10个数字&#xff08;限定在0~1000范围内&#x…

Rust基本数据类型-切片

一、切片是什么&#xff0c;怎么用 1、切片是什么 切片并不是 Rust 独有的概念&#xff0c;在 Go 语言中就非常流行&#xff0c;它允许你引用集合中部分连续的元素序列&#xff0c;而不是引用整个集合。 对于字符串而言&#xff0c;切片就是对 String 类型中某一部分的引用&…

FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器

AVS3是中国AVS工作组制定的第三代音视频编解码技术标准&#xff0c;也是全球首个已推出的面向8K及5G产业应用的视频编码标准。AVS工作组于2019年3月9日完成第三代AVS视频标准&#xff08;AVS3&#xff09;基准档次的制订工作&#xff0c;参考软件的测试表明&#xff0c;AVS3基准…

webpack-babel2

浏览器的兼容性问题 浏览器的兼容性问题不知包括随屏幕大小而变化&#xff0c;还包括针对浏览器支持的特性&#xff08;如css特性&#xff0c;js特性&#xff09; 做处理。 目前市场上有很多浏览器&#xff1a;Chrome,Safari,IE,Edge等&#xff0c;要根据它们的市场占有率来决…

将城市名称替换成简写

图片左边是城市全称&#xff0c;右边是城市简写。 现在有一句话“this is Republic of Korea,that is United States of America”&#xff0c;要将其中的城市全称替换成城市简写。 #"Republic of Korea"替换成 South Korea s"this is Republic of Korea,that …

三、Flask模型基础

ORM 创建模型 # exts.py&#xff1a;插件管理 # 扩展的第三方插件 # 1.导入第三方插件 from flask_sqlalchemy import SQLAlchemy # ORM插件 from flask_migrate import Migrate # 2. 初始化 db SQLAlchemy() # ORM migrate Migrate() # 数据迁移 # 3. 和app对象绑定 def…

生态短讯 | Tapdata 与 TDengine 完成产品兼容性互认证,打造物联网实时数据生态

近月&#xff0c;深圳钛铂数据有限公司&#xff08;以下简称钛铂数据&#xff09;自主研发的实时数据平台&#xff08;Tapdata Live Data Platform&#xff09;与北京涛思数据科技有限公司&#xff08;以下简称涛思数据&#xff09;自主研发的大数据平台 TDengine&#xff0c;已…

SpringBoot集成Sleuth

引入Maven依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency> 配置yml文件 bootstrap.yml文件增加如下配置 注&#xff1a;这个配置不是必须要&#…

WordPress SQLite Docker 镜像封装细节

为了让大家用的放心&#xff0c;同时解答 GitHub 社区中的疑问。这篇文章聊聊上一篇文章的 Docker 容器封装细节。 写在前面 在前一篇文章《WordPress 告别 MySQL&#xff1a;Docker SQLite WordPress》中&#xff0c;如果你跟着文章实践&#xff0c;大概三分钟就能够启动一个…

(三)组合特征与特征变换 学习简要笔记 #机器学习特征工程 #CDA学习打卡

目录 一. 统计及组合特征 1&#xff09;统计特征 2&#xff09;业务特征 3&#xff09;组合特征 &#xff08;a&#xff09;简单组合特征 &#xff08;b&#xff09;模型特征组合 二. 特征变换 1&#xff09;对数变换&#xff08;Logarithmic Transformation&#xff0…

KingbaseES存储过程的用法

数据库版本&#xff1a;KingbaseES V008R006C008B0014 简介 存储过程是一种强大的数据库编程工具&#xff0c;可以帮助开发人员实现复杂的业务逻辑和数据操作&#xff0c;用于提高数据库的性能、安全性和可维护性。 存储过程一般是将业务逻辑和数据操作封装起来&#xff0c;以便…

深度学习之图像分割从入门到精通——基于unet++实现细胞分割

模型 import torch from torch import nn__all__ [UNet, NestedUNet]class VGGBlock(nn.Module):def __init__(self, in_channels, middle_channels, out_channels):super().__init__()self.relu nn.ReLU(inplaceTrue)self.conv1 nn.Conv2d(in_channels, middle_channels, …

Redis底层数据结构之SDS

目录 一、概述二、SDS结构三、为什么使用SDS 下一篇 redis底层数据结构之ziplist 一、概述 Redis 中的 SDS&#xff08;Simple Dynamic String&#xff0c;简单动态字符串&#xff09;是 Redis 用于存储字符串值的底层实现&#xff0c;是对 C 语言传统字符串&#xff08;以 nu…

如何使用 Node.js 发送电子邮件全解和相关工具推荐

大多数Web应用程序都需要发送电子邮件。它可能用于注册、密码重置、状态报告&#xff0c;甚至是完整的市场营销活动&#xff0c;如新闻和促销。本教程解释了如何在Node.js中发送电子邮件&#xff0c;但其概念和挑战适用于您正在使用的任何系统。 你会在 npm 上找到大量与电子邮…