1 变量的定义

A variable is a name defined in a makefile to represent a string of text, called the variable’s

value. These values are substituted by explicit request into targets, prerequisites, recipes,

and other parts of the makefile. (In some other versions of make, variables are called macros.)

makefile中,变量就是一个名字,变量的值就是一个文本字符串。在makefile中的目标,依赖,命令或其他地方引用变量时,变量会被它的值替代。

Makefile 中变量和函数的展开(除规则命令行中的变量和函数以外),是在 make

读取 makefile 文件时进行的,这里的变量包括了使用“=”定义和使用指示符

“define”定义的

2 变量的特点

2.1 变量的值

Variables can represent lists of file names, options to pass to compilers, programs to run,

directories to look in for source files, directories to write output in, or anything else you can

imagine.

变量的值可以是 文件名列表,编译选项列表,程序运行时的选项参数列表,搜索源文件的目录列表,编译输出的目录列表,或者其他你能够想到的需要表示的事物。

2.2 变量名的命名规则

2.2.1 变量名大小写敏感

‘hello’,'Hello','HELLO' 表示的是三个不同的变量。

2.2.2 变量名的命名规范

It is traditional to use upper case letters in variable names, but we recommend using lower

case letters for variable names that serve internal purposes in the makefile, and reserving

upper case for parameters that control implicit rules or for parameters that the user should

override with command options.

makefile中变量名传统的定义方式是使用大写字母。作为一个专业的程序员,不管写什么代码都要保持好的code规范。常用的做法是:对于makefile中内部定义的变量使用小写字母表示,对于一些参数变量使用大写字母表示(参数变量可能会被其他文件include)。当然,以上命名方式不是强制的,只是一种风格。

A variable name may be any sequence of characters not containing ‘:’, ‘#’, ‘=’, or white-

space. However, variable names containing characters other than letters, numbers, and

underscores should be considered carefully, as in some shells they cannot be passed through

the environment to a sub-make . Variable names beginning with ‘.’ and an uppercase letter may be given special meaning in future versions of make.

变量名不能包含 ':','#','='或者空格,一般使用字母,数字,写划线来表示变量名。

3 变量的使用

一般使用'/\((var)'或者'/\){var}'引用变量。

3.1 两种变量定义

3.1.1 递归展开变量

这种类型的变量是通过'='或者'define'指示符定义的。

The value you specify is

installed verbatim; if it contains references to other variables, these references are expanded

whenever this variable is substituted (in the course of expanding some other string).

aa = $(bb)
bb = $(cc)
cc = hello all:
echo $(aa)

源码路径:https://github.com/suonikeyinsuxiao/trunk/tree/master/makefile_project/variable/recursively_expanded_var/var1

echo $(aa)中的变量aa会被展开成$(bb),而变量bb又会被展开成$(cc),而变量cc最终展开成hello。

此种类型的变量的优点在于:可以引用其他的之前没有定义的变量。

CFLAGS = $(inc_dirs) -O
inc_dirs = -Ia/include -Ib/include

最终CFLAGS会被展开为"-Ia/include -Ib/include -O",显然这是这用很简约方便的表达方式。但是,但是,但是,也会产生问题。

Q1: 无限递归

CFLAGS = $(CFLAGS) -O

all:
echo $(CFLAGS)

源码路径:https://github.com/suonikeyinsuxiao/trunk/tree/master/makefile_project/variable/recursively_expanded_var/var2

如果变量引用了自己,那就会出现无限递归,最终makefile的执行会报错(makefile:2: * Recursive variable 'CFLAGS' references itself (eventually). Stop)退出。在多层次makefile架构中,会使编译异常。

Q2: 如果变量定义中使用了函数,会使make的执行效率降低或者会导致不可控的错误

3.1.2 直接展开变量

这种类型的变量通过':='来定义。

必须先定义,后引用;否则引用为空。

可避免无限递归问题。

CFLAGS := $(CFLAGS) -O

all:
echo $(CFLAGS)

源码路径:https://github.com/suonikeyinsuxiao/trunk/blob/master/makefile_project/variable/recursively_expanded_var/var3/makefile

echo $(CFLAGS)结果为 -O。

CFLAGS = -Wall -O
CFLAGS := $(CFLAGS) -O all:
echo $(CFLAGS)

源码路径:https://github.com/suonikeyinsuxiao/trunk/blob/master/makefile_project/variable/recursively_expanded_var/var3/makefile2

echo $(CFLAGS)结果为 -Wall -O -O。

CFLAGS = -Wall -O
CFLAGS := $(CFLAGS) -O
CFLAGS := -O2 all:
echo $(CFLAGS)

源码路径:https://github.com/suonikeyinsuxiao/trunk/blob/master/makefile_project/variable/recursively_expanded_var/var3/makefile3

echo $(CFLAGS)结果为 -O2。

总结一下,在复杂的makefile中一般使用直接展开变量,尽量避免递归展开变量的使用。

3.2 '?='操作符

给未定义的变量赋默认值.

aa ?= hello   

all:
echo $(aa)

显示 hello

aa := world
aa ?= hello all:
echo $(aa)

显示 world

源码路径:https://github.com/suonikeyinsuxiao/trunk/tree/master/makefile_project/variable/var2

makefile之变量的更多相关文章

  1. makefile之变量赋值

    makefile中变量赋值有4种方法: = ,   := ,  += ,  ?= = :直接赋值 变量 = 值 :=   :位置相关赋值 如果右值为一个值,那么它和=没区别,如果右值为变量,那么左边变 ...

  2. Makefile的变量赋值和函数

    在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地 展开在所使用的地方.其与C/C++所不同的是,你可以在Make ...

  3. [转] Makefile 基础 (5) —— Makefile 使用变量

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...

  4. Makefile总述②文件命名、包含其他文件makefile、变量、重建重载、解析

    Makefile的内容 在一个完整的 Makefile 中,包含了 5 个东西:显式规则.隐含规则.变量定义.指示符和注释. 显式规则:它描述了在何种情况下如何更新一个或者多个被称为目标的文件( Ma ...

  5. Makefile 自动化变量

    Makefile中常用自动化变量解释如下: $@------规则的目标文件名 $<------规则的第一个依赖项文件名 $^------规则的所有依赖文件列表,以空格隔开. $?-------所 ...

  6. C语言的本质(38)——makefile之变量

    我们详细看看Makefile中关于变量的语法规则.先看一个简单的例子: foo = $(bar) bar = Huh? all: @echo$(foo) 我们执行make将会打出Huh?.当make读 ...

  7. 关于makefile中变量的多次赋值以及override指令

    1 基本原则如下 1.1 原则1 变量的普通赋值是有先后顺序的,后面的赋值会覆盖掉前面的赋值. 1.2 原则2 使用的时候,用的是其前面最后的赋值,就算其后面有使用了override指令的赋值也不会影 ...

  8. makefile vpath变量

    在讲vpath之前,我们首先了解以下makefile文件. 在类Unix系统中,当我们使用源码编译某个软件的时候,我们会使用confiure,make,make install这三个命令,其中cofi ...

  9. Makefile中变量定义中末尾不能有空格

    我在Makefile中添加了 ifndef EMASSDIR EMASSDIR=$(shell emassTop.py)endif 但是emassTop.py)后面不小心加入了空格,造成出现“Make ...

随机推荐

  1. net登录积分(每天登录积分仅仅能加一次) 时间的比較

      public void jifenchange()//积分方法     {         //积分模块//推断如今的日期和任务完毕日志数据库取出来 的日期大小,注意:Compare()方法仅仅会 ...

  2. iOS:详解MJRefresh刷新加载更多数据的第三方库

    原文链接:http://www.ios122.com/2015/08/mjrefresh/ 简介 MJRefresh这个第三方库是李明杰老师的杰作,这个框架帮助我们程序员减轻了超级多的麻烦,节约了开发 ...

  3. Linux自定义应用程序及其菜单图标

    在Linux桌面系统中,如果需要自己添加一个应用程序,如果是标准的bin, lib, share结构,我通常将其放在/usr/local/bin中.如果非这样,或者程序文件很多,易造成Linux系统目 ...

  4. 捕获和记录SQL Server中发生的死锁

    经带在论坛上看到有人在问怎么捕获和记录死锁信息,在这里,我将自己的一些心得贡献出来,与大家分享,也请各位指正. 我们知道,可以使用SQL Server自带的Profiler工具来跟踪死锁信息.但这种方 ...

  5. 如何使用SQLMAP绕过WAF

    WAF(web应用防火墙)逐渐成为安全解决方案的标配之一.正因为有了它,许多公司甚至已经不在意web应用的漏洞.遗憾的是,并不是所有的waf都是不可绕过的!本文将向大家讲述,如何使用注入神器SQLMa ...

  6. NormalMap 贴图 【转】

    转载: http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html   说起Normal Map(法线贴图),就 ...

  7. [Angular] Angular i18n Pluralization Support

    // Component: this.coursesTotal = this.course,length <div i18n>{coursesTotal, plural, =0 {No c ...

  8. LeetCode Add Binary |My Solution

    Given two binary strings, return their sum (also a binary string). For example, a = "11" b ...

  9. mysql结构相同的三张表查询一条记录\将一张表中的数据插入另外一张表

    将一张表中的数据插入另外一张表 1.两张表结构相同 insert into 表1名称 select * from 表2名称 2.两张结构不相同的表 insert into 表1名称(列名1,列名2,列 ...

  10. DataBase 之 数据库设计六大范式

    范式是符合某一种级别的关系模式的集合.关系数据库中的关系必须满足一定的要求,即满足不同的范式. 目前关系数据库有六种范式:第一范式(1NF).第二范式(2NF).第三范式(3NF).第四范式(4NF) ...