安卓源码环境下编译多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

相关推荐

  1. 环境编译module app

    2024-05-09 14:06:08       13 阅读
  2. 去掉混淆

    2024-05-09 14:06:08       9 阅读
  3. MediaRecorder(3)音频采集编码写入详细分析

    2024-05-09 14:06:08       28 阅读
  4. MediaRecorder(4)视频采集编码写入详细分析

    2024-05-09 14:06:08       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-09 14:06:08       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-09 14:06:08       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-09 14:06:08       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-09 14:06:08       18 阅读

热门阅读

  1. centos 找到并删除重复文件 去重

    2024-05-09 14:06:08       11 阅读
  2. 如何进行SQL优化

    2024-05-09 14:06:08       10 阅读
  3. Oracle 更改数据文件位置的几种常用方式

    2024-05-09 14:06:08       11 阅读
  4. 跨域问题解决方案

    2024-05-09 14:06:08       7 阅读
  5. wifi执法记录仪移植出现的问题

    2024-05-09 14:06:08       10 阅读
  6. 邮件服务器有什么作用?

    2024-05-09 14:06:08       9 阅读