【Linux】make/Makefile --- 自动化构建项目的工具

目录

一、make/Makefile的简单使用

二、Makefile 的语法规则

三、实现的原理

3.1 make/Makefile识别文件新旧

3.2 .PHONY修饰的伪目标总是被执行

3.3 make/Makefile是具有依赖性的推导能力的

四、语法技巧

五、注意事项


Linux中自动化构建项目最简单的方式:make/Makefile
make:是一个命令
Makefile:是一个在当前目录下存在的一个具有特定格式的文本文件。
(Makefile首字母可以小写,但建议使用大写)

makefile文件中,保存了编译器和链接器的参数选项,并且描述了所有源文件之间的关系。make程序会读取makefile文件中的数据,然后根据规则调用编译器,汇编器,链接器产生最后的输出。

一、make/Makefile的简单使用

  • 创建Makefile
    touch Makefile
  •  编写Makefile:
    vim Makefile
  • 编写要生成的可执行程序mybin和项目清理clean:
  • 使用make命令生成可执行程序
    make
  • 使用make命令进行项目清理
    make clean

二、Makefile 的语法规则

Makefile 中包括依赖关系(目标依赖)依赖方法(命令)
下面是 Makefile 中一些要素的基本语法规则:

目标:指定了要生成的文件或要执行的操作名。

例如:上面的mybin就是要生成的目标文件名

依赖:指定了目标所依赖的文件或其他目标。

例如:上面的test.c 是目标文件依赖的文件。一个目标文件可以有多个依赖文件,用空格分开。
目标和依赖构成了依赖关系

命令(依赖方法):包含了生成目标所需的具体操作步骤,通常是一条或多条 Shell 命令。

第二行必须以Tab开头,不能是空格,紧接着是生成目标文件的命令。

例如:上面的gcc test.c -o mybin -std=c99
(gcc test.c -o mybin 与gcc -o mybin test.c 相同,-o后面跟目标文件名即可)

伪目标:伪目标是指在 Makefile 中.PHONY定义的不对应实际文件的目标,通常用于执行一些特定的操作,比如清理临时文件。 
例如:上面的clean目标用于执行清理操作,删除mybin文件。
注:make默认执行的是第一行的命令,一般把清理工作放在最后面。

注释:使用 # 符号来添加注释,注释从 # 开始一直到该行的末尾。

变量:可以使用变量来存储命令选项、编译器名称等信息,然后在规则中引用这些变量。
语法格式:VAR_NAME = value

条件判断:可以使用条件判断(ifeq、ifdef 等)来根据不同的条件执行不同的命令。

函数:Makefile 支持一些内置函数,可以用于字符串处理、文件查找等操作。

使用make和make clean,就可以方便地完成项目自动化构建和清理。

三、实现的原理

3.1 make/Makefile识别文件新旧

make命令不是每次都会重新编译,只有更改过的文件才会重新编译。(提高编译效率)
若源代码没有更改也重新编译,那么每次预处理编译汇编链接的时间比较长,成本高。

make/Makefile是如何知道文件更改过的?
答:通过源文件的修改时间和形成的可执行程序(也是文件)的修改时间做对比

重新编译的本质:重新写入一个二进制的可执行文件(bin文件),文件的修改时间会跟着更改。

  • 第一次的时候,一定是先有源文件,才有bin文件。
    源文件的修改时间 < bin文件的修改时间
  • 第二/n次的时候,我们对源文件做任何修改的时候,
    源文件的修改时间 > bin文件的修改时间
    ​​​​​
    重新编译形成可执行

大部分情况下重新编译都没问题,问题的产生不仅仅是修改新文件就能解决的。有些历史问题需要重新清理项目才可以解决。

文件 = 内容 + 属性,所以文件的ACM时间肯定与内容或属性有关。

Access(最近访问时间):普通文本文件打开:cat、vim,或者对目录进入、ls显示等

Modify (对内容修改):当文件内容发生变化时,修改时间(mtime)会被更新。

Change(对属性修改):当文件的权限、所有者、链接数或文件名发生变化时,更改时间(ctime)会被更新。

注:

  • 三种时间会出现联动,例如对内容修改,Access和Change时间也会更改。
  • Access时间不是每次访问时都更改,读取查看文件操作最频繁,如果每次都改的话,比较浪费时间,因为文件一般都在磁盘存放,更改时间的本质就是访问磁盘。但是访问磁盘的速度比较慢(相对cpu而言),读取查看文件操作又是很频繁,如果每次都更改Access time的话,系统效率就会降低很多,所以就会隔一段时间更改一次。
    (具体间隔时间和是否间隔,由内核版本决定)
  • 使用touch命令可以修改ACM时间。
    -a 选项  修改Access时间,但同时也修改了change时间,因为access时间也是属性。
    -m 选项 修改Modify时间,但是Change时间也会跟着改。

