我们在前面学习了 makefile 中的相关知识,今天我们来看看在 makefile 中变量值的替换。它的替换是指使用指定字符(串)替换变量值中的后缀字符(串),语法格式为:$(var:a=b) 或 ${var:a=b}。注意:a> 替换表达式中不能有任何的空格;b> make 中支持使用 ${ } 对变量进行取值。格式如下

还有种便是变量的模式替换是指使用 % 保留变量值中的指定字符,替换其他字符。语法格式为:$(var:a%b=x%y) 或 ${var:a%b=x%y}。注意:a> 替换表达式中不能有任何的空格;b> make 中支持使用 ${ } 对变量进行取值。格式如下

规则中的模式替换如下

它的意义是通过 target-pattern 从 targets 中匹配子目标;再通过 prereq-pattern 从子目标生成依赖;进而构成完整的规则。我们来看看规则中的模式替换示例如下

下来我们通过代码来分析说明

src1 := a.cc b.cc c.cc
obj1 := $(src1:cc=o)test1 :@echo "obj1 => $(obj1)"src2 := a11b.c a22b.c a33b.c
obj2 := $(src2:a%b.c=x%y)test2 :@echo "obj2 => $(obj2)"

我们根据之前说的,在 obj1 中将会把 .cc 替换成  .o,把 obj2 中的 a11b.c a22b.c a33b.c 替换成 x11y x22y x33y。我们来看看编译器效果

我们看到结果和我们分析的是一样的。下来再来看看模式替换,将之前的 makefile 进行改编

CC := g++
TARGET := hello-makefile.out
OBJS := func.o main.o$(TARGET) : $(OBJS)$(CC) -o $@ $^$(OBJS) : %.o : %.c$(CC) -o $@ -c $^.PHONY : rebuild clean allrebuild : clean allall : $(TARGET)clean : $(RM) *.o $(TARGET)

我们来看看编译效果和之前的是一样的吗?

结果是一样的,这样的写的意义在哪呢?在大型的工程项目中,.c源文件是成千上万的。我们就可以利用模式替换来代替重复的工作,比如我们想添加一个 const.c 文件,便可以直接在第 3 行直接加上 const.o 就OK了。我们来试试看

const.c 源码

const char* g_hello = "hello makefile";

func.c 源码

#include "stdio.h"extern char* g_hello;void foo()
{printf("void foo() : %s\n", g_hello);
}

main.c 源码

extern void foo();int main()
{foo();return 0;
}

我们来看看编译效果

我们看到在编译的时候自动加上了编译 const.c 的命令,并最终正确打印出结果。这样感觉是不是很方便哈。那么在 makefile 中变量值还可以嵌套引用,就是一个变量名之中可以包含对其它变量的引用,嵌套引用的本质是使用一个变量来表示另外一个变量。格式如下

下来我们来说说命令行变量,在运行 make 时直接在命令行定义变量。命令行变量默认覆盖 makefile 中定义的变量,格式如下

那么命令行变量可以覆盖 makefile 中定义的变量,如果我们不小心手误覆盖了呢?这时 override 关键字就登场了。它是用于指示 makefile 中定义的变量不能被覆盖,变量的定义个赋值都需要使用 override 关键字。格式如下

下来我们来看看 makefile 中的  define 关键字,它是用于在 makefile 中定义多行变量,多行变量的定义从变量名开始带 endef 结束。可使用 override 关键字防止变量被覆盖,define 定义的变量等价于使用 = 定义的变量。格式入下

下来我们还是以代码为例来进行说明

hm := hello makefileoverride var := override-testdefine foo
I'm fool!
endefoverride define cmd@echo "run cmd ls ..."@ls
endeftest :@echo "hm => $(hm)"@echo "var => $(var)"@echo "foo => $(foo)"${cmd}

我们来编译看看结果

我们看到在没有被 override 关键字修饰的变量 hm 可以在命令行对它进行改写,但是变量 cmd 因为被 override 修饰了,因此就在命令行里面的修改是无效的。下来我们还说说 makefile 中的环境变量(全局变量),在 makefile 中能够直接使用环境变量的值。它是在定义了同名变量的话,环境变量将被覆盖,运行 make 时指定“-e”选项,优先使用环境变量。那么为什么要在 makefile 中使用环境变量呢?它的优势是环境变量可以在所有的 makefile 中使用,劣势是过多的依赖于环境变量便会导致移植性降低。那么变量在不同的 makefile 支架的传递方式有哪些呢?a> 直接在外部定义环境变量进行传递;b> 使用 export 定义变量进行传递;c> 定义 make 命令进行传递(一般推荐使用这种)。

下来我们还是以代码为例来进行分析

export var := D.T.Software
new := TDelphitest :@echo "make another file ..."@$(MAKE) -f makefile.4@$(MAKE) -f makefile.4 new:=$(new)

makefile.4 源码

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

我们来看看编译结果

我们看到在第一次的时候 new 为空,在第二次的时候 new 为我们设置的字符串。两次的 var 都传递过去了就是因为我们使用了 export 这个关键字。下来我们来看看目标变量(局部变量),其作用域只在指定目标及连带规则中。格式如下

那么模式变量便是目标变量的扩展,其作用域只在符合模式的目标及连带规则中。格式如下

下来还是以代码为例来进行分析说明

var := D.T.Software
new := TDelphitest : var := test-var
%e : override new := test-newtest : another@echo "test :"@echo "var => $(var)"@echo "new => $(new)"another :@echo "another :"@echo "var => $(var)"@echo "new => $(new)"rule :@echo "rule :"@echo "var => $(var)"@echo "new => $(new)"

