【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还可以在不同的平台上使用,使得程序的构建更加灵活和可移植。

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

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

相关文章

智汇恒星科技|控乐屋.全宅智能冠军代言来啦, 智慧家居千亿蓝海

随着5G、大数据、云计算、物联网等技术的发展,智能化正覆盖人们生活的方方面面,全屋智能的出现为“一键式”智能家居生活享受提供无限可能。近年来智能家居行业总体规模增长迅速,数据显示,2022年中国智能家居行业市场规模约为6200…

Java期末复习题之封装

点击返回标题->23年Java期末复习-CSDN博客 第1题. 定义一个类Person,定义name和age私有属性,定义有参的构造方法对name和age进行初始化。在测试类中创建该类的2个对象,姓名、年龄分别为lili、19和lucy、20,在屏幕打印出2个对象的姓名和年龄…

2024年江苏省职业院校技能大赛信息安全管理与评估 理论题(样卷)

2024年江苏省职业院校技能大赛信息安全管理与评估 理论题(样卷) 理论技能与职业素养(100分) 2024年江苏省职业院校技能大赛(高职学生组) 模块三“信息安全管理与评估”理论技能 【注意事项】 Geek极安云…

软考高级信息系统项目管理师经验分享

考了三次终于考过了。 第一次,没准备,打酱油。 第二次,不舍得花钱,自己复习,结果教材改版了都不知道。 第三次,改机考了。 总结一下这三次的经验: 一、不是学霸型的一定要报班 报班的优点&…

实时动作识别学习笔记

目录 yowo v2 yowof 判断是在干什么,不能获取细节信息 yowo v2 https://github.com/yjh0410/YOWOv2/blob/master/README_CN.md ModelClipmAPFPSweightYOWOv2-Nano1612.640ckptYOWOv2-Tiny

QML中Dialog获取close与open状态

1.新建MyDialog.qml import QtQuick 2.15import QtQuick.Dialogs 1.2Dialog {id: rootvisible: falsetitle: qsTr("弹出对话框")width: 250height: 200} 2.main.qml中调用MyDialog import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15…

JS原生实现浏览器滚动条滚动侧边栏高亮响应

目录 演示 ​编辑 需求 代码 css html script 代码解释 1、获取所有link-content 2、定义一个rectContent数组,然后循环allContents调用getClientRects()[0]获取每个link-content元素与浏览器视口的关系 3、为数组追加link-content,用于设置侧…

软件设计师——面向对象技术(一)

📑前言 本文主要是【面向对象技术】——软件设计师—面向对象技术的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 &#…

官网IDM下载和安装的详细步骤

目录 一、IDM是什么 二、下载安装 三、解决下载超时的问题 四、谷歌浏览器打开IDM插件 谷歌浏览器下载官网👇 五、测试 六、资源包获取 一、IDM是什么 IDM(internet download manager)是一个互联网下载工具插件,常见于用…

资深IT经理分享如何选择商用远控软件三:评估产品方案匹配度

作为企业必要的IT管理和远程办公工具,远程控制解决方案的挑选和采购是需要IT部门慎重考虑的。 对于具体如何在诸多产品中选择合适的商用远程控制解决方案,此前我们就分享了一位资深IT经理的相关经验,目前已经涵盖初期的业务需求调研&#xf…

【ESP32 IDF】ESP32移植u8g2库,实现oled界面显示

ESP32移植u8g2库,实现oled界面显示 1. 简单描述2. 环境准备1. 硬件准备2. 软件准备 3. IIC屏幕 【基于 ssd1362 256*64 】4. SPI屏幕 【基于 ssd1306 128*32】 1. 简单描述 开发方式为 IDF5.0参考连接为 iic基于esp-idf移植使用u8g2 spi基于esp-idf移植使用u8g2 …

探索创意无限的Photoshop CC 2020Mac/Win版

作为一款功能强大的图像处理软件,Photoshop CC 2020(简称PS 2020)在全球范围内备受设计师、摄影师和艺术家的喜爱和推崇。它不仅为用户提供了丰富多样的工具和功能,还不断推出新的创意特效和改进的功能,让用户的创意无…

C# Solidworks二次开发:选择管理器相关的API介绍

今天在讲述主要内容之前,先说一个不太相关的问题。 我之前在其他文章中看到有一些朋友在问为什么获取到的点位数据需要乘以1000进行单位转换,其实原因是这样的,在所有使用的API中如果没有特殊说明,所有的长度单位都是米&#xff…

苹果Vision Pro即将量产

据界面新闻消息,苹果公司将在今年12月正式量产第一代MR(混合现实)产品Vision Pro。苹果公司对Vision Pro寄予了厚望,预计首批备货40万台左右,2024年的销量目标是100万台,第三年达到1000万台。 苹果的供应…

springboot + thymeleaf + layui 初尝试

一、背景 公司运营的同事有个任务,提供一个数据文件给我,然后从数据库中找出对应的加密串再导出来给他。这个活不算是很难,但时不时就会有需求。 同事给我的文件有时是给excel表格,每一行有4列,逗号隔开,…

编译和使用WPS-ghrsst-to-intermediate生成SST

一、下载 V1.0 https://github.com/bbrashers/WPS-ghrsst-to-intermediate/tree/masterV1.5(使用过程报错,原因不详,能正常使用的麻烦告知一下方法) https://github.com/dmitryale/WPS-ghrsst-to-intermediate二、修改makefile…

【CVE 复现】CVE-2022-0185 fsconfig之整数溢出

影响版本:Linux-v5.1~v5.16.2 测试版本:Linux-5.11.22,由于懒得搞环境,所以直接用的 bsauce 大佬提供的 测试环境 看看 patch: diff --git a/fs/fs_context.c b/fs/fs_context.c index b7e43a780a625b..24ce12f0db32…

ResNeXt(2017)

文章目录 Abstract1. Introductionformer workour work 2. Related Work多分支卷积网络分组卷积压缩卷积网络Ensembling 3. Method3.1. Template3.2. Revisiting Simple Neurons3.3. Aggregated Transformations3.4. Model Capacity 4. Experiment 原文地址 源代码 Abstract 我…

14.Java程序设计-基于Springboot的高校社团管理系统设计与实现

摘要 随着高校社团活动的不断丰富和社团数量的逐渐增加,高校社团管理面临着日益复杂的挑战。为了提高社团管理的效率和透明度,本研究基于Spring Boot框架设计并实现了一套高校社团管理系统。该系统旨在整合社团创建、成员管理、活动发布等多个功能&…

[FPGA 学习记录] 数码管动态显示

数码管动态显示 文章目录 1 理论学习1.1 数码管动态扫描显示原理 2 实战演练2.1 实验目标2.2 程序设计2.2.1 框图绘制2.2.2 数据生成模块 data_gen2.2.2.1 波形绘制2.2.2.2 代码编写2.2.2.3 代码编译2.2.2.4 逻辑仿真2.2.2.4.1 仿真代码编写2.2.2.4.2 仿真代码编译2.2.2.4.3 波…