当前位置: 首页 > news >正文

[Linux入门]---Linux项目自动化构建工具-make/Makefile

目录

  • 1.背景
  • 2.make指令
    • 输入make默认为Makefile文件第一条指令执行
    • Makefile文件对gcc指令特殊处理及原理
    • 特殊符号
  • 3.总结

1.背景

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:DelphimakeVisual C++nmakeLinuxGNUmake。可见,makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2.make指令

我们使用vim编辑器创建了test.c文本文件编译了如下代码:

#include <stdio.h>
int main()
{
printf("hello Makefile\n");
return 0;
}

输入指令:

gcc -o mytest test.c//编译允许代码

Xshell演示结果如下:
在这里插入图片描述

这个编译运行可执行程序过程还算简单,那如果需要代码代码预处理、编译、汇编、链接生成可执行程序等等过程的时候,那么就需要输入如下指令:

gcc -E test.c -o test.i #预处理
gcc -S test.i -o test.s #编译
gcc -c test.s -o test.o #汇编
gcc test.o -o test #生成可执行程序
./test #找到对应路径下可执行程序运行

使用完之后,或者发生错误,需要删除文件

rm -rf test.i test.s test.o test

Xshell演示结果如下:
在这里插入图片描述

上面的指令输入一次还算简单,假设你的代码需要多次修改,就需要重复输入预处理、编译、汇编、链接、删除指令,会很麻烦!这时候我们就需要使用到Makefile文件/makefile文件(首字母m大小写都可以)。

使用vim编辑器创建Makefile文件,向里面编入如下指令

test:test.ogcc test.o -o test 
test.o:test.sgcc -c test.s -o test.o
test.s:test.igcc -S test.i -o test.s
test.i:test.cgcc -E test.c -o test.i
clean:rm -rf test test.o tes.s test.i

Xshell演示结果如下:
在这里插入图片描述
在这里插入图片描述

  • test:test.o为依赖关系,即test文件生成需要依赖于test.c文件该指令写在行首;gcc test.o -o test 为依赖方法,通过gcc指令处理test.o文件得到test文件,该指令前有一个tab键的空格;所以必须要有test.o文件,而test.o文件的生成依赖于test.s文件,test.s文件依赖于test.i文件,test.i文件依赖于test.c文件,依赖关系后面伴随着依赖(实现)方法,由此可以看出test文件需要依靠层层依赖关系以及依赖方法才能得到;(像递归一样)
  • ②而clean指令后面为空格,无依赖关系表明clean不依赖于任何文件、指令,同时有自己的依赖(实现)方法。

输入make默认为Makefile文件第一条指令执行

指令实现顺序如下:
在这里插入图片描述
只输入make指令:
在这里插入图片描述
指令实现顺序如下:
在这里插入图片描述
只输入make指令:
在这里插入图片描述

①只输入make指令,只会执行Makefile文件实现的第一条指令(从上到下),一般我们程序执行指令放在作为Makefile文件的第一条指令;其他指令通过make+Makefile指令/文件名实现!
②Makefile文件的各文件依赖关系指令可以在任意位置(不一定是从上到下),系统会在Makefile文件中找到得到目标文件需要实现的依赖方法,所以对应的依赖关系缺失会导致指令运行不起来!总而言之就是make会自动推导Makefile中的依赖关系(栈式结构)

Makefile文件对gcc指令特殊处理及原理

为什么进行编译拦截?
在这里插入图片描述

我们使用make指令对test文件进行多次编译运行,发现只有第一次make指令被执行了,再次输入make指令却不被执行!这是为什么呢?就像机器提示那样:test文件没有更新,所以不需要进行多次编译!为什么机器会对我们的多次编译的指令进行拦截呢?多次编译消耗时间,会使Linux机器的工作效率大大降低,我们现在之所以没有感受出来,是因为写的代码太少了,当程序代码量很大的时候,编译一次编译需要消耗几十分钟、几个小时甚至更久,我相信对同样的代码编译多次的行为,作为程序员的你是第一个不答应的!😾😾😾

怎么做到对相同源文件只做一次编译呢?
一般情况下是由源文件生成可执行文件(即先有源文件,才有可执行文件),所以源文件最近修改时间比可执行文件早(老)。如果我们更改了源文件,此时源文件的修改时间比旧的可执行文件晚,所以此时我们使用make指令就可以将修改后的源代码重新编译生成新的可执行文件。该过程是怎么样的呢?接下来让我们认识一条指令!
stat指令

