【Linux】Linux下的项目自动化构建工具——make和makefile

❤️前言

        大家好,好久不见!今天小狮子为大家带来的文章是一篇关于Linux下的项目自动化构建工具——make和makefile的博客,希望能帮助到大家。

正文

        当我们进行涉及多文件的工程开发时,我们需要对很多不同类型、不同功能,存在于不同目录下的源文件进行编译操作,这时错综复杂的文件关系会对我们造成很大的麻烦。那么这时我们就需要使用到make和makefile这样的自动化构建工具。

        我们先大致地对make和makefile进行描述:

        makefile是一个文件,其中定义了各个源文件的编译规则,比如说哪个文件应该先编译,哪个文件应该后编译,哪些文件需要重新编译等。除此之外,在makefile中还可以进行一些功能操作,例如对工程中的老旧文件进行清理。

 

        make是一条指令,它可以解析makefile中的各种指令,从而自动化地对工程中的源文件进行各种操作。

 

        make和makefile搭配使用可以大大地减少我们的工作量,达成“自动化编译”,这时我们只需要一个指令便可以使整个工程完全自动编译。

        当我们大致地了解了make和makefile之后,我们接着对这两者进行详细的学习。

简单的运用

        当我们想要使用make和makefile,我们首先需要在当前目录下创建一个makefile,makefile的文件名可以为makefileMakefile或者GNUmakefile。这时固定的,因为在默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件。

        那么我们以经典的“Hello world!”来简单演示和讲解make和makefile的使用方法。当我们创建了一个makefile之后,我们还需要创建该程序所需要的源文件,我将它命名为main.c,并在其中编写相关的代码(输出"Hello world!")。

        准备过程完成如下:

          现在我们进行对makefile文件的编写,编写makefile时,我们需要写入的内容主要有两个,分别称为依赖关系依赖方法

依赖关系:

        表示一个文件的生成是依附于另一个文件,语法为 【目标文件:被编译文件】 ,也就是表明目标文件依赖被编译文件。

依赖方法:

        代表依赖关系中的依赖文件该如何转化为目标文件,语法为 【tab 由依赖文件生成目标文件的手段】(这里必须使用tab作为前缀)。

        那么让我们看看Hello world对应的makefile的依赖关系和依赖方法该如何编写:

         这样设定好依赖关系和依赖方法之后我们就可以使用make创建出名为 HW 的可执行文件。语法为【make 指令】。其中 :

  • makefile中可能会有多个目标文件,但是makefile会以第一个目标作为终极目标。
  • 使用make时的默认动作就是第一个目标对应的规则,也就是只输入make就会默认生成第一个目标。
  • make扫描makefile的顺序是从上到下。

         除此之外,如果我们现在想要对编译过程中产生的临时文件进行清理或者清理旧版本的程序时,如果我们直接使用rm指令进行清除,这样的行为未免有些粗鲁和危险。于是makefile中也需要支持对文件的清理工作,也就是clean。同样按照依赖关系和依赖方法的形式进行编写:

         那么我们现在可以尝试使用makefile中的规则对文件进行清理:

                 上面就是make和makefile的一些简单运用,现在我们来看看makefile的工作原理:

  1. 目标的生成: a. 检查依赖关系中的依赖文件是否存在; b. 若依赖文件不存在,则寻找是否有某个规则用来生成该依赖文件。
  2. 目标的更新: a. 检查目标的所有依赖,任何一个依赖有更新时,就重新生成目标; b. 目标文件比依赖文件时间晚,则需要更新。

        在目标的更新中提到了文件时间的问题,这里简单的拓展一些关于文件时间的知识。我们都知道,文件=文件内容+文件时间。文件时间一般被分成三个时间,可以简单记为ACM三个时间:A(Access)、C(Change)、M(Modify)。Change代表最近改变文件内容的时间,Modify代表最近改变文件属性的时间,Access代表最近读文件的时间。

伪目标

        如果我们不想考虑文件时间,而想要无论什么情况都重新编译,这时就需要设置伪目标。伪目标表示这个目标总是被执行。一般来说产生可执行文件的逻辑是不会用伪目标修饰的,伪目标一般用于clean。

特殊符号

        makefile中有一些特殊符号,这里列举一些特殊符号。

        - :表示此命令即使执行出错,也依然继续执行后续命令。如:

        -rm a.o build/

        @:表示该命令只执行,不回显。一般规则执行时会在终端打印出正在执行的规则,而加上此符号后将只执行命令,不回显执行的规则。如:

        @gcc -o HW main.c

        $@和$^ 前者指的是依赖关系中的目标文件,后者指的是依赖关系中的依赖文件。如;

        HW:main.c

        gcc -o $@ $^

🍀结语

        以上就是make和makefile的基本入门知识啦,希望能对大家有所帮助。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于R语言Meta分析与【文献计量分析、贝叶斯、机器学习等】多技术融合方法与应用

Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…

