『Linux项目自动化构建工具』make/Makefile
前言
如题可知,make/Makefile为在Linux下的项目自动化构建工具;
在上一篇文章『Linux - gcc / g++』c程序翻译过程 中讲解了C/C++程序的翻译过程;
而make/Makefile即可以看成,是Makefile在使用gcc/g++使在Linux环境下能够更好的高效率的进行项目构建;
在此之前首先要对make/Makefile进行说明:
- make
首先,make是一条命令,也可以说通过make命令可以解析Makefile文件; - Makefile
而Makefile是一个文件,是用来告诉make命令该如何编译工程,生成可执行程序;
当然,必须要现有Makefile文件才能使用make命令解析Makefile文件从而达到自动化构建项目的作用;
编写Makefile
假设存在一个.cpp文件,代码为:
#include<iostream>
//测试代码 用来测试make
int main()
{std::cout<<"it's a test file!"<<std::endl;
}
若是需要使该文件生成对应可执行文件即可使用命令:
g++ -o mytest test.cpp #将程序进行翻译直到链接结束生成可执行程序为止
而现在需要一个对应的Makefile文件来使其可以自动化构建项目;
先用命令touch来建立一个Makefile文件;
touch Makefile
建立完Makefile文件后使用vim进行编辑;
mytest:test.cpp g++ -o mytest test.cpp .PHONY:clean
clean: rm -rf mytest
拥有该Makefile文件后即可使用make命令对Makefile文件进行解析从而达到构建项目的的效果;

当然对应的也可以进行项目的清理;
由于Makefile文件中拥有一个用来清理项目的伪目标clean,在调用时使用命令:
make clean
即可对项目进行清理,当然会根据我们在Makefile文件中所指定的规则进行清理;

既然如此那么在Makefile文件中的每一行分别是什么?
由上到下每一行依次分别为:
- 第1行 - 依赖关系
mytest:test.cpp
#以冒号:作为分界,冒号的左侧为目标文件,冒号的右侧为依赖文件列表;
目标文件即为目标生成的文件,依赖文件列表即为所生成的文件依赖的文件,在这里可以表示为,这里的可执行文件mytest是由test.cpp翻译生成的,所以依赖于test.cpp文件;
同时在Makefiel的语法中,目标文件必须在顶格,且必须跟冒号:
- 第2行 - 依赖方法
g++ -o mytest test.cpp #依赖方法 该行必须紧挨着第一行,不能空行,且该行必须以table键开头
#可以理解为,生成mytest可执行程序时需要依靠命令g++ -o mytest test.cpp
同时在语法中,依赖方法所在行前必须有其他依赖方法或者是紧跟依赖关系行;
- 第4行 - .PHONY伪目标修饰
.PHONY:clean
该关键字.PHONY的作用即为修饰 : 后的目标文件为伪目标;
- 第5,6行
与第1,2行相同,不同的是在这里的依赖关系中,目标文件clean不需要依赖文件;
此处是用作清除,而在大多数的开源中所使用的清除都是用的clean;
也可以使用其他名;
clean: #该行与第一行相同,冒号左边为目标文件,右侧为依赖文件列表,不同的是该目标文件不需要依赖文件rm -rf mytest #依赖方法#该处的四五六行是用来清理的#有了四五六行即可以在Makefile文件所对应的文件夹中使用 make clean 进行对应文件的清理;
在执行make命令时 , 默认使用Makefile文件中的第一对依赖关系与依赖方法;(自顶向下扫描会形成第一个遇到的目标文件)
此处若是将 形成对应文件的依赖关系依赖方法 与 清理对应文件的依赖关系依赖方法 调换再执行make命令时;
首先将会执行 清理对应文件的依赖关系与方法 ;
.PHONY:所修饰的伪目标
在很多教材之中,对于伪目标的描述是这样的:“伪目标是总是被执行的”;
但是这里的总是被执行是什么意思?

若是多次进行make,则只有第一次会被执行;
而后面的几次将不会被执行;
而若是执行make clean时则不同;

每一次的make clean都会被执行;
这个原因就是因为clean被修饰成为了伪目标;
这里的 “ 伪目标总是被执行的 ” 这句话的意思即为,伪目标总是会根据依赖关系,执行此依赖方法;
在一般的习惯中,都会将clean设置为伪目标;
若是希望其他的目标文件同样可以总是被执行,可以将其修饰为伪目标;
编译器和Makefile是如何得知可执行程序是最新的

