新知一下
海量新知
6 0 8 6 8 4 9

如何方便的查看 Android Native 源码

字节流动 | 一个开发者的认知、技术与生活感 2021/09/12 13:10

目录

  1. 背景

  2. Android源码下载

  3. 源码编译及遇到的问题

  4. 使用CLion 导入

  5. 资料

  6. 收获

一、背景

对Framework层的了解学习是我们进阶的一个重要阶段。通过 AS 查看 Framework 代码体验非常好,无论是索引还是界面都让人很满意,但是当你跟踪代码,发现进入 native 逻辑时,就会发现 Android Studio 对 native 代码的支持非常不好,不能索引不支持符号搜索不能跳转等。

网页上可以通过cs.android.com 或者 http://androidxref.com/ 比较方便的查看源码。但是还是不够,因为我们如果想系统的追踪分析流程,往往会需要跳来跳去,有时候还会加些注释。这时候网页端的就不太方便。如果能在本地端方便的实现上述功能,可定是一个比较高效率而 愉悦的事情。

Source Insight可以比较方便的进行跳转,但是只是在window支持(虽然Mac上可以通过Parallels 方便的安装window环境;Ubuntu上也可以win的方式使用Source Insight但是总是不太方便)。

那么有没有其他的工具或者方式,比较方便的查看native代码呐?

可以通过CLion导入,但是需要有对应的cmakelist,这就需要对下载源码,然后进行编译,然后再用CLion导入。下面我们来看下具体的实践。

二、Android源码下载

查看官方文档