综上,make 是通过对比源文件和bin文件的Modify时间确定文件新旧的。

3.2 .PHONY修饰的伪目标总是被执行

通过时间对比,可以做到不让有些代码进行重新编译(不让某些操作进行)。

总是被执行就是:不考虑其他任何问题,总是执行依赖方法,不会被任何情况拦截
(make/makefile不再依靠时间对比了,直接执行对应的命令)

例如:mybin被.PHONY修饰,则多次make时,都会执行gcc命令,把可执行程序重新形成。

3.3 make/Makefile是具有依赖性的推导能力的

上一节讲到gcc编译生成一个可执行程序需要经过预处理、编译、汇编和连接,中间会产生.i,.o,.s文件。但是在上面的操作中都没有生成中间文件。
但是我们知道一件事:生成bin文件,就需要对应的.o文件。

以Makefile的推导过程如下:(类似一个栈结构)

生成了临时文件 code.o code.s code.i

以上写法只是为了了解编译推导的过程,实际上不推荐使用。

建议直接用gcc形成可执行!


四、语法技巧

  1. Makefile里面的指令执行时会自动回显出来,可以在前面加上 符号使其不回显,不显示指令信息。
  2. 可以使用 echo 添加一些输出信息。
  3. 依赖方法可以不止一个,用回车隔开。
  4. makefile中用 注释
  5. makefile中可以编写变量,表达式之间不建议带空格
    通过 $(变量名) 来引用变量的值。

    用途:之后如果想使用g++,只需要把gcc改成g++,mybin改成mybin.exe
  6. 可以用 #^ 符号代替依赖关系中的所有内容,#@ 代替要形成的目标文件

 


五、注意事项

  • 首次make时,make扫描Makefile文件时,自顶向下。如果发现第一个目标文件,则尝试根据该目标及其依赖关系构建目标文件。(默认一次形成一个最终的目标文件)
  • 伪目标文件没有实际的依赖关系,每次都会执行其定义的命令,而不是构建文件。
  • Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
    显式规则说明了,如何生成一个或多个目标文件。
  • make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写makefile,比如源文件与目标文件之间的时间关系判断。
  • 在makefile中可以定义变量,当makefile被执行时,其中的变量都会被扩展到相应的引用位置上,通常使用 $(var) 表示引用变量。
  • 文件指示。在一个makefile中引用另一个makefile,类似C语言中的include;
    ".mk" 是用来表示 Makefile 文件的扩展名。
    include path/to/another_makefile.mk
    
    target: dependency
        command
    
  • 注释,makefile中可以使用 # 在行首表示行注释
  • 默认的情况下,make命令会在当前目录下按顺序找寻文件名为"GNUmakefile"、"makefile"、"Makefile"的文件。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux系统---简易伙伴系统

顾得泉&#xff1a;个人主页 个人专栏&#xff1a;《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂&#xff0c;年薪百万&#xff01; 一、题目要求 1.采用C语言实现 2.伙伴系统采用free_area[11]数组来组织。要求伙伴内存最小为一个页面&#xff0c;页面大小为4KB…

C语言习题

写一个函数&#xff0c;输入一个四位数字&#xff0c;要求输出这四个数字字符&#xff0c;但每两个数字间空一个空格。如输入1990&#xff0c;输出1 9 9 0 如下&#xff1a; #include<stdio.h> void Print(int n) { if(n>9) { Print(n/10); } printf("%d "…

ssm的健身房预约系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; ssm的健身房预约系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spring…

【trino权威指南】使用trino详解:trino client安装、查询sql、DBeaver连接trino、java通过JDBC连接trino

文章目录 一. Trino CLI1. 安装client2. 使用client执行sql 二. JDBC driver 连接Trino1. 通过DBeaver用户界面连接2. JDBC Driver in java2.1. 环境配置2.2. 注册和配置driver2.3. 连接参数2.4. 查询例子 一. Trino CLI 1. 安装client Trino CLI提供了一个基于终端的交互式s…

H264之NALU结构详解

摘要&#xff1a;本文详细描述了AVC的NALU的码流结构&#xff0c;以及各个层面上NALU详细的构成。   关键字&#xff1a;AVC&#xff0c;NALU 1 NALU简介 NAL层即网络抽象层&#xff08;Network Abstraction Layer&#xff09;&#xff0c;是为了方便在网络上传输的一种抽象…

