变量的高级主题(六)

我们在前面学习了 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 [email protected] $^

$(OBJS) : %.o : %.c
    $(CC) -o [email protected] -c $^

.PHONY : rebuild clean all

rebuild : clean all

all : $(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 makefile

override var := override-test

define foo
I'm fool!
endef

override define cmd
    @echo "run cmd ls ..."
    @ls
endef

test :
    @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 := TDelphi

test :
    @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 := TDelphi

test : var := test-var
%e : override new := test-new

test : 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。

原文地址:http://blog.51cto.com/12810168/2129140

时间: 2024-08-01 10:43:02

变量的高级主题(六)的相关文章

第7课 - 变量的高级主题(下)

第7课 - 变量的高级主题(下) 1. makefile中的环境变量(全局变量) (1)makefile中使用系统环境变量 makefile中可以直接使用系统中的环境变量(系统环境变量的本质就是全局的键值对) 如果 makefile 中定义了同名变量,那么环境变量将会被覆盖 运行 make 时指定 "-e" 选项,优先使用环境变量 1 # 测试makefile中环境变量的使用 2 3 # 例1 4 PATH := my path 5 6 test : 7 @echo "PAT

web前端之JavaScript高级程序设计六:事件

web前端之JavaScript高级程序设计六:事件 JavaScript 与 HTML 之间的交互是通过事件实现的.事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间.可以使用侦听器(或处理程序)来预订事件,以便事件发生时执行相应的代码.这种在传统软件工程中被称为观察员模式的模型,支持页面的行为(JavaScript 代码)与页面的外观(HTML 和 CSS 代码)之间的松散耦合. 事件流: 事件流描述的是从页面中接收事件的顺序.但有意思的是, IE 和 Netscape 开发团队居然提出了

Python——类的高级主题

介绍关于类的一些高级主题,这些是可选的,在Python应用程序中,不会常常遇到. ========================================================================== slots实例 将字符串属性名称顺序赋值给特殊的__slots__类属性.就能够限制类的实例将有的合法属性集. 这个特殊属性通常是在class语句顶层内将字符串名称顺序赋值给变量__slots__而设置:仅仅有__slots__列表内的这些变量名可赋值为实例属性.而实

android开发笔记之高级主题—传感器的简单介绍

今天我们开始进入讲解android中的一些高级主题的用法,比如传感器.GPS.NFC.语音和人脸识别等. 这次来对传感器的一个简单介绍: Android平台支持三大类的传感器: 位移传感器 这些传感器测量沿三个轴线测量加速度和旋转.这类包含加速度,重力传感器,陀螺仪,和矢量传感器. 环境传感器 这些传感器测量各种环境参数,例如周围的空气温度和压力,光线,和湿度.这类包含气压,光线,和温度传感器. 位置传感器 这些传感器测量设备的物理位置.这类包含方向和磁力传感器. 这些传感器的一些是基于硬件的,

第九章 变量的高级用法

内部变量 1.BASH 记录了bash Shell的路径(通常为/bin/bash) [[email protected] tmp]# echo "$BASH" /bin/bash 2.BASH_VERSINFO 为一个数组,分别存储bash shell的主版本号,此版本号,补丁级别,编译版本,发行状态,硬件架构 [[email protected] tmp]# cat c.sh #! /bin/bash for n in 0 1 2 3 4 5 do echo "BASH_

MySQL数据库高级(六)——索引

MySQL数据库高级(六)--索引 一.索引简介 1.索引简介 索引(Index)是帮助MySQL高效获取数据的数据结构.在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的.MyISAM和InnoDB存储引擎只支持BTREE索引,MEMORY/HEAP存储引擎支持HASH和BTREE索引. 2.索引的优点 A.提高数据检索效率,降低数据库的IO成本.B.通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗.C.大大加快数据的查询速度. 3.索引的缺点 A.

PowerShell_零基础自学课程_8_高级主题:WMI对象和COM组件

本系列文章从最初的初识开始,基本上可以完成一些简单的系统管理了,为了更方便的管理系统,同时为了更好的发掘系统的性能,就需要用到系统提供 的一些高级特性,在Windows Server系列的OS中,如果可以利用最新的特性对系统进行管理,将会是一件非常不错的事情,虽然目前WinServer用的比较少 但是在一些地方还是有用到,尤其当某些场合需要非计算机专业的人员在服务器上进行操作的时候,winServer以其比Unix/Linux简单性更加适合应用.今天 这里就对PS中一些高级特性进行介绍. 一.W

JavaEE Tutorials (21) - Java EE安全:高级主题

21.1使用数字证书331 21.1.1创建服务器证书332 21.1.2向证书安全域增加用户334 21.1.3为GlassFish服务器使用一个不同的服务器证书33421.2认证机制335 21.2.1客户端认证335 21.2.2相互认证33521.3使用JDBC安全域完成用户认证338 21.3.1配置JDBC认证安全域33921.4保护HTTP资源安全34021.5保护应用客户端安全343 21.5.1使用登录模块343 21.5.2使用编程式登录34421.6保护企业信息系统应用安全

Python 3 初探,第 2 部分: 高级主题

Python 3 是 Guido van Rossum 功能强大的通用编程语言的最新版本.它虽然打破了与 2.x 版本的向后兼容性,但却清理了某些语法方面的问题.本文是这个由两部分组成的系列文章中的第二篇,本文构建在此系列 前一期文章 的基础之上,内容涵盖了 Python 更多的新特性和更高深的一些主题,比如在抽象基类.元类和修饰符等方面的变化. Cesar Otero, 顾问, 自由职业 2009 年 5 月 04 日 内容 有关 Python 版本 3—,也即 Python 3000 或 P