阅览本文前,需求以下前置基础知识:
- Ubuntu 运用快速入门
- Make 构建东西入门
- AOSP 极速上手
1. 什么是 Product
在 App 的开发中,咱们要去打渠道包,根据不同运用市场的要求打包出不同的 apk 包。
相同的道理,Android 的体系源码,经过简略的装备,能够打包出不同的体系镜像,用于不同的产品。例如小米 12s,小米12s pro,小米12s ultra 均源于骁龙8+渠道。
Android 体系源码是经过装备文件来实现 “分包” 的,装备文件将咱们的源码装备为了不同的 Product,每一个 Product 适用于特定的硬件产品,这一系列的装备文件咱们称为 Product。
2. AOSP 中预制的 Product
咱们在编译源码之前需求履行 lunch :
lunch
You're building on Linux
Lunch menu... pick a combo:
1. aosp_arm-eng
2. aosp_arm64-eng
3. aosp_blueline-userdebug
4. aosp_bonito-userdebug
5. aosp_car_arm-userdebug
6. aosp_car_arm64-userdebug
7. aosp_car_x86-userdebug
8. aosp_car_x86_64-userdebug
9. aosp_cf_arm64_phone-userdebug
10. aosp_cf_x86_64_phone-userdebug
11. aosp_cf_x86_auto-userdebug
12. aosp_cf_x86_phone-userdebug
13. aosp_cf_x86_tv-userdebug
14. aosp_coral-userdebug
15. aosp_coral_car-userdebug
16. aosp_crosshatch-userdebug
17. aosp_crosshatch_car-userdebug
18. aosp_flame-userdebug
19. aosp_marlin-userdebug
20. aosp_sailfish-userdebug
21. aosp_sargo-userdebug
22. aosp_taimen-userdebug
23. aosp_walleye-userdebug
24. aosp_walleye_test-userdebug
25. aosp_x86-eng
26. aosp_x86_64-eng
27. beagle_x15-userdebug
28. car_x86_64-userdebug
29. fuchsia_arm64-eng
30. fuchsia_x86_64-eng
31. hikey-userdebug
32. hikey64_only-userdebug
33. hikey960-userdebug
34. hikey960_tv-userdebug
35. hikey_tv-userdebug
36. m_e_arm-userdebug
37. mini_emulator_arm64-userdebug
38. mini_emulator_x86-userdebug
39. mini_emulator_x86_64-userdebug
40. poplar-eng
41. poplar-user
42. poplar-userdebug
43. qemu_trusty_arm64-userdebug
44. uml-userdebug
Which would you like? [aosp_arm-eng]
这儿的每一个选项便是一个 Product, AOSP 预制了许多 Product。对应于 x86_64 模拟器,咱们选择的是 aosp_x86_64-eng。
AOSP 中 Product 装备文件保存在以下两个目录:
- build/target:aosp 供给的 product 装备文件保存在这个目录下,咱们选择的 aosp_x86_64-eng Product 就装备在这个目录下。
- device:芯片及方案厂商供给的 product 装备文件保存在这个目录下
先运用 tree 命令查看 build/target 根本的目录结构:
tree . -L 2
.
├── board
│ ├── Android.mk
│ ├── BoardConfigEmuCommon.mk
│ ├── BoardConfigGsiCommon.mk
│ ├── BoardConfigMainlineCommon.mk
│ ├── BoardConfigModuleCommon.mk
│ ├── BoardConfigPixelCommon.mk
│ ├── emulator_arm
│ ├── emulator_arm64
│ ├── emulator_x86
│ ├── emulator_x86_64
│ ├── emulator_x86_64_arm64
│ ├── emulator_x86_arm
│ ├── generic
│ ├── generic_64bitonly_x86_64
│ ├── generic_arm64
│ ├── generic_x86
│ ├── generic_x86_64
│ ├── generic_x86_64_arm64
│ ├── generic_x86_arm
│ ├── go_defaults_512.prop
│ ├── go_defaults_common.prop
│ ├── go_defaults.prop
│ ├── gsi_arm64
│ ├── gsi_system_ext.prop
│ ├── gsi_system_ext_user.prop
│ ├── mainline_arm64
│ ├── mainline_sdk
│ ├── mainline_x86
│ ├── mainline_x86_64
│ ├── mainline_x86_arm
│ ├── module_arm
│ ├── module_arm64
│ ├── module_x86
│ ├── module_x86_64
│ └── ndk
├── OWNERS
└── product
├── AndroidProducts.mk
├── aosp_64bitonly_x86_64.mk
├── aosp_arm64.mk
├── aosp_arm.mk
├── aosp_base.mk
├── aosp_base_telephony.mk
├── aosp_product.mk
├── aosp_x86_64.mk
├── aosp_x86_arm.mk
├── aosp_x86.mk
├── base.mk
├── base_product.mk
├── base_system_ext.mk
├── base_system.mk
├── base_vendor.mk
├── cfi-common.mk
├── core_64_bit.mk
├── core_64_bit_only.mk
├── core_minimal.mk
├── core_no_zygote.mk
├── default_art_config.mk
├── developer_gsi_keys.mk
├── empty-preloaded-classes
├── empty-profile
├── emulated_storage.mk
├── emulator.mk
├── emulator_system.mk
├── emulator_vendor.mk
├── full_base.mk
├── full_base_telephony.mk
├── full.mk
├── full_x86.mk
├── generic.mk
├── generic_no_telephony.mk
├── generic_ramdisk.mk
├── generic_system_arm64.mk
├── generic_system.mk
├── generic_system_x86_64.mk
├── generic_system_x86_arm.mk
├── generic_system_x86.mk
├── generic_x86.mk
├── go_defaults_512.mk
├── go_defaults_common.mk
├── go_defaults.mk
├── gsi
├── gsi_release.mk
├── handheld_product.mk
├── handheld_system_ext.mk
├── handheld_system.mk
├── handheld_vendor.mk
├── languages_default.mk
├── languages_full.mk
├── mainline_sdk.mk
├── mainline_system_arm64.mk
├── mainline_system.mk -> generic_system.mk
├── mainline_system_x86_64.mk
├── mainline_system_x86_arm.mk
├── mainline_system_x86.mk
├── media_product.mk
├── media_system_ext.mk
├── media_system.mk
├── media_vendor.mk
├── module_arm64.mk
├── module_arm.mk
├── module_common.mk
├── module_x86_64.mk
├── module_x86.mk
├── ndk.mk
├── non_ab_device.mk
├── OWNERS
├── product_launched_with_k.mk
├── product_launched_with_l.mk
├── product_launched_with_l_mr1.mk
├── product_launched_with_m.mk
├── product_launched_with_n.mk
├── product_launched_with_n_mr1.mk
├── product_launched_with_o.mk
├── product_launched_with_o_mr1.mk
├── product_launched_with_p.mk
├── profile_boot_common.mk
├── runtime_libart.mk
├── sdk_arm64.mk
├── sdk.mk
├── sdk_phone_arm64.mk
├── sdk_phone_armv7.mk
├── sdk_phone_x86_64.mk
├── sdk_phone_x86.mk
├── sdk_x86_64.mk
├── sdk_x86.mk
├── security
├── sysconfig
├── telephony.mk
├── telephony_product.mk
├── telephony_system_ext.mk
├── telephony_system.mk
├── telephony_vendor.mk
├── updatable_apex.mk
├── userspace_reboot.mk
├── vboot.mk
├── verity.mk
├── virtual_ab_ota
├── virtual_ab_ota.mk -> virtual_ab_ota/launch.mk
├── virtual_ab_ota_plus_non_ab.mk -> virtual_ab_ota/plus_non_ab.mk
└── virtual_ab_ota_retrofit.mk -> virtual_ab_ota/retrofit.mk
board目录下首要是一些硬件相关的装备, product 目录首要是产品相关的装备
针对咱们选择的 aosp_x86_64-eng,咱们首要重视以下几个文件:
-
/board/generic_x86_64/BoardConfig.mk
: 用于硬件相关装备 -
/product/AndroidProducts.mk
/product/aosp_x86_64.mk
:用于装备 Product
接下来咱们来看看这三个装备文件:
BoardConfig.mk 用于界说和硬件相关的底层特性和变量,比如当时源码支撑的 cpu 位数(64/32位),bootloader 和 kernel, 是否支撑摄像头,GPS导航等一些板级特性。
# x86_64 emulator specific definitions
TARGET_CPU_ABI := x86_64
TARGET_ARCH := x86_64
TARGET_ARCH_VARIANT := x86_64
TARGET_2ND_CPU_ABI := x86
TARGET_2ND_ARCH := x86
TARGET_2ND_ARCH_VARIANT := x86_64
TARGET_PRELINK_MODULE := false
include build/make/target/board/BoardConfigGsiCommon.mk
include build/make/target/board/BoardConfigEmuCommon.mk
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
# Wifi.
BOARD_WLAN_DEVICE := emulator
BOARD_HOSTAPD_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
WPA_SUPPLICANT_VERSION := VER_0_8_X
WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
WIFI_DRIVER_FW_PATH_STA := "/dev/null"
WIFI_DRIVER_FW_PATH_AP := "/dev/null"
其间还经过 include 包括了 BoardConfigGsiCommon.mk 和 BoardConfigEmuCommon.mk 两个装备文件,前者用于通用体系映像的装备,后者用于模拟器的装备
首要和硬件相关,有一个根本的了解即可。一般很少改动。
AndroidProducts.mk 界说咱们履行 lunch 命令时,打印的列表以及每个选项对应的装备文件
# Unbundled apps will be built with the most generic product config.
# TARGET_BUILD_APPS 编译Android体系时,这个值为空,编译单模块时,这个值为所编译模块的途径
#编译单模块
ifneq ($(TARGET_BUILD_APPS),)
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_arm64.mk \
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/aosp_x86_64.mk \
$(LOCAL_DIR)/aosp_x86.mk \
$(LOCAL_DIR)/full.mk \
$(LOCAL_DIR)/full_x86.mk \
#编译体系
else
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/aosp_64bitonly_x86_64.mk \
$(LOCAL_DIR)/aosp_arm64.mk \
$(LOCAL_DIR)/aosp_arm.mk \
$(LOCAL_DIR)/aosp_x86_64.mk \
$(LOCAL_DIR)/aosp_x86_arm.mk \
$(LOCAL_DIR)/aosp_x86.mk \
$(LOCAL_DIR)/full.mk \
$(LOCAL_DIR)/full_x86.mk \
$(LOCAL_DIR)/generic.mk \
$(LOCAL_DIR)/generic_system_arm64.mk \
$(LOCAL_DIR)/generic_system_x86.mk \
$(LOCAL_DIR)/generic_system_x86_64.mk \
$(LOCAL_DIR)/generic_system_x86_arm.mk \
$(LOCAL_DIR)/generic_x86.mk \
$(LOCAL_DIR)/mainline_system_arm64.mk \
$(LOCAL_DIR)/mainline_system_x86.mk \
$(LOCAL_DIR)/mainline_system_x86_64.mk \
$(LOCAL_DIR)/mainline_system_x86_arm.mk \
$(LOCAL_DIR)/ndk.mk \
$(LOCAL_DIR)/sdk_arm64.mk \
$(LOCAL_DIR)/sdk.mk \
$(LOCAL_DIR)/sdk_phone_arm64.mk \
$(LOCAL_DIR)/sdk_phone_armv7.mk \
$(LOCAL_DIR)/sdk_phone_x86_64.mk \
$(LOCAL_DIR)/sdk_phone_x86.mk \
$(LOCAL_DIR)/sdk_x86_64.mk \
$(LOCAL_DIR)/sdk_x86.mk \
endif
PRODUCT_MAKEFILES += \
$(LOCAL_DIR)/mainline_sdk.mk \
$(LOCAL_DIR)/module_arm.mk \
$(LOCAL_DIR)/module_arm64.mk \
$(LOCAL_DIR)/module_x86.mk \
$(LOCAL_DIR)/module_x86_64.mk \
# 装备咱们在 lunch 时的选项
COMMON_LUNCH_CHOICES := \
aosp_arm64-eng \
aosp_arm-eng \
aosp_x86_64-eng \
aosp_x86-eng \
PRODUCT_MAKEFILES 用于引进产品的装备文件
COMMON_LUNCH_CHOICES 用于增加 lunch 时的选项,选项的姓名由两部分过程 产品名 + 构建形式
:
- 产品名便是 PRODUCT_MAKEFILES 中引进的产品装备文件名去掉
.mk
后缀,例如 aosp_x86_64 - 构建形式有三种:用户形式 user、用户调试形式 userdebug 和工程形式 eng
首要差异如下:、
用户形式 user
- 仅装置标签为 user 的模块
- 设定特点 ro.secure=1,翻开安全查看功用
- 设定特点 ro.debuggable=0,封闭运用调试功用
- 默认封闭 adb 功用
- 翻开 Proguard 混淆器
- 翻开 DEXPREOPT 预先编译优化
用户调试形式 userdebug
- 装置标签为 user、debug 的模块
- 设定特点 ro.secure=1,翻开安全查看功用
- 设定特点 ro.debuggable=1,启用运用调试功用
- 默认翻开 adb 功用
- 翻开 Proguard 混淆器
- 翻开 DEXPREOPT 预先编译优化
工程形式 eng
- 装置标签为 user、debug、eng 的模块
- 设定特点 ro.secure=0,封闭安全查看功用
- 设定特点 ro.debuggable=1,启用运用调试功用
- 设定特点 ro.kernel.android.checkjni=1,启用 JNI 调用查看
- 默认翻开 adb 功用
- 封闭 Proguard 混淆器
- 封闭 DEXPREOPT 预先编译优化
aosp_x86_64.mk:这个文件便是咱们产品装备的主基地。
PRODUCT_USE_DYNAMIC_PARTITIONS := true
# The system image of aosp_x86_64-userdebug is a GSI for the devices with:
# - x86 64 bits user space
# - 64 bits binder interface
# - system-as-root
# - VNDK enforcement
# - compatible property override enabled
# This is a build configuration for a full-featured build of the
# Open-Source part of the tree. It's geared toward a US-centric
# build quite specifically for the emulator, and might not be
# entirely appropriate to inherit from for on-device configurations.
# GSI for system/product
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_common.mk)
# Emulator for vendor
$(call inherit-product-if-exists, device/generic/goldfish/x86_64-vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
# Enable mainline checking for excat this product name
ifeq (aosp_x86_64,$(TARGET_PRODUCT))
PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
endif
PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
root/init.zygote32_64.rc \
root/init.zygote64_32.rc \
# Copy different zygote settings for vendor.img to select by setting property
# ro.zygote=zygote64_32 or ro.zygote=zygote32_64:
# 1. 64-bit primary, 32-bit secondary OR
# 2. 32-bit primary, 64-bit secondary
# init.zygote64_32.rc is in the core_64_bit.mk below
PRODUCT_COPY_FILES += \
system/core/rootdir/init.zygote32_64.rc:root/init.zygote32_64.rc
# Product 根本信息
PRODUCT_NAME := aosp_x86_64
PRODUCT_DEVICE := generic_x86_64
PRODUCT_BRAND := Android
PRODUCT_MODEL := AOSP on x86_64
inherit-product 函数表明承继另外一个文件
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product-if-exists, device/generic/goldfish/x86_64-vendor.mk)
在 Makefile 中可运用 “-include” 来替代 “include”,来疏忽由于包括文件不存在或许无法创建时的错误提示(“-”的意思是告诉make,疏忽此操作的错误。make持续履行),如果不加-,当 include 的文件犯错或许不存在的时分, make 会报错并退出。
-include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
include 和 inherit-product 的差异:
- 假定
PRODUCT_VAR := a
在 A.mk 中,PRODUCT_VAR := b
在 B.mk 中。 - 如果你在 A.mk 中 include B.mk,你终究会得到
PRODUCT_VAR := b
。 - 但是如果你在 A.mk inherit-product B.mk,你会得到
PRODUCT_VAR := a b
。并 inherit-product 确保您不会两次包括同一个 makefile 。
Product 装备文件中涉及的变量可分为一下几类:
- 通用变量
- 途径变量
- 自界说变量
- 功用变量
通用变量
PRODUCT_BRAND := Android
PRODUCT_NAME := sdk_phone_x86_64
PRODUCT_DEVICE := generic_x86_64
PRODUCT_MODEL := Android SDK built for x86_64
常用的途径变量
- SRC_TARGET_DIR 其值为 build/target
- LOCAL_DIR 代表当时目录
自界说变量,表明该变量怎么运用, 取决于自己,如:
BOARD_DDR_VAR_ENABLED := true
功用变量:表明改变量有特别功用
- PRODUCT_COPY_FILES: 用于完结拷贝,能够将源码中的文件拷贝到编译好的分区文件中
PRODUCT_COPY_FILES += vendor/rockchip/common/phone/etc/spn-conf.xml:system/etc/spn-conf.xml
- PRODUCT_PROPERTY_OVERRIDES: 用于设置体系特点(掩盖)
PRODUCT_PROPERTY_OVERRIDES += \
ro.product.version = 1.0.0 \
3. 增加自己的 Product
这儿假定咱们的公司名叫果冻(Jelly),咱们预备开发一款对标苹果 14 的手机,取名叫 大米14(Rice14)。
接下来咱们在源码中增加咱们自己的产品(Product)
在 device 目录下增加如下的目录与文件:
Jelly/
└── Rice14
├── AndroidProducts.mk
├── BoardConfig.mk
└── Rice14.mk
BoardConfig.mk 包括了硬件芯片架构装备,分区大小装备等信息这儿咱们直接运用 aosp_x86_64 的 BoardConfig.mk 就行。BoardConfig.mk 拷贝自 build/target/board/generic_x86_64/BoardConfig.mk
# x86_64 emulator specific definitions
TARGET_CPU_ABI := x86_64
TARGET_ARCH := x86_64
TARGET_ARCH_VARIANT := x86_64
TARGET_2ND_CPU_ABI := x86
TARGET_2ND_ARCH := x86
TARGET_2ND_ARCH_VARIANT := x86_64
TARGET_PRELINK_MODULE := false
include build/make/target/board/BoardConfigGsiCommon.mk
include build/make/target/board/BoardConfigEmuCommon.mk
BOARD_USERDATAIMAGE_PARTITION_SIZE := 576716800
BOARD_SEPOLICY_DIRS += device/generic/goldfish/sepolicy/x86
# Wifi.
BOARD_WLAN_DEVICE := emulator
BOARD_HOSTAPD_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_simulated
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_simulated
WPA_SUPPLICANT_VERSION := VER_0_8_X
WIFI_DRIVER_FW_PATH_PARAM := "/dev/null"
WIFI_DRIVER_FW_PATH_STA := "/dev/null"
WIFI_DRIVER_FW_PATH_AP := "/dev/null"
Rice14.mk 拷贝自 build/target/product/aosp_x86_64.mk
其间的 if 句子需求注释掉,一起需求修正最终四行
PRODUCT_USE_DYNAMIC_PARTITIONS := true
# The system image of aosp_x86_64-userdebug is a GSI for the devices with:
# - x86 64 bits user space
# - 64 bits binder interface
# - system-as-root
# - VNDK enforcement
# - compatible property override enabled
# This is a build configuration for a full-featured build of the
# Open-Source part of the tree. It's geared toward a US-centric
# build quite specifically for the emulator, and might not be
# entirely appropriate to inherit from for on-device configurations.
# GSI for system/product
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/gsi_common.mk)
# Emulator for vendor
$(call inherit-product-if-exists, device/generic/goldfish/x86_64-vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/emulator_vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/board/generic_x86_64/device.mk)
# Enable mainline checking for excat this product name
#ifeq (aosp_x86_64,$(TARGET_PRODUCT))
PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := relaxed
#endif
PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
root/init.zygote32_64.rc \
root/init.zygote64_32.rc \
# Copy different zygote settings for vendor.img to select by setting property
# ro.zygote=zygote64_32 or ro.zygote=zygote32_64:
# 1. 64-bit primary, 32-bit secondary OR
# 2. 32-bit primary, 64-bit secondary
# init.zygote64_32.rc is in the core_64_bit.mk below
PRODUCT_COPY_FILES += \
system/core/rootdir/init.zygote32_64.rc:root/init.zygote32_64.rc
# Overrides
PRODUCT_BRAND := Jelly
PRODUCT_NAME := Rice14
PRODUCT_DEVICE := Rice14
PRODUCT_MODEL := Android SDK built for x86_64 Rice14
AndroidProducts.mk 内容如下:
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/Rice14.mk
COMMON_LUNCH_CHOICES := \
Rice14-eng
Rice14-userdebug
Rice14-user
最终验证:
source build/envsetup.sh
lunch Rice14-eng
make -j16
emulator
以上示例给出了最简略的模拟器 Product 的增加,首要是用于咱们的学习。
参考资料
- 增加新设备
- Android体系10 RK3399 init进程启动(十五) 装备新产品
- Android体系开发入门-2.增加product
- 怎么为 AOSP 的 lunch 新增一个菜单项