知识图库
Java知识库
JDK线程池实现原理
Java中的强、软、弱、虚引用
深入拆解Java虚拟机
01 开篇词 | 为什么我们要学习Java虚拟机?
02 Java代码是怎么运行的?
03 Java的基本类型
04 Java虚拟机是如何加载Java类的?
05 JVM是如何执行方法调用的?(上)
06 JVM是如何执行方法调用的?(下)
7 JVM是如何处理异常的?
Java面试常见问题整理
Java面试常见问题-Java 基础篇
Java面试常见问题-Jvm篇
Java面试常见问题-并发篇
Android知识库
Kotlin编程第一课
1 开篇词 | 入门Kotlin有多容易,精通Kotlin就有多难
2 Kotlin基础语法:正式开启学习之旅
3 面向对象:理解Kotlin设计者的良苦用心
4 Kotlin原理:编译器在幕后干了哪些“好事”?
5 实战:构建一个Kotlin版本的四则运算计算器
6 object关键字:你到底有多少种用法?
7 扩展:你的能力边界到底在哪里?
8 高阶函数:为什么说函数是Kotlin的“一等公民”?
9 实战:用Kotlin写一个英语词频统计程序
10 加餐一 | 初识Kotlin函数式编程
11 委托:你为何总是被低估?
12 泛型:逆变or协变,傻傻分不清?
13 注解与反射:进阶必备技能
14 实战:用Kotlin实现一个网络请求框架KtHttp
15 加餐二 | 什么是“表达式思维”?
16 加餐三 | 什么是“不变性思维”?
17 加餐四 | 什么是“空安全思维”?
18 春节刷题计划(一)| 当Kotlin遇上LeetCode
19 春节刷题计划(二)| 一题三解,搞定版本号判断
20 春节刷题计划(三)| 一题双解,搞定求解方程
21 春节刷题计划(四)| 一题三解,搞定分式加减法
22 什么是“协程思维模型”?
23 如何启动协程?
24 挂起函数:Kotlin协程的核心
25 Job:协程也有生命周期吗?
26 Context:万物皆为Context?
27 实战:让KtHttp支持挂起函数
28 期中考试 | 用Kotlin实现图片处理程序
29 题目解答 | 期中考试版本参考实现
30 Channel:为什么说Channel是“热”的?
31 Flow:为什么说Flow是“冷”的?
32 select:到底是在选择什么?
33 并发:协程不需要处理同步吗?
34 异常:try-catch居然会不起作用?坑!
35 实战:让KtHttp支持Flow
36 答疑(一)| Java和Kotlin到底谁好谁坏?
37 集合操作符:你也会“看完就忘”吗?
38 协程源码的地图:如何读源码才不会迷失?
39 图解挂起函数:原来你就是个状态机?
40 加餐五 | 深入理解协程基础元素
41 launch的背后到底发生了什么?
42 Dispatchers是如何工作的?
43 CoroutineScope是如何管理协程的?
44 图解Channel:如何理解它的CSP通信模型?
45 图解Flow:原来你是只纸老虎?
46 Java Android开发者还会有未来吗?
47 Kotlin与Jetpack简直是天生一对!
48 用Kotlin写一个GitHub Trending App
49 结课测试 | “Kotlin编程第一课”100分试卷等你来挑战!
50 结束语 | 不忘初心
Android Framework 教程—基础篇
01 Ubuntu 使用快速入门
02 Make 构建工具入门
03 理解 Unicode UTF-8 UTF-16 UTF-32
04 Linux Shell 脚本编程入门1——核心基础语法
05 SeAndroid 使用极速上手
06 理解 C++ 的 Memory Order
07 AOSP 极速上手
08 系统开发工具推荐
09 添加 Product
运动相关知识
爱上跑步
01 开篇词 | 跑步,不那么简单的事儿
02 跑两步就喘了,是不是我不适合跑步?
03 正确的跑步姿势是什么样的?
04 为什么跑步要先热身?
05 怎样制定你的第一个10公里跑步计划?
06 快跑和慢跑,哪个更燃脂?
07 普通跑步者应该如何选择跑鞋?
08 买跑步装备,不要踩这些坑儿
09 跑步前到底应不应该吃东西?
10 跑步到底伤不伤膝盖?
11 参加了20场马拉松,我是如何准备的?
12 除了马拉松,还能参加哪些跑步赛事?
13 热点问题答疑 :跑完第二天浑身疼,还要不要继续跑?
健身房计划
[DeepSeek]减脂塑形计划
【DeepSeek】训练周期安排
每日餐饮热量控制
减脂期间食物推荐避坑指南
HarmonyOS知识库
其他知识类目
心理学相关
如何学点心理学——关于非专业人士学心理学的一点建议
投射性认同
-
+
首页
09 添加 Product
### 1. 什么是 Product 在 App 的开发中,我们要去打渠道包,根据不同应用市场的要求打包出不同的 apk 包。 同样的道理,Android 的系统源码,经过简单的配置,可以打包出不同的系统镜像,用于不同的产品。例如小米 12s,小米12s pro,小米12s ultra 均源于骁龙8+平台。  Android 系统源码是通过配置文件来实现 “分包” 的,配置文件将我们的源码配置为了不同的 Product,每一个 Product 适用于特定的硬件产品,这一系列的配置文件我们称为 Product。 ### 2. AOSP 中预制的 Product 我们在编译源码之前需要执行 lunch : ```bash 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 基本的目录结构: ```shell 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导航等一些板级特性。 ```bash # 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 命令时,打印的列表以及每个选项对应的配置文件 ```bash # 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**:这个文件就是我们产品配置的主基地。 ```bash 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** 函数表示继承另外一个文件 ```bash $(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 会报错并退出。 ```bash -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 配置文件中涉及的变量可分为一下几类:** - 通用变量 - 路径变量 - 自定义变量 - 功能变量 **通用变量** ```makefile 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 代表当前目录 **自定义变量**,表示该变量如何使用, 取决于自己,如: ```makefile BOARD_DDR_VAR_ENABLED := true ``` **功能变量:**表示改变量有特殊功能 - PRODUCT_COPY_FILES: 用于完成拷贝,可以将源码中的文件拷贝到编译好的分区文件中 ```makefile PRODUCT_COPY_FILES += vendor/rockchip/common/phone/etc/spn-conf.xml:system/etc/spn-conf.xml ``` - PRODUCT_PROPERTY_OVERRIDES: 用于设置系统属性(覆盖) ```makefile PRODUCT_PROPERTY_OVERRIDES += \ ro.product.version = 1.0.0 \ ``` ### 3. 添加自己的 Product 这里假设我们的公司名叫果冻(Jelly),我们准备开发一款对标苹果 14 的手机,取名叫 大米14(Rice14)。 接下来我们在源码中添加我们自己的产品(Product) 在 device 目录下添加如下的目录与文件: ```bash 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` ```bash # 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 语句需要注释掉,同时需要修改最后四行 ```makefile 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 内容如下: makefile 代码解读复制代码PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/Rice14.mk COMMON_LUNCH_CHOICES := \ Rice14-eng \ Rice14-userdebug \ Rice14-user \ ``` ### 最后验证: ```bash source build/envsetup.sh lunch Rice14-eng make -j16 emulator ``` 以上示例给出了最简单的模拟器 Product 的添加,主要是用于我们的学习。 ### 参考资料 - [添加新设备](https://link.juejin.cn/?target=https%3A%2F%2Fsource.android.com%2Fdocs%2Fsetup%2Fcreate%2Fnew-device) - [Android系统10 RK3399 init进程启动(十五) 配置新产品](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fldswfun%2Farticle%2Fdetails%2F121931548%3Fspm%3D1001.2014.3001.5502) - [Android系统开发入门-2.添加product](https://link.juejin.cn/?target=http%3A%2F%2Fqiushao.net%2F2019%2F11%2F19%2FAndroid%25E7%25B3%25BB%25E7%25BB%259F%25E5%25BC%2580%25E5%258F%2591%25E5%2585%25A5%25E9%2597%25A8%2F2-%25E6%25B7%25BB%25E5%258A%25A0product%2F) - [如何为 AOSP 的 lunch 新增一个菜单项](https://link.juejin.cn/?target=https%3A%2F%2Fgitee.com%2Faosp-riscv%2Fworking-group%2Fblob%2Fmaster%2Farticles%2F20220315-howto-add-lunch-entry.md%23%2Faosp-riscv%2Fworking-group%2Fblob%2Fmaster%2Farticles%2F20220908-add-app-in-aosp.md) - [android build system中product的继承(inherit-product),加载(import-products)和选择(lunch)](https://link.juejin.cn/?target=https%3A%2F%2Fblog.csdn.net%2Fayu_ag%2Farticle%2Fdetails%2F74742842)
嘿手大叔
2025年1月3日 17:28
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码