我们来看看编译结果

因为 %e 的匹配规则,所以在目标 rule 中,它的 new 为 test-new,凡是跟 test 目标相关的 var 都是 test-var。通过对 makefile 中变量的学习,总结如下:1、makefile 中的变量值能够嵌套引用;2、命令行中定义的变量能够覆盖 makefile 中定义的变量;3、override 用于提示 makefile 中定义的变量不能被覆盖;4、define 用于在 makefile 中定义值为多行的变量;5、makefile 中的三种变量:a> 全局变量是指 makefile 外部定义的环境变量;b> 文件变量是在 makefile 中定义的变量;c> 局部变量是指定目标的变量。

欢迎大家一起来学习 makefile,可以加我QQ:243343083。

转载于:https://blog.51cto.com/12810168/2129140

变量的高级主题(六)相关推荐

  1. 【Makefile由浅入深完全学习记录7】Makefile中变量的高级主题下

    加qq:1126137994 微信:liu1126137994 一起学习更多技术~ 继续上一篇文章关于变量的学习! 1.环境变量(全局变量) -makefile中能够直接使用环境变量的值 如果make ...

  2. 【Makefile由浅入深完全学习记录6】Makefile中变量的高级主题上

    抓住基础,学习更多技术,迎接挑战,加qq:1126137994 微信:liu1126137994 一起学习更多技术~ 上一篇文章学习了makefile中的预定义变量的使用,今天来继续学习makefil ...

  3. Redis 高级主题之布隆过滤器(BloomFilter)

    最近计划准备整理几篇关于Reids高级主题的博文,本文整理的是关于布隆过滤器在Redis中如何应用,先来一张思维导图浏览全文. 1. 认识BloomFilter 1.1 原理 布隆过滤器,英文叫Blo ...

  4. Spread for Windows Forms高级主题(7)---自定义打印的外观

    2019独角兽企业重金招聘Python工程师标准>>> 表单打印的多个部分都可以进行自定义,大多数的自定义选项存在于PrintInfo对象中.大多数打印选项是在PrintInfo对象 ...

  5. Spread for Windows Forms高级主题(4)---自定义用户交互

    你可以从多方面自定义用户界面来自定义用户与Spread控件的交互方式.同时,你还可以自定义如何处理用户交互方式. 设置允许用户进行的操作 下面的列表总结了通过控件的数据区域,你可以授权用户进行的操作( ...

  6. 六西格玛的六大主题六步法

    ​ 六西格玛是一套具有"领导地位"的方法系统.我们把其关键要素提炼成六个主题.这些主题是有助于六西格玛在业务中发挥作用的初步指导.本书中将要介绍的许多工具和方法都支持这些原则. 主 ...

  7. ExoPlayer详解——高级主题(官方文档)

    ExoPlayer详解系列文章 ExoPlayer详解--入门(官方文档) ExoPlayer详解--媒体类型(官方文档) ExoPlayer详解--高级主题(官方文档) 一.数字版权管理 ExoPl ...

  8. Spread for Windows Forms高级主题(3)---单元格的编辑模式

    理解单元格的编辑模式 通常情况下,当终端用户双击单元格时,编辑控件将允许用户在该单元格中输入内容.在一个单元格中编辑的能力被称为编辑模式.一些属性和方法可以用来自定义编辑模式的使用. 当一个单元格处于 ...

  9. Spread for Windows Forms高级主题(5)---数据处理

    2019独角兽企业重金招聘Python工程师标准>>> 使用表单的API处理数据 你可以将数据以有格式或无格式字符串或者数据对象的形式填充到单元格中.将数据填充到单元格的最好方式取决 ...

最新文章

  1. PHP函数series,PHP: 简介 - Manual
  2. 人脸识别市场广 离不开政策支持及市场强劲需求
  3. 在哪里学python好-自学python好还是去培训机构好?
  4. 【采用】【科技金融】CART树现金贷风控策略
  5. java最后一个注解@SuppressWarnings
  6. mysql与web服务器之间的分离操作
  7. loadrunner代理录制脚本方法介绍
  8. 征服用计算机弹法,征服WIN7
  9. JFinal Db + Record模式 - ORM 框架
  10. JavaScript大杂烩17 - 性能优化
  11. mysql 多个库一起导出_MYSQL 导出多个库
  12. linux能运行英魂之刃吗,英魂之刃需要什么电脑配置
  13. freeSSL申请证书加阿里云域名解析加nginx配置
  14. UNIAPP中IOS和安卓应用热更新和整包更新app的方法
  15. UNI-APP_uni-app uni.getUserProfile微信授权,微信授权信息显示微信用户解决
  16. sap固定资产号码范围_SAP 固定资产的配置与逻辑
  17. Outlook打不开附件
  18. 腾讯企点QTrade 金融OTC合规解决方案
  19. 计算机基础图文混排笔记,计算机基础知识与基本操作——图文混排课件.doc
  20. oracle分区表的作用

热门文章

  1. Deep TEN: Texture Encoding Network
  2. 编译器是怎样工作的?用lex和yacc 写一个计算器(2)
  3. jQuery——获取当前索引值
  4. Javascript 滑动效果菜单 TreeView [Javascript]
  5. 【更新指南】Aspose.CAD for Java更新至v19.5版本,实施导出的“警告”通知机制!...
  6. HashMap、HashTable、ConcurrentHashMap、HashSet区别 线程安全类
  7. 具体分析Struts工作流程
  8. pc站转手机站的首页(扫二维码)
  9. 算法笔记 --- 记忆搜索算法 --- 动态规划算法
  10. 【乱】乱,乱,乱,android真乱!