安卓源码环境下编译多module app

背景

项目的背景是要将 android studio 下开发的 apk 源码,放到安卓系统源码中进行编译,并随系统版本发布。对于稍复杂一些的 apk,可能存在多模块,这类文章比较少。这里对于这类项目,本文至少可以提供一些实践及思路。

apk 源码结构

一个标准的 Android Studio apk 项目源码结构。

--app
----....//一些项目文件
----module1
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml
----module2
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml
----module3
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml

思路

实际上 Android Studio 使用的 gradle 构建 apk,而安卓源码,使用Soong 构建系统。因此,需要编写 Android.bp 文件,才能将 apk 添加到源码构建过程中进行构建。

因为是在Android Studio中开发维护,尽量保留整体项目的结构,可以通过添加 Make 配置 和 Sonng 配置(.bp) 达到这样的目的。

--app
----Android.mk
----....//一些项目文件
----module1
------Android.bp
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml
----module2
------Android.bp
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml
----module3
------Android.bp
------...//一些module文件
------src/main/java
------src/main/res
------src/main/cpp
------src/main/AndroidManifest.xml

其中根目录的Android.mk很简单

include $(call all-subdir-makefiles)

作用也很简单,就是将当前目录下的所有子目录的 Make 配置(.mk)和 Soong 配置(.bp)全部包含进来。

我们在相应的每个module下,都创建了一个Android.bp,来完成每个 module 的构建工作。Anroid.mk,将他们联合到一起。在不改变目录结构,和原有项目完整性的基础上,通过添加 Android.mk 和 Android.bp,对原有代码无侵入的完成整合。

接下来就是各个module的Android.bp编写,这部分需要根据具体情况来分析,大体介绍几种。

Android.bp编写

Android.bp 文件中的模块以模块类型开头,后跟一组 name: “value”, 格式的属性:

Soong示例

cc_library_shared {
     name: "libxmlrpc++",

     rtti: true,
     cppflags: [
           "-Wall",
           "-Werror",
           "-fexceptions",
     ],
     export_include_dirs: ["src"],
     srcs: ["src/**/*.cpp"],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

这里模块类型是 cc_ilbrary_shared,表明这是一个共享库(.so)的配置。
name即是共享库的名字,成功编译会生成libxmlrpc++.so。
其余配置,可参考文档Android.bp 文件格式

更详细的文档,具体到每个参数,还是要参考下的:
Soong Modules Reference

c++静态库,动态库

c++静态库,动态库的一个简单例子,libtwo动态库引用libone静态库。
最终生成libone.a ,libtwo.so


cc_library_static{
    name:"libone",
    srcs: ["src/main/cpp/one.cpp"],
    local_include_dirs: ["src/main/cpp"],
    export_include_dirs: ["."],

    sdk_version: "current",
    min_sdk_version: "21",
    cflags: [
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wall",
        "-std=c++11",
        "-frtti",
        "-fexceptions",
        "-Wno-unused-parameter",
    ],
    
    // for including the jni.h file
    header_libs: ["jni_headers"],
}

cc_library_shared{
    name:"libtwo",
    srcs: ["src/main/cpp/two.cpp"],
    local_include_dirs: ["src/main/cpp"],
    export_include_dirs: ["."],

    static_libs: ["libone"],
    shared_libs: ["liblog"],

    sdk_version: "current",
    min_sdk_version: "21",
    cflags: [
        "-Werror",
        "-Wno-error=deprecated-declarations",
        "-Wall",
        "-std=c++11",
        "-frtti",
        "-fexceptions",
        "-Wno-unused-parameter",
    ],
    
    // for including the jni.h file
    header_libs: ["jni_headers"],
}

jar 或 aar

这里以aar为例,且带有aidl资源

android_library {
    name: "libtest",

    srcs: ["src/main/java/**/*.java",
           "src/main/aidl/**/*.aidl"],
    aidl:{
        local_include_dirs: ["src/main/aidl",
                       "src/main/java",
                      ],
    },

    resource_dirs: ["src/main/res"],
    manifest: "src/main/AndroidManifest.xml",

    libs: ["android-support-v7-appcompat"],

    sdk_version: "current",
    min_sdk_version: "21",

    java_version: "1.8",

}

将 aidl 和 java 都参与编译,且将资源文件打包到 aar。
使用 java_library 打包成 jar,但是资源文件无法打包进 jar,没有resource_dirs 选项,这是由 jar 和 aar 的特点决定的,所以需要注意 java_library 和 android_library 在选项上的异同,并不是换个模块类型那么简单。

编译apk

android_app {
    name: "testapp",

    srcs: ["src/main/java/**/*.java"],

    resource_dirs: ["src/main/res"],
    manifest: "src/main/AndroidManifest.xml",

    static_libs: ["android-support-v7-appcompat",
           "gson-prebuilt-jar",
          ],
    
    jni_libs:["libtwo"],

    sdk_version: "current",
    min_sdk_version: "21",

    java_version: "1.8",

    certificate: "platform",
}

这里,static_libs 选择依赖的库,包括appcompat和gson,也可以是之前编译的libtest。
jni_libs选择之前编译的动态so,libtwo。会将该so放到 /system/lib/下。

将整个目录放到安卓源码下

找到合适的位置,放置apk源码,同时,找到某个.mk文件,将该目录添加进即可。

PRODUCT_PACKAGES += \
   app
  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值