Linux下的Makefile基本操作

news2024/11/28 21:51:32

1.Makefile与 make介绍

在Linux中, Makefile 是⼀个⽂件, 令会在当前⽬录下找 make 是⼀个指令,当使⽤ Makefile ⽂件从⽽执⾏内部的内容

2.创建第一个 Makefile并使用make

⾸先,在当前⽬录下创建⼀个makefile文件

接下来在同级⽬录下创建⼀个 code.c ⽂件

使⽤vim编辑器输⼊下⾯的内容:

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

保存c ode.c ⽂件后退出当前vim,使⽤vim打开 Makefile 文件 输⼊下⾯的内容:

code:code.c
 gcc -o code code.c
 .PHONY:clean
 clean:
 rm -rf code

需要注意, gcc -o code code.c和 rm -rf code前⽅是⼀个Tab键的⼤ ⼩,⽽不是4个或者8个空格

保存M akefile ⽂件后退出当前vim,在当前⽬录下输⼊ make 指令即可在当前⽬录下 创建code.c 对应的可执⾏⽂件(具有可执⾏权限并且⽂件本身可执⾏) code ,例 如下图:

通过常规⽅式运⾏该可执⾏⽂件 ./code 即可看到打印输出的内容:

接着使⽤ make clean 指令清理刚才⽣成的可执⾏⽂件 code :

3.Makefile文件基本格式介绍

以前⾯例⼦中的 Makefile 为例:

 code:code.c
 gcc -o code code.c
 .PHONY:clean
 clean:
 rm -rf code

第⼀⾏中的 code:code.c 代表依赖关系, code 表示⽬标⽂件, 赖⽂件列表中的⽂件,第⼆⾏的 code.c 表示依 gcc -o code code.c代表依赖⽅法(指令)

第三⾏中的 .PHONY 表示⽣成⼀个伪⽬标, clean 表示伪⽬标的名字(可以类⽐ 变量名)

第四⾏及第五⾏与第⼀⾏及第⼆⾏含义⼀致,表示依赖关系和依赖⽅法,⽽因为 clean 没有需要依赖的⽂件,所以 clean: 后没有任何依赖⽂件列表⽂件

依赖关系:表示两个⽂件之间构成的⼀定关系,⽐如⽗⼦关系

依赖⽅法:通过依赖⽅法可以执⾏的对应的指令

依赖⽂件列表: code.c 所处的位置即为依赖⽂件列表,为了⽣成⽬标⽂件 code 而需要的⽂件称为依赖⽂件,依赖⽂件列表可以含有不⽌⼀个⽂件

注意:理论上来说,依赖⽂件列表中的  code.c 在当前情况下可以不写,但是如 果不写,在第⼀次执⾏ make 指令后,不论之后 code.c 是否修改,再执⾏ make 指令都⽆法执⾏对应的依赖⽅法,因为 code ⽂件已经存在,所以为了保 证可以修改,需要加上 code.c

从上⾯的运⾏结果可以看出,每⼀次执⾏make时都会在控制台回显出对应的依赖⽅ 法,如果将编译指令改为 echo "测试",则效果如下:

可以看到先回显了对应的依赖⽅法,再执⾏依赖⽅法,如果不希望出现这种情况,可 以在执⾏的指令前加上@使指令不再回显,所以上⾯的 Makefile 可以修改为:

 code:code.c
  2   @echo "Start Compiling..."
  3   @gcc -o code code.c
  4   @echo "End Comliling"
  5 .PHONY:clean
  6 clean:
  7     @echo "Cleaning code..."
  8     @rm -rf code
  9     @echo  "End Cleaning..."
 10                                                                                   
~

⼀个依赖集中可以有多个依赖⽅法

此时正常运⾏结果如下:

如果代码出现错误,则 gcc 会中断编译,所以此时运⾏结果如下:

使⽤. PHONY 可以⽣成⼀个指定名字的伪⽬标,伪⽬标的作⽤是:清除依赖⽅法执⾏ 时进⾏的⽂件时间对⽐,下⾯是具体介绍: ⾸先,在Linux中可以使⽤ stat+⽂件名查看⽂件当前的属性,对于 code.c 有:

执⾏结果中,主要关注三个部分: Access 、 Modify 和 Change ,这三个部分分别 表示⽂件最近⼀次的访问时间、⽂件内容被修改的时间和⽂件属性被修改的时间

Access 时间:⼀般不是特别精确,因为如果⼀个⽂件访问⼀次就需要更新⼀次 访问时间,那么对于多个⽂件来说,这种操作的消耗对于CPU来说是很⼤的

Modify 时间: Modify 时间只表示⽂件内容被修改的时间,如果⽂件属性时间 修改,则不影响 Modify 时间,但是需要注意, 着Ch Modify 时间⼀旦改变⼀般伴随 ange 时间改变,因为修改⽂件内容有时会影响到⽂件的相关属性(例如⽂ 件⼤⼩等)

Change 时间:Change 时间只表示⽂件属性被修改的时间,修改⽂件属性时间不会影响Modify时间

接着,观察对于没有添加伪⽬标的 Makefile 第⼀部分依赖集,如果code文件已经存在,再一次进行make的效果:

code:code.c
 @echo "Start Compiling..."
 @gcc -o code code.c
 @echo "End Compiling..."

那么指令是如何知道⽂件是否被修改呢?就是通过前⾯提到的 Modify 时间和 Change 时间,过程如下图所示:

因为code.c 创建的时间早于 code.c 编译的时间,所以开始时不存在 所以第⼀次执⾏ code ⽂件, make 指令时正常执⾏。

当code.c ⽂件未修改时,第⼆次执⾏ make 指令会发现 code.c 的 Change 时间依旧在 make 之前,因为第⼀次已经满⾜了 Modify 时间和 code.c 的两个时间在 code ⽂件的两个时间之前,所以 gcc 就不会再进⾏⼀次编译。

当修改 code.c ⽂件后, code.c 的 的两个时间在 Modify 时间和 Change 时间改变,导致 code ⽂件的两个时间之后,此时 code.c gcc 就可以正常执⾏,从⽽ make 指 令不受影响

⽽如果再 Makefile 中为这⼀部分添加⼀个伪⽬标,则可以清除指令中⽂件时间的对 ⽐过程:

.PHONY:code
     code:code.c
 @echo "Start Compiling..."
 @gcc -o code code.c
 @echo "End Compiling..."

此时⽆论执⾏多少次 make 指令,都不会出现 : make 指令中 gcc 因为⽂件时间对⽐⽽导致执⾏结果不同

make 指令虽然结果完全相同,但是不代表依赖⽅法没有执⾏,即⽂件确实每⼀ 次都重新编译

执⾏完编译部分的 make 指令,想要执⾏删除 code ⽂件对应的 make 后加上 clean ,这个 make 指令需要在 clean 代表伪⽬标名,之所以前⾯直接使⽤ make 就可以 执⾏编译指令,是因为 make 指令在读取 Makefile ⽂件时是从上⾄下顺序查找,⽽ 直接使⽤ make ,就会执⾏第⼀个依赖集对应的依赖⽅法,执⾏完毕后就不会再继续 往下读;⽽对于删除 code ⽂件的指令来说,其所在位置时Makefile 中的第⼆个依赖集,所以需要告诉 make 指令找哪⼀部分

所以,此处可以看出.PHONY 的第⼆个作⽤就是声明⼀个伪⽬标,通过该伪⽬标帮助make 指令快速定位需要执⾏的依赖集

如果细⼼可以发现,对于 clean 依赖集来说,不论是否有 .PHONY 都可以⽆限制执⾏ rm -rf依赖⽅法,所以可以推断出 rm -rf指令本身不会考虑⽂件的时间属性,但 是为什么此处还需要加 .PHONY ?⼀⽅⾯是为了声明伪⽬标,另⼀⽅⾯是为了当前依 赖集中的其他指令会有时间对⽐

4.Makefile通用写法

在前⾯的Makefile中,每⼀个依赖⽅法都需要在前⾯的依赖关系部分的⽂件重新写⼀ 遍,为了简化过程,可以使⽤下⾯的写法:

 TARGET=code
 SRC=code.o
 $(TARGET):$(SRC)
 $(CC) -o $@ $<
 %.o:%.c
 $(CC) -c $< -o $@
 .PHONY:clean
 clean:
 @rm -rf $(TARGET) $(SRC)

