AOSP.~ Android.bp 添加自定义模块

早期的Android系统都是采用Android.mk的配置来编译源码,从Android 7.0开始引入Android.bp。很明显Android.bp的出现就是为了替换掉Android.mk。如果你从 Android7.0 的代码一路看到 Android10.0,你就会发现系统的各个模块正在逐步替换成 Android.bp。既然官方都在逐步弃用 Android.mk 了,那我们也跟随官方的脚步使用 Android.bp 来创建新模块。

可执行文件:cc_binary

下面我们以一个 hello world 模块为例来初步认识一下一个 Android.bp 模块的相关概念。
在 device/qiushao/pure 目录下创建一个 hello 目录,创建 hello.cpp:

#include <cstdio>
#include <android/log.h>

#define LOG_TAG "qiushao"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG ,__VA_ARGS__)

int main() {
    printf("hello qiushao\n");
    LOGD("hello qiushao");
    return 0;
}

在 hello 目录下创建 Android.bp

cc_binary {              //模块类型为可执行文件
    name: "hello",       //模块名hello
    srcs: ["hello.cpp"], //源文件列表
    vendor: true,        //编译出来放在/vendor目录下(默认是放在/system目录下)
    shared_libs: [       //编译依赖的动态库
        "liblog",
    ],
}

至此一个模块就已经添加完成了,接下来我们可以在 hello 目录下用 mm 命令测试一下是否可以编译通过

qiushao@qiushao-pc:~/source/android-10/device/qiushao/pure/hello$ mm -j
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=10
TARGET_PRODUCT=pure
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_ARCH=x86_64
TARGET_ARCH_VARIANT=x86_64
TARGET_2ND_ARCH=x86
TARGET_2ND_ARCH_VARIANT=x86_64
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.0.0-37-generic-x86_64-Ubuntu-18.04.3-LTS
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=QD1A.190821.011
OUT_DIR=out
============================================
[100% 7/7] Install: out/target/product/pure/vendor/bin/hello

#### build completed successfully (1 seconds) ####

qiushao@qiushao-pc:~/source/android-10/device/qiushao/pure/hello$

在 device/qiushao/pure/pure.mk 中添加配置

PRODUCT_PACKAGES += hello

添加这个配置之后,编译系统时就会自动编译并打包这个模块到系统里面。
我们完整编译一下系统,运行虚拟机,然后连接 adb shell 执行刚刚添加的模块:

qiushao@qiushao-pc:~/source/android-10$ adb shell
pure:/ # hello                                                                                                                                                                                                                  
hello qiushao
pure:/ # which hello
/vendor/bin/hello
pure:/ #

我们来回顾一下 Android.bp 的内容,也就几行配置而已,非常简单。当然其实还有非常多的配置我们并没有使用到。
具体的配置项可以参考以下文档 cc_binary

c/c++ 库:cc_library

cc_library {               //模块类型为c/c++库, 会同时编译动态库和静态库, 
                           //如果要指定编译动态库或者静态库,则应该要用 cc_library_shared 或者 cc_library_static
    name: "libpure_utils", //模块名
    vendor: true,          //安装到 vendor 分区
    export_include_dirs: ["include"], //导出头文件目录,这样其他模块要使用本模块的时候,就不需要用 include_dirs 指定头文件目录了。
    srcs: ["src/pure_log.cpp", "src/pure_thread.cpp"], //源文件列表, 如果不想要一个一个列出来,
                                                       //可以使用 srcs: ["**/*.cpp"] 这种方式来查找所有的 cpp 文件。
    shared_libs: [         //依赖的动态库
        "liblog",
    ],
}

java 库:java_library

java_library {         //模块类型为 java 库,这个类型与 java_library_static 是完全一样的
    name: "api.pure",  //模块名
    installable: true, //下面详细说明
    enabled: true,     //是否编译这个模块,有时候我们需要根据某些条件,关闭某个模块。 
    dex_preopt: {
        enabled: false, //不做 preopt, 
    },
    srcs: [
        "java/**/*.java", //文件列表
    ],
    libs: [
        "android.hidl.manager-V1.0-java", //依赖的其他 java 库
    ],
}

其中 installable 配置有必要作下说明,官方文档是这么写的:

java_library builds and links sources into a .jar file for the device, and possibly for the host as well. By default, a java_library has a single variant that produces a .jar file containing .class files that were compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used as a static_libs dependency of another module. Specifying installable: true will product a .jar file containing classes.dex files, suitable for installing on a device.

简单的说就是如果不指定 installable: true, 则编译出来的 jar 包里面是 .class 文件。这种包是没法安装到系统上的,只能给其他 java 模块作为 static_libs 依赖。
指定 installable: true, 则编译出来的 jar 包里面是 classes.dex 文件。这种才是 Android 虚拟机可以加载的格式。

上面的这几个例子是最常见的模块。Android 系统中还有非常多种类型的模块。这里面就不一一举例了,需要定义其他类型的模块时,可以参考以下文档 soong。或者参考系统已有的 Android.bp 模块。

