生成Android SDK的深入探索
基于 KitKat(KRT16S)、ARM 平台配置进行描述。
一、基础概念
1、 sdk 级别
高级别 sdk:一般就是指 android.jar,这个在做应用开发的时候可以直接导入;
低级别 sdk:通过如 "make sdk" 命令生成的 zip 文件,包含 platforms、platform-tools、tools 等目录,以及模拟器、avd 管理器、sdk 管理器等;这个需要开发工具如 eclipse 进行配置方可使用;也是本文档所描述的 sdk 形式;
2、 android 完整代码的编译
简单的来说,完整的编译过程是三个步骤:
步骤一:"source bulid/envsetup.sh",配置通用的编译环境变量;
步骤二:"lunch",选择 product(或称 device),配置平台相关的编译环境变量;
官方的代码如果未做任何修改一般是显示如下 product(或称 device) 选择菜单:
- 1.aosp_arm - eng 2.aosp_x86 - eng 3.aosp_mips - eng 4.vbox_x86 - eng 5.aosp_manta - userdebug 6.mini_mips - userdebug 7.mini_armv7a_neon - userdebug 8.mini_x86 - userdebug 9.aosp_deb - userdebug 10.aosp_grouper - userdebug 11.aosp_tilapia - userdebug 12.aosp_flo - userdebug 13.aosp_hammerhead - userdebug 14.aosp_mako - userdebug
选择不同的 product(或称 device) 项,则用于编译的主要环境变量 TARGET_PRODUCT、TARGET_BUILD_VARIANT、TARGET_BUILD_TYPE、TARGET_ARCH_VARIANT、TARGET_CPU_VARIANT 均有所不同。例如,如果选择第 7 项,相关环境变量是:
- TARGET_PRODUCT = mini_armv7a_neon TARGET_BUILD_VARIANT = userdebug TARGET_BUILD_TYPE = release TARGET_ARCH_VARIANT = armv7 - a - neon TARGET_CPU_VARIANT = cortex - a9
在官方实现的基础上可以通过自行定制来扩展 product(或称 device),如 vendor_test_eng,相关环境变量是:
- TARGET_PRODUCT = vendor_test TARGET_BUILD_VARIANT = eng TARGET_BUILD_TYPE = release TARGET_ARCH_VARIANT = armv7 - a - neon TARGET_CPU_VARIANT = cortex - a7
步骤三:make [-j N]如果跳过步骤二直接执行步骤三,则相关环境变量设置如下:
- TARGET_PRODUCT = full TARGET_BUILD_VARIANT = eng TARGET_BUILD_TYPE = release TARGET_ARCH_VARIANT = armv7 - a TARGET_CPU_VARIANT = generic
3、 android 的编译系统用于 android 代码编译的配置文件都集中存放于 build/core 目录下,而官方提供的 product(或称 device) 配置文件则集中存放于 build/target 目录下。通过 lunch 的选择,将相应的配置文件加载后即进入编译环节。编译系统如何搜寻到对应 product(或称 device) 的配置文件是在 build/core/config.mk 中决定的:
- board_config_mk: =\$(strip $(wildcard\$(SRC_TARGET_DIR) / board / $(TARGET_DEVICE) / BoardConfig.mk\$(shell test - d device && find device - maxdepth 4 - path '*/$(TARGET_DEVICE)/BoardConfig.mk')\$(shell test - d vendor && find vendor - maxdepth 4 - path '*/$(TARGET_DEVICE)/BoardConfig.mk')\))
根据这些内容,可以得出搜索 product(或称 device) 配置文件目录的优先级:(1) build/target/board/$(TARGET_DEVICE)/BoardConfig.mk这也是官方提供的系列 product(或称 device) 的配置文件所在目录
(2) device/*/$(TARGET_DEVICE)/BoardConfig.mk这也是自行定制 product(或称 device) 存放的目录
(3) vendor/*/$(TARGET_DEVICE)/BoardConfig.mk这个目录在官方代码中不存在,其它公司如高通的代码存在这个目录。
二、生成官方 sdk 的方式1、 官方的文档介绍在代码树中主要有三个文档描述了生成官方 sdk 的方式:(1) sdk/README.txt严格来说,这个文档只是描述要生成官方 sdk 的预备工作,以及如何更新 sdk tools。值得关注的就是 tools/base 和 tools/swt 这两个仓库已经做为非缺省下载的仓库了,如果在 repo init 的时候不按要求进行,这两个仓库是不会下载的,也就无法完成官方 sdk 的生成工作。对于大多数开发的公司来说,拿到的代码已经是上游芯片厂商做过修改的非官方原始版本了,有可能芯片厂商的代码仓库中已经不包含这两个仓库了。在生成官方 sdk 的实际过程中,从第三方开源项目 (如 codeaurora) 中复制这两个仓库过来也顺利生成了官方 sdk,这样就避免了无法从芯片厂商获取到仓库的问题。
(2) sdk/docs/howto_build_SDK.txt这个文档描述了在 linux 下生成运行于 linux 或 windows 平台的官方 sdk 的方法以及一些注意事项。很多人认为其中描述的方法不对是因为对于第一章节提及的基础概念理解不透彻,相关的问题是:A) make sdk(或 make win_sdk) 会失败此种情况一般是 lunch 选择了定制的 product(或称 device) 后出现的错误,此时 TARGET_PRODUCT 和 TARGET_CPU_VARIANT 的值对应的是定制 prodcut(或称 device),也就是需要到 device/*/$(TARGET_DEVICE) 目录下配置文件去寻找的信息。如果跳过 lunch 直接 make sdk(或 make win_sdk),则 TARGET_PRODUCT 是 full,TARGET_CPU_VARIANT 是 generic,这个与官方的初衷是相违背的,原因见 B)
B) make PRODUCT-sdk-sdk(或 make PRODUCT-win_sdk) 成功文档中介绍的方法是 lunch sdk-eng、make sdk,通过对比关键的环境变量发现两者其实是一致的,下面是最重要的两个环境变量值:
- TARGET_PRODUCT = sdk TARGET_CPU_VARIANT = generic
因此得出三点结论:第一,生成官方 sdk 是需要 TARGET_PRODUCT 为 sdk 的 (对应 build/target/product/sdk.mk);第二,不管执不执行 lunch,make PRODUCT-sdk-sdk 的环境变量都一样,所以它是将两步操作合二为一的操作,命令中第一个 "sdk" 关键字是指定 product 类型为 sdk;第三,官方没有提供生成自定制 product(或称 device) 的 sdk(下称 vendor sdk) 的方法,为此引出了问题 C)
C) 此问题其实是问题 A) 的引申,即在定制 vendor sdk 后会出现错误:
- build / core / main.mk: 664 : ***:Module 'bluetooth-health' in PRODUCT_PACKAGES has nothing toinstall ! .Stop.
关于此问题的原因,最终在官方论坛上找到了正式说法:Question:Module 'bluetooth-health' inPRODUCT_PACKAGES has nothing to install
Answer:This works as intended.We intentionally made that be an error forsdk, for we want to make sure the SDK build installs everything in its productconfig.Actually we want to enforce this check forall device builds as well, but unfortunately it takes much work to clean up thelegacy product configs.You need to build the sdk in the sdkproduct config; or you should clean the dangling module names from the productconfig.Anyway, we should remove those danglingmodule names (bluetooth-health hostapd wpa_supplicant.conf audio dhcpcd.confnetwork pand sdptool egl.cfg) from the build system.也就是说这是有意为之,因为官方无法完全兼容所有 vendor sdk 的配置项,只能通过错误信息的方式来让 vendor 自行修改并生成 vendor sdk。
D) 资源相关问题框架的布局、图片、文字等资源信息是存放在 frameworks/base/core/res 下的,上游芯片厂商或下游开发公司在定制框架的时候也需要增加资源,但是出于某种目的会将资源以 overlay 的方式存放于 product(或称 device) 的目录下,框架中仅做引用,这就会导致在生成官方 sdk 的时候出现资源缺失错误。遇到这种问题,办法一就是复制相关资源到框架中,办法二就是想办法生成 vendor sdk(下有描述)。
(3) sdk/monitor/HOWTO-BUILD严格来说,这个文档是与生成 vendor sdk 相关,对于官方 sdk 可忽略此部分。在 sdk 中有一个工具 monitor(具体用法本文不探讨),在官方 sdk 方式下能生成,在 vendor sdk 方式下无法生成。通过查阅此文档发现生成 monitor 的配置文件 sdk/monitor/Android.mk 生效条件是:
- #Expose the Monitor RCPonly
- for the SDK builds.ifneq(, $(is_sdk_build) $(filtersdk sdk_x86 sdk_mips, $(TARGET_PRODUCT)))
即仅在 product 类型为 sdk、sdk_x86、sdk_mips 的情况下生成 monitor,也就是官方 sdk 的方式。
三、生成厂商 sdk 的方式其实生成官方 sdk 已经能满足应用开发需求,但是由于未包含厂商相关的内容,在联机调试时是否会有问题还有待考证。根据前面二个章节的描述,生成 vendor sdk 除了要选择正确的 product(或称 device),还必须做一些配置文件的修改和调整,主要是针对几个错误进行:错误一:build/core/main.mk:664: *** : Module 'X' inPRODUCT_PACKAGES has nothing to install!. Stop.遇到这种问题就是屏蔽此模块在配置文件中的引用。
错误二:make[1]: *** No rule to make target`monitor', needed by `PRODUCT-vendor_test-aapt'. Stop.解决办法见第二章节的相关说明。
错误三:make[1]: Nothing to be done for `X'.这个发生在生成 zip 文件时,主要是如 aidl、adb、emulator 等工具无法获取 (实际已在 out 目录下生成),暂时的解决办法也是屏蔽。但为什么官方 sdk 无此错误,就需要比对 product 配置信息了。
四、引用1、Android Makefile 中是 如何识别 TARGET_PRODUCT 的http://blog.csdn.net/stevenliyong/article/details/5285334
2、Android 平台开发 - Customize newdevice - 定制新设备http://blog.sina.com.cn/s/blog_60862cad0100wuaf.html
3、编译 Android 模拟器(make sdk),以及错误处理http://blog.csdn.net/gaojinshan/article/details/9420869
4、Module 'bluetooth-health' inPRODUCT_PACKAGES has nothing to installhttps://code.google.com/p/android/issues/detail?id=61210
5、Android 编译系统详解 (一)——build/envsetup.shhttp://www.cloudchou.com/android/post-134.html
来源: http://lib.csdn.net/article/android/49082