makefile 编写规则

news2024/11/15 17:24:47

1.概念

1.1 什么是makefile

Makefile 是一种文本文件,用于描述软件项目的构建规则和依赖关系,通常用于自动化软件构建过程。它包含了一系列规则和指令,告诉构建系统如何编译和链接源代码文件以生成最终的可执行文件、库文件或者其他目标文件。

1.2 使用makefile的优点

Makefile 主要用于管理大型项目的构建过程,它可以:

  1. 自动检测源代码文件的变化,只编译发生变化的文件,以提高构建效率。
  2. 根据依赖关系自动构建所需的目标文件,无需手动管理编译顺序。
  3. 支持通过简单的命令来进行构建、清理和其他任务,提高了项目的可维护性和可重复性。
  4. 可以轻松地添加自定义的构建规则和操作,满足特定项目的需求。

Makefile 使用一种称为 Make 的构建工具来解析和执行其中的规则。Make 工具会根据 Makefile 中定义的规则和依赖关系,确定需要重新构建的目标文件,并执行相应的命令来完成构建过程。

2.演变的过程

2.1 gcc编译

在我们平常linux下编译文件的时候通过gcc全部编译链接生成可执行的文件

这样编译导致的后果是每次改动某一个代码,其他文件都要跟着编译,非常的繁琐每次,那我们有什么更简单的方法吗,有

2.2 gcc单个文件编译后链接

很明显,大家已经看到了,虽然有一点优化,但不多。这也是不可取的。这时候在linux编译链接的时候就出现了makefile文件。

2.3 Makefile的工作原理

Makefile 的工作原理主要涉及两个部分:规则(rules)和依赖关系(dependencies)。Makefile 中包含了一系列规则,每个规则描述了如何生成一个或多个目标文件,并指定了生成目标文件所需的依赖文件和生成命令。Make 工具会根据这些规则来自动执行构建过程。
下面是 Makefile 的工作原理的详细解释:

1.目标和依赖关系定义:

  • Makefile 中的每个规则由一个或多个目标(targets)和其对应的依赖关系(dependencies)组成。目标通常是文件名,代表生成的目标文件或执行的操作。依赖关系是目标文件所依赖的文件列表,通常是源文件或其他目标文件。
  • 每个规则的格式通常为
 target: dependencies
     command
  • target 是目标文件或操作的名称,dependencies 是生成 target 所需的依赖文件列表,command 是生成 target 的命令。
      检查文件时间戳
    • 在执行 Makefile 时,Make 工具会检查每个目标文件和其依赖文件的时间戳,以确定哪些文件需要重新生成。
    • 如果目标文件不存在,或者其时间戳早于任何一个依赖文件的时间戳,那么 Make 工具会执行生成目标文件的命令。
    • 执行生成命令

      • 当确定需要重新生成目标文件时,Make 工具会执行该目标的生成命令。生成命令通常是编译源文件、链接目标文件或执行其他操作的命令。
      • Make 工具会按照 Makefile 中规定的顺序依次执行每个目标的生成命令,直到所有目标文件都被成功生成。
    • 递归处理依赖

      • 如果一个目标文件的依赖文件也是其他目标文件,则 Make 工具会递归处理这些依赖关系,确保所有依赖文件都被生成。
    • 增量构建

      • Make 工具会根据文件的时间戳判断哪些文件需要重新生成,从而实现增量构建。只有发生了变化的文件及其依赖文件才会重新生成,提高了构建效率。
    • 通过这样的方式,Makefile 提供了一种简洁而有效的方法来管理项目的构建过程,自动化了源代码的编译、链接和其他构建操作,使得项目的开发和维护更加高效和可靠。

      2.4 初阶Makefile文件

    • 这个版本的Makefile虽然有了一定的用途,但还是无法解决文件太多的问题。如何解决这一难题呢,我们接着向下看
    • 2.5 中阶Makefile文件


    • 虽然这个看起来已经比较完善了,但是依旧在文件太多的时候,会出现很多编译.c的文件,那有没有什么办法,让其不用这么麻烦呢
    • 2.6 后阶Makefile文件

    • CXX = gcc
      TARGET = aio
      OBJ = BintrayTree.o Queue.o test.o
      
      CXXFLAGS = -c -Wall
      
      $(TARGET) : $(OBJ)
      # $@ 表示目标文件
      # $^ 所依赖文件
      	$(CXX) -o $@ $^
      # % 是一个通配符,用于匹配任意长度的字符序列
      %.o : %.c
      # $< 第一个依赖文件
      	$(CXX) $(CXXFLAGS) $< -o $@
      
      # .PHONY防止出现于clear重名的文件而发生歧义
      .PHONY: clear
      # make clear 执行下面的命令(删除后缀.o和编译链接后的目标文件)
      clear:
      	rm -r *.o $(TARGET)

    • 这样我们,其实已经足够优化了,但是我们任然有可优化的地方,比如,我们可不可不列出链接的依赖文件,当然可以的

    • 2.7 终极版本

    • 到这里,我们就可以很清楚的认识到Makefile的优化过程
      CXX = gcc
      TARGET = aio
      #将后缀为.c的文件放入windcard中
      SRC = $(wildcard *.c)
      #路径替换,将SRC中的.c替换为.o
      OBJ = $(patsubst %.c, %.o, $(SRC))
      
      
      CXXFLAGS = -c -Wall
      
      $(TARGET) : $(OBJ)
      # $@ 表示目标文件
      # $^ 所依赖文件
      	$(CXX) -o $@ $^
      # % 是一个通配符,用于匹配任意长度的字符序列
      %.o : %.c
      # $< 第一个依赖文件
      	$(CXX) $(CXXFLAGS) $< -o $@
      
      # .PHONY防止出现于clear重名的文件而发生歧义
      .PHONY: clear
      # make clear 执行下面的命令(删除后缀.o和编译链接后的目标文件)
      clear:
      	rm -r *.o $(TARGET)


      3,Makefile的编码规则

    • 我们之前已经有所了解Makefile的编码规则,但是在这里我还是觉得有必要总体讲一下

      在编写 Makefile 时,遵循一些编码规则可以使其更加清晰、易于维护和跨平台。下面是一些常见的 Makefile 编码规则:

      1.缩进使用Tab键:
      Makefile 中命令行必须使用 Tab 键进行缩进,而不是空格。这是因为 Make 工具默认使用 Tab 键作为命令行的缩进标识,使用空格可能会导致 Make 解析错误。
      2.目标和依赖关系之间的冒号:
      目标(target)和依赖关系(dependencies)之间使用冒号(:)分隔。冒号前面是目标,后面是依赖关系。
      3.命令行前面的Tab键:
      在每个规则中,命令行必须以 Tab 键开头,表示该命令是该规则的执行命令。除了注释以外,任何其他以 Tab 键开头的行都被视为命令。
      4.变量使用大写字母:
      为了与命令和目标区分开,通常将变量使用大写字母命名。例如:CC = gcc。
      5.使用变量代替硬编码的命令和路径:
      使用变量来代替硬编码的命令和路径,使得 Makefile 更加灵活和可移植。例如,将编译器命令使用变量表示:CC = gcc,然后在规则中使用 $(CC) 来引用。

    • 6.使用伪目标:
      对于不产生实际文件的操作(如清理、安装等),使用伪目标(.PHONY)来定义。这样可以确保即使存在同名文件,也不会误导 Make 工具。例如:.PHONY: clean。
      7.注释使用 #:
      使用 # 符号来添加注释,使得 Makefile 更具可读性。注释可以帮助理解 Makefile 中每个规则的作用。
      8.模块化设计:
      将 Makefile 模块化,分成多个小的 Makefile 文件,然后通过 include 指令引入。这样可以提高 Makefile 的可维护性和可读性,减少重复代码。
      9.合理使用条件语句:
      可以使用条件语句(如 ifeq、ifdef 等)来根据不同的条件执行不同的规则或命令,以实现更灵活的构建过程。
      10.跨平台兼容性:
      考虑到不同平台下的路径分隔符和命令格式的差异,编写具有跨平台兼容性的 Makefile。可以使用自动化工具或条件语句来处理不同平台下的差异。

      遵循这些规则可以使 Makefile 更加规范、易读和易于维护,有助于提高项目的构建效率和可靠性。

      4,每期一问

    • 4.1 上期答案

      // 计算树的高度
      int getHeight(struct TreeNode* root) {
          if (root == NULL) {
              return 0;
          }
          int leftHeight = getHeight(root->left);
          int rightHeight = getHeight(root->right);
          return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
      }
      
      // 判断是否是平衡二叉树的辅助函数
      bool isBalancedHelper(struct TreeNode* root) {
          if (root == NULL) {
              return true;
          }
          int leftHeight = getHeight(root->left);
          int rightHeight = getHeight(root->right);
          if (abs(leftHeight - rightHeight) <= 1 && isBalancedHelper(root->left) && isBalancedHelper(root->right)) {
              return true;
          }
          return false;
      }
      
      // 判断是否是平衡二叉树
      bool isBalanced(struct TreeNode* root) {
          return isBalancedHelper(root);
      }

      4.2 本期问题. - 力扣(LeetCode)

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

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