在我们make了一次之后,在没有修改源文件之前再次make时都会显示一个类似于 “当前的可执行程序为最新” 的提示;
但若是在该处修改了源文件,并再次进行make指令时又会重新生成相应的可执行程序;
既然如此,那么编译器或者Makefile是如何知道当前可执行程序是最新的呢?
在Linux中有一条为 stat 的命令,该命令可以查看一个文件中最重要的三个时间;
stat mytest

这三个时间分别为:
| 时间 | 内容 |
|---|---|
| (Access)访问时间 | 访问文件的修改已经在Linux内核中进行了改动,在原先的Linux版本中,对于文件的访问(cat,ls等操作)都是会进行修改的,而这种,由于对文件的访问是一个高频操作;而文件是存在磁盘当中,若是每次访问文件都对Access进行改动的话,说明这个高频操作将会大量的去对磁盘进行访问,而高频的磁盘访问定会降低访问程序的效率;故在Linux的内核中修改为,当对文件进行一段时间的访问(累计)过后才会修改该属性; |
| (Modify)修改(内容)时间 | 文件内容的修改时间; |
| (Change)修改(属性)时间 | 文件属性的修改时间 |
回归正题,为什么编译器和Makefile能够知道当前的可执行程序是最新的;
真正来说,在使用make指令来对Makefile进行操作时,若是当前已经拥有一个可执行程序;
则会将各个源文件与当前的可执行程序进行Modify时间的比较,若是当前可执行文件的修改时间晚于各个源文件,则代表当前可执行程序为最新;

多文件使用Makefile
假设当前有三个文件(不包括Makefile文件),分别为两个源文件(test.cpp main.cpp)与一个头文件(test.hpp);
若是用指令编译则为:
g++ main.cpp test.cpp -o test
在Makefile文件中也可以使用该指令;
mytest:test.cpp main.cppg++ main.cpp test.cpp -o mytest.PHONY:clean #修饰为伪目标
clean:rm -f mytest
但是一般多文件进行Makefile操作时习惯使用.o进行连接;

