一、概述
要在AOSP源码中添加二进制可执行程序,需我们需要知道以下几个目录
1
2
3
4
/system
/vendor
/odm
/product
同时需要知道Android硬件产品(电视、手机、平板)开发的常规流程如下:
- Google 开发和迭代 AOSP + Kernel
- 芯片厂商,针对自己的芯片特点,移植 google 开源的 AOSP + Kernel,使其在自己的芯片上跑起来
- 方案厂商(很多芯片厂商也扮演了方案厂商的解决),设计电路板,添加外设。软件上主要是开发硬件驱动和hal,实力强的厂商还会修改部分bug和做一些性能优化。
- 产品厂商,通常就是 odm oem 厂商,主要是做系统软件开发。实力强的厂商可能还会修改主板,添加自己的外设和芯片,软件上开发自己的驱动和hal程序。另外,修改bug和性能优化是产品厂商的永远干不完的工作。
产品厂商最终写的代码,大多会写到/product
和/odm
分区。
二、添加C++源码
2.1 添加源代码文件
首先我们需要在我们定义的product
目录下新增一个helloworld
目录,然后在该目录下添加一个helloworld.cpp
文件,内容如下:
1
2
3
4
5
6
#include <iostream>
int main() {
std::cout << "Hello, World! Android C/C++" << std::endl;
return 0;
}
2.2 添加Android.bp文件
该文件用于描述编译规则,在helloworld
目录下新增一个helloworld.bp
文件,内容如下:
cc_binary {
name: "helloworld",
srcs: ["helloworld.cpp"]
}
2.3 单模块编译
首先我们执行单模块编译,命令如下
1
2
3
4
5
6
7
8
# 执行初始化
source build/envsetup.sh
# 选择编译目标
lunch rice14-eng
# 进入源码目录
cd device/jelly/rice14/helloworld/
# 执行编译
mm
编译成功后,终端将输出如下信息
1
2
3
4
15:47:32 Build configuration changed: "aosp_x86_64-eng" -> "rice14-eng", forcing installclean
[100% 23/23] Install: out/target/product/generic_x86_64/system/bin/helloworld
#### build completed successfully (01:13 (mm:ss)) ####
2.4 整体编译
2.4.1 将可执行文件添加到system分区
首先需要在product目录的rice14.mk
添加如下一行两个关键变量,分别用于打包可执行文件到系统和添加可执行文件到system分区的白名单。
1
2
3
4
5
6
7
8
9
10
11
12
# 添加helloworld
PRODUCT_PACKAGES += helloworld
# 添加可执行文件到系统白名单
PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
system/bin/helloworld
# 原产品名称变量
PRODUCT_NAME := rice14
PRODUCT_DEVICE := generic_x86_64
PRODUCT_BRAND := Android
PRODUCT_MODEL := AOSP on x86_64
执行整体便利,命令如下
1
2
3
4
5
6
# 执行初始化
source build/envsetup.sh
# 选择编译目标
lunch rice14-eng
# 编译
m
2.4.2 将可执行文件添加到product分区
不过我们需要注意的是,不管是做芯片、方案、产品厂商,都尽量避免添加到/system
目录下。通常是放在 product
分区,因此需要在Android.bp
添加product_specific: true
,最终代码如下:
cc_binary {
name: "helloworld",
srcs: ["helloworld.cpp"],
product_specific: true
}
同时需要把rice14.mk
的如下代码删除
1
2
3
# 添加可执行文件到系统白名单
PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST += \
system/bin/helloworld
再执行一次整体编译,命令如下
1
m
最终编译完成后,终端将输出如下信息
1
2
3
4
5
The new table will be used at the next reboot.
The operation has completed successfully.
out/host/linux-x86/bin/sgdisk --clear out/target/product/generic_x86_64/system-qemu.img
#### build completed successfully (01:47 (mm:ss)) ####
2.5 验证可执行程序
编译完成后,使用emulator
命令启动模拟器,并在终端使用adb shell
命令打开安装shell,查看/product/bin
目录下是否存在helloworld
可执行程序,可以看到如下图
如果正常执行,则代表操作成功。
2.6 总结
系统源码中的二进制程序一般预制到product分区,需要在Android.bp
中添加product_specific: true
。
如果我们一定要将二进制程序添加到system分区,则需要在Android.bp
中添加product_specific: false
,同时需要在rice14.mk
中通过PRODUCT_ARTIFACT_PATH_REQUIREMENT_WHITELIST
变量设置白名单。
三、添加可执行文件
3.1 准备二进制可执行文件
有时候我们需要将可执行文件直接添加到系统源码中,而不是通过添加源代码最后编译生成。接下来我们使用 busybox
添加到系统源码中。我们先在product目录新建一个prebuild
目录,代表编译好的二进制文件目录。再在prebuild
目录下新建一个busybox
目录,将编译好的二进制文件busybox
拷贝到该目录下。以上过程执行命令如下
1
2
3
mkdir -p device/jelly/rice14/prebuild/busybox
cd device/jelly/rice14/prebuild/busybox
wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox
在同级目录添加Android.bp
文件,内容如下:
1
2
3
4
5
cc_prebuilt_binary {
name: "busybox",
srcs: ["busybox"],
product_specific: true
}
接下来在rice14.mk
中添加如下代码:
1
2
PRODUCT_PACKAGES += helloworld \
busybox
3.2 执行整体编译
命令如下
1
2
3
source build/envsetup.sh
lunch rice14-eng
m
编译完成后,关闭虚拟机,再重新使用emulator
启动虚拟机,使用adb shell
命令查看/product/bin
目录下是否存在busybox
可执行程序,可以看到如下图`
结果如图所示则代表操作成功。
四、添加Java源码
4.1 准备Java源码
在product目录新增一个hellojava
目录,首先建包的路径tech.webcoding.main
,使用以下命令创建目录
1
mkdir -p device/jelly/rice14/hellojava/tech/webcoding/main
在tech.webcoding.main
目录下新建一个HelloJava.java
文件,内容如下:
1
2
3
4
5
6
7
package tech.webcoding.main;
public class HelloJava {
public static void main(String[] args) {
System.out.println("Hello Java");
}
}
另外添加Android.bp
文件,内容如下
java_library {
name: "hellojava",
installable: true,
product_specific: true,
srcs: ["**/*.java"],
sdk_version: "current"
}
需要注意的是,如果不指定installable: true
,那么编译产物都是.class
文件,这种文件在Android无法直接运行。最后需要在rice14.mk
中添加如下代码:
1
2
3
PRODUCT_PACKAGES += helloworld \
busybox \
hellojava
4.2 执行编译并验证
接着执行编译
1
2
3
source build/envsetup.sh
lunch rice14-eng
m
编译完成之后运行模拟器,并使用adb shell
打开终端,查看product/framework/
目录下是否存在hellojava.jar
,如果存在则执行以下命令
1
2
3
4
# 配置 classpath
export CLASSPATH=/product/framework/hellojava.jar
# 执行程序
app_process /product/framework/ tech.webcoding.main.HelloJava
正常输出结果代表操作成功。
五、添加Jar包
在product目录新增一个hellojavajar
目录,我们直接把第四步编译出的hellojava.jar
拷贝到hellojavajar
目录下,如下命令
1
cp out/target/product/generic_x86_64/system/product/framework/hellojava.jar device/jelly/rice14/hellojavajar/
然后添加Android.bp
文件,内容如下:
1
2
3
4
5
6
java_import {
name: "hellojavajar",
installable: true,
jars: ["hellojava.jar"],
product_specific: true
}
为了避免冲突,我们需要把第四步的hellojava
删除掉。再在rice14.mk
中添加如下代码变更PRODUCT_PACKAGES
变量如下
1
2
3
PRODUCT_PACKAGES += helloworld \
busybox \
hellojavajar
再执行编译,命令如下
1
2
3
source build/envsetup.sh
lunch rice14-eng
m
编译完成后,重新启动模拟器,再使用adb shell
打开终端,查看product/framework/
目录下是否存在hellojavajar.jar
,如果存在则执行以下命令
1
2
3
4
# 配置 classpath
export CLASSPATH=/product/framework/hellojavajar.jar
# 执行程序
app_process /product/framework/ tech.webcoding.main.HelloJava
正常输出结果代表操作成功。