相关文章

【杂七杂八】Huawei Gt runner手表系统降级

文章目录 Step1&#xff1a;下载安装修改版华为运动与健康Step2&#xff1a;在APP里进行配置Step3&#xff1a;更新固件(时间会很长) 目前在使用用鸿蒙4 111版本的手表系统&#xff0c;但是感觉睡眠检测和运动心率检测一言难尽&#xff0c;于是想到是否能回退到以前的版本&…

NFT Insider #131:Mocaverse NFT市值破3.5万ETH,The Sandbox 参加NFCsummit

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members&#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、…

element-ui手机区号+手机号

需求场景 项目开发中对方要求手机号带上全球区号 需求分析 项目使用的是若依前端框架&#xff0c;element-ui的框架。尝试使用已经网上的组件vue-country-intl等发现不怎么适配element-ui的样式等。这还不是关键的&#xff0c;关键的是弹窗中使用这些组件发现区号的下拉展示框…

OpenFeign快速入门 替代RestTemplate

1.引入依赖 <!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--负载均衡器--><dependency><groupId>org.spr…

本特利330103-03-09-10-02-00 PLC模块技术分析与应用探讨

本特利330103-03-09-10-02-00 PLC模块技术分析与应用探讨 一、引言 在工业自动化领域中&#xff0c;可编程逻辑控制器&#xff08;PLC&#xff09;作为核心控制设备&#xff0c;其性能的稳定性和可靠性直接关系到整个生产线的运行效率。本特利&#xff08;Bentley&#xff09;…

2.行为参数的演变过程

2.行为参数的演变过程 ​ 行为参数化是软件开发模式&#xff0c;可以处理频繁变更的需求。它让你把一个代码块准备好但不执行&#xff0c;以后可以被其他部分调用&#xff0c;也可以作为参数传递给另一个方法&#xff0c;推迟执行。这样&#xff0c;方法的行为就基于参数化的代…

一文深度剖析 ColBERT

近年来&#xff0c;向量搜索领域经历了爆炸性增长&#xff0c;尤其是在大型语言模型&#xff08;LLMs&#xff09;问世后。学术界开始重点关注如何通过扩展训练数据、采用先进的训练方法和新的架构等方法来增强 embedding 向量模型。 在之前的文章中&#xff0c;我们已经深入探…

领券拿外卖返利红包,最低0元吃外卖

小蚕荟是利用本地资源和自媒体优势构建的“本地生活服务”平台&#xff0c;总部位于杭州&#xff0c;旨在为用户提供热门的吃喝玩乐本地生活服务类产品。布局已覆盖杭州、南京、上海等一二线城市。 小蚕荟是一款专为用户吃外卖省钱的生活工具&#xff0c;单单可返利15元起&…

使用霍尔效应传感或磁场传感技术的应用

随着支持技术的增强&#xff0c;使用霍尔效应传感或磁场传感技术的应用目前已变得有效。本技术文档介绍了霍尔效应技术&#xff0c;并对应用进行了回顾&#xff0c;特别是区分霍尔传感器 IC 的主要类型以及它们可以支持的各种传感行为。此外&#xff0c;它还探讨了一些使能技术…

用智能插件(Fitten Code: Faster and Better AI Assistant)修改好了可以持久保存的vue3留言板

天际 第一修改是选项式&#xff1a; <!-- 模板结构 --> <template><div><textarea placeholder"请输入备注内容" v-model"newItem"></textarea><button click"addItem">添加</button><hr><…

