Makefile基础教程(变量的高级主题,变量的拓展)

news2024/11/26 13:45:03

文章目录

  • 前言
  • 一、变量值的替换
    • 1.简单替换
    • 2.模式替换
      • 1.变量的模式替换
      • 2.规则中的模式替换
  • 二、变量值的嵌套
  • 三、命令行变量
  • 四、define和override
    • 五.环境变量
    • 六.局部变量
    • 七.模式变量
  • 总结


前言

本篇文章将给大家讲解一下变量的高级主题,变量的拓展,这些主题可以让你更加灵活地编写和维护 Makefile。

一、变量值的替换

1.简单替换

变量替换语法格式:

$(var:a=b)

其中,a 可以是一个字母,表示 var 中每个单词结尾的这个字母。b 则是替换的字符串。它会替换每个单词结尾的 a(如果有的话)。

这个语法通常用于修改一些表示文件路径或文件名的变量,以方便进行操作。

这里给出一个例子:

src := a.bc b.bc c.bc
obj := $(src:bc=oo)


test:
	@echo "src=>$(src)"
	@echo "obj=>$(obj)"

运行结果:
在这里插入图片描述

2.模式替换

1.变量的模式替换

在变量中使用模式替换就是将%前面和后面的换成我们想要替换的值。

src2 := a11b.c a22b.c a33b.c
src3 := $(src2:a%b.c=x%y)

test : 
	@echo "src3=>$(src3)"

运行结果:
在这里插入图片描述

2.规则中的模式替换

在工程开发中会有很多个需要被编译的文件,那么我们肯定不会和之前一样一个目标对应一个依赖,这样写是非常低效的,当要修改时也是非常困难的,所以在这里我们采取模式替换的方式来编写。

CC := gcc
TARGET := hello
OBJS := hello.o func.o


TARGET : $(OBJS)
	$(CC) -o $@ $^

$(OBJS) : %.o : %.c
	$(CC) -c -o $@ $<

.PHONY: clean rebuild all

rebuild : clean all

all : TARGET

clean :
	$(RM) *.o TARGET

二、变量值的嵌套

在Makefile中,变量可以嵌套使用,以方便进行更加复杂的操作。嵌套变量的语法格式如下:

$(first_var$(second_var))

其中,first_var和second_var都是变量名。Make会首先展开$(second_var),以获取second_var的值,然后再将其插入到$(first_var)中,以展开为最终的变量值。

下面举一个例子:

x := y
y := z
a := $($(x))

test3 :
	@echo "x=>$(x)"
	@echo "y=>$(y)"
	@echo "a=>$(a)"

运行结果:
在这里插入图片描述

三、命令行变量

在Makefile中,命令行变量指的是通过make命令行传递给Makefile的参数。这些参数可以用于控制Makefile执行过程中的一些行为,例如指定编译器、调试选项等等。命令行变量的定义方式如下:

make <variable>=<value>

其中,variable 是命令行变量的名称,value是其值。在Makefile中,可以使用$(variable)来引用这个命令行变量的值。

这里举一个例子说明一下:

test := hello makefile

all : 
	@echo $(test)

运行结果:
在这里插入图片描述

四、define和override

在 Makefile 中,define 和 override 是两种比较重要的关键字。

define 关键字用来定义一个多行字符串,它的语法格式如下:

define <variable_name>
    <string>
endef

其中,<variable_name> 是定义的变量名,<string> 是这个变量名所对应的字符串,endef 表示字符串定义的结束标志符。事实上,define 定义的是一个多行的文本字符串,可以是命令、参数或者其他内容。定义后,这个变量就可以在 Makefile 的其他地方使用。

举个例子,你可以这样定义一个变量:

define MY_VARIABLE
    echo "hello world"
endef

然后在 Makefile 的其他地方,使用 $(MY_VARIABLE) 得到 “hello world” 的输出。

输出结果:
在这里插入图片描述

override关键字用于指示makefile中定义的变量不能被覆盖。

我们尝试着使用命令行来替换这个override 定义的变量:

define MY_VARIABLE
    "hello world"
endef

override var := hello

all : 
	@echo $(MY_VARIABLE)
	@echo $(var)

运行结果:
在这里插入图片描述
这里可以发现使用override定义的变量无法被命令行参数覆盖。

五.环境变量

在 Makefile 中,可以使用环境变量来传递参数或设置选项。环境变量是一种全局变量,对于整个 shell 都是可见的。Makefile 中可以访问这些环境变量,并在其中读取或设置值。

1.CFLAGS:编译选项的环境变量,可以用来设置编译器选项,例如 -Wall 和 -O2 等。

2.LDFLAGS:链接选项的环境变量,可以用来设置链接器选项,例如 -L 和 -l 等。

