Makefile的入门学习

一、Makefile的入门学习

编译工具及构建工具介绍

在之前的课程,都是直接使用gcc对代码进行编译,这对简单的工程是可以的,但当我们遇到复杂的工程时,每次用gcc等编译工具去操作就会显得很低效。因此make工具就出现了, make的出现是为了解决手动编译和链接大型工程的问题,它可以避免重复的工作,提高效率,保证正确性。make工具就根据makefile中的命令进行编译和链接的。但是当工程非常大的时候,手写makefile也是非常麻烦的,如果换了个平台makefile又要重新修改,因此更高级的一些构建系统或者工具工具像cmake、qmake、ninja和auto make就出现了,它们可以根据一些配置文件来自动化编译和链接软件项目。

在这里插入图片描述

  • cmake是一个跨平台的构建系统,它可以根据CMakeLists.txt中的指令来生成不同平台和工具的工程文件,例如Makefile、Visual Studio解决方案、Ninja文件等。cmake可以支持多种语言和多种架构,它还提供了一些高级功能,如测试、打包、安装等。
  • qmake是一个用于Qt项目的构建系统,它可以根据.pro或.pri中的指令来生成Makefile或其他形式的工程文件。
  • ninja是一个小巧而快速的构建工具,它可以根据ninja.build中的规则来执行编译和链接命令。ninja主要关注于性能和效率,它可以利用多核处理器和并行处理来加速构建过程。ninja通常不需要用户直接编写配置文件,而是由其他构建系统(如cmake)来生成。
  • auto make是一个用于生成Makefile.in文件的工具,Makefile.in是一种用于auto conf的配置文件格式,auto conf是一个用于生成configure脚本的工具。configure脚本是一个用于检测系统环境并生成最终的Makefile文件的脚本Makefile.am是一种用于auto make的配置文件格式,它包含了一些指令和变量,用于定义程序或库的源文件、目标文件、依赖关系和编译选项等。
  • make是一个经典而通用的构建工具,它可以根据Makefile中的规则来执行编译和链接命令。make可以支持多种平台和工具,它还提供了一些高级功能,如条件判断、函数调用、模式匹配。

二.Makefile的简单讲解

  1. 编译的四个阶段

    回顾下编译的四个过程:预处理(Pre-Processing)、编译(Compiling)、汇编 (Assembliang)、链接(Linking)。

    在这里插入图片描述

  2. Makefile的规则

    TARGET....: prerequisites...
    <tab缩进>command
    <tab缩进>...
    <tab缩进>...
    

    TARGET 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签( Label),对于标签这种特性,在后续的讲“伪目标”中会有叙述。prerequisites 就是,要生成那个 target 所需要的文件或是目标。command 也就是 make 需要执行的任意shell命令。

    Makefile一个示例:

    #这是一个Makefile
    debug:@echo "hello world"
    

    Makefile采用#进行一行注释,采用\作为续行符。make后,打印hello world@的作用是不打印echo指令本身。

    如果,我们要编译下面这个最简单的例子:

    #include <stdio.h>
    int main(int argc, char *argv[])
    {printf("hello world!\n");return 0
    }
    

    Makefile修改如下:

    debug :@echo "hello world"hello :gcc -o hello hello.cclean :@rm -f hello.PHONY: clean
    

    在终端只输入make,执行第一个命令即make debugmake hello相当于在终端输入gcc -o hello hello.c,同理make clean相当于在终端输入rm -f hello

    .PHONY伪目标,如果一个目标和一个实际文件同名,那么make会认为该目标已经是最新的,不需要重新生成,也不会执行其命令。通过将目标声明为伪目标,可以避免这种情况,强制执行其命令。

  3. 变量赋值和预定义变量

    Makefile中的变量赋值运算符有四种,分别是=:=?=+=

    • = 表示延迟展开赋值,即变量的值是在使用时才确定,可能会受到后面的赋值影响。
    • := 表示直接赋值,即变量的值是在定义时就确定,不会受到后面的赋值影响。
    • ?= 表示条件赋值,即只有当变量没有被赋值时,才使用等号后面的值作为变量的值。
    • += 表示追加赋值,即将等号后面的值追加到变量原来的值之后,形成一个新的值。
    • $@ 表示生成的目标文件;$^ 表示所有的依赖文件;$< 代表第一个依赖文件。

    示例:

    TARGET = hello
    CC := gcc
    TARGET1 := $(CC) $(TARGET)#'='为延迟赋值 ':='为立即赋值
    CC ?= g++# "?=" 表示如果前面没有定义CC,就定义为g++,如果定义了CC,就不定义了
    CC += -g#'+='为追加。在CC后面追加-g$(TARGET): hello.c$(CC) -o $@ $^compile: $(TARGET)clean:@rm -rf $(TARGET_DIR).PHONY: clean compile
    

    make compile编译的结果为gcc -g -o hello hello.c