上⾯的代码中,⾸先创建了两个变量分别代表⽣成的⽬标⽂件 code 以及第⼀个依赖 集中的依赖⽂件列表中的⽂件,在依赖⽅法中使⽤了两个⾃动变量(⼀般建议⼤ 写),分别是$@和$<

在M akefile 中, $@ 表示⽣成的⽬标⽂件,$<表示从依赖⽂件列表中取出⼀个⽂ 件,对应的还有$^表示依赖⽂件列表中的所有⽂件

⽽对于gcc来说,在 Makefile 中可以使⽤内置变量 如果涉及到多个⽂件编译,则在 SRC 和 CC (表示C编译器的名字)代替 %.c 处使⽤空格分隔每⼀个⽂件

⾄此,⼀个基本的 Makefile ⽂件编写语法就这么多

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

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

相关文章

【小工具分享】下载保存指定网页的所有图片

一、保存百度首页所有的图片 先看一下保存的图片情况 二、思路 1、打开网页 2、获取所有图片 3、依次下载保存图片到指定路径 三、完整代码 from selenium import webdriver from selenium.webdriver.common.by import By b webdriver.Firefox() import urllib.request…

企业如何借力AI,提升人力资源管理的效率完成组织提效变革

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 企业面临的压力&#xff1a; 在当今这个充…

LeetCode|70.爬楼梯

这道题很像斐波那契数列&#xff0c;但是初始值不同&#xff0c;也有动态规划的解法&#xff0c;但是一开始我想到的是递归写法。现在我们站在第n阶台阶&#xff0c;那么&#xff0c;我们上一步就有两种可能&#xff1a;1、我们从第n-1阶台阶走一步上来的&#xff1b;2、我们从…

商家转账到零钱接口开通

商家想要开通“商家转账到零钱”功能&#xff0c;需要遵循一系列详细步骤和条件&#xff0c;以确保顺利通过审核。以下是开通办法的详解&#xff1a; 申请流程&#xff1a; 主体资格确认&#xff1a;确保申请主体为公司性质&#xff08;有限公司&#xff09;&#xff0c;个体工…

ScribbleDiff:使用涂鸦引导扩散,实现无需训练的文本到图像生成

ScribbleDiff可以通过简单的涂鸦帮助计算机生成图像。比如你在纸上随意画了一些线条&#xff0c;表示你想要的图像的轮廓。ScribbleDiff会利用这些线条来指导图像生成的过程。 首先&#xff0c;它会分析这些涂鸦&#xff0c;确保生成的图像中的对象朝着你画的方向。比如&#…

品民俗、看展演、逛非遗市集……在海淀,重阳节还可以这样过

秋菊溢彩、叠翠鎏金。由北京市海淀区文化和旅游局主办,北京市海淀区文化馆承办,海淀区上庄镇文化活动中心支持的品鉴民俗 巧手绘梦——2024年海淀区重阳节非遗主题文化活动于10月11日在上庄镇市民活动中心顺利举办。海淀非遗传承人以非遗为媒,与地区群众度过了一个温馨、热闹、…

第四次论文问题知识点及问题

1、NP-hard问题 NP-hard&#xff0c;指所有NP问题都能在多项式时间复杂度内归约到的问题。 2、启发式算法 ‌‌启发式算法&#xff08;heuristic algorithm&#xff09;是相对于最优化算法提出的。它是一种基于直观或经验构造的算法&#xff0c;旨在以可接受的花费给出待解决…

Android 如何实现远程网页控制售卖机出商品:RabbitMQ的对接,如何使用?如何断网重连?连接不上后台的MQ有哪些方面的原因

目录 一、如何实现远程网页控制售卖机出商品&#xff1f; 比如&#xff0c;我们想实现&#xff0c;通过一个网页去控制自动售卖机&#xff08;自动售卖机装有Android系统&#xff0c;装有App&#xff09;出商品&#xff0c;也就是我们熟知的远程控制&#xff0c;不用你人到现场…

搭建电商商城系统各项功能时需要用到的电商API数据采集接口

