Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

    • 001.AOSP 极速上手
    • 002.Android 系统开发工具推荐
    • 003.添加 Product
    • 004.添加可执行程序
    • 005.添加 C/C++、Java 库
      • 1.添加 C/C++ 程序库
        • 1.1 源码方式添加
        • 1.2 so 包方式添加
      • 2. 添加 Java 库
        • 2.1 源码方式添加
        • 2.2 Jar 包方式添加
      • 参考资料
    • 006.添加配置文件与删除已有模块
    • 007.玩转 AOSP 之系统 App 源码添加
    • 008.使用 Android Studio 开发系统 App
    • 009.SeAndroid 使用极速上手
    • 010.添加开机自启动 Shell 脚本
    • 011.如何阅读 Android 系统源码 —— C/C++ 篇
    • 012.如何阅读 Android 系统源码 —— Java 篇
    • 013.系统开发专用版 Android Studio 上手指南
    • 014.Repo 使用入门
    • 015.Android14 Native 图形化调试上手
    • 016.2025 Android Studio For Platform 上手指南
  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

  • Framework
  • 玩转AOSP篇
阿豪
2023-07-05
目录

005.添加 C/C++、Java 库

本文基于 AOSP Android10_r41 源码环境。

如果提前阅读了以下文章,本文阅读起来会更加顺利:

  • 玩转 AOSP 篇之极速上手
  • 玩转 AOSP 篇之添加 Product
  • 添加可执行程序
  • 添加 C C++、Java 库

# 1.添加 C/C++ 程序库

# 1.1 源码方式添加

在 device/Jelly/Rice14/ 目录下创建以下的目录和文件

libmymath
├── Android.bp
├── my_math.cpp
└── my_math.h
1
2
3
4

libmymath 是一个动态库。其 Android.bp 内容如下:

cc_library_shared {
    name: "libmymath",

    srcs: ["my_math.cpp"],

    export_include_dirs: ["."],

    product_specific: true,

    // 可编译出 32 64 位的 so 包
    // compile_multilib: "both"

}
1
2
3
4
5
6
7
8
9
10
11
12
13

my_math.h 内容如下:

#ifndef __MY_MATH_H__
#define __MY_MATH_H__

int my_add(int a, int b);
int my_sub(int a, int b);

#endif
1
2
3
4
5
6
7

my_math.cpp 内容如下:

#include "my_math.h"

int my_add(int a, int b)
{
	return a + b;
}

int my_sub(int a, int b)
{
	return a - b;
}
1
2
3
4
5
6
7
8
9
10
11

接着修改我们之前添加的 hello 项目:

修改 hello.cpp

#include <cstdio>
#include "my_math.h" //添加头文件

int main()
{
    printf("Hello Android %d \n", my_add(1,2)); //添加函数调用
    return 0;
}
1
2
3
4
5
6
7
8

修改 Android.bp:

cc_binary {              
    name: "hello",       
    srcs: ["hello.cpp"], 
    cflags: ["-Werror"], 
    product_specific: true,        
    shared_libs: ["libmymath"]    //添加动态库依赖
}
1
2
3
4
5
6
7

接下来编译系统:

source build/envsetup.sh
lunch Rice14-eng
make -j16
1
2
3

编译完成启动虚拟机后,就可以通过 adb shell 运行我们的 hello 程序了

emulator
adb shell hello
1
2

执行结果如下图所示:

# 1.2 so 包方式添加

在 device/Jelly/Rice14 目录下创建如下的文件与文件夹:

libmymathprebuild
├── Android.bp
├── include
│   └── my_math.h
└── lib
    ├── x86
    │   └── libmymath.so
    └── x86_64
        └── libmymath.so
1
2
3
4
5
6
7
8
9
  • 其中 libmymath.so 是上一节中的编译产物,x86/libmymath.so 拷贝自 out/target/product/Rice14/system/product/lib/libmymath.so
  • x86_64/libmymath.so 拷贝自 out/target/product/Rice14/system/product/lib64/libmymath.so
  • my_math.h 是上一节中 libmymath 模块中拷贝过来的头文件

Android.bp 的内容如下:

cc_prebuilt_library_shared {
    name: "libmymathprebuild",

     arch: {
        x86: {
            srcs: ["lib/x86/libmymath.so"],
        },
        x86_64: {
            srcs: ["lib/x86_64/libmymath.so"],
        }
    },

    export_include_dirs: ["include"],

    product_specific: true,

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

为了避免冲突,我们把上一节添加的 libmymath 移出系统源码目录或者删除。

接下来,编译整个系统,开启虚拟机

source build/envsetup.sh
lunch Rice14-eng
make -j16
emulator
1
2
3
4

接下来执行 hello 程序

adb shell hello
1

执行结果如下图所示:

# 2. 添加 Java 库

# 2.1 源码方式添加

在 device/Jelly/Rice14/ 目录下创建以下的目录和文件:

libmymathjava
├── Android.bp
└── com
    └── yuandaima
        └── mymath
            └── MyMath.java
1
2
3
4
5
6

libmymathjava 是一个 java 库。其 Android.bp 内容如下:

java_library {
    name: "libmymathjava",
    installable: false,
    product_specific: true,
    srcs: ["**/*.java"],
    sdk_version: "current"
}
1
2
3
4
5
6
7

如果不指定 installable: true, 则编译出来的 jar 包里面是 .class 文件。这种包是没法安装到系统上的,只能给其他 java 模块作为 static_libs 依赖。最终生成的 jar 包不会被直接存放到 Android 的文件系统中,而是打包进依赖于当前模块的其他模块中。

MyMath.java 内容如下:

package com.yuandaima.mymath;

public class MyMath
{

    public MyMath() {

    }

	public int add(int a, int b)
	{
		return (a+b);
	}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

接着我们把 helllojavajar 删除,将之前写好的 hellojava 模块移动到 device/Jelly/Rice14 目录下,并做以下修改:

修改 helljava/Android.bp:

java_library {
    name: "hellojava",
    installable: true,
    product_specific: true,
    srcs: ["**/*.java"],
    sdk_version: "current",
    static_libs: ["libmymathjavajar"]
}
1
2
3
4
5
6
7
8

在 device/Jelly/Rice14/Rice14.mk 中添加:

PRODUCT_PACKAGES += hellojava
1

接下来编译系统:

source build/envsetup.sh
lunch Rice14-eng
make -j16
1
2
3

编译完成启动虚拟机后:

# 进入模拟器shell
adb shell
# 配置 classpath
export CLASSPATH=/product/framework/hellojava.jar
app_process /product/framework/ com.ahaoyuandaima.main.HelloJava 
1
2
3
4
5

执行结果如下图所示:

# 2.2 Jar 包方式添加

在系统源码目录下执行:

source build/envsetup.sh
lunch Rice14-eng
1
2

接下来编译获得 jar 包:

cd device/Jelly/Rice14/libmymathjava
mm
#编译完成后,会打印出编译产物路径 out/target/product/Rice14/obj/JAVA_LIBRARIES/libmymathjava_intermediates/javalib.jar
1
2
3

为避免冲突我们把 device/Jelly/Rice14/libmymathjava 移动到源码以外的目录或者删除

在 device/Jelly/Rice14/ 下重新创建如下的目录结构:

libmymathjavajar
├── Android.bp
└── libmymathjava.jar
1
2
3

其中 libmymathjava.jar 是拷贝自编译产物 out/target/product/Rice14/obj/JAVA_LIBRARIES/libmymathjava_intermediates/javalib.jar,并改名为 libmymathjava.jar

Android.bp 的内容如下:

java_import {
    name: "libmymathjavajar",
    installable: false,
    jars: ["libmymathjava.jar"],
    product_specific: true,   
}
1
2
3
4
5
6

接着修改 hellojava 模块的依赖:

java_library {
    name: "hellojava",
    installable: true,
    product_specific: true,
    srcs: ["**/*.java"],
    sdk_version: "current",
    static_libs: ["libmymathjavajar"]  //修改这里
}
1
2
3
4
5
6
7
8

编译系统,并启动模拟器:

source build/envsetup.sh
lunch Rice14-eng
make -j16
emulator
1
2
3
4

验证 libmymathjavajar 模块是否被正确编译到 hellojava 模块中。

# 进入模拟器shell
adb shell
# 配置 classpath
export CLASSPATH=/product/framework/hellojava.jar
app_process /product/framework/ com.ahaoyuandaima.main.HelloJava 
1
2
3
4
5

执行结果如下:

# 参考资料

  • How to include prebuilt library in Android.bp file? (opens new window)
  • Android系统开发入门-5.添加预编译模块 (opens new window)
  • Android.bp 文件中引入aar、jar、so库正确编译方法(值得收藏) (opens new window)
  • 在AOSP中添加jar包和aar包依赖 (opens new window)
  • Android系统开发入门-4.添加自定义模块 (opens new window)
  • Android 10 根文件系统和编译系统(十九):Android.bp各种模块编译规则 (opens new window)
  • Soong Modules Reference (opens new window)
  • Android.bp编译提示ninja: error: unknown target ‘MODULES-IN-xxx‘终极指南 (opens new window)
  • Failing builds for Lineage-19.0 due to artifact path requirement (opens new window)
  • 自定义 SELinux (opens new window)
  • Android系统build阶段签名机制 (opens new window)
  • android系统源码中添加app源码(源码部署移植) (opens new window)
004.添加可执行程序
006.添加配置文件与删除已有模块

← 004.添加可执行程序 006.添加配置文件与删除已有模块→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
HWC 接口分析
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式