三.Makefile的一些常见函数

Makefile函数的基本格式是: ( ) 或者是 ( )或者是 ()或者是{ },其中,是函数名,是函数的参数,参数之间要用逗号分隔开,参数和函数名之间使用空格分开。调用函数的时候要使用字符“$”,后面可以跟小括号或者大括号。

  1. wildcard 通配符

    Makefile中的wildcard 是一个函数,用于扩展通配符,返回与通配符匹配的文件列表。通配符是一种特殊的字符,可以表示多个文件名或目录名,常见的通配符有 * 和 ?,分别表示任意长度的任意字符和单个任意字符。格式如下:

    #格式:$(wildcard argments)
    #示例:
    SRC = $(wildcard src/*.c)
    #SRC赋值为src目录中的所有.c文件
    
  2. shell

    shell为在终端执行后面的命令并返回结果。

    #格式:$(shell <cmd> <args>)
    #示例:
    SRC = $(shell find . -name *.c)
    #找到当前文件下的所有.c文件
    
  3. patsubst替换函数

    #格式:$(patsubst pattern,replacement,text)
    #`patsubst`将text中的pattern全部替换为replacement,pattern和replacement可以包含%通配符。
    #示例:
    SRC = $(wildcard src/*.c)
    OBJ = $(patsubst %.c,%.o,$(SRC))
    #将SRC中的所有.c文件替换为.o文件
    
  4. subst替换函数

    #格式:$(subst from,to,text)
    #subst和patsubst类似,是将text中的from替换为to,并返回修改后的字符串。
    #示例:
    $(subst ee,EE,feet on the street)
    #返回结果:fEEt on the strEEt
    
  5. dir

    #格式:$(dir NAMES...)
    #dir函数是一个用于从文件名序列中提取目录部分的函数。
    #示例:
    SRC = $(wildcard ./src/*.c)
    OBJ = $(subst .c,,$(SRC))
    TARGET := $(patsubst ./src/%,./obj/%,$(subst .c,,$(SRC)))
    TARGET_DIR = $(dir $(TARGET))
    #SRC为src目录下的所有.c文件,OBJ为将SRC的结果去掉.c,TARGET将OBJ的结果的目录从src变为obj,最后通过TARGET_DIR得到TARGET中的目录,即:./obj/
    
  6. suffix

    #格式:$(suffix <names...>)
    #suffix为从文件名序列中取出各个文件名的后缀,返回文件名序列的后缀序列,如果文件没有后缀,则返回空子串。
    #示例:
    $(suffix ./src/foo.c ./src-1.0/bar.c hacks)
    #返回结果:.c .c
    
  7. basename

    #格式:$(basename <names...>)
    #从文件名序列中取出各个文件名的前缀部分,返回文件名序列的前缀序列,如果文件没有前缀,则返回空字串。
    #示例:
    $(basename ./src/foo.c ./src-1.0/bar.c hacks)
    #返回结果:./src/foo ./src-1.0/bar hacks
    
  8. addsuffix

    #格式:$(addsuffix <suffix>,<names...>)
    #把后缀加到每个单词后面,返回加过后缀的文件名序列。
    #示例:
    $(addsuffix .c,foo bar)
    #返回结果:foo.c bar.c
    
  9. addprefix

    #格式:$(addprefix <prefix>,<names...>)
    #把后缀加到每个单词后面,返回加过后缀的文件名序列。
    #示例:
    $(addprefix src/,foo bar)
    #返回结果:src/foo src/bar
    
  10. foreach循环函数

    #格式:$(foreach <var>,<list>,<text>)
    #把list中使用空格分割的单词依次取出并赋值给变量var, 然后执行text表达式。
    #示例:
    #$(I_FLAGS)可以-I包含INCLUDE里的库
    INCLUDE = /usr/inclue \/usr/local/inclue
    I_FLAGS := $(foreach var,$(INCLUDE),-I$(var))
    @echo $(I_FLAGS)
    #输出结果:-I/usr/include -I/usr/local/include
    
  11. 条件判断

    • ifeq/ifneq语句:

      #ifeq语句:判断参数是否相等,相等为true,否则是false。
      ifeq (arg1, arg2)#arg1 arg2 相等执行这里的语句
      else#arg1 arg2 不相等执行这里的语句
      endif#ifneq语句:判断参数是否不等,不等为true,否则为false。
      ifneq (arg1, arg2)#arg1 arg2 不相等执行这里的语句
      else#arg1 arg2 相等执行这里的语句
      endif
      
    • ifdef/ifndef语句:

      #ifdef语句:判断参数是否有值,有值为true,否则是false。
      ifdef var#如果定义了var,执行这里的内容
      else#如果没定义var,执行这里的内容
      endif#ifndef:判断参数是否没有值,没有值为true,否则为false。
      infdef var#如果没定义var,执行这里的内容
      else#如果定义var,执行这里的内容
      endif
      

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

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

相关文章

LeetCode1137第N个泰波那契数

题目描述 泰波那契序列 Tn 定义如下&#xff1a; T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2给你整数 n&#xff0c;请返回第 n 个泰波那契数 Tn 的值。 解析 递归应该会超时&#xff0c;可以用循环&#xff0c;或者官方解法的矩阵的幂。 public int tr…

(4) qml动态元素

文章目录 概述注意 动画元素变化的策略Animation on 变化behavior on⽤standalone animation注意 缓冲曲线&#xff08;Easing Curves&#xff09;动画分组 概述 这⼀章介绍如何控制属性值的变化&#xff0c;通过动画的⽅式在⼀段时间内来改变属性值。这项技术是建⽴⼀个现代化…

获取(复制)网页上的文字

获取&#xff08;复制&#xff09;网页上的文字 今天在搜索历史课本上一段文言文的翻译时&#xff0c;找到的网页&#xff0c;屏蔽了右键&#xff0c;不能选择&#xff0c;当然不让复制啦。对于这样的网站可以采用如下方法进行数据的获取&#xff0c;以chrome为例。 1、网页另…

keil5常见使用技巧记录(更新)

快速到函数定义 F12或自己定义快捷键CTRLK&#xff08;个人设定&#xff09; 修改快捷键 下图实例是快速跳转到函数或变量定义位置&#xff0c;当然可以定义其他功能快捷键&#xff0c;如快速注释多行&#xff0c;快速消除注释等 标记全部查找变量的蓝色框取消 CTRLshiftF2…

【YOLOv10改进[Backbone]】图像修复网络AirNet助力YOLOv10目标检测效果 + 含全部代码和详细修改方式 + 手撕结构图 + 全网首发

本文带来的是图像复原网络AirNet&#xff0c;它由基于对比度的退化编码器( CBDE )和退化引导的恢复网络( DGRN )两个模块组成。可以在一个网络中恢复各种退化图像。AirNet不受损坏类型和级别的先验限制&#xff0c;仅使用观察到的损坏图像进行推理。本文中将使用图像修复网络Ai…

使用Python绘制瀑布图

使用Python绘制瀑布图 瀑布图效果代码 瀑布图 瀑布图&#xff08;Waterfall Chart&#xff09;是一种数据可视化工具&#xff0c;用于展示累积数值的变化&#xff0c;尤其适合于展示随时间或过程中的增减变化。它通常用于财务分析&#xff0c;如展示收入、支出和净利润的变化过…

【离散数学】数理逻辑集合论知识点汇总

期末题型&#xff1a; 一、 单选题&#xff08;每题2分&#xff0c;10题共20分&#xff09; 命题判定、哈斯图边计算等 二、 填空题&#xff08;每空1分&#xff0c;共20分&#xff09; 与非和或非的表示等 三、 简答题&#xff08;10题&#xff0c;每题6分&#xff0c;共60分&…

安装禅道,帮助测试,测试打磨项目精度。

先检查docker版本。 sudo docker network create --subnet172.172.172.0/24 zentaonet sudo docker run --name zentao2 -p 8080:80 -p 3307:3306 --networkzentaonet --ip 172.172.172.3 -e MYSQL_INTERNALtrue -v /media/cykj/3T/ze…

【十年java搬砖路】Jumpserver docker版安装及配置Ldap登陆认证

Jumpserver docker 安装启动教程 拉取镜像 docker pull JumpServer启动进行前确保有Redis 和Mysql 创建jumperServer数据库 在MYSQL上执行 创建数据库 登陆MYSQL mysql -u root -p 创建Jumperserveri库 create database jumpserver default charset utf8mb4;可以为jumperSe…

【软件开发】Java学习路线

本路径视频教程均来自尚硅谷B站视频&#xff0c;Java学习课程我已经收藏在一个文件夹下&#xff0c;B站文件夹同时会收藏其他Java视频&#xff0c;感谢关注。指路&#xff1a;https://www.bilibili.com/medialist/detail/ml3113981545 2024Java学习路线&#xff08;快速版&…

揭秘YAML:Python中的PyYAML应用

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 本章节介绍YAML文件格式的操作&#xff0c;通过Python的第三方库 PyYaml 来实现文件操作&#xff0c;在 Pyhon 代码中无论读取还是写入&#xff0c;都是使用…

【机器学习】逻辑回归:原理、应用与实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 逻辑回归&#xff1a;原理、应用与实践引言1. 逻辑回归基础1.1 基本概念1.2 Sig…

视频汇聚EasyCVR安防系统对接公安部GA/T 1400视图库布控、告警、订阅流程描述

随着信息技术的飞速发展&#xff0c;视频监控在公共安全领域的应用越来越广泛&#xff0c;对于视频监控系统的要求也日益严格。为了满足公安系统对视频图像信息应用的高标准需求&#xff0c;视频汇聚平台EasyCVR视频监控系统全面支持GA/T 1400标准协议&#xff0c;为公安部门提…

基于JSP的母婴用品网站系统

你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果有需求可以文末加我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;IDEA/Eclipse、Navicat、Maven 系统展示 首页 管理员功能界面 用户功能界面 前台首页功能界面 …

Java开发-面试题-0003-List、Set 和 Map的区别

Java开发-面试题-0003-List、Set 和 Map的区别 更多内容欢迎关注我&#xff08;持续更新中&#xff0c;欢迎Star✨&#xff09; Github&#xff1a;CodeZeng1998/Java-Developer-Work-Note 技术公众号&#xff1a;CodeZeng1998&#xff08;纯纯技术文&#xff09; 生活公众…

BioPorto胰高血糖素样肽-1抗体(GLP-1)

丹麦BioPorto Diadnostics公司致力于提供世界领先的GLP-1抗体。基于结合GLP-1位点的不同&#xff0c;他们筛选出了不同的抗GLP-1抗体。有的抗体可以同时结合GLP-1的活性形式和非活性形式&#xff0c;有的专门结合生物活性形式的GLP-1。在开发和检测GLP-1相关治疗的过程中&#…

deepin 社区月报 | 2024年5月,deepin V23 RC 正式发布,校园联盟走进海外!

deepin&#xff08;深度&#xff09;社区5月总览 2024年5月&#xff0c;有1052位小伙伴加入了deepin&#xff08;深度&#xff09;社区大家庭&#xff0c;目前共有论坛伙伴154962位&#xff1b; 在5月&#xff0c;deepin V23 正式发布了RC版本&#xff0c;在本次发布的RC版本…

最新版点微同城源码34.7+全套插件+小程序前后端

带全套插件 自己耐心点配置一下插件 可以H5可以小程序 一款专属的同城服务平台对于企业和个人而言&#xff0c;无疑是拓展业务、提升服务品质的重要一环。点微同城源码搭配全套插件&#xff0c;以及完善的小程序前后端&#xff0c;将为您的业务发展提供强大支持 源码免费下载…

黑马程序员——Spring框架——day04——SpringMVC基础

目录&#xff1a; SpringMVC简介 背景SpringMVC概述技术体系定位快速入门 目的需求步骤代码实操测试工具 PostMan简介PostMan安装PostMan使用知识点总结请求与参数处理 请求路径 环境准备问题分析解决方式请求方式 环境准备技术分析参数 基本数据类型POJO嵌套POJO数组集合&…

【JAVA |总结】JAVASE基础大总结(含思维导图)

✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天开心哦&#xff01;✨✨ &#x1f388;&#x1f388;作者主页&#xff1a; &#x1f388;丠丠64-CSDN博客&#x1f388; ✨✨ 帅哥美女们&#xff0c;我们共同加油&#xff01;一起…