语法:stat 选项 文件名
功能: 显示文件\文件系统的详细信息,包括文件的访问时间,文件内容修改时间,文件属性的修改时间。
在这里插入图片描述
Access:文件的访问时间,查看、修改文件内容都可以算访问,Access显示的时间更新;Modify:文件内容修改时间,只有对文件内容进行增删等修改文件内容操作,Modify时间更新;Change:文件属性的修改时间,文件大小、文件拥有者、文件所属组等文件属性修改,Change显示时间会被更新。②文件内容修改一次,Modify显示的时间会被更新;文件属性内容修改一次,Change显示的时间会被更新;因为平时我们访问文件的次数比较频繁,所以访问文件达到一定次数Access显示的时间才会被更新。③修改源文件内容而引起的时间变化,源文件是否被编译比较源文件和可执行文件的是Modify显示的时间。
在这里插入图片描述
在这里插入图片描述

使用touch指令更新时间

指令1: touch -a 文件名(使用该指令更新文件的Access显示的时间、Change显示的时间)
指令2: touch -m 文件名(使用该指令更新文件的Modify显示时间)
先使用touch -m 文件名更新源文件的Modify显示时间,然后使用make指令重新编译源文件!
在这里插入图片描述

特殊符号

在这里插入图片描述
使用特殊符号:
在这里插入图片描述
使用之后:
在这里插入图片描述

$@表示冒号左边的文件名,$^表示冒号右边的文件名,在Makefile文件可以使用@放在语句前进行注释!

使用.PHONY将目标文件成为伪目标
在这里插入图片描述
在这里插入图片描述

使用.PHONY可以将test指令(文件)变成伪目标,使该指令(文件)总是被执行!一般情况,我们将clean指令(文件)设置为伪目标!
在这里插入图片描述

3.总结

1make会在当前目录下找名字叫“Makefile”“makefile”的文件。
2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test”这个文件,并把这个文件作为最终的目标文件。
3. 如果test文件不存在,或是test所依赖的后面的test.o文件的文件修改时间要比test这个文件新,就会执行后面所定义的命令来生成test这个文件。
4. 如果test所依赖的test.o文件不存在,那么make会在当前文件中找目标为test.o文件的依赖性,如果找到则再根据那一个规则生成test.o文件。(这有点像一个堆栈的过程)
5. test.o的依赖方法存在,make会生成test.o文件,然后再用 test.o 文件声明make的终极任务,也就是执行test文件了。
6. make的依赖性:make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make不执行。
8. make只管文件的依赖性,即,如果在make找到依赖关系之后,冒号后面的文件还是不在,make不执行
9.工程是需要被清理的,像clean这种指令没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
10.一般我们将clean的目标文件设置为伪目标,用 .PHONY 修饰伪目标的特性是,总是被执行的。
11.make指令会判定文件的新旧,判定是否需要重新进行执行依赖关系,进行编译!

相关文章:

[Linux入门]---Linux项目自动化构建工具-make/Makefile

目录 1.背景2.make指令输入make默认为Makefile文件第一条指令执行Makefile文件对gcc指令特殊处理及原理特殊符号 3.总结 1.背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放…...

[Python进阶] 程序打包之Pyinstaller参数介绍

5.4 Pyinstaller参数介绍 5.4.1 选项参数 参数名 说明 -h、–help 查看Pyinstaller所有命令的用法和帮助 -v、–version 查看当前Pyinstaller版本 –distpath DIR 设置dist位置&#xff0c;默认当前目录 –workpath WORKPATH 设置build位置&#xff0c;默认当前目录 -y、–no…...

Python中如何判断列表中的元素,是否在一段文本中??

#我的Python教程 #官方微信公众号&#xff1a;wdPython1.要判断列表中的每个元素是否在一段文本中&#xff0c;可以使用Python中的字符串的 in 运算符来实现。以下是一个示例代码&#xff1a; text "Hello, how are you today?" word_list ["Hello", &…...

spark Structured报错解决

报错&#xff0c;不想看原因的直接去解决方案试试 Exception in thread "main" java.lang.IllegalArgumentException: Pathname /C:/Users/Administrator/AppData/Local/Temp/1/temporary-611514af-8dc5-4b20-9237-e5f2d21fdf88/metadata from hdfs://master:8020/C…...

Matter 协议系列:发现

Commissionable 发现 Commissionable 发现发生在投入使用&#xff08;未绑定&#xff09;之前&#xff0c;指的是发现和识别Commissionable 节点的过程。有三种方法可以通过这些方法中的任何一种来 广播Commissionable 的节点&#xff1a; 蓝牙低功耗&#xff08;BLE&#xff…...

Oracle 12c Docker镜像配置SSL

一、Docker运行Oracle 12c服务 a.拉取镜像 docker pull truevoly/oracle-12cb.运行 docker run -d -p 1521:1521 -p 2484:2484 -v /data/oracle/:/opt/oracle --name oracle_12c truevoly/oracle-12cc.查看日志 docker logs -f oracle_12cd.出现如下信息&#xff0c;则启动…...

版本控制系统git:一文了解git,以及它在生活中的应用,网站维护git代码,图导,自动化部署代码