HAL库点LED灯

文章目录 一、创建CubeMX项目操作步骤1.STM32CubeMX创建工程2.选择芯片3.Pinout & Configuration配置4.Clock Configuration配置5.Project Manager配置 二、实验&#xff08;一&#xff09;LED流水灯1.Keil修改代码2.实验现象3.keil波形仿真 &#xff08;二&#xff09;2只…

JVM学习-堆空间(一)

堆空间 每个进程&#xff08;JVM实例&#xff09;拥有唯一的方法区和堆空间&#xff0c;拥有唯一的Runtime实例(基于饿汉式方式)&#xff0c;线程共享进程的方法区和堆空间&#xff0c;每个线程拥有独立的程序计数器、本地方法栈和虚拟机栈。 一个JVM实例只存在一个堆内存&am…

MySQL主从复制(三):主从延迟

主备流程图&#xff1a; 谈到主备的复制能力&#xff0c;要关注的是上图中的两个黑色箭头。 一个箭头代表了客户端写入主库&#xff0c;另一个箭头代表的是sql_thread执行中转日志&#xff08;relay log&#xff09;。如果用箭头的粗细来代表并行度的话&#xff0c;那么真实情…

spring-boot集成slf4j(二)logback配置详解

一、configuration 根节点&#xff1a;configuration&#xff0c;作为顶级标签&#xff0c; 可以用来配置一些lockback的全局属性&#xff0c;常见的属性如下&#xff1a; &#xff08;1&#xff09;scan“true” &#xff1a;scan是否开启自动扫描&#xff0c;监控配置文件更…

【Crypto】看我回旋踢

文章目录 一、看我回旋踢二、知识点什么是ROT13&#xff1f;工作原理分析字符串格式 解题感悟 一、看我回旋踢 关键词回旋&#xff0c;盲猜ROT13 因为以 synt{ 开头&#xff0c;并以 } 结束&#xff0c;基本可以判断是ROT13 小小flag&#xff0c;拿下&#xff01; 二、知识点 …

Algoriddim djay Pro Ai for Mac:AI引领,混音新篇章

当AI遇上音乐&#xff0c;会碰撞出怎样的火花&#xff1f;Algoriddim djay Pro Ai for Mac给出了答案。这款专业的DJ混音软件&#xff0c;以AI为引擎&#xff0c;引领我们进入混音的新篇章。 djay Pro Ai for Mac的智能混音功能&#xff0c;让每一位DJ都能感受到前所未有的创作…

LAMDA面试准备(2024-05-23)

有没有学习过机器学习&#xff0c;提问了 FP-Growth 相比 Apriori 的优点 1. 更高的效率和更少的计算量&#xff08;时间&#xff09; FP-Growth 通过构建和遍历 FP-树 (Frequent Pattern Tree) 来挖掘频繁项集&#xff0c;而不需要像 Apriori 那样生成和测试大量的候选项集。具…

GQL 来了!ISO/IEC 正式发布 GQL 数据库国际标准!

历时四年筹备&#xff0c;超过20个国家的标准和技术专家参与制定&#xff0c;ISO/IEC GQL &#xff08;图查询语言&#xff09;标准于2024年4月12日正式发布&#xff01; 作为国际标准化组织&#xff08;ISO&#xff09;继 1987年 发布SQL后&#xff0c;唯一发布的数据库查询语…

数据库迁移——kettle开发01

背景&#xff1a;数据库的多种多样&#xff0c;在搭建项目之初&#xff0c;并没有详细考虑到数据库的建设&#xff0c;当增加配置不能满足业务场景需要时&#xff0c;这时候考虑到使用更高性能的数据库&#xff0c;如将MySQL更换为oracle数据库。或者在搭建新项目时&#xff0c…

【EXCEL_VBA_基础知识】08 在VBA中使用公式 ※

课程来源&#xff1a;王佩丰老师的《王佩丰学VBA视频教程》&#xff0c;如有侵权&#xff0c;请联系删除&#xff01; 目录 1. 函数在哪找&#xff1f; 1.1 工作表函数&#xff08;Application.WorksheetFunction.func&#xff09; 1.2 VBA函数 2. 常用VBA变量 3. 函数应用…