模块编译输出分区

前面的几个例子,我们只有输出到 system 或者 vendor 分区这两种选择, 其实系统还有其它几个目录可以输出的,下面对这些目录的作用及怎么指定模块的输出分区作下说明:

system :主要包含 Android 框架, google 官方实现

  • Android.mk 默认就是输出到 system 分区,不用指定
  • Android.bp 默认就是输出到 system 分区,不用指定

vendor :SoC芯片商分区(系统级核心厂商,如高通), 为他们提供一些核心功能和服务,由 soc 实现

  • Android.mk LOCAL_VENDOR_MODULE := true
  • Android.bp vendor: true

odm :设备制造商分区(如华为、小米),为他们的传感器或外围设备提供一些核心功能和服务

  • Android.mk LOCAL_ODM_MODULE := true
  • Android.bp device_specific: true

product :产品机型分区

  • Android.mk LOCAL_PRODUCT_MODULE := true
  • Android.bp product_specific

参考


2020-05-23 Android系统开发入门-16.Android系统添加 bootjar
2020-02-05 Android系统开发入门-15.Android.bp 条件编译
2020-02-04 Android系统开发入门-14.Android studio 导入系统源码
2020-02-03 Android系统开发入门-13.Binder服务死亡讣告
2020-01-10 Android系统开发入门-12.hidl服务回调
2020-01-07 Android系统开发入门-11.添加hidl服务
2019-12-31 Android系统开发入门-10.native服务回调
2019-12-29 Android系统开发入门-9.添加native系统服务
2019-12-22 Android系统开发入门-8.java服务回调
2019-12-20 Android系统开发入门-7.添加java层系统服务
2019-12-12 Android系统开发入门-6.删除Android原生内置APK
2019-12-10 Android系统开发入门-5.添加预编译模块
2019-11-22 Android系统开发入门-4.添加自定义模块
2019-11-20 Android系统开发入门-3.添加系统属性
2019-11-19 Android系统开发入门-2.添加product
2019-11-16 Android系统开发入门-1.Android系统源码下载编译
2019-11-15 Android系统开发入门-0.开发环境准备

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android AOSP 源码的 device 目录下添加自定义的 framework 模块的步骤如下: 1. 创建新的模块目录: 在 device/{vendor_name}/{device_name}/ 目录下创建一个新的子目录,用于存放自定义的 framework 模块。例如,可以创建一个名为 myframework 的目录: ``` mkdir -p device/{vendor_name}/{device_name}/myframework ``` 2. 添加 Android.mk 文件: 在 myframework 目录下创建一个名为 Android.mk 的文件,用于定义自定义的 framework 模块。例如,可以添加以下代码: ``` LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := myframework LOCAL_MODULE_TAGS := optional LOCAL_MODULE_CLASS := JAVA_LIBRARIES LOCAL_SRC_FILES := MyFramework.java LOCAL_SDK_VERSION := current LOCAL_JAVA_LIBRARIES := core-libart LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 LOCAL_STATIC_ANDROID_LIBRARIES := libsqlite include $(BUILD_JAVA_LIBRARY) ``` 其中: - LOCAL_MODULE 定义了模块名称; - LOCAL_MODULE_TAGS 定义了模块的标签,optional 表示该模块是可选的; - LOCAL_MODULE_CLASS 定义了模块的类型,JAVA_LIBRARIES 表示该模块是一个 Java 库; - LOCAL_SRC_FILES 定义了该模块中包含的 Java 源代码文件; - LOCAL_JAVA_LIBRARIES 定义了该模块所依赖的 Java 库; - LOCAL_STATIC_JAVA_LIBRARIES 和 LOCAL_STATIC_ANDROID_LIBRARIES 定义了该模块所依赖的静态库和 Android 库。 3. 添加 Android.bp 文件: 在 myframework 目录下创建一个名为 Android.bp 的文件,用于定义自定义的 framework 模块。例如,可以添加以下代码: ``` java_library { name: "myframework", srcs: ["MyFramework.java"], static_libs: [ "core-libart", "android-support-v4", ], shared_libs: [ "libsqlite", ], sdk_version: "current", installable: true, } ``` 其中: - name 定义了模块名称; - srcs 定义了该模块中包含的 Java 源代码文件; - static_libs 定义了该模块所依赖的静态库; - shared_libs 定义了该模块所依赖的共享库; - sdk_version 定义了该模块所需的 Android SDK 版本; - installable 定义了该模块是否可安装。 4. 编译 Android 系统: 在编译 Android 系统之前,需要先执行以下命令: ``` source build/envsetup.sh ``` 然后编译 Android 系统: ``` lunch {device_name}-{build_type} make -j{n} ``` 其中 {device_name} 是设备名称,{build_type} 是编译类型(如 userdebug),{n} 是编译线程数。 编译完成后,就可以在 Android 系统中使用自定义的 framework 模块了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值