目录 1.Git是什么 2.git在生活中的应用 2.1git自动化部署代码 3.网站维护git代码 3.1如何在Git代码托管平台等上创建一个仓库 3.2相关文章 4.ruby实现基础git 4.1.Git add 4.2 Git commit 4.3 Git log 1.Git是什么 Git是一个版本控制系统&#xff0c;它可以追踪文件的…...

uqrcode+uni-app 微信小程序生成二维码

使用微信小程序需要弹出动态二维码的需求&#xff0c;从插件市场选了一个下载次数较多的组件引入到项目中uqrcode&#xff0c;使用步骤如下&#xff1a; 1、从插件市场下载 插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id1287&#xff0c;若你是跟我一样是用uni-…...

从零开始的 MyBatis 拦截器之旅:实战经验分享

文章目录 MyBatis拦截器可以做什么&#xff1f;Mybatis核心对象介绍四大核心对象如何实现&#xff1f;接口讲解Interceptor接口intercept方法plugin方法setProperties 完整SQL打印拦截器实战拦截器实现拦截器注册 MyBatis拦截器可以做什么&#xff1f; MyBatis拦截器是MyBatis…...

网络编程day05(IO多路复用)

今日任务&#xff1a; TCP多路复用的客户端、服务端&#xff1a; 服务端代码&#xff1a; #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> …...

人声分离网站,帮你快速提取视频中的人声和背景音乐

今天给大家带来一个可以分离人声的网站——音分轨&#xff0c;他运用人工智能算法可以将音频中的人声部分和音乐部分分离&#xff0c;使我们的视频制作过程可以更方便。 我们点击右下角“选择文件”上传一个音频&#xff0c;上传好音频后&#xff0c;人工智能就开始处理我们上传…...

计算机网络常见问题

1.谈一谈对OSI七层模型和TCP/IP四层模型的理解&#xff1f; 1.1.为什么要分层&#xff1f; 在计算机中网络是个复杂的系统&#xff0c;不同的网络与网络之间由于协议&#xff0c;设备&#xff0c;软件等各种原因在协调和通讯时容易产生各种各样的问题。例如&#xff1a;各物流…...

上PICO,沉浸式观看亚运直播,参与跨国界游戏竞技

备受瞩目的杭州第19届亚运会&#xff0c;将于9月23日正式开幕。据悉&#xff0c;这也是有史以来项目最多的一届亚运会&#xff0c;除部分传统奥运项目外&#xff0c;还包含武术、藤球、板球、克柔术、柔术等亚洲特色项目&#xff0c;以及霹雳舞、电子竞技等深受年轻人喜爱的新兴…...

无重复字符的最长子串 - 力扣(LeetCode)

3. 无重复字符的最长子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长…...

企业行政许可的种类有哪些?

从行政许可的性质、功能和适用条件的角度来说&#xff0c;大体可以划分为五类&#xff1a;普通许可、特许、认可、核准、登记。 1.普通许可 普通许可是一种允许符合特定条件的相对方行使某种权利的行为。在许多情况下&#xff0c;需要普通许可的活动都与国家安全、公共安全息…...

Flink--4、DateStream API(执行环境、源算子、基本转换算子)

星光下的赶路人star的个人主页 注意力的集中&#xff0c;意象的孤立绝缘&#xff0c;便是美感的态度的最大特点 文章目录 1、DataStream API1.1 执行环境&#xff08;Execution Environment&#xff09;1.1.1 创建执行环境 1.2 执行模式&#xff08;Execution Mode&#xff09;…...

#循循渐进学51单片机#指针基础与1602液晶的初步认识#not.11

1、把本节课的指针相关内容&#xff0c;反复学习3到5遍&#xff0c;彻底弄懂指针是怎么回事&#xff0c;即使是死记硬背也要记住&#xff0c;等到后边用的时候可以实现顿悟。学会指针&#xff0c;就是突破了C语言的一道壁垒。 2&#xff0c;1602所有的指令功能都应用一遍&#…...

Lua学习笔记:探究package

前言 本篇在讲什么 理解Lua的package 本篇需要什么 对Lua语法有简单认知 对C语法有简单认知 依赖Visual Studio工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级…...

【面试经典150 | 双指针】三数之和

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;暴力枚举方法二&#xff1a;双指针 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对…...

现代卷积网络实战系列3:PyTorch从零构建AlexNet训练MNIST数据集

1、AlexNet AlexNet提出了一下5点改进&#xff1a; 使用了Dropout&#xff0c;防止过拟合使用Relu作为激活函数&#xff0c;极大提高了特征提取效果使用MaxPooling池化进行特征降维&#xff0c;极大提高了特征提取效果首次使用GPU进行训练使用了LRN局部响应归一化&#xff08…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Unity VR/MR开发-VR开发与传统3D开发的差异

视频讲解链接&#xff1a;【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...