AOSP构建时如何选择源码编译或使用预编译文件
AOSP构建:通过环境变量切换源码/预编译media-service模块的方案
问题背景
正在开展AOSP构建相关工作,需为新增的media-service调整构建系统:
- 源码编译:依赖
vendor/rishit/services/media-service/下的Android.bp定义目标及依赖,可正常运行 - 预编译构建:将预编译文件放入
vendor/oculus/exported-services/,通过该目录的Android.bp定义目标(移除源码目录时可正常构建)
需求:保留源码目录的前提下,通过环境变量在lunch构建时选择使用源码或预编译文件,但两者共存时出现模块重复定义错误:
error: vendor/oculus/exported-prebuilts/Android.bp:1128:1: module "prebuilt_libmediadetector" already defined vendor/rishit/services/media-capture/libs/libmediadetector/Android.bp:11:1 <-- previous definition here
目录结构:
./vendor ├── ./vendor/oculus │ └── ./vendor/oculus/exported-services │ └── ./vendor/oculus/exported-services/Android.bp └── ./vendor/rishit └── ./vendor/rishit/services ├── ./vendor/rishit/services/Android.bp └── ./vendor/rishit/services/media-service ├── ./vendor/rishit/services/media-service/aidl ├── ./vendor/rishit/services/media-service/apps ├── ./vendor/rishit/services/media-service/include ├── ./vendor/rishit/services/media-service/libs ├── ./vendor/rishit/services/media-service/mocks ├── ./vendor/rishit/services/media-service/services ├── ./vendor/rishit/services/media-service/test └── ./vendor/rishit/services/media-service/tools
当前疑问:考虑过改用.mk文件定义目标,构建时选择引入对应的makefile,但不确定是否为最优方案;想了解是否可通过soong_namespaces实现,或是否需要将两个Android.bp转为Android.mk。
可行解决方案
方案一:利用Soong条件编译(推荐)
Soong支持通过环境变量控制模块是否编译,无需转换为Android.mk,是AOSP当前的主流方式:
- 在源码模块的Android.bp(
vendor/rishit/services/media-service/libs/libmediadetector/Android.bp)中添加条件判断:
if (!defined(env.get("USE_PREBUILT_MEDIA_SERVICE")) || env.get("USE_PREBUILT_MEDIA_SERVICE") != "true") { cc_library { name: "libmediadetector", // 原源码模块的所有配置(srcs、includes、shared_libs等) } }
- 在预编译模块的Android.bp(
vendor/oculus/exported-services/Android.bp)中添加条件判断:
if (defined(env.get("USE_PREBUILT_MEDIA_SERVICE")) && env.get("USE_PREBUILT_MEDIA_SERVICE") == "true") { cc_prebuilt_library_shared { name: "libmediadetector", srcs: ["path/to/prebuilt/libmediadetector.so"], // 原预编译模块的其他配置 } }
- 使用方式:
- 编译源码版本:直接执行常规构建命令(无需设置环境变量)
- 编译预编译版本:构建前先设置环境变量
export USE_PREBUILT_MEDIA_SERVICE=true lunch <your-target> m
方案二:Soong Namespaces配合模块重定向(备选)
单纯的Soong Namespaces无法解决模块名重复问题,需配合模块重命名+依赖切换:
- 将预编译模块名改为
prebuilt_libmediadetector,源码模块保持libmediadetector - 在依赖该模块的上层Android.bp中,通过环境变量选择依赖的模块:
cc_binary { name: "media-service", shared_libs: [ env.get("USE_PREBUILT_MEDIA_SERVICE") == "true" ? "prebuilt_libmediadetector" : "libmediadetector", // 其他依赖 ], }
此方案适合需要同时保留两个模块定义的场景,但不如方案一直接。
方案三:改用Android.mk(兼容旧构建流程)
如果需要兼容传统Make构建流程,可将模块定义转为Android.mk,并通过条件引入:
- 将源码模块的配置转为
vendor/rishit/services/media-service/Android.mk,预编译模块转为vendor/oculus/exported-services/Android.mk - 在顶层的
vendor/rishit/services/Android.mk中添加条件判断:
ifeq ($(USE_PREBUILT_MEDIA_SERVICE),true) include $(LOCAL_PATH)/../oculus/exported-services/Android.mk else include $(LOCAL_PATH)/media-service/Android.mk endif
- 确保对应的Android.bp文件被排除(比如重命名为
Android.bp.disabled),避免Soong重复扫描
总结
优先选择方案一,利用Soong原生的环境变量条件编译,无需修改构建系统结构,符合AOSP当前的构建趋势,实现成本最低且灵活性最高。
内容的提问来源于stack exchange,提问作者Rishit
相关产品推荐
相关产品推荐