3.CC:编译器的环境变量,可以用来指定使用的编译器。例如 CC=gcc 表示使用 gcc 编译器。

使用export定义环境变量

一次定义一个变量和它的值:

export VARIABLE=value

示例代码:

test:
	@echo "var => $(var)"

定义环境变量:
在这里插入图片描述

运行结果:

在这里插入图片描述
这里定义的环境变量不仅可以在这个makefile当中使用也可以在其他的makefile中使用。

环境变量也能够被命令行变量覆盖:
在这里插入图片描述
使用-e选项可以优先使用环境变量:

var := abc

test :
	@echo "var =>$(var)"

使用make -e选项运行结果:
在这里插入图片描述

六.局部变量

在 Makefile 中,可以使用局部变量(也称为自动化变量),用于临时存储一些值,例如命令行参数、编译器选项和源文件列表等。和全局变量不同,局部变量只在当前的规则中有效。

test : test1

test : var1:=test-var1

test : test1
	@echo "var1=>$(var1)"

test1 :
	@echo "var1=>$(var1)"

test2 : 
	@echo "var1=>$(var1)"

运行效果:

从结果可以看出局部变量只在指定目标和连带规则中有效。
在这里插入图片描述

七.模式变量

模式变量则是一种构建在模式规则之上的变量类型,它可以让我们更方便地定义和管理模式规则的组合。

var := D.T.Software
new := TDelphi

%e : override new:= test-new
	
test : rule
	@echo "var => $(var)"
	@echo "new => $(new)"
	
rule :
	@echo "var => $(var)"
	@echo "new => $(new)"

运行结果:
从结果中可以看出模式变量作用域只在符合模式的目标及连带规则中。
在这里插入图片描述

总结

本篇文章知识点较多,这些内容也是makefile中比较重要的一些内容大家看完后要多加练习。

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

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

相关文章

详解C++类和对象(下篇)

目录 一&#xff0c;再谈构造函数 1.1 构造函数体赋值 1. 2 初始化列表 1.21 自定义类型成员 1.22 const 成员变量 1.23 引用成员变量 1. 24 初始化列表的“坑” 1. 3 explicit 关键字 二&#xff0c;static 成员 2.1 概念 2.2 特性 三&#xff0c; 友元 3.…

阿里云数据库RDS MySQL Serverless测评

文章目录 1. 背景2. 概念3. 操作步骤3.1 购买产品3.2 配置RDS账号3.3 设置网络访问权限3.4 连接实例 4. 与自建数据库相比的优势4.1 弹性设置4.2 监控比较直观4.3 报警比较灵活4.4 备份更安全、更方便 5. 总结 1. 背景 作为一枚程序员&#xff0c;在日常工作中少不了跟云产品打…

Linux C/C++并发编程实战(0)谈谈并发与并行

作为并发编程的第一讲&#xff0c;比较轻松&#xff0c;我们先来谈谈什么是并发和并行。 并发&#xff08;Concurrency&#xff09;是指一个处理器同时处理多个任务。 并行&#xff08;Parallelism&#xff09;是指多个处理器或者是多核的处理器同时处理多个不同的任务。 并发…

git rebase的理解

首先看下图 比如提价了三次&#xff0c;都是同一个文件的修改&#xff0c;有三次commit的信息 想把提交的版本信息变的好看一点&#xff0c;或者变成一次提交信息 // 这个表示要查看提交的三个版本并进行合并 git rebase -i HEAD~~~// 如何要合并多个版本 git rebase -i HEA…

媲美ChatGPT4的免费工具来了!傻瓜式教程不用魔法也能使用!

嗨呀 又是元气满满的一周啦 废话不多说直接进入正题&#xff0c;仅在注册时可能需要使用一些科学方法&#xff0c;使用完全无限制 优势 对中文的支持非常强大 无需魔法上网 不受限制 免费&#xff01;&#xff01;&#xff01; 实测优于ChatGPT3.5&#xff0c;略逊于4.0&…

vue-7:组件库(移动端vant)(PC端element)

移动端vant 插件安装&#xff08;按需导入&#xff09; 重启生效 # 通过 npm 安装 npm i unplugin-vue-components -D# 通过 yarn 安装 yarn add unplugin-vue-components -D 导入基于 vite 的项目&#xff1a; 如果是基于 vite 的项目&#xff0c;在 vite.config.js 文件中…

Git详细用法:Git概述 安装 常用命令 分支操作 团队协作 、GitHub、idea集成Git、idea集成GitHub、Gitee 码云、GitLab

0 课程介绍 说明&#xff1a; 在公司想要使用idea集成git&#xff1a; 首选需要下载安装Git&#xff08;查看第2章&#xff09;之后在中设置用户签名&#xff08;查看3.1&#xff09;然后在idea中集成Git&#xff08;查看第7章&#xff09;… 0.1 学习目标 第1章 Git 概述 …