tomcat篇---第四篇

系列文章目录 文章目录 系列文章目录前言一、为什么我们将tomcat称为Web容器或者Servlet容器 ?二、tomcat是如何处理Http请求流程的?三、tomcat结构目录有哪些?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这…

Mysql索引一篇就够了

索引 定义 索引是对数据库表中一列或者多列的值进行排序的结构。 目的 数据库索引好比一本书的目录&#xff0c;提高查询效率。但是为表设置索引要付出相应的代价&#xff1a; 增加了数据库的存储空间 在插入和修改时需花费更多的时间&#xff08;因为索引也要随之变动&#…

带有 RaspiCam 的 Raspberry Pi 监控和延时摄影摄像机

一、说明 一段时间以来&#xff0c;我一直想构建一个运动激活且具有延时功能的树莓派相机&#xff0c;但从未真正找到我喜欢的案例。我在thingiverse上找到了这个适合树莓派和相机的好案例。它是为特定的鱼眼相机设计的&#xff0c;但从模型来看&#xff0c;我拥有的廉价中国鱼…

【基于Python的二手车数据可视化平台的设计与实现】

基于Python的二手车数据可视化平台的设计与实现 前言数据获取与处理网络爬虫数据存储 可视化平台的设计与实现Flask框架数据可视化 创新点结语 前言 随着社会的不断发展&#xff0c;二手车市场也逐渐成为一个备受关注的领域。为了更好地为二手车的买家和卖家提供信息&#xff…

Pycharm设置为中文版

文章目录 关注公众号&#xff1a;『AI学习星球』 算法学习、4对1辅导、论文辅导或核心期刊可以通过公众号或CSDN滴滴我 在使用Pycharm的时候&#xff0c;会发现里面的菜单栏以及内容都是英文为主。 英文版的优点是&#xff1a;比较稳定&#xff0c;其次大家都在用英文版&…

MobaXterm成功连接到开发环境后,过一段时间会自动断开。

问题现象 MobaXterm成功连接到开发环境后&#xff0c;过一段时间会自动断开。 原因 配置MobaXterm工具时&#xff0c;没有勾选“SSH keepalive”或专业版MobaXterm工具的“Stop server after”时间设置太短。

Android 样式小结

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、使用3.1 创建并应用样式3.2 创建并…

zabbix 通过 odbc 监控 mssql

1、环境 操作系统&#xff1a;龙蜥os 8.0 zabbix&#xff1a;6.0 mssql&#xff1a;2012 2、安装odbc 注意&#xff1a;需要在zabbix server 或者 zabbix proxy 安装 odbc驱动程序 dnf -y install unixODBC unixODBC-devel3、安装mssql驱动程序 注意&#xff1a;我最开始尝试…

【Unity】Addressable包资源加载失败:CRC Mismatch.

Error while downloading Asset Bundle: CRC Mismatch. 是资源下载校验失败&#xff0c;但是资源和上次打包的资源是一样的。没有排查到原因&#xff0c;在谷歌搜索后看到 大概就是指Unity版本修改后打包&#xff0c;会破坏原来的CRC信息&#xff0c;导致导报出来的资源无法通…

一篇文章带你了解并使用mybatis框架

mybatis简介&#xff1a; MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;P…

深度学习之全面了解预训练模型

在本专栏中&#xff0c;我们将讨论预训练模型。有很多模型可供选择&#xff0c;因此也有很多考虑事项。 这次的专栏与以往稍有不同。我要回答的问题全部源于 MathWorks 社区论坛&#xff08;ww2.mathworks.cn/matlabcentral/&#xff09;的问题。我会首先总结 MATLAB Answers …

Python time模块详解

time 模块主要包含各种提供日期、时间功能的类和函数。该模块既提供了把日期、时间格式化为字符串的功能&#xff0c;也提供了从字符串恢复日期、时间的功能。 在 Python 的交互式解释器中先导入 time 模块&#xff0c;然后输入 [e for e in dir(time) if not e.startswith(_)…

【数据结构】万字一文手把手解读哈希————(开/闭散列)解决哈希冲突完整详解(6)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 数据结构 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴 数据结构 专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一.哈希&#xff08…

【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

一、翔云 人工智能开放平台 API文档开发示例下载 二、编译openSSL支持libcurl的https访问 安装SSL依赖库openSSL(使用工具wget)libcurl库重新配置&#xff0c;编译&#xff0c;安装运行&#xff08;运行需添加动态库为环境变量&#xff09; 三、编程实现人脸识别 四、Base6…