mytest:test.o main.o #所生成的文件依赖test.o与main.o文件g++ test.o main.o -o mytest #需要生成mytest文件需要对两个.o文件进行链接(头文件被#include展开后可以不用再管)main.o:main.cpp #make首先会看到上面第一对依赖关系与依赖方法,但是上面的依赖文件列表并没有.o文件 将会继续往下找第二对依赖关系与方法g++ -c main.cpp -o main.o
test.o:test.cpp #以此类推g++ -c test.cpp -o test.o.PHONY:clean
clean:rm -f *.o mytest #此处删除所有的.o文件同时删除mytest文件
相关文章:
『Linux项目自动化构建工具』make/Makefile
前言 如题可知,make/Makefile为在Linux下的项目自动化构建工具; 在上一篇文章『Linux - gcc / g』c程序翻译过程 中讲解了C/C程序的翻译过程; 而make/Makefile即可以看成,是Makefile在使用gcc/g使在Linux环境下能够更好的高效率的进行项目构建; 在此之前首先要对make/Makefile…...
github提示Permission denied (publickey),如何才能解决
当GitHub提示“Permission denied (publickey)”错误,这通常意味着您的SSH密钥没有被正确地配置。以下是一些常见的解决步骤,帮助您诊断和解决该问题: 检查是否已设置SSH密钥: 运行以下命令检查是否存在SSH密钥: bash…...
金x软件有限公司安全测试岗位面试
目录 一、自我介绍 二、你是网络空间安全专业的,那你介绍下网络空间安全这块主要学习的东西? 三、本科专业是网络工程,在嘉兴海视嘉安智城科技有限公司实习过,你能说下干的工作吗?(没想到问的是本科实习…...
c语言之strlen函数使用和实现
文章目录 前言一、strlen函数使用二、实现方法 前言 c语言之strlen函数使用和实现 一、strlen函数使用 strlen函数返回的是在字符串中的个数,但不包含字符串结束符’\0’ #include<stdio.h> #include<string.h> int main() {char str1[] "abcd…...
网络初识(JAVA EE)
文章目录 一、网络发展史二、网络通信基础三、协议分层四、封装和分用 一、网络发展史 独立模式:计算机之间相互独立,每个终端都各自持有客户数据,且当处理一个业务时,按照业务流程进行 网络互连:将多台计算机连接在一…...
kantts docker化
kan-tts docker本地化 环境安装 下载docker镜像(python3.8的) registry.cn-hangzhou.aliyuncs.com/modelscope-repo/modelscope:ubuntu20.04-cuda11.8.0-py38-torch2.0.1-tf2.13.0-1.9.2 安装基础模型 pip install modelscope 安装语音模型 pip install "modelscope…...
Axure RP医疗在线挂号问诊原型图医院APP原形模板
医疗在线挂号问诊Axure RP原型图医院APP原形模板,是一款原创的医疗类APP,设计尺寸采用iPhone13(375*812px),原型图上加入了仿真手机壳,使得预览效果更加逼真。 本套原型图主要功能有医疗常识科普、医院挂号…...
Vuex的基础使用存值及异步
目录 一、概述 ( 1 ) 讲述 ( 2 ) 概念 ( 3 ) 作用 二、取值 1. 安装 2. 菜单栏 3. 模块 4. 引用 三、改值 四、异步&后台请求 带来的获取 一、概述 ( 1 ) 讲述 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的…...
git 重置到某次提交
情形1: 回滚到之前的某版本,且删除该版本之后的提交 1)用 git log 查看版本号(commit后的就是版本号) 2)用 git reset --hard <版本号> 命令回滚到之前某版本. 此时本地已经回滚,远程仓库还未回滚 3&…...
Delphi 生成包含图片的 HTML 文件并使用 Edge 浏览器打开
在 Delphi 中,可以使用以下代码生成包含图片的 HTML 文件,并使用 Edge 浏览器打开该文件。 procedure GenerateHTMLWithImageAndOpenWithEdge; varOpenDialog: TOpenDialog;HTMLFileName: string;HTMLContent: TStringList; beginOpenDialog : TOpenDi…...
凉鞋的 Godot 笔记 108. 第二个通识:增删改查
在这一篇,我们来学习此教程的第二个通识,即:增删改查。 增删改查我们不只是一次接触到了。 在最先接触的场景窗口中,我们是对 Node 进行增删改查。 在文件系统窗口中,我们是对文件&文件夹进行增删改查࿱…...
AI Web3 盛会「EDGE」在港闭幕,融云国际影响力持续提升
👆点击报名「爱嗨游」线上发布会 9 月 25 日至 27 日,全球规模最大的 AI & Web3 投资盛会——EDGE 峰会在中国香港举办,融云作为战略合作伙伴与来自世界各地的企业家、投资人、学者和热门项目方一同完成了这一盛会。关注【融云全球互联网…...
启动Spring Boot项目
介绍启动运行Spring Boot项目打包的jar 1、使用java -jar命令启动项目 java -jar project.jar 执行效果: 使用java -jar 文件名.jar启动项目,项目在前台运行,项目运行的日志将打印在当前控制台上,若退出当前控制台,…...
竞赛选题 深度学习 机器视觉 车位识别车道线检测 - python opencv
0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) …...
axios调用springboot项目接口获取数据简述版
简述版 前端 <div idZjw> <table> <tr v-for"item in all"><td>{{item.cno}}</td><td>{{item.name}}</td><td>{{item.age}}</td><td><img :src"item.picUrl" style"height: 130px;…...
MPP 架构在 OLAP 数据库的运用
MPP 架构: MPP 架构的产品: Impala ClickHouse Druid Doris 很多 OLAP 引擎都采用了 MPP 架构 批处理系统 - 使用场景分钟级、小时级以上的任务,目前很多大型互联网公司都大规模运行这样的系统,稳定可靠,低成本。…...
什么影响香港服务器的速度原因
1、服务器缓存:清理缓存即可,不同服务器方法不一,根据自身服务器系统可百度。 2、运行内存被占满:运行内存被占满就好像我们手机的运行内存一样,一旦同时运行较多的程序或软件,那么运行内存就会 出现这种情…...
HTML复习笔记
HTML(超文本标记语言) 文章目录 HTML(超文本标记语言)1.HTML1.概念2.标签2.1双标签超链接音频标签视频标签无序列表有序列表定义列表表格合并单元格 表单表单项单选框-**radio**文件上传-file多选框-checkbox 下拉菜单文本域-text…...
「五度情报站」网罗全量企业情报,找客户、查竞品、寻商机!
在当下严峻的市场经济环境下,准确、及时的情报信息,就如同指引企业前行的明灯,能够让企业在风起云涌的市场大潮中保持敏锐的洞察力,掌握最新的市场动态,洞悉竞争对手的一举一动,先知先动,保持竞…...
Ubuntu 22.04‘Temporary failure resolving‘ 解决方案
终极解决方案 首先安装resolvconf sudo apt-get install resolvconf 使用 cd /etc/resolvconf/resolv.conf.d/ 进入文件夹,使用 ls 查看目录,会显示 base head tail 使用 sudo vim base 编辑base文件, 进入时为空,点击 i 添加 …...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