XUbuntu22.04之解决蓝牙鼠标不停掉线问题(追凶过程)(一百八十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

Linux网络基础 — 网络层

目录 IP协议 IP协议报头格式 网段划分 特殊的IP地址 IP地址的数量限制 私有IP地址和公网IP地址 路由 补充 网络层 在复杂的环境中确定一个合适的路径。 IP协议 ip具有将数据从 主机A 跨网络送到 主机B 的能力。 主机: 配有IP地址,但是不进行路由控制的设备…

【Redis】Transaction(事务)

🎯前言 Redis事务是一个组有多个Redis命令的集合,这些命令可以作为一个原子操作来执行。 Redis事务通常用于以下两种情况: 保证操作的原子性:在多个命令的执行过程中,如果有一个命令执行失败,整个事务都需…

挖矿记录+解决方案:利用GitLab组件对服务器进行挖矿导致CPU占用200%

文章目录 什么是云服务器挖矿?事件记录事件分析产生影响解决方案后期预防什么是云服务器挖矿? 云服务器挖矿是指利用云服务器从事赚取比特币的活动。比特币是一种虚拟数字货币,挖矿是将一段时间内比特币系统中发生的交易进行确认,并记录在区块链上形成新区块的过程。 用于…

【字节流】写数据的三种方式以及两个问题

字节流写数据 1.字节流写数据三种方式 void write(int b):将指定的字节写入此文件输出流一次写一个字节数据 package com.bytestream; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamDemo02 {public static void ma…

融云「北极星」数据监控平台:数据可视通晓全局,精准分析定位问题

↑ 点击预约“融云北极星”直播↑ 点击预约“实时社区”直播 近期,融云“北极星”数据系统完成功能迭代,新模块“数据监控平台”正式“履新上任”。关注【融云全球互联网通信云】了解更多 点击图片查看更多详情 此前,“北极星”系统主要为客…

水声功率放大器的作用是什么

水声功率放大器是一种专门用于水声设备的高功率电子设备,主要用于提升水下信号的传输距离和保证语音清晰度。它的作用在水下通信、水下测量、海洋科学等领域都非常重要。 其主要作用有以下几个方面: 增强信号传输距离 水声信号在水中传播会受到各种因素的…

有哪些好用的远程传输大文件的软件

随着网络技术的日益进步和普及,大文件远程传输已经成为了人们生活和工作中必不可少的一部分。然而,在远程传输大文件的过程中,经常会遇到传输速度慢、容易受到干扰等问题,因此需要一款高效、稳定、安全的大文件远程传输软件来解决…

离线安装docker

目录 1、下载docker 安装包 2、上传docker 到服务器目录/opt/ 3、解压docker-19.03.9.tgz 4、解压的docker文件夹全部移动至/usr/bin目录 5、将docker注册为系统服务 6、重启生效 6.1、重新加载配置文件 6.2、启动Docker服务 6.3、查看启动状态 ​6.4、 设置docker为开…

伦敦金分析时切勿过分自信

伦敦金价格会呈趋势变动,这是投资者进行技术分析最根本、最核心的因素。根据物理学上的动力法则,趋势的运行会延续,直到有反转的现象产生为止。事实上,虽然伦敦金的价格不断上下波动,但终究是朝一定的方向前进的&#…

数组

数组: 数字组成的组,组里即可以,int类型,string,字符串,数组当中的数据类型,可以由用户自定义 同一种,也可以是不同的数据类型组成的元素集合 数组最大的作用,可以一次…

JVM系列(5)——类加载过程

一、类的生命周期 加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using&#xff09…

在ICC/ICC2/FC中运行Calibre

1. which calibre找到calibre的安装目录 > which calibre > /eda/mentor/ixl_cal_version/bin/calibre 2. 在 /eda/mentor/ixl_cal_version目录下使用find ./* -name "icc_calibre.tcl",找到icc_calibre.tcl 3. 打开icc_calibre.tcl里面有不同工具(ICC2/FC/…

uniapp 封装公共方法(无需每个页面引用,直接调用)

封装方法: 1. 在根目录下建立common文件夹 创建com.js 2.在main.js中挂载(写在定义vue之后) import $com from /common/com.js Vue.prototype.$com $com 3.在com.js中按照以下格式定义方法 export default {//定义需要的方法 } 4.使用 click"$com.已经定义的方法名&q…

Java 装箱拆箱原理 包装类型缓存池

JAVA中的基本数据类型 byteshortintlongfloatdoublebooleanchar 为了让上述基本数据类型可以转为对象,Java在1.5推出了一系列包装类,基本类和包装类互相转换的过程,称为装箱和拆箱 缓存池 缓存池也叫常量池。它是事先存储一些常量数据用以…

openvpnas安装,可视化远程连接控制

本次安装环境为 centos7.9 本次安装软件为 openvpnas, 默认是两个连接授权,可以通过代码注入实现多连接授权 1.基础环境以及Python36安装 yum install python36 python36-devel wget -y 2.安装 openvpnas 1.在线安装 yum -y install https://as-repository.openv…

LeetCode 790. 多米诺和托米诺平铺 - 二维空间的动态规划

多米诺和托米诺平铺 中等 304 相关企业 有两种形状的瓷砖:一种是 2 x 1 的多米诺形,另一种是形如 “L” 的托米诺形。两种形状都可以旋转。 给定整数 n ,返回可以平铺 2 x n 的面板的方法的数量。返回对 109 7 取模 的值。 平铺指的是每个…

ES6的类 vs TypeScript的类:解密两种语言中的面向对象之争

文章目录 ES6 类ES6 类的常见特性1. 构造函数2. 实例方法3. 静态方法4. 继承 TypeScript 类TypeScript 类的特性1. 类型注解2. 访问修饰符3. 类型推断4. 接口实现 ES6 类 ES6(ECMAScript 2015)引入了类的概念,为 JavaScript 增加了面向对象编…