Android系统开发入门-2.添加product

前面我们都是编译 Android 内置的 product 进行验证的,但真正做产品的时候,我们通常是需要添加自己的 product的。
一般来说一个 product 有四个要素:

  • vendorsetup.sh : 把 product 添加到 lunch 选择项中
  • BoardConfig.mk : 芯片硬件相关配置,分区设置等
  • AndroidProducts.mk : 指定 product 配置
  • product.mk : 一个产品的软件相关的配置,比如内置哪些软件模块,由AndroidProducts.mk 中的PRODUCT_MAKEFILES指定

但在 Android 10 的时候 vendorsetup.sh 文件已经不需要了,对应的功能被移到了AndroidProducts.mk中。
下面我们参考 aosp_x86_64 这个 product 来一步一步创建一个我们自己的 product。

1. 创建 device 目录

上面我们说了一个 product 有四个要素,那这四个要素总得有个容身之处。
在 Android 系统上,product 的四要素放在两个地方, 一个是 device 目录,用来给各厂商放 product 的。
另一个是 build/target 目录,用来放 google 官方内置的 aosp product。
build/target/product 里面放 AndroidProducts.mk, 跟 product.mk, build/target/board 里面放 BoardConfig.mk 等。

我们在 device 目录添加 product 就行。先创建 device 目录。
目录结构按这种形式创建: device/[company]/[device]

1
mkdir -p device/qiushao/pure

注意,这里我们说的是 device 目录, 而不是 prodcut 目录。
我们可以这么理解, device 是硬件相关的芯片平台级配置, product 是软件相关的配置。
一个 device 下面可以有多个 product,即同一块硬件板子上,可以内置不同的软件模块。

2. 新建板级配置 BoardConfig.mk

BoardConfig.mk 包含了硬件芯片架构配置,分区大小配置等信息
这里我们直接使用 aosp_x86_64 的 BoardConfig.mk 就行

1
include $(SRC_TARGET_DIR)/board/generic_x86_64/BoardConfig.mk

3. 新建 product 配置 pure.mk

我们直接继承 aosp_x86_64 的 product 配置,再稍作修改就行

1
2
3
4
$(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_x86_64.mk)

PRODUCT_NAME := pure
PRODUCT_DEVICE := pure

其中 PRODUCT_NAME 跟 PRODUCT_DEVICE 是最重要的两个变量,需要我们自己重新赋值。
PRODUCT_NAME 要保持跟配置文件名一致。编译输出目录就是由这个变量决定的。
PRODUCT_DEVICE 跟BoardConfig.mk相关,编译系统会根据$(PRODUCT_DEVICE) 来加载对应目录下的BoardConfig.mk文件。

4. 新建 AndroidProducts.mk

AndroidProducts.mk 中定义了变量 PRODUCT_MAKEFILES,列出了我们在第三步添加的 product 配置文件。
在 Android 10 中还多了一个变量 COMMON_LUNCH_CHOICES。这个变量是用来取代 vendorsetup.sh 的作用的。

1
2
3
4
5
PRODUCT_MAKEFILES := \
$(LOCAL_DIR)/pure.mk

COMMON_LUNCH_CHOICES := \
pure-eng

我们在 lunch 界面可以看到 pure-eng 这个选项,就是由这里的COMMON_LUNCH_CHOICES变量配置的。
其中 pure 为 product name。这里我们可以添加多个 product,但为了简单起见,只添加一个就行。
eng 为 build type。有以下几种配置:

  • eng : 对应到工程版。编译打包所有模块。同时ro.secure=0, ro.debuggable=1, ro.kernel.android.checkjni=1,表示adbd处于ROOT状态,所有调试开关打开
  • userdebug : 对应到用户调试版。同时ro.debuggable=1,打开调试开关,但并没有放开ROOT权限
  • user : 对应到用户版。同时ro.secure=1,ro.debuggable=0,关闭调试开关,关闭ROOT权限。最终发布到用户手上的版本,通常都是user版。

5. 编译验证

至此,我们就定义好了一个最简单的 product 出来了, 目录结构如下:

1
2
3
4
5
qiushao
└── pure
├── AndroidProducts.mk
├── BoardConfig.mk
└── pure.mk

接下来编译验证一下看看能否用虚拟机跑起来,如果跑不起来请仔细核对一下以上步骤是否有问题。

1
2
3
4
source build/envsetup.sh
lunch pure-eng
make -j
emulator

启动虚拟机后我们看一下设置中的系统版本信息如下:
add-product-emulator

product name, 编译时间都对上了,说明我们自己创建的 product 已经可以编译运行了。
后面我们就可以慢慢的在这个 product 上加功能了。