【Linux】Makefile/make - 快速理解入门

news2024/11/17 23:58:29

目录

一、概念理解

1、基本概念

2、举例说明

二、编写 Makefile

1、依赖关系和依赖方法

2、文件清理

3、扩展内容


一、概念理解

1、基本概念

在我们学习 Linux 的过程中,我们可以直接使用 gcc 指令对程序的文本文件逐个进行编译处理,这是因为我们写的程序很少,可能只有两三个。

但是如果在日后的工程项目之中,我们要编译处理的程序文本文件会非常的多,难道我们还是需要使用 gcc 指令对每一个文件都进行一次编译吗?这样效率也太低了。所以我们需要引出一个概念:Makefile 和 make。

会不会写Makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。Makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个 make 命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make 是一个命令工具,是一个解释 Makefile 中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

make是一条命令,Makefile是一个文件,两个搭配使用,完成项目自动化构建。Makefile 文件一般放在当前的源代码路径下。

2、举例说明

接下来我们快速写一个 demo ,来见一见 Makefile 文件是如何使用的。我们先在当前源代码路径下创建一个 Makefile 文件:

touch Makefile

当前源代码 myfile.c 所在的路径下就有了一个 Makefile 文件。我们打开 Makefile 文件,进行编写,操作细节大家可能还不理解,不过没关系,下面的内容会详细的介绍,现在只是让大家了解 Makefile 的用法:

 保存退出。从此之后,我们想再去编译源代码文件 myfile.c 就不再需要在命令行里敲 gcc 指令了。可以直接使用 make 指令,它会自动的在当前目录下查找 Makefile 文件,然后执行我们刚刚内置好的指令:

make

此时我们的可执行程序已经生成了,那么我们如果想把所有的可执行程序都删除怎么办呢,数量较少可以直接使用 rm 指令,如果数量较多,还是需要使用 Makefile 文件来处理。

继续打开 Makefile 文件进行编辑:

 保存退出。这样我们清理的时候直接使用指令:

make clean

可运行文件已经被删除了。


从此之后,我们对于该路径下的任何源文件进行修改之后,都直接使用 make 命令直接重新进行编译,不想要了就直接使用 make clean 命令进行清除,非常简单快捷。这就是 Makefile 。

二、编写 Makefile

相信同学们看了以上操作,对于 Makefile 文件的编写一定有很多疑问,接下来我就来说明它是如何编写的。

1、依赖关系和依赖方法

打开 Makefile 文件

来看第一行代码,我们形成 myfile 这个目标文件所依赖的文件是 myfile.c 。意思是要用 myfile.c 形成 myfile 。我们把他们之间的关系称为 依赖关系

根据 myfile.c 要怎么形成 myfile 呢?我们来看第二行代码,这一行代码被称为 依赖方法 依赖方法必须要以 Tab 键开头,这是依赖方法的固定语法格式。

所以 Makefile 文件是一个围绕 依赖关系 和 依赖方法 构建的一个自动化编译的工具。Makefile 文件生效必须要有 正确的依赖关系 + 正确的依赖方法。


在 Makefile 文件被识别时,是 从上往下识别 的。我故意把前两行代码写的复杂一些,方便大家理解:

开始时,myfile 文件依赖于 myfile.o 文件。但是程序中没有 myfile.o 文件,于是向下找到 myfile.o 文件依赖于 myfile.s 文件。但是程序中没有 myfile.s 文件,于是向下找到 myfile.s 文件依赖于 myfile.i 文件。这样依次向下寻找,终于找到了程序中存在的 myfile.c 文件,根据依赖关系与依赖方法生成 myfile.i 文件,依次向上返回,这个识别方式是借助 来实现的。最终得到了 myfile 文件。

这种写法是我故意复杂化的写法,只是让大家理解 Makefile 文件的识别方式,实际上没有人这么写代码。


2、文件清理

打开 Makefile 文件,我先对 Makefile 做一下准备做的修改:

依赖关系中,目标文件对应的依赖文件列表可以是空。 保存退出。 

我们再来执行 make clean 指令:

 可以看到指定字符确实打印出来了。那么我们在执行清除指令时,为什么要在 make 后面加一个 clean 呢?

这是因为 myfile 是我们从上到下扫描所遇到的第一组依赖关系与方法。而 clean 是第二组依赖关系与方法。Makefile 在从上到下扫描时,默认只会执行第一组依赖关系与方法。所以我们执行编译操作只需要 make 指令就可以了,而执行 clean ,就需要 make clean 


 而我们之前所写的这个第10行代码是什么意思呢? .PHONY 是 Makefile 语法当中的一个关键字,用来修饰目标文件。

