文章目录
- [prop属性在Android SDK中如何创建的](#prop属性在Android SDK中如何创建的)
- 新增自定义prop属性
-
- 修改产品配置文件
- [修改 buildinfo.sh 脚本以生成属性](#修改 buildinfo.sh 脚本以生成属性)
- build/make/core/product.mk
- build/make/core/product_config.mk
- build/make/core/Makefile
- Android相关专栏
需求是在设备mk文件中定义一个新的变量,让其传递到系统build.prop中,通过getprop能查到。
prop属性在Android SDK中如何创建的
安卓设备输入getprop指令可获取到类似ro.product.model的值
bash
adb shell getprop ro.product.model
prop属性生成流程
在 Android 的整体构建流程中,有一个步骤是生成系统的属性文件 build.prop。这个过程会调用 build/make/tools/buildinfo.sh 脚本。
这个调用发生在构建系统的某个 Makefile 规则中。当 Makefile 执行这个脚本时,它会将之前加载mk的所有相关环境变量(包括 PRODUCT_MODEL)传递给这个 Shell 脚本。
因此,在 buildinfo.sh 脚本内部,PRODUCT_MODEL 这个变量就有了值(例如 RK3399_MID),echo "ro.product.model=$PRODUCT_MODEL" 这行代码就能正确地输出 ro.product.model=RK3399_MID。
buildinfo.sh
prop的值,很多可以在Android 系统的build/make/tools/buildinfo.sh脚本中找到
shell
echo "ro.build.id=$BUILD_ID"
echo "ro.build.display.id=$BUILD_DISPLAY_ID"
echo "ro.build.version.incremental=$BUILD_NUMBER"
echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.build.version.preview_sdk=$PLATFORM_PREVIEW_SDK_VERSION"
echo "ro.build.version.codename=$PLATFORM_VERSION_CODENAME"
echo "ro.build.version.all_codenames=$PLATFORM_VERSION_ALL_CODENAMES"
echo "ro.build.version.release=$PLATFORM_VERSION"
echo "ro.build.version.security_patch=$PLATFORM_SECURITY_PATCH"
echo "ro.build.version.base_os=$PLATFORM_BASE_OS"
echo "ro.build.date=`$DATE`"
echo "ro.build.date.utc=`$DATE +%s`"
echo "ro.build.type=$TARGET_BUILD_TYPE"
echo "ro.build.user=$USER"
echo "ro.build.host=`hostname`"
echo "ro.build.tags=$BUILD_VERSION_TAGS"
echo "ro.build.flavor=$TARGET_BUILD_FLAVOR"
if [ -n "$BOARD_BUILD_SYSTEM_ROOT_IMAGE" ] ; then
echo "ro.build.system_root_image=$BOARD_BUILD_SYSTEM_ROOT_IMAGE"
fi
if [ -n "$AB_OTA_UPDATER" ] ; then
echo "ro.build.ab_update=$AB_OTA_UPDATER"
fi
echo "ro.product.model=$PRODUCT_MODEL"
echo "ro.product.brand=$PRODUCT_BRAND"
echo "ro.product.name=$PRODUCT_NAME"
echo "ro.product.device=$TARGET_DEVICE"
这里可以看到ro.product.model的值是由$PRODUCT_MODEL 赋值的

xx.mk文件
这个PRODUCT_MODEL通常是在设备专属的产品配置文件中定义,可以在device或vendor目录下查找。不同的厂商放置位置不一样,这里以RK的芯片为例:
这些文件通常位于以下两个位置:
- Rockchip 官方 SDK 中的设备配置目录
路径通常是:device/rockchip/<your_board_name>/
例如:device/rockchip/rk3399/
文件名通常是 lunch 时你选择的产品名称,例如 rk3399_mid.mk 或 rk3399_box.mk。 - Rockchip 官方 SDK 中的通用板级配置目录
路径通常是:device/rockchip/common/
文件名可能是 BoardConfig.mk 或其他通用配置文件。
比如device/rockchip/rk3399/rk3399_mid.mk
makefile
# 这是一个典型的产品配置文件
# 1. 首先,它会继承一个通用的产品配置
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base.mk)
# 2. 然后,它会定义本产品的特定信息
PRODUCT_NAME := rk3399_mid
PRODUCT_DEVICE := rk3399
PRODUCT_BRAND := Rockchip
PRODUCT_MANUFACTURER := Rockchip
# 3. 在这里定义了产品型号!
# 这个值就是最终写入到 build.prop 中的 "ro.product.model" 的值
PRODUCT_MODEL := RK3399_MID
新增自定义prop属性
通过上面简单地分析,大致知道怎么改了,我们将创建一个名为 TEST_MODEL 的新属性,
修改产品配置文件
例如:device/rockchip/rk3399/rk3399_mid.mk
makefile
# ... 其他定义 ...
PRODUCT_NAME := rk3399_mid
PRODUCT_DEVICE := rk3399
PRODUCT_BRAND := Rockchip
PRODUCT_MANUFACTURER := Rockchip
PRODUCT_MODEL := RK3399_MID
# --- 在这里添加你的新变量 ---
# 注意:变量名通常使用大写字母和下划线
TEST_MODEL := My_Custom_Model_XYZ
# ---------------------------
修改 buildinfo.sh 脚本以生成属性
定义了变量后,我们需要告诉构建系统,在生成 build.prop 文件时,要把这个变量的值也写进去。这需要修改 buildinfo.sh 脚本。
- 打开 buildinfo.sh 脚本
路径是:build/make/tools/buildinfo.sh - 添加 echo 语句
在脚本中找到 ro.product.model 那一行,在它的附近(例如下面)添加一行新的 echo 命令。
示例 (build/make/tools/buildinfo.sh):
shell
# ... 其他 echo 语句 ...
echo "ro.product.model=$PRODUCT_MODEL"
# --- 在这里添加你的新 echo 语句 ---
# 使用 $NTT_MODEL 来引用我们在步骤一中定义的变量
echo "ro.product.test_model=$TEST_MODEL"
# ----------------------------------
echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
# ... 其他 echo 语句 ...
ro.product.test_model 是最终会出现在 build.prop 文件中的属性名。
但是很遗憾,以上两处修改后,ro.product.test_model结果是空的。
为什么无效?
- PRODUCT_MODEL 是 Android内置变量,构建系统已经默认导出为 Shell 环境变量;
- 自定义的 TEST_MODEL 是新变量,没有被加入导出列表,因此 Shell 脚本 buildinfo.sh 无法读取;
- 必须通过 product.mk 与 Makefile 中调用脚本时显式传递,才能让变量进入 Shell 环境。
build/make/core/product.mk
build/make/core/product.mk
makefile
#
# Functions for including product makefiles
#
_product_var_list := \
PRODUCT_NAME \
PRODUCT_MODEL \
PRODUCT_LOCALES \
PRODUCT_AAPT_CONFIG \
PRODUCT_AAPT_PREF_CONFIG \
PRODUCT_AAPT_PREBUILT_DPI \
PRODUCT_PACKAGES \
PRODUCT_PACKAGES_DEBUG \
PRODUCT_PACKAGES_ENG \
PRODUCT_PACKAGES_TESTS \
PRODUCT_DEVICE \
PRODUCT_MANUFACTURER \
PRODUCT_BRAND \
PRODUCT_PROPERTY_OVERRIDES \
PRODUCT_DEFAULT_PROPERTY_OVERRIDES \
PRODUCT_CHARACTERISTICS \
PRODUCT_COPY_FILES \
PRODUCT_OTA_PUBLIC_KEYS \
_product_var_list 这个变量是 Android 构建系统用来识别、收集和导出产品相关核心变量的清单,自定义的 TEST_MODEL 必须被加入这个列表,才能被构建系统识别并传递到 buildinfo.sh 中

build/make/core/product_config.mk
product_config.mk中可以找到PRODUCT_MODEL
product.mk中的_product_var_list 只是「变量白名单」(告诉构建系统要收集这个变量),但 product_config.mk 才是「变量赋值入口」------ 它会把产品配置文件中定义的变量值,最终赋值到构建系统的全局 TEST_MODEL 变量中
product_config.mk
makefile
PRODUCT_BRAND := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_BRAND))
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MODEL))
ifndef PRODUCT_MODEL
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
endif
修改
makefile
# 原有 PRODUCE_MODEL 赋值逻辑
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_MODEL))
ifndef PRODUCT_MODEL
PRODUCT_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_NAME))
endif
# 新增 NTT_MODEL 的赋值逻辑(核心!)
TEST_MODEL := $(strip $(PRODUCTS.$(INTERNAL_PRODUCT).TEST_MODEL))
build/make/core/Makefile
在 build/make/core/Makefile 中能搜索到 buildinfo.sh与PRODUCT_MODEL等变量
makefile
BUILDINFO_SH := build/tools/buildinfo.sh
VENDOR_BUILDINFO_SH := build/tools/vendor_buildinfo.sh
$(intermediate_system_build_prop): $(VENDOR_BUILDINFO_SH) $(BUILDINFO_SH) $(INTERNAL_BUILD_ID_MAKEFILE) $(BUILD_SYSTEM)/version_defaults.mk $(system_prop_file) $(INSTALLED_ANDROID_INFO_TXT_TARGET)
@echo Target buildinfo: $@
@mkdir -p $(dir $@)
$(hide) echo > $@
ifneq ($(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES),)
$(hide) echo "#" >> $@; \
echo "# PRODUCT_OEM_PROPERTIES" >> $@; \
echo "#" >> $@;
$(hide) $(foreach prop,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_OEM_PROPERTIES), \
echo "import /oem/oem.prop $(prop)" >> $@;)
endif
$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
TARGET_DEVICE="$(TARGET_DEVICE)" \
PRODUCT_NAME="$(TARGET_PRODUCT)" \
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
PRODUCT_DEFAULT_LOCALE="$(call get-default-product-locale,$(PRODUCT_LOCALES))" \
PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
PRODUCT_MODEL="$(PRODUCT_MODEL)" \
PRODUCT_MANUFACTURER="$(PRODUCT_MANUFACTURER)" \
PRIVATE_BUILD_DESC="$(PRIVATE_BUILD_DESC)" \
BUILD_ID="$(BUILD_ID)" \

修改build/make/core/Makefile,将我们的TEST_MODEL加到PRODUCT_MODEL放置的地方
makefile
$(hide) TARGET_BUILD_TYPE="$(TARGET_BUILD_VARIANT)" \
TARGET_BUILD_FLAVOR="$(TARGET_BUILD_FLAVOR)" \
TARGET_DEVICE="$(TARGET_DEVICE)" \
PRODUCT_NAME="$(TARGET_PRODUCT)" \
PRODUCT_BRAND="$(PRODUCT_BRAND)" \
PRODUCT_DEFAULT_LOCALE="$(call get-default-product-locale,$(PRODUCT_LOCALES))" \
PRODUCT_DEFAULT_WIFI_CHANNELS="$(PRODUCT_DEFAULT_WIFI_CHANNELS)" \
PRODUCT_MODEL="$(PRODUCT_MODEL)" \
TEST_MODEL="$(TEST_MODEL)" \
经过上面这几个步骤的修改后,编译固件再推到设备中,就可以在getprop中查找到新增的prop属性了。
Android相关专栏
Android Framework专栏链接
Android专栏
作者:帅得不敢出门