在搭建电商商城系统时&#xff0c;选择合适的电商API接口至关重要。以下是一些常用的电商API接口提供商及其功能&#xff1a; 常用电商API接口提供商 淘宝开放平台&#xff1a;提供淘宝、天猫、1688等阿里巴巴集团旗下的电商平台接口&#xff0c;用于商品检索、订单管理、物流…

如何把pdf转换成jpg图片?在线pdf转图片,这6种方法很简单!

“如何把pdf转换成jpg图片&#xff1f;”相信很多小伙伴们都有这个疑问。pdf格式是如今在商业和其他正式场合中使用最广泛的文档类型&#xff0c;因为它能以安全且方便的方式共享信息。然而&#xff0c;查看pdf文件通常需要使用一些专业的pdf阅读器&#xff0c;这可能给一些用户…

服务端给客户端push消息的demo的实现流程

摘要&#xff1a; 本示例演示了一个基本的服务端5分钟定时向客户端app推送消息的WebSocket机制。服务端使用WebSocket协议接受客户端的订阅和取消订阅请求&#xff0c;并根据客户端的订阅状态发送实时消息。服务端记录并打印带有时间戳的日志&#xff0c;以监控订阅活动。客户…

python画图|二维动态柱状图输出

【1】引言 在前面的学习过程中&#xff0c;已经探索过二维柱状图和三维柱状图的绘制教程&#xff0c;包括且不限于的文章链接有&#xff1a; python画图|水平直方图绘制_绘制水平直方图-CSDN博客 python画图|3D bar进阶探索_ax.bar3d-CSDN博客 此外也学习了动态的直线输出和…

调用AI 通过相机识别地标

https://www.youtube.com/watch?vViRfnLAR_Uc&listPLQkwcJG4YTCRJxkPPDBcKqDWrfF5qanQs&index3学习视频 TensorFlow Hub 机器学习模型的代码库 找到地标模型 如何在Android上使用ts模型 https://blog.tensorflow.org/2018/03/using-tensorflow-lite-on-android.html…

10.11每日作业

数据表 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//想要添加某个数据库if(!db.contains("stu.db")){//如果当前对象中没有包含所需数据库&…

dowhy中反驳实验怎么做?

首先&#xff0c;我们打开最新的dowhy版本网站。 https://www.pywhy.org/dowhy/v0.11.1/index.html 我们主要看标题栏的User Guide和Examples就可以了&#xff0c;如果在User Guide 里找不到使用方法&#xff0c;就去Examples里找例子&#xff0c;里面的数据读取修改为自己的数…

HI6338 (DIP-8内置75W方案)

Hi6338 combines a dedicated current mode PWM controller with integrated high voltage power MOSFET.Vcc low startup current and low operating current contribute to a reliable power on startup design with Hi6338. the IC operates in Extended ‘burst mode’ to …

前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析

本文属于进阶篇&#xff0c;并不是太适合新人阅读&#xff0c;但纯粹的学习还是可以的&#xff0c;因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端&#xff0c;提前预习和复习下。ddp协议是一个C/S架构的协议&#xff0c;但是客户端也同时可以是服务端。 什…

Java程序打包成jar包

步骤1 打开项目结构 步骤2 配置工件 选择你要打包的模块选择主类(程序的主入口main类)提取到目标会把库文件的jar包打包到目标,一般选择这个,更方便在不同电脑上运行 步骤3 构建并生成jar包 最后,在对应的out/artifacts文件夹中找到jar包,在终端输入java -jar xxxx.jar就可以正…

mac电脑如何删除应用程序?怎么删除苹果电脑里的软件

在使用Mac电脑的过程中&#xff0c;随着时间的推移&#xff0c;我们可能会安装大量的应用程序。然而&#xff0c;这些应用程序中有很多可能只是临时使用&#xff0c;或者已经不再需要了。这些无用的应用程序不仅占据了宝贵的硬盘空间&#xff0c;还可能拖慢Mac系统的运行速度。…

JAVA基础 day12

一、File、IO流 File是java.io.包下的类&#xff0c;file类的对象&#xff0c;用于代表当前操作系统的文件&#xff08;可以代表文件、文件夹&#xff09;&#xff0c;使用File可以操作文件及文件夹。 注意&#xff1a;File只能对文件本身进行操作&#xff0c;不能读写文件里…