.PHONY 含义:总是被执行的

这句话可能不是很好懂,我来说明一下:如果我们重复多次使用 make 指令来编译 myfile 文件,会出现这样的提示:

显示我们当前的可执行程序是源代码匹配的最新的可执行程序,不需要再被更新了。这种现象就叫做 不是总是被执行的

我们给 myfile 也加上 .PHONY  

再来试一试多次输入 make 指令:

 可以看到已经变为 总是被执行的了

我们称被 .PHONY 修饰的符号为 伪目标,伪目标的典型特点,就是总是被执行的。

为了防止时间的浪费,我们一般把程序的编译设为 不是总被执行的,程序的清理设为 总是被执行的:

同学们注意,问题又来了!make 指令怎么能知道当前的可执行程序是源代码匹配的最新的可执行程序了呢?

是通过对比时间来判断的,正常来说,一定是先有的源代码,然后才有的编译之后的可执行程序,也就是说可执行程序的最近修改时间一定在原代码最近修改的时间之后,如果不符合这个条件,就重新编译。

 

3、扩展内容

根据以上原理,我们可以通过修改时间来欺骗 make 指令。具体操作如下:

显示文件时间指令:

stat [文件名]

 再使用 touch 指令操作:

touch [文件名]:如果文件不存在,则创建该文件。如果该文件存在,更新该文件的时间。

touch myfile.c

 此时,源文件的时间就比可执行文件的时间更新了,我们就可以再次使用 make 指令来编译文件了。


关于 Makefile 的基本知识就讲到这里,希望同学们多多支持,如果有不对的地方,欢迎大佬指正,谢谢!

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

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

相关文章

ASP.NET Core 3.1系列(26)——Autofac中的实例生命周期

1、前言 前面的博客主要介绍了Autofac中的一些注册方法,下面就来介绍一下Autofac中实例的生命周期。之前在介绍ASP.NET Core内置IoC容器的时候说过,实例的生命周期有:瞬时生命周期、域生命周期、全局单例生命周期,而Autofac在这三…

mysql-8.0.31-winx64详细安装教程

一、下载MySQL MySQL官网:https://www.mysql.com/cn/ mysql-8.0.31-winx64下载地址:https://dev.mysql.com/downloads/mysql/ 2、下载结束后,解压到指定目录,笔者存放在D盘 ,为求简单,设置目录如下&#…

数据库历史数据年度备份

数据库历史数据年度备份 1、文件说明 matomo_backup.sql 备份库表结构脚本(这个根据自己数据结构准备,对于时间命名的表结构就不要加了,只加非时间命名的表结构) export.sh 数据导出脚本 clean.sh 源数据库历史数据清除脚本 2、需求与思路 需求 对…

怎么把PDF转换成图片?来看看这几个方法吧!

要说我们手机里最多的一种文件格式是什么?那应该就是图片了。相信在智能手机的时代,每个人手机里都会有至少几百上千张照片吧。毕竟有许多的事情我们都希望通过图片、照片的形式来记录下来。所以说如何将其他格式的文件变成图片格式就成了一个不大不小的…

开发那点事(十八)Vue开发PC桌面应用案例

写在前面的话 最近有在研究electron框架,踩了不少坑 ,现在把这几天研究的成果分享给大家。 研究成果 vue项目打包成exe可安装程序pc应用版本升级(需要配合oss服务器) vue应用配置 路由文件base配置为空mode模式为默认的hashv…

智慧门户、信创门户、国产门户、数字化门户,如何构建出七大特色亮点?

作者:郑文平 概述 调研结果显示,世界500强企业100%建设了适合自己的集团门户管理系统,也叫作办公门户或内网门户,并通过统一门户最终提升各自整体的业务管理水平和流转效率,没有建设门户的公司面临如下制约&#xff…

二,Spring IOC以及整合mybatis

0 复习 工厂设计模式 工厂设计模式代替new方式创建对象,目的是解耦合。 Spring做为工厂的使用 applicationContext.xml配置bean标签 如何从工厂中获取对象 //创建工厂 ApplicationContext ctx new ClassPathXmlApplicationContext("classpath:applicationCont…

AWS实战:Aurora到Redshift数据同步

