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

【Linux系统编程】项目自动化构建工具make/Makefile

介绍:

        make和Makefile是用于编译和构建C/C++程序的工具和文件。Makefile是一个文本文件,其中包含了编译和构建程序所需的规则和指令。它告诉make工具如何根据源代码文件生成可执行文件,里面保存的是依赖关系依赖方法。make是一个命令行工具,用于根据Makefile文件中定义的依赖关系依赖方法来生成程序。

make/Makefile的使用:

        在使用此构建工具时,首先,我们要建立一个名称为 Makefilemakefile 文件,这里要注意 的是名称是固定的,不可更改。建立之后就要进入vim编辑步骤,输入依赖关系依赖方法来对指定程序进行指令控制。

        下面,我们使用最简单的gcc编译操作来对C语言源文件程序进行控制。

[zhu@zhujunhao ~]$ vim Makefile
[zhu@zhujunhao ~]$ cat Makefile
code.exe:code.c       #第一行叫做依赖关系,即对文件code.c进行操作
    gcc code.c -o code.exe   #第二行叫做依赖方法,该方法对code.c文件进行编译
[zhu@zhujunhao ~]$ make  #直接make,开始执行Makefile文件中指令
gcc code.c -o code.exe   #Makefile 的依赖方法操作
[zhu@zhujunhao ~]$ ll
total 24
-rw-rw-r-- 1 zhu zhu  181 Dec  7 09:15 code.c
-rwxrwxr-x 1 zhu zhu 8360 Dec  7 17:02 code.exe   #make形成可执行文件code.exe
-rw-rw-r-- 1 zhu zhu  827 Dec  5 14:52 install.sh
-rw-rw-r-- 1 zhu zhu   40 Dec  7 17:01 Makefile

      其中,依赖关系是所要针对的文件,上面依赖关系 code.exe:code.c 中的 mybin 叫做目标文件,make 操作的就是此文件,code.c 叫做依赖文件列表,两者之间用 “ : ” 分割。依赖方法是要对此文件进行指令操作,上面的依赖方法 gcc code.c -o code.exe 是对code.c文件进行编译处理。

        这里要注意的是,当我们使用make后,就不能再次使用make对其进行编辑。这时我们需在Makefile文件中对相关东西进行清理工作。如下:

[zhu@zhujunhao ~]$ vim Makefile
[zhu@zhujunhao ~]$ cat Makefile
clear:                           #定义clear的依赖关系
    rm -f code.exe        #clear对应的依赖方法
code.exe:code.c        #定义目标文件code.exe依赖关系
    gcc code.c -o code.exe       #code.exe的依赖方法
[zhu@zhujunhao ~]$ make     #默认执行第一个依赖关系所对应的依赖方法
rm -f code.exe
[zhu@zhujunhao ~]$ ll
total 12
-rw-rw-r-- 1 zhu zhu 181 Dec  7 09:15 code.c
-rw-rw-r-- 1 zhu zhu 827 Dec  5 14:52 install.sh
-rw-rw-r-- 1 zhu zhu  65 Dec  7 18:04 Makefile

[zhu@zhujunhao ~]$ make code.exe     #进行说明执行第二个依赖关系所对应的依赖方法
gcc code.c -o code.exe
[zhu@zhujunhao ~]$ ll
total 24
-rw-rw-r-- 1 zhu zhu  181 Dec  7 09:15 code.c
-rwxrwxr-x 1 zhu zhu 8360 Dec  7 18:05 code.exe
-rw-rw-r-- 1 zhu zhu  827 Dec  5 14:52 install.sh
-rw-rw-r-- 1 zhu zhu   65 Dec  7 18:04 Makefile

        这里需注意,Makefile 定义的依赖关系中的 “目标文件” 不一定非要是文件,主要作用在于依赖方法,比如上面的 clear 功能就是删除文件操作。这里的 “目标文件” 是一个抽象的概念。

        Makefile和make 形成目标文件的时候,默认是从上到下扫描Makefile文件的,若不加以说明,默认形成的是第一个目标文件。

        上面说到 make 只能编译一次。但是我们发现,当修改源文件时,可再次进行 make 编辑,这是因为make会根据文件所对应时间的修改而再次进行编辑。使用 stat [文件或目录] 可查看【文件或目录i】所对应的详细时间记录。

