1. 问题背景
在Android各设备上,同一个字符串ID,通过配置不同的product参数用来显示不同的字符串,这样子就可以用一套代码,不同设备加载不同的字符串资源,显示在不同的终端设备上,呈现给用户的描述就是合理准确的,我们来看看字符串ID是怎么定义的
同一个字符串ID,这里有四种产品型号:平板,手机,其他设备,模拟器,这样子不同的设备上就显示了对应的”关于xx”的字符串。
2. 问题描述
我的设备明明是平板设备,但是显示的是“关于手机”的字符串,明显不对。应该就是产品属性相关的配置项没有配置对,也就是product=”XXX”的值不对。
3. 相关字段
通过以往的工作经验,涉及的配置项为:ro.build.characteristics= ?
default默认为手机设备。而我手上的设备为平板,我该如何修改呢?
我们来看看此ro值是位于平板设备的product/build.prop文件中,那此ro属性是如何编译到build.prop文件中来的呢,我们一起来探究下?
4. 加载原理
涉及到编译脚本文件基本都在 build/make/core/ 此路径下,我们找一下此属性定义的位置:
build/make/core/Makefile 文件中
来看看具体定义内容:
$(hide) echo "#" >> $@; \
echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
echo "#" >> $@; \
echo "ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)" >> $@;
也就是ro属性的值是变量 TARGET_AAPT_CHARACTERISTICS定义的,接下来看看它是定义的地方: build/make/core/product_config.mk
这段话的意思:
如果没有定义 PRODUCT_CHARACTERISTICS,则默认为default值,也就是手机产品,如果定义了,则为其定义的产品类型,好了到这里,就知道怎么去配置了,所以最后需要配置
PRODUCT_CHARACTERISTICS := tablet 就可以解决啦!
5. product/build.prop 生成过程
Android10的源码路径为:build/make/core/makefile文件
# -----------------------------------------------------------------
# product build.prop
INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/build.prop
$(warning 调试 in Makefile 打印TARGET_OUT_PRODUCT的值: $(TARGET_OUT_PRODUCT))
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_PRODUCT_BUILD_PROP_TARGET)
ifdef TARGET_PRODUCT_PROP
product_prop_files := $(TARGET_PRODUCT_PROP)
else
product_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/product.prop)
$(warning 调试 in Makefile 打印TARGET_DEVICE_DIR的值: $(TARGET_DEVICE_DIR))
endif
FINAL_PRODUCT_PROPERTIES += \
$(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES) $(ADDITIONAL_PRODUCT_PROPERTIES))
FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
$(FINAL_PRODUCT_PROPERTIES),=)
$(INSTALLED_PRODUCT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(product_prop_files)
@echo Target product buildinfo: $@
@mkdir -p $(dir $@)
$(hide) echo > $@
ifdef BOARD_USES_PRODUCTIMAGE
$(hide) $(call generate-common-build-props,product,$@)
endif # BOARD_USES_PRODUCTIMAGE
$(hide) $(foreach file,$(product_prop_files), \
if [ -f "$(file)" ]; then \
echo Target product properties from: "$(file)"; \
echo "" >> $@; \
echo "#" >> $@; \
echo "# from $(file)" >> $@; \
echo "#" >> $@; \
cat $(file) >> $@; \
echo "# end of $(file)" >> $@; \
fi;)
$(hide) echo "#" >> $@; \
echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
echo "#" >> $@; \
echo "ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)" >> $@;
$(hide) $(foreach line,$(FINAL_PRODUCT_PROPERTIES), \
echo "$(line)" >> $@;)
$(hide) build/make/tools/post_process_props.py $@
$(error 调试 到这里停止)
代码解读:
1. 首先看了这段代码,内容不多,我们一句一句来分析下,首先把关键的位置加上log,并在结尾加上:$(error 调试 到这里停止), 在工程中编译,就会到这里停止下来。
2. 编译工程自己加的打印log如下:
build/make/core/Makefile:289: warning: 调试 in Makefile 打印TARGET_OUT_PRODUCT的值 out/target/product/ums512_1h10/product
build/make/core/Makefile:413: warning: 调试 in Makefile 打印TARGET_DEVICE_DIR的值 device/sprd/sharkl5Pro/ums512_1h10
build/make/core/Makefile:497: error: 调试 到这里停止
产品工程为展锐平台:sprd 产品项目名:ums512_1h10
关于在Makefile中如何添加打印log,请移步到我的另外一篇文章:Android源码编译makefile文件的调试方法_broadview_java的博客-CSDN博客
3. INSTALLED_PRODUCT_BUILD_PROP_TARGET := $(TARGET_OUT_PRODUCT)/build.prop 这句话表达的意思是:最后编译版本的输出路径为out/target/product/ums512_1h10/product/build.prop
4. product_prop_files := $(wildcard $(TARGET_DEVICE_DIR)/product.prop) :
wildcard 是通配符的意思,代码表达的意思:就是遍历device/sprd/sharkl5Pro/ums512_1h10路径下的所有product.prop文件,赋值给product_prop_files变量。
5.
FINAL_PRODUCT_PROPERTIES += \
$(call collapse-pairs, $(PRODUCT_PRODUCT_PROPERTIES) $(ADDITIONAL_PRODUCT_PROPERTIES))
这段代码里面有个call方法 collapse-pairs 就是函数名,后面带两个参数,我们看看这个函数定义的地方:build/make/core/common/string.mk
###########################################################
## Convert "a=b c= d e = f" into "a=b c=d e=f"
##
## $(1): list to collapse
## $(2): if set, separator word; usually "=", ":", or ":="
## Defaults to "=" if not set.
###########################################################
define collapse-pairs
$(eval _cpSEP := $(strip $(if $(2),$(2),=)))\
$(strip $(subst $(space)$(_cpSEP)$(space),$(_cpSEP),$(strip \
$(subst $(_cpSEP), $(_cpSEP) ,$(1)))$(space)))
endef
就是把 = : := 赋值的语句,或带有空格的赋值语句,统一格式化为 a=b 得样式
6.
FINAL_PRODUCT_PROPERTIES := $(call uniq-pairs-by-first-component, \
$(FINAL_PRODUCT_PROPERTIES),=)
这段代码,就是调用 uniq-pairs-by-first-component 函数,同样我们看看定义的地方:
build/make/core/common/string.mk文件中
###########################################################
## Given a list of pairs, if multiple pairs have the same
## first components, keep only the first pair.
##
## $(1): list of pairs
## $(2): the separator word, such as ":", "=", etc.
define uniq-pairs-by-first-component
$(eval _upbfc_fc_set :=)\
$(strip $(foreach w,$(1), $(eval _first := $(word 1,$(subst $(2),$(space),$(w))))\
$(if $(filter $(_upbfc_fc_set),$(_first)),,$(w)\
$(eval _upbfc_fc_set += $(_first)))))\
$(eval _upbfc_fc_set :=)\
$(eval _first:=)
endef
就是去掉重复的赋值语句,只保留第一条
7.
$(INSTALLED_PRODUCT_BUILD_PROP_TARGET): $(BUILDINFO_COMMON_SH) $(product_prop_files)
@echo Target product buildinfo: $@
@mkdir -p $(dir $@)
$(hide) echo > $@
这段代码就是一个target 语句,makefile的语法规则如下:
翻译过来就是:
out/target/product/ums512_1h10/product/build.prop 是由下面2个文件编译生成的:
BUILDINFO_COMMON_SH := build/make/tools/buildinfo_common.sh
还有device/sprd/sharkl5Pro/ums512_1h10路径下的所有product.prop。
$(hide) 我们来看看 hide这个变量定义的地方: build/make/core/config.mk
hide := @
通常makefile会将其执行的命令行在执行前输出到屏幕上。如果将‘@’添加到命令行前,这个命令将不被make回显出来。
例如:@echo –hello world—-; // 屏幕输出 —hello world—-
echo –hello world—-; // 没有@ 屏幕输出 echo —hello world—-
8.
$(hide) $(foreach file,$(product_prop_files), \
if [ -f "$(file)" ]; then \
echo Target product properties from: "$(file)"; \
echo "" >> $@; \
echo "#" >> $@; \
echo "# from $(file)" >> $@; \
echo "#" >> $@; \
cat $(file) >> $@; \
echo "# end of $(file)" >> $@; \
fi;)
这段代码通过for循环语句,把4中device/sprd/sharkl5Pro/ums512_1h10路径下的所有product.prop文件的内容重定向输出到同一个product.prop中
9.
$(hide) echo "#" >> $@; \
echo "# ADDITIONAL PRODUCT PROPERTIES" >> $@; \
echo "#" >> $@; \
echo "ro.build.characteristics=$(TARGET_AAPT_CHARACTERISTICS)" >> $@;
这里就是把 ro.build.characteristics属性编译到build.prop文件中,好了,到这里就分析完毕了。
6. product/build.prop 内容
内容如下:
我们配置的PRODUCT_CHARACTERISTICS := table 属性最终编译生成到product/build.prop 文件中。
7. 总结
系统生成的system/build.prop vendor/build.prop 分析方法也同上,首先还是要掌握makefile和shell的基本语法规则,然后也要了解makefile的调试方法,看不懂的地方去打log看,就大致明白其编译过程了。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/34174.html