Android 11 系统映像可直接将 ARM 指令转换成 x86 指令,因此以前很多需要真机测试的情况,现在只需要模拟器就可以进行操作了。
不过,根据官方博客 Run ARM apps on the Android Emulator 尾部的一段注意事项:
这段事项说明,自己编译的镜像是没办法用上这个功能的,必须是Google编译好的镜像。
由于众所周知的原因,我们是没办法正常下载Android
的源代码的,因此只能使用国内的镜像来操作了。
1.安装repo
工具以及依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
$ sudo apt-get install gcc make perl $ sudo apt-get install ccache $ sudo apt-get install curl $ sudo apt-get install python # 安装repo的时候需要指定 --devmode ,否则同步的时候,会报告如下错误信息: #repo sync -j4 --fail-fast #/snap/git-repo/18/usr/bin/python: can't open file '~/aosp/.repo/repo/main.py': [Errno 13] Permission denied # 不要使用 snap 安装的repo, 目前存在很多异常问题, # ubuntu 20.04缺少repo 原因是 repo 废弃 python2 的进度慢了一些, # 导致没办法集成到这个版本的系统里面 # sudo snap install git-repo --devmode # 手工下载 repo $ mkdir -p ~/.bin $ PATH="${HOME}/.bin:${PATH}" $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo $ chmod a+rx ~/.bin/repo $ echo "PATH=${HOME}/.bin:${PATH}" >> ~/.bashrc $ sudo apt-get install aria2 $ sudo apt-get install git $ sudo apt install -y libssl-dev # 解决 # prebuilts/clang/host/linux-x86/clang-3289846/bin/clang.real: error while loadin g shared libraries: libncurses.so.5: cannot open shared object file: No such fi le or directory $ sudo apt install libncurses5 # 安装VSCode,方便后续查看代码 $ sudo snap install code --classic $ git config --global user.email "user@email.com" $ git config --global user.name "user" |
2.在需要存储代码的地方创建文件夹
1 2 3 |
$ mkdir ~/AndSrc $ cd ~/AndSrc |
3.使用镜像下载Android
源代码
清华大学的镜像
1 2 3 4 5 6 7 8 9 10 11 |
# 建议直接下载压缩包,使用repo更新基本上都会失败,即使用国内镜像也是一样(目前大约96GB) $ aria2 -c https://mirrors.ustc.edu.cn/aosp-monthly/aosp-latest.tar $ tar xvf aosp-latest.tar $ cd aosp # 解决 fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle $ git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo |
4.Android 模拟器编译(可选)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# 配置默认的 python为python3,否则会在运行时报错 SyntaxError: invalid syntax to repo init in the AOSP code $ sudo mv /usr/bin/python /usr/bin/python.bak $ sudo ln -s /usr/bin/python3 /usr/bin/python # Android 11模拟器对应分支 emu-30-release $ repo init -b emu-30-release # 可能会失败多次,不断尝试,直到完全成功 $ repo sync -j4 --fail-fast $ cd external/qemu/android/ $ ./rebuild.sh --no-tests |
编译完成之后,产生的模拟器可执行文件及库文件都位于external/qemu/objs/android
目录下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
~/AndSrc/aosp/external/qemu/android/objs$ ls android_emu64_unittests emulator64-mips android_emu_metrics64_unittests emulator64_simg2img bin64 emulator64_test_crasher build emulator64-x86 emugl64_common_host_unittests emulator-check emulator lib emulator64-arm lib64 emulator64_crashreport_unittests lib64GLcommon_unittests emulator64-crash-service lib64OpenglRender_unittests emulator64_img2simg qemu emulator64_libui_unittests resources emulator64_make_ext4fs |
后面就可以像执行 SDK 中的模拟器那样,执行我们编译的模拟器了:
1 2 3 |
# 下面是个例子,只有设备上已经通过Android SDK 创建过 Nexus_5_API_30_x86,才可以成功执行 ~/AndSrc/aosp/external/qemu/android/objs$ ./emulator -avd Nexus_5_API_30_x86 |
5.列出android-11全部分支
1 |
$ cd .repo/manifests && git branch -a | cut -d / -f 3 | grep android-11 |
6.编译Android 11系统镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ cd ~/AndSrc/aosp # 前面的编译可能会产生部分垃圾文件,需要清理一下,清理之前,编译好的文件提前备份一下 $ rm -rf * # 解决 fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle $ git clone https://gerrit-googlesource.lug.ustc.edu.cn/git-repo # 配置默认的 python为python3,否则会在运行时报错 SyntaxError: invalid syntax to repo init in the AOSP code $ sudo mv /usr/bin/python /usr/bin/python.bak $ sudo ln -s /usr/bin/python3 /usr/bin/python $ repo init -b android-11.0.0_r48 # 可能会失败多次,不断尝试,直到完全成功 $ repo sync -j4 --fail-fast # 如果上面的命令失败,可以尝试调整为单线程,目前测试发现单线程虽然慢点,但是基本不会失败,多线程经常失败 # repo sync -j1 --fail-fast |
7.引入编译环境变量
1 |
$ source build/envsetup.sh |
8.设置编译目标,此处我们指定编译x86_64
下的完整调试版本
1 2 3 4 5 6 7 |
# eng:代表 engineer,开发工程师的版本,拥有最大的权限(root等),具有额外调试工具的开发配置。 # 执行 lunch 命令可以输出全部的编译目标列表 # 更多的编译选项可以从 build/make/target/product/ 下看到 # lunch aosp_x86_arm-eng 编译后的镜像可以安装 arm 应用, 不过在不进行任何代码调整的情况下,应用启动会崩溃 # 不能安装 arm 应用 $ lunch aosp_x86_64-eng |
9.如果需要跟踪调试代码,建议编译为调试类型
1 |
$ export TARGET_BUILD_TYPE=debug |
10.编译
1 2 3 4 5 6 7 |
$ export USE_CCACHE=1 # 清理代码,为编译准备干净的环境 $ make clobber $ make -j8 |
注意此处如果发生编译失败,原因基本上是编译顺序导致的引用出错,也就是某些模块还没有编译完成,其他模块已经开始尝试链接,导致依赖错误,此时只要把多线程并发编译修改成单线程编译即可,即直接执行
1 |
$ make |
如果由于内存不足导致的编译失败,可以增加物理内存。但是如果内存无法增加的话,那么适当增加交换分区/交换文件的大小(建议配置16GB以上的交换分区)可以解决此问题,只是编译速度会下降。
运行镜像
选择system-qemu.img和vendor-qemu.img,这两个镜像是专门为qemu运行制作的,如果选择system.img 和vendor.img,则avd运行失败。
1 2 3 4 5 6 7 8 9 10 11 |
$ cd ~/AndSrc/aosp $ export ANDROID_BUILD_TOP=~/AndSrc/aosp $ export PATH=$PATH:$ANDROID_BUILD_TOP/out/host/linux-x86/bin $ export ANDROID_SWT=$ANDROID_BUILD_TOP/out/host/linux-x86/framework $ export ANDROID_PRODUCT_OUT=$ANDROID_BUILD_TOP/out/target/product/generic_x86_64 $ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -verbose -show-kernel |
上面运行起来的镜像是从~/AndSrc/aosp/out/debug/target/product/generic/hardware-qemu.ini
即可读取配置信息的,但是这个文件直接修改无效,我们如果需要修改参数,只能从启动参数中设置。
比如我们如果需要增大内存,开启GPU
的支持,则执行如下命令:
1 |
$ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -gpu on -memory 4096 -verbose -show-kernel |
编译支持ARM应用的镜像
尽管根据
我们自己编译的镜像是没办法直接从源代码编译支持安装运行 ARM 应用的。
但是有两个变通方案:
- 从Google官方的 Android 11 镜像中提取需要的文件塞到我们自己编译的镜像里,参考方案: Adding ARM native bridge to the AOSP11 x86 emulator、android_vendor_google_emu-x86
- 使用 Intel Houdini 实现支持,参考方案:Include Intel Houdini in Android-x86
首先,我们尝试从Google官方的 Android 11 镜像中提取需要的文件,执行如下脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 安装镜像文件提取依赖库 $ sudo apt install curl rsync zip unzip binwalk # git clone https://gitlab.com/android-generic/android_vendor_google_emu-x86 vendor/google/emu-x86 $ git clone https://gitlab.com/LongSky/android_vendor_google_emu-x86.git vendor/google/emu-x86 $ . vendor/google/emu-x86/update.sh x86_64 $ sed -i '$a\\n-include vendor/google/emu-x86/board/native_bridge_arm_on_x86.mk' build/make/target/board/generic_x86_64/BoardConfig.mk $ sed -i '$a\\n$(call inherit-product-if-exists, vendor/google/emu-x86/target/native_bridge_arm_on_x86.mk)' build/make/target/board/generic_x86_64/device.mk $ sed -i '$a\\n$(call inherit-product-if-exists, vendor/google/emu-x86/target/libndk_translation.mk)' build/make/target/board/generic_x86_64/device.mk |
执行编译:
1 2 3 4 5 6 |
# 禁用系统文件目录文件拷贝检查 $ export DISABLE_ARTIFACT_PATH_REQUIREMENTS="true" $ lunch aosp_x86_64-eng $ make |
参考链接
- Android 模拟器下载、编译及调试
- Ubuntu 16.04下载Android源代码
- Android 模拟器支持运行 ARM 应用,Android 11 系统映像可直接将 ARM 指令转换成 x86 指令
- Android 镜像使用帮助
- 解决:Cannot get http://gerrit.googlesource.com/git-repo/clone.bundle
- Android 开源项目简介
- AOSP(Android) 镜像使用帮助
- macOS Sierra (10.12.3)上编译ARM版本Android 5.1.1_r38 (Lollipop)源代码
- 手动修改android模拟器的system.img
- AOSP编译好的rom,烧录入Android Studio里的avd emulator
- snap version gets "Permission denied
- Why is the “repo” package unavailable in Ubuntu 20.04? How can I install it?
- 解决ubuntu编译aosp报错问题:error while loading shared libraries: libncurses.so.5
- SyntaxError: invalid syntax to repo init in the AOSP code
- repo init 错误SyntaxError:invalid syntax
- Building Android 11 for x86 with ARM compatibility
- Run ARM apps on the Android Emulator
- The Android Cuttlefish emulator
- How to create a custom sdk for x86 and arm for Android 11
- Support x86+arm multilib build.
- ARM binary code translator
- Adding ARM native bridge to the AOSP11 x86 emulator
- Include Intel Houdini in Android-x86
- Android x86 Arm NativeBridge (libhoudini)
- android_vendor_google_emu-x86
- Integrate Houdini to emulator
- Building QEMU Instances for Scaled Dynamic Android App Analysis
- Android 12 S artifact_path_requirements Offending entries Build failed ckati failed with/ aosp预制apk
请教下,emulator能否脱离sdk或者aosp独立运行呢?比如使用qemu运行,我编译了emulator源码,但按照帮助命令并不能启动模拟器:
See -help-build-images for more details.
If you're neither using the SDK or the Android build system, you
can still run the emulator by explicitely providing the paths to
*all* required disk images through a combination of the following
options: -sysdir, -datadir, -kernel, -ramdisk, -system, -data, -cache
-sdcard and -snapstorage.
这个报错说明模拟器是可以的,只是给模拟器的参数有问题,可以试着指定 -sysdir, -datadir, -kernel, -ramdisk, -system, -data, -cache
-sdcard and -snapstorage 这些参数的位置试试