[zhu@zhujunhao ~]$ stat code.c         #查看code.c文件所对应的时间记录
  File: ‘code.c’
  Size: 181           Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 1052177     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/     zhu)   Gid: ( 1001/     zhu)
Access: 2023-12-07 09:15:21.064989027 +0800
Modify: 2023-12-07 09:15:21.060988852 +0800
Change: 2023-12-07 09:15:21.060988852 +0800
 Birth: -

        这里,所对应的时间为Access、Modify、Change三个记录。其中,Access是最近一次对文件进行访问(即读文件)的时间,Modify是最近一次对文件内容进行修改的时间,Change是最近一次对文件属性进行修改的时间。要注意的是Access所对应的文件访问的时间不是每次访问都会更新,在短时间内频繁的访问系统不会更新。这样保证了不会对系统带来太大的负担。

文件时间:

        make编辑文件时查看文件所对应的时间查看的是Modify所对应的时间,也就是说只要Modify所对应的时间被修改,make即可再次进行编辑。这里,我们可使用 touch [文件] 指令,当不存在【文件】时将会创建文件,当存在【文件】时将会全部更新文件所对应的时间。

Makefile/makefile语法使用:       

1,.PHONY的使用

        当我们不想改变文件所对应的时间时进行连续编译,这时需要在Makefile/makefile文件中进行.PHONY修饰伪目标。

[zhu@zhujunhao ~]$ vim Makefile
[zhu@zhujunhao ~]$ cat Makefile
.PHONY:code.exe    #修饰code.exe目标文件,成为一个伪目标,使其总是可以被执行
clean:                      #我们也可用.PHONY修饰clean目标,即.PHONY:clean,使其总是执行
    rm -f code.exe
code.exe:code.c  
    gcc code.c -o code.exe
[zhu@zhujunhao ~]$ make code.exe
gcc code.c -o code.exe
[zhu@zhujunhao ~]$ make code.exe
gcc code.c -o code.exe
[zhu@zhujunhao ~]$ make code.exe
gcc code.c -o code.exe

2,名称的替换

        在Makefile/makefile文件中可用 “ = ” 进行名称替换工作,使用别名时只需用 $(别名) 进行替换即可,如下:

#使用 = 进行名称的替换
   g=gcc
   o=-o
   c=code.c
   exe=code.exe

#使用别名替换,即:$(别名)
   .PHONY:$(exe)    #修饰code.exe目标文件,成为一个伪目标,使其总是可以被执行
   clean:
       rm -f $(exe)
   $(exe):$(c)  
       gcc $^ $(o) $@   # $@代表目标文件,$^代表依赖文件列表     

3,语法推导

        在Makefile/makefile中,若存在多个依赖关系,当make运行其中一个依赖关系的依赖方法时,系统会先判断依赖关系中对应的依赖文件列表,并且对应的依赖文件不存在时,将会自动往下继续寻找,直到找到指定的命令来生成这个目标文件,若找不到,系统将会报出异常;若找到了,系统将会往上不断返回执行对应的指令,以便生成这个目标文件。如下:

[zhu@zhujunhao ~]$ vim makefile
[zhu@zhujunhao ~]$ cat makefile
code.exe:code.o
    gcc $^ -o $@
code.o:code.s
    gcc -c $^ -o $@
code.s:code.i
    gcc -S $^ -o $@
code.i:code.c
    gcc -E $^ -o $@

以上的makefile的工作流程是这样的:

  1. 首先,当你运行 make code.exe时,make会检查 code.exe是否已经存在。如果存在,make就不会重新编译。如果不存在,make会找到它的依赖文件code.o,若依赖文件code.o 不存在,系统将往下查找,运行指定的命令来生成这个目标文件。这个过程会一直继续,直到所有的目标文件都被生成。
  2. 然后,对于每个目标文件,makefile都会检查是否所有的依赖文件都已经被更新。如果是,那么目标文件就会被重新编译。这个过程会一直继续,直到所有的目标文件都被更新。 如果命令失败了或全部指令运行完之后目标文件还没有被更新,make会停止并显示错误信息。

       总的来说,makefile定义了如何将C语言源代码code.c编译成可执行文件code.exe的过程。在编译过程中,它首先将C语言源代码预处理为中间文件code.i,然后将中间文件编译为汇编文件code.s,接着将汇编文件code.s编译成二进制文件code.o,最后将二进制文件链接为可执行文件code.exe。

