【三】makefile中的变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaoxu2050/article/details/83928152

一、变量赋值

  • 直接展开式 :=

特点:在定义时立即展开应用的变量

示例:

value1 := 5
value2 := $(value1) #value2会立即被赋值成5
value1 :=6
var-test:
    @echo "value2", $(value2)

输出:

make var-test
value2, 5
  • 递归展开式 =

特点:定义变量时候其实相当于声明,只有在实际引用时才展开

示例:

value1 = 5
value2 = $(value1) #此处只是声明,不对value2赋值
value1 = 6

var-test:
    #此处对value1赋值给value2,此时value1=6
    @echo "value2", $(value2)

输出:

make var-test
value2, 6
  • 直接展开式 ?=

特点:当变量为空时才赋值

示例:

value1 = 111
value1 ?= 000 #value1的值认为111
  • 追加赋值 += 

特点:追加赋值,使用空格分隔

value1 = a.cpp
value1 += b.cpp #value1的值为a.cpp b.cpp

相当于

value1 := $(value1) b.cpp

只是更简洁了,需要注意追加赋值使用的立即展开,即:=,不是递归展开

  • 综合示例

示例1:

VAR_A = abc
VAR_B = $(VAR_A) 222
#展开VAR_C的同时,引用了VAR_A,两个变量都被赋值成abc
VAR_C := $(VAR_A)
VAR_A = def

var-test:
    @echo "VAR_A", $(VAR_A)
    @echo "VAR_B", $(VAR_B)
    @echo "VAR_C", $(VAR_C)

输出:

VAR_A, def
VAR_B, def 222
VAR_C, abc

示例2:

VAR_A = abc
VAR_B = $(VAR_A) 222
VAR_C := $(VAR_A) #直接展开VAR_C = abc
VAR_A = def

VAR_A:=$(VAR_B) 222 #直接展开,引用VAR_B,VAR_B展开成def 222
VAR_B=$(VAR_A)

var-test:
    @echo "VAR_A", $(VAR_A)
    @echo "VAR_B", $(VAR_B)
    @echo "VAR_C", $(VAR_C)

输出:

VAR_A, def 222 222
VAR_B, def 222 222
VAR_C, abc

示例3:定义一个空格变量

nullstring :=
space := $(nullstring) #end of the line
dir := /foo/bar # directory to put the frobs in

因为在操作符的右边 是很难描述一个空格的,这里先定义一个空变量nullstring,先用空变量nullstring来标明变量的值开始,而后面用“#”注释符来表示变量定义的终止,这样可以定义出其值是一个空格的变量了。

注释符“#”的这种特性值得我们注意,例子中变量dir的值是“/foo/bar”,后面还跟了4个空格,如果我们使用这样变量来指定别的目录——“$(dir)/file”那么就出错了。

二、变量的高级用法

  • 多行变量

使用define关键字可以定义多行变量,语法:

define 变量名
...
....
endef

示例:

define echo_va
    echo v
    echo a
endef

  • 变量替换

语法:

$(var:a=b)
#或者
$(var:%a=%b)

变量var中包括多个字符串,这些字符串被空格或结束符分割,其中以a结尾的字符串,会被改成以b结尾。

示例:

foo = a.o.o b.c.o d.o.e
bar = $(foo:.o=.c)
$(info bar)
far = $(foo:%.o=%.c)
$(info far)


all:
    @echo done

执行make all 输出

a.o.o b.c.o d.o.e
a.o.c b.c.c d.o.e
a.o.c b.c.c d.o.e
done
  • 在make命令行中设置变量

语法:

make var=value

示例:

a_objects = a.o b.o c.o
1_objects = 1.o 2.o 3.o

#变量a1值决定编译不同脚本
source = $($(a1)_objects:%.o=%.c)

all:
    @echo $(source)

执行make a1=1,输出

1.c 2.c 3.c

执行make a1=a,输出

a.c b.c c.c
  • 把变量的值再当成变量

示例1:

a = b
b = c
#$(a)是b,这个值还是作为变量使用,所有d的值为c
d = $($(a))

示例2:

first_second = Hello a = first b = second all = $($a_$b) #all的值为“hello”
  • 引用环境变量

在make开始运行时会将系统环境变量载入到运行环境中,所以可以在makfile脚本中引用环境变量, 这里定义一个测试用的系统环境变量:

export demoPath=/usr/local/demo

在makefile便可以通过$符号引用:

DEMOPATH = ${demoPath} # 也可以直接应用$(demoPath)

系统环境变量使用全部大写表示,区别普通的变量。如果makfile脚本中定义了该环境变量,系统环境变量将会被覆盖。

  • 目标变量

作用:目标变量只在目标编译过程中有效,相当于c语言中局部变量

示例:

prog : CFLAGS = -g 
prog : prog.o foo.o bar.o 
    $(CC) $(CFLAGS) prog.o foo.o bar.o 

prog.o : prog.c
 $(CC) $(CFLAGS) prog.c 

foo.o : foo.c 
    $(CC) $(CFLAGS) foo.c 

bar.o : bar.c 
    $(CC) $(CFLAGS) bar.c

无论全局$(CFLAGS)是什么值,在prog目标及其引发的目标中都会被变成debug模式。

  • 模式变量

作用:模式变量和目标变量类似,只不过目标是一个正则表达式。

示例:

%.o : CFLAGS= -o

二、常见的内置变量

CC = cc #c语言编译器的名称
CPP = $(cc) -E #c文件预处理器的名称
CFLAGS #C文件的编译选项
CPPFLAGS #C文件预处理的编译选项
CXXFLAGS #CPP文件的编译选项
LDFLAGS #连接的动态库

CURDIR := /home/zxy/... #当前路径
MAKEFLAGS = p #make命令选项
RM = rm -f

VPATH #文件的搜索路径

打印环境变量和内置变量方法:

make -p

猜你喜欢

转载自blog.csdn.net/xiaoxu2050/article/details/83928152
今日推荐