Physical Address:
ChongQing,China.
WebSite:
在移植适配Android的过程中,经常会编写makefile来进行一些差异化的配置,这其中会经常用到if条件控制,通过判断某个变量的值来进行分支管理。
某次当我编写如下Makefile时:
ENABLE_SOA_DAL ?= true
ifeq ($(ENABLE_SOA_DAL) , true)
PRODUCT_PACKAGES += \
dal_test_listener \
dal_test_talker \
libcyberfastcdr \
libcyberfastrtps \
endif
编译过程没有报错,按照我的设想,我已经为ENABLE_SOA_DAL变量赋值为true,所以接下来的ifeq判断应当通过,从而集成相应的模块;但是当我编译之后却发现以上模块并没有按照我们设想的那样正常集成。
于是我通过info或warning函数进行打印,发现ENABLE_SOA_DAL值确实是true,但偏偏就是没有进入ifeq对应的分支;我以为是我的语法规则有问题,于是将ifeq改写如下:
ifeq ($(ENABLE_SOA_DAL) , true )
这样修改以后,确实能编译过了,这让我误以为当变量判断时需要与括号间保留空格作为间隔,但是通过与原生系统中其他makefile中的ifeq语句进行对比时,发现又不是这样的。所以问题可能在于:我为ENABLE_SOA_DAL赋值时并不是为true,而是为true ,没错——就是多了一个空格。
为了验证我的猜想,我使用cat 命令查看了该makefile的文本内容:
cat -A Android.mk:
ENABLE_SOA_DAL ?= true $
$
ifeq ($(ENABLE_SOA_DAL) , true)$
PRODUCT_PACKAGES += \$
^I dal_test_listener \$
^I dal_test_talker \$
仔细一点我们就会发现,$特殊字符代表行的末尾,而ENABLE_SOA_DAL ?= true $明显多了一个空格;于是我重新编辑了该makefile,将该空格进行去除,然后编译打包,能够正常集成了。
针对这类问题,我们最好的办法是使用strip函数对变量进行额外处理,以去除变量头部或者尾部的空格,strip函数的用法如下:
$(strip $(VAR))
所以在上面的makefile中,我们可以结合strip函数来做处理;
ifeq ($(strip $(ENABLE_SOA_DAL)), true)
最终进行测试,此时即使我们在变量赋值时前后都添加了空格,也不会影响其值判断,这种处理方式可以有效避免大家在改动时错误添加了空格导致条件判断失效。但需要说明的是,strip函数只能处理头部与尾部的空格,若空格在字符串内部,则无法进行处理。