[zhu@zhujunhao ~]$ make
gcc -E code.c -o code.i
gcc -S code.i -o code.s
gcc -c code.s -o code.o
gcc code.o -o code.exe

        可看出,Makefile/makefile的程序指令运行中,依赖关系如同栈结构中不断推导进栈,当查找到最终所以属的目标文件时,依赖关系中对应的依赖方法将会不断的出栈运行。这种形式就叫做makefile/Makefile的语法推到过程。

总:使用make和Makefile/makefile可以简化编译和构建程序的过程,只需要编写一个简单的Makefile/makefile文件,就可以自动化地编译和链接程序。同时,Makefile/makefile还可以在不同的平台上使用,使得程序的构建更加灵活和可移植。

相关文章:

【Linux系统编程】项目自动化构建工具make/Makefile

介绍: make和Makefile是用于编译和构建C/C程序的工具和文件。Makefile是一个文本文件,其中包含了编译和构建程序所需的规则和指令。它告诉make工具如何根据源代码文件生成可执行文件,里面保存的是依赖关系和依赖方法。make是一个命令行工具&a…...

harmony开发之Text组件的使用

TextInput、TextArea是输入框组件,通常用于响应用户的输入操作,比如评论区的输入、聊天框的输入、表格的输入等,也可以结合其它组件构建功能页面,例如登录注册页面。 图片来源黑马程序员 Text组件的使用: 文本显示组…...

using meta-SQL 使用元SQL 六

%Table Syntax %Table(recname) Description Use the %Table construct to return the SQL table name for the record specified with recname. 使用%Table构造返回使用recname指定的记录的SQL表名。 This construct can be used to specify temporary tables for runn…...

如何将浮点数点左边的数每三位添加一个逗号,如 12000000.11 转化为『12,000,000.11』

// 方法二 function format1(number) {return Intl.NumberFormat().format(number); } // 方法三 function format2(number) {return number.toLocaleString("en"); }...

朴素贝叶斯 贝叶斯方法

朴素贝叶斯 贝叶斯方法 背景知识 贝叶斯分类:贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。先验概率:根据以往经验和分析得到的概率。我们用 P ( Y ) P(Y) P(Y)来代表在没有训练数据前假设…...

探索鸿蒙 TextInput组件

TextInput 根据组件名字,可以得知他是一个文本输出框。 声明代码👇 TextInput({placeholder?:ResourceStr,text?:ResourceStr}); placeholder: 就是提示文本,跟网页开发中的placeholder一样的 text:输入框当前的文本内容 特殊属…...

CNN,DNN,RNN,GAN,RL+图像处理常规算法(未完待续)

好的,让我们先介绍一些常见的神经网络模型,然后再讨论图像处理的常规算法。 神经网络模型: 1. CNN(卷积神经网络) 原理: CNN主要用于处理图像数据。它包含卷积层、池化层和全连接层。卷积层通过卷积操作…...

C# 语法笔记