什么是AuroraAmazon Aurora是一种基于云且完全托管关系型数据库服务,与MySQL 和 PostgreSQL 数据库兼容,完全托管意味着自动对数据库进行管理,包括管理数据备份、硬件配置和软件更新等操作Amazon Aurora提供了企业级性能Amazon Aurora提供了多…

【C/C++】动态顺序表详解(附完整源码)

本章内容 写在前面 1.静态与动态是指什么? 2.动态顺序表结构的定义 3.动态顺序表的函数接口实现 4.动态顺序表的问题及思考 5.关于顺序表的OJ题 6.OJ答案及解析 1.移除元素 2.删除有序数组中的重复项 ​3.合并两个有序数组 7.动态顺序表完整源码 1.SeqL…

《mSystems》最新研究| 李香真老师亲临凌波微课LorMe云讲堂解读贡嘎山反硝化菌群组装模式和驱动因素

2021年11月2日,李香真团队在《mSystems》期刊正式发表了题为“Patterns and Drivers of nirK-Typeand nirS-Type Denitrifier Community Assembly along an Elevation Gradient”的研究论文。该研究以青藏高原东部边界最高山——贡嘎山作为研究平台,比较…

小程序与普通网页开发有什么区别?

小程序的开发同普通的网页开发相比有很大的相似性,小程序的主要开发语言也是 JavaScript,但是二者还是有些差别的。 普通网页开发可以使用各种浏览器提供的 DOM API,进行 DOM 操作,小程序的逻辑层和渲染层是分开的,逻…

[前端笔记] 1.WEB基本概念

[前端笔记] 1.WEB基本概念基本概念1.资源 resourse2.链接3.HTTP 协议4.网页的真实样子:HTML静态网页与动态网页1.静态网页2.动态网页现代网站架构1.网站架构当我们访问一个网站时,后台都会发生什么事情捏?www——万维网 www:World Wide Web …

JAVA中医舌诊接口使用示例代码,JAVA舌象图特征人工智能识别代码,JAVA实现舌象特征检测与识别

中医舌诊接口使用示例-Java示例项目 中医舌诊健康状态检测API 1.此文档适用于集成中国中医舌诊开放平台功能的用户。 2.此文档说明了与中国中医舌诊开放平台的数据交互方法(restful接口),按需使用体质健康API、脏腑健…

盖子的c++小课堂——第十讲:字符

前言 我呢,早上刚发布第九讲,心里想的是马桶盖终于保住了,结果…… 生产队的刘同学:快,继续更,不然你下次吃泡面没调料包 其他粉丝:啊……啊对对对 啊!!!&…

OPTEE TA介绍

前言 本文主要介绍OPTEE的TA(Trusted Applications),翻译自官方文档:Trusted Applications — OP-TEE documentation documentation (optee.readthedocs.io) 有两种方法可以实现可信应用程序 (TA):伪 TA 和用户模式 T…

Speedoffice(word)如何输入特殊符号?

Word文档有时需要输入人民币单位“元”()的符号,那么怎么打出来了,以我最常用的Speedoffice为例和大家分享一下方法。步骤:1,首先运行office软件,新建一份word,找到“插入”菜单栏里…

再学C语言33:函数——地址运算符

C中最重要、最复杂的概念之一就是指针(pointer) 指针是用于存储地址的变量 例如:scanf()函数中使用地址作为参数 当需要改变调用函数中的某个值时,任何被调用的无返回值的C函数都需要使用地址参数完成该任务 一、地址运算符&a…

c语言重点

1、以下代码循环几次&#xff1f;&#xff08;面试题&#xff09; void test(){int i; // 局部变量 i 的值是不确定的for(;i<10;i){;} }答案是---------不确定&#xff0c;在 c 语言中局部变量 i 没有初始化&#xff0c;值是不确定的&#xff0c;所以 i 的值可能是…

GeoHash 的编码方法

对一组经纬度进行 GeoHash 编码时&#xff0c;我们要先对经度和纬度分别编码&#xff0c;然后再把经纬度各自的编码组合成一个最终编码。 对于一个地理位置信息来说&#xff0c;它的经度范围是[-180,180]。GeoHash 编码会把一个经度值编码成一个 N 位的二进制值&#xff0c;我…

MySQL进阶篇之存储引擎

01、存储引擎 1.1、MySQL体系结构 连接层 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 服务层 第二层架构主要完成大多数的核心服务功能&#xff0c;如SQL…