高级语句(二)

一、VIEW&#xff08;视图&#xff09; 1、 概念 可以被当作是虚拟表或存储查询 视图跟表格的不同是&#xff0c;表格中有实际储存资料&#xff0c;而视图是建立在表格之上的一个架构&#xff0c;它本身并不实际储存资料。 临时表在用户退出或同数据库的连接断开后就自动消…

关于预处理器 sass 的超全用法

随着用户需求的增加&#xff0c;应用于页面的 css 代码越来越复杂越发臃肿难以维护&#xff0c;但是又没有 css 的替代品&#xff0c;css 预处理器作为 css 的扩展&#xff0c;出现在前端技术中。 sass 是 css 预处理器中常用的一种&#xff0c;它是一种动态样式语言&#xff0…

基于html+css图展示58

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

C++系列九:预处理功能

预处理功能 1. 宏定义2. 文件包含3. 条件编译4. 代码注释5. 预处理器注意事项6. 总结 预处理器是 C 编译器提供的一个工具&#xff0c;允许程序员在编译之前对源代码文件做出修改。它主要是根据在代码中命名实体的定义&#xff08;如宏、条件编译指令&#xff09;、源文件调用等…

分布函数有什么意义?

累积分布函数&#xff08;CDF&#xff09;有什么意义&#xff1f; 参考文献&#xff1a;姜咏梅. 浅析分布函数的意义与应用[J]. 科学与财富,2014(10):207-207,208. DOI:10.3969/j.issn.1671-2226.2014.10.183. 关于PMF、PDF、CDF的介绍&#xff0c;移步至我的笔记&#xff1a…

【SPSS】因子分析详细操作教程(附案例实战)

🤵‍♂️ 个人主页:@艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞👍🏻 收藏 📂加关注+ 目录 因子分析 因子分析案例 因子分析

Clion开发STM32之OTA升级模块(一)

什么是OTA 百度百科解释个人理解&#xff1a;就是不通过烧录的方式&#xff0c;通过串口、网口、无线对主板运行的程序进行升级。减少后期的一个维护迭代程序的一个成本。 STM32的OTA升级模块的一个设计 程序启动的一个框架流程图(大致流程) FLASH的一个划分框图 BootLoader…

Nautilus Chain 或成未来最好的链上隐私生态

Nautilus Chain 目前仍旧处于测试网阶段&#xff0c;作为目前行业内首个&#xff0c;也是最受关注的 Layer3 模块化链&#xff0c;Nautilus Chain 在测试网早期阶段&#xff0c;整体就有着十分出色的数据表现。而该链有望在 6 月上线主网&#xff0c;面向更为广泛的开发者、用户…

分布式数据库设计与实现

分布式数据库设计与实现 摘要背景二期项目包括数据库选型分布式数据库设计数据集成测试部署分布式数据库扩展阅读 摘要 : 本文论述《金蚕工程》的分布式数据库的设计和实现。该项目的设计目标是实现企业间茧、丝等的合同交易&#xff08;交易规则和期货交易一样&#xff09;、…

【springcloud 微服务】springcloud openfeign使用详解

目录 一、前言 二、openfeign介绍 2.1 openfeign介绍 2.2 openfeign优势 三、Spring Cloud Alibaba整合OpenFeign 3.1 前置准备 3.2 代码整合过程 3.2.1 添加feign依赖 3.2.2 添加feign接口类 3.2.3 调整调用的方法 3.2.4 核心配置文件 3.2.5 接口模拟测试 四…

libevent介绍和使用

libevent介绍 libevent 是一个开源的事件通知库&#xff0c;它提供了一个跨平台的抽象接口&#xff0c;libevnet处理的事件包括网络IO事件&#xff0c;定时事件以及信号事件。它可以在不同的操作系统上使用&#xff0c;包括Linux、Windows和Mac OS X等。libevent 的主要目的是…

最全面的ChatGPT镜像网址:值得三连~~~

ChatGPT是一个基于人工智能的聊天机器人&#xff0c;它可以与用户进行自然语言交互。ChatGPT使用了最新的自然语言处理技术&#xff0c;包括深度学习和神经网络&#xff0c;以便更好地理解用户的意图和回答用户的问题。 ChatGPT可以回答各种问题&#xff0c;包括但不限于常见问…

69.建立手风琴组件第二部分

上节课我们构建了下图一样的基本样式&#xff0c;这节课我们来构建布局&#xff01; ● 建立阴影&#xff0c;并生成grid布局 .item {box-shadow: 0 0 32px rgba(0,0,0,0.1);#添加外阴影&#xff0c;为半透明黑色&#xff0c;大小为0&#xff0c;0&#xff0c;32pxpadding: 24p…