1.ref、out:参数传递的两种方式 ref:引用传递 using System; namespace CalculatorApplication {class NumberManipulator{public void swap(ref int x, ref int y){int temp;temp x; /* 保存 x 的值 */x y; /* 把 y 赋值给 x */y temp; /* 把 t…...

el-table 表格多选(后端接口搜索分页)实现已选中的记忆功能。实现表格数据和已选数据(前端分页)动态同步更新。

实现效果:(可拉代码下来看:vue-demo: vueDemo) 左侧表格为点击查询调用接口查询出来的数据,右侧表格为左侧表格所有选择的数据,由前端实现分页。 两个el-table勾选数据联动更新 实现逻辑: el-…...

Vue3自定义Hooks定义

在Vue3中,自定义Hooks的定义是通过创建一个函数来共享逻辑或状态,以便在多个组件之间重复使用。Vue3中的自定义Hooks与React中的自定义Hooks非常相似,但有一些细微的差别。 要定义一个自定义Hook,可以按照以下步骤进行操作&#x…...

为什么Java程序员需要掌握多线程?揭秘并发编程的奥秘

为什么Java程序员需要掌握多线程?揭秘并发编程的奥秘 个人简介前言多线程对于Java的意义📌1.提高程序性能:📌2 提高用户体验:📌3支持并发处理:📌4 资源共享和同步:&#…...

数组实现循环队列(新增一个空间)

目录 一、前言 1.如何实现循环? 2.如何判断队列为空? 3.如何判断队列为满? 二、循环队列的结构定义 三、循环队列的创建及其初始化 四、入队 五、出队 六、取队头元素 七、取队尾元素 八、判空 九、判满 十、销毁队列 一、前言 …...

Mysql 索引概念回顾

一、什么是索引 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据…...

基于SpringBoot+Vue学生成绩管理系统前后端分离(源码+数据库)

一、项目简介 本项目是一套基于SpringBootVue学生成绩管理系统,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目可以直接作为bishe使用。 项目都经过严格调试,确…...

Hadoop集群破坏试验可靠性验证

集群环境说明: 准备5台服务器,hadoop1、hadoop2、hadoop3、hadoop4、hadoop5; 分别部署5个节点的zookeeper集群、hadoop集群、hbase集群 本次对于Hadoop集群测试主要分为五个方面: 手动进行datanode节点删除:&#…...

Notepad++ 安装TextFx插件失败

据说TextFx插件是Notepad常用插件之一;有很多格式化代码的功能;下面安装一下; 插件管理里面看一下,没有这个TextFx; 根据资料,先安装NppExec; 然后下一个5.9老版本的Notepad,如下图…...

探究Logistic回归:用数学解释分类问题

文章目录 前言回归和分类Logistic回归线性回归Sigmoid函数把回归变成分类Logistic回归算法的数学推导Sigmoid函数与其他激活函数的比较 Logistic回归实例1. 数据预处理2. 模型定义3. 训练模型4. 结果可视化 结语 前言 当谈论当论及机器学习中的回归和分类问题时,很…...

杨辉三角

打印n行杨辉三角&#xff0c;n<10。 输入格式: 直接输入一个小于10的正整数n。 输出格式: 输出n行杨辉三角&#xff0c;每个数据输出占4列。 输入样例: 5输出样例: 11 11 2 11 3 3 11 4 6 4 1代码长度限制 16 KB 时间限制 400 ms 内存限制 6…...

MS5228/5248/5268:2.7V 到 5.5V、 12/14/16Bit、内置基准、八通道数模转换器

MS5228/MS5248/MS5268 是一款 12/14/16bit 八通道输出的电压型 DAC &#xff0c;内部集成上电复位电路、可选内部基准、接口采用四线串口模式&#xff0c; 最高工作频率可以到 40MHz &#xff0c;可以兼容 SPI 、 QSPI 、 DSP 接口和 Microwire 串口。输出接到一个 …...

2024年江苏省职业院校技能大赛 信息安全管理与评估 第二阶段教师组 (样卷)

2024年江苏省职业院校技能大赛 信息安全管理与评估 第二阶段教师组 (样卷) 项目竞赛样题 本文件为信息安全管理与评估项目竞赛-第二阶段样题&#xff0c;内容包括&#xff1a;网络安全事件响应、数字取证调查、应用程序安全。 本次比赛时间为180分钟。 介绍 GeekSec专注技能竞…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

FFmpeg avformat_open_input函数分析

函数内部的总体流程如下&#xff1a; avformat_open_input 精简后的代码如下&#xff1a; int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...

Shell 解释器​​ bash 和 dash 区别

bash 和 dash 都是 Unix/Linux 系统中的 ​​Shell 解释器​​&#xff0c;但它们在功能、语法和性能上有显著区别。以下是它们的详细对比&#xff1a; ​​1. 基本区别​​ ​​特性​​​​bash (Bourne-Again SHell)​​​​dash (Debian Almquist SHell)​​​​来源​​G…...

MCP和Function Calling

MCP MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09; &#xff0c;2024年11月底&#xff0c;由 Anthropic 推出的一种开放标准&#xff0c;旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...