######################################## # makefile 中使用环境变量 # 在shell 命令中欲使用$符号,makefile中须用$$,$$被make解析为$ # 例子: ######################################## all: @echo $$PATH # $$被make解析为$, 执行的shell 命令为 echo $path, 所以说环境变量的引用要用两个$ @echo "-----" @echo $PATH # $P 被认为是一个变量,解析成一个空,所以只显示ATH测试结果: make
/opt/bin:/opt/ffmpeg_build/bin:/home/hjj/bin:/usr/local/sbin:/usr/local/bin
-----
ATH
测试代码:
######################################## # Makefile 立即赋值和延时赋值研究 ######################################## var1 = foo var2 = $(var1) var3 := $(var2) # 因为是:= 所以立即求值了,就是解析到数据库时就已经求值了 #var3 = $(var2) # 因为是 = 赋值,所以在使用时才会求值,就是执行echo 命令时 var1 = bar all: @echo $(var3)=========================================================================
当用 := 时,解析到数据库时就已经把数据求值了
# makefile (从“Makefile”,行 5)
var2 = $(var1)
# makefile (从“Makefile”,行 6)
var3 := foo
# makefile (从“Makefile”,行 8)
var1 = bar
# 要执行的配方 (从“Makefile”,行 11):
@echo $(var3)
还注意到,第4行 var1 = foo 根本在数据库中没有出现,它被 var1 = bar 覆盖了.
=========================================================================
当用 = 时, 解析到数据库还是原样照印,没有求值。
# makefile (从“Makefile”,行 7)
var3 = $(var2)
关于第4行 var1 = fool 还是没有出现, 因为它没有必要再数据库中出现了,也没有它的位置,
因为后面var1 = bar 出现了。 谁再引用var1变量,那便是"bar" 了
所以 make 的过程大体分2步。
第一步:把文件source 到数据库中,需要立即求值的先展开求值。这里的求值叫立即求值
第二步: 根据数据库及依赖规则来调用命令make 目标,这里的求值叫延时求值#####################################################################
再研究一个复杂点的例子
#####################################################################
var1 = foo # = 赋值,是滞后展开, $(flavor var1)=recursive var2 = $(var1) #var3 := $(var2) # 因为是:= 所以立即求值了,就是解析到数据库时就已经求值了, 其flavor 是simple var3 = $(var2) # 因为是 = 赋值,所以在使用时才会求值,就是执行echo 命令时 y-$(var3) = "abc" #目标中有变量,都会立即展开. 这样显然简化了make的运算 #var1 = bar all: @echo "var3 is " $(var3) $(warning "var1 flavor is "$(flavor var1)) @echo "y-$(var3) is " $(y-$(var3))结论:
立即求值的变量其flavor是simple,延时求值的是recursive
目标变量中包含变量求值的会立即先求值得到目标变量名称
########################################
感言: 阅读makefile 最难读的是什么?
########################################
1.是对变量递归展开,
2.是对变量循环执行某种操作,
3.是调用命令包对变量进行展开,调用eval函数直接扩展了make命令。
所以来龙去脉很难找,因为变量的来历太复杂,纵使借助dbase也不行,
有些语句是用函数生成的(eval 命令包). 有的变量会被反复赋值.
不过如果你搞定了这些问题,估计也就搞定了make
remake 出现了,带debug的make版本, make 可以退出历史舞台了! remake 登场.用了一下确实好,需要参考官方文档才好使用.
remake - GNU Make with comprehensible tracing, profiling, extended error messages, and a debugger — remake 4.3+dbg-1.4 documentation