主要分为3步,

  1. 下载安装repo 启动器

  2. 下载mainfest

  3. 开始sync下载: repo sync -c -j8

    其中第2步配置manifest时需要注意,如果直接使用

    epo init -u https://android.googlesource.com/platform/manifest -b master

     因为网络原因会比较难下载成功。我们可以使用清华的镜像来配置 `repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b master

    即将 https://android.googlesource.com/ 全部使用 https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/ 代替即可

清华大学-Android 镜像使用帮助

还有一点需要注意,如果没有特殊的要求,可以根据需要下载对应的分支,比如上面第2步中配置的是 master分支,这样只会同步master最新分支,保证代码的最新和下载的量比较小比较快。

如果是linux系统就可以直接进入编译阶段。但是如果是mac上如果只是按照上面的操作进入编译,就会遇到问题。我们在编译阶段来一起看下,怎么处理。

三、源码编译及遇到的问题

3.1 配置和编译命令

  1. 编译前配置下生成cmakelist文件这样后面才可以使用CLion导入

export SOONG_GEN_CMAKEFILES=1

export SOONG_GEN_CMAKEFILES_DEBUG=1

  1. 然后执行envsetup.sh脚本 进行配置

. envsetup.sh

  1. 再执行 choosecombo ,这个命令用阿里选择编译目标,比如硬件平台、开发者还是使用者等,一般默认配置就好。

  2. 最后开始make。make -j8

Android平台提供了三个命令用于编译,它们分别是make、mmm和mm

make 用于编译整个系统,时间比较长,

make xxx:用于编译某个模块,比如编译framework。make framework即可

mmm xxx:用于编译指定目录下的模块,不会编译它依赖的模块

mm xxx: 该命令和mmm差不多,区别在于它会先cd到xxx目录然后在编译。

在具体的编译中遇到了很多问题,汇总如下。

3.2 编译中遇到的问题

问题1: Mac make时报如下错误

% make -j16 frameworks

19:44:38 You are building on a case-insensitive filesystem.

19:44:38 Please move your source tree to a case-sensitive filesystem.

19:44:38 ************************************************************

19:44:38 Case-insensitive filesystems not supported

#### failed to build some targets (1 seconds) ####

这个问题就是上面提到的,如果是linux系统可以直接编译,但是如果是mac系统编译就会遇到这个问题。

问题的原因是

在默认安装过程中,Mac OS 会在一个保留大小写但不区分大小写的文件系统中运行。Git 并不支持此类文件系统,而且此类文件系统会导致某些 Git 命令(例如

git status

)的行为出现异常

参考:https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment 和 Move Android source into case-sensitive image

那么该如何解决呐?

上面链接给出的建议始终在区分大小写的文件系统中对 AOSP 源文件进行操作

有了适当的文件系统,在新型 Mac OS 环境中编译

master

 分支就会变得非常简单

但是我代码已经下载好了。。。。,

所以只能在创建下区分大小写的文件系统,然后把代码copy过去。

Mac上建立区分大小的文件系统

hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg

然后进行挂载

hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android;

对应的detach命令如下:

hdiutil detach /Volumes/android;

如果以后需要更大的存储卷,还可以使用以下命令来调整稀疏映像的大小:

hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage

需要注意的 ,: 如果系统创建的是 .dmg.sparseimage 文件,请将 ~/android.dmg 替换成 ~/android.dmg.sparseimage。

解决方案来源:Building Android O with a Mac

问题2 :copy过去之后不再报上面的错误了,但是出现如下错误

error: external/kotlinx.atomicfu/Android.bp:13:1: module "external_kotlinx.atomicfu_license": glob: stat /Volumes/android/androidsource/external/kotlinx.atomicfu/NOTICE: no such file or directory

error: external/kotlinx.coroutines/Android.bp:24:1: module "external_kotlinx.coroutines_license": module source path "external/kotlinx.coroutines/LICENSE" does not exist

20:50:19 soong bootstrap failed with: exit status 1

ninja: build stopped: subcommand failed.

#### failed to build some targets (16 seconds) ####

在网上搜了下也有人遇到同样的问题但是没有解决方案。。。

我的处理方案是 修改bp脚本,把上面的NOTICE和LICENSE依赖给去掉,然后就编译过去了。

问题3: 提示文件描述超过了上限(具体错误信息忘记保存了)

# set the number of open files to be 1024

ulimit -S -n 1024

设置文件描述符数量上限

在 Mac OS 中,可同时打开的文件描述符的默认数量上限太低,在高度并行的编译流程中,可能会超出此上限。

要提高此上限,请将下列行添加到 ~/.bash_profile 中:

调大了文件描述符数量,同时 把并行的线程从16减4( 这个是关键 ),不报上面的错误了,但是又有如下错误

问题4: ninja: build stopped: subcommand failed

error: bionic/libc/Android.bp:1860:1: module "libc_llndk_headers" variant "android_recovery_arm_armv7-a-neon": glob failed: &fs.PathError{Op:"fcntl", Path:"/Volumes/android/androidsource/bionic/libc/kernel/uapi/asm-arm", Err:0x18}

21:17:37 soong bootstrap failed with: exit status 1

ninja: build stopped: subcommand failed.

---》重新运行了了 make -j4 framework, 上 的编译又通过了,不知道为什么。

本来还想在降低并发的线程数量到2. make -j2

经过15分钟左右终于编译完成。哈哈哈

#### build completed successfully (14:16 (mm:ss)) ####

此时可以在/Volumes/android/androidsource/out/development/ide/clion/frameworks 路径下看到各个子文件夹下都有CMakeLists.txt生成,但是却是分散在各个子文件夹下面的。

编译出来的是各个模块单独的CMakeLists.txt,一个CMakeLists.txt表示一个CLion工程,所以不能直接导入全部的工程。

那该怎么办呐?

可以新建一个总的

/Volumes/android/androidsource/out/development/ide/clion/frameworks/CMakeLists.txt

然后可以先add一个工程,导入到CLion后再add其他工程

当导入时,有些cmakelist找不到。怀疑 没有全编译引起的? 于是 索性 make -j4来个全编译

下面是全编译遇到的问题

问题5: fatal error: 'linux/netfilter/xt_DSCP.h'

external/iptables/include/linux/netfilter_ipv4/ipt_ECN.h:13:10: fatal error: 'linux/netfilter/xt_DSCP.h' file not found

#include <linux/netfilter/xt_DSCP.h>

1 error generated.

09:04:41 ninja failed with: exit status 1

#### failed to build some targets (01:34:26 (hh:mm:ss)) ####

从Building Android O with a Mac这里找了个解决方案

---> In this case create a symbolic name xt_dscp.h for the original file xt_DSCP.h with the following command lines:

cd external/iptables/extensions/../include/linux/netfilter

ln -s xt_dscp.h xt_DSCP.h

按照上面的修改,但是没什么用还是报相应的错误

于是手动的找到对应的文件,external/iptables/include/linux/netfilter/xt_dscp.h -->对其进行重命名为xt_DSCP.h,解决掉这个问题。

问题6: 漫长的编译过程 出现了main.go:171:9: undefined: syscall.Sysinfo

build/soong/cmd/multiproduct_kati/main.go:170:11: undefined: syscall.Sysinfo_t

build/soong/cmd/multiproduct_kati/main.go:171:9: undefined: syscall.Sysinfo

10:27:57 ninja failed with: exit status 1

网上搜了下也没有找到相关的解决方案。于是找对对应的文件,把修改相关的代码(把对应的代码注释掉),继续编译

经过上述折腾终于编译完了,哈哈哈。

[100% 19269/19269] Target vbmeta image: out/target/product

#### build completed successfully ####

四、使用CLion 导入

具体步骤如下

  1. 打开CLion

  2. 选择「New CMake Project from Sources」

  3. 指定包含 CMakeLists.txt 的目录out/development/ide/clion

  4. 选择「Open Existing Project」

    然后就可以很愉快的进行Android Native源码的跳转查看。

五、资料

  1. 搭建编译环境 (https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment)

  2. https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment

  3. Move Android source into case-sensitive image(https://stackoverflow.com/questions/8341375/move-android-source-into-case-sensitive-image)

  4. 清华大学 android source 镜像站(http://aosp.tuna.tsinghua.edu.cn/android/)

  5. http://blog.hanschen.site/2019/10/11/aosp-native-ide/

  6. 自己动手调试Android源码(https://blog.csdn.net/dd864140130/article/details/51815253)

  7. Android Opensource Project build error

    FAILED: out/soong/build.ninja

  8. CLion调试Android 11 Native代码(https://blog.csdn.net/iamdy/article/details/111272854)

  9. AOSP Native代码导入IDE(CLion)(https://blog.csdn.net/iamdy/article/details/106658583)

  10. 图书:《邓凡平-深入理解Android》

六、收获

  1. 源码的下载、编译以及通过CLion导入方便的查看Native源码

  2. 解决编译中遇到的各种问题

更多“Android”相关内容

更多“Android”相关内容

新知精选

更多新知精选