音视频开发之旅(57) -如何方便的查看AndroidNative源码

1,259 阅读8分钟

目录

  1. 背景

  2. Android源码下载

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

  4. 使用CLion 导入

  5. 资料

  6. 收获

一、背景

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

网页上可以通过cs.android.com 或者 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 mirrors.tuna.tsinghua.edu.cn/git/AOSP/pl… -b master
    即将 android.googlesource.com/ 全部使用 mirrors.tuna.tsinghua.edu.cn/git/AOSP/ 代替即可

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

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

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

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

3.1 配置和编译命令

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

    export SOONG_GEN_CMAKEFILES=1export SOONG_GEN_CMAKEFILES_DEBUG=1

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

    . envsetup.sh

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

  4. 最后开始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 frameworks19: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)的行为出现异常
参考:source.android.com/source/init… 和 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 directoryerror: external/kotlinx.coroutines/Android.bp:24:1: module "external_kotlinx.coroutines_license": module source path "external/kotlinx.coroutines/LICENSE" does not exist20:50:19 soong bootstrap failed with: exit status 1ninja: build stopped: subcommand failed.#### failed to build some targets (16 seconds) ####

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

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

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

# set the number of open files to be 1024ulimit -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 1ninja: 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/netfilterln -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_tbuild/soong/cmd/multiproduct_kati/main.go:171:9: undefined: syscall.Sysinfo10: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源码的跳转查看。

其中在 androidsource/out/development/ide/clion/CMakeLists.txt如下(目前主要是看 av相关的代码,所有只加了相关的子路径)

五、资料

  1. 搭建编译环境 (source.android.com/source/init…)

  2. source.android.com/source/init…

  3. Move Android source into case-sensitive image(stackoverflow.com/questions/8…)

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

  5. blog.hanschen.site/2019/10/11/…

  6. 自己动手调试Android源码(blog.csdn.net/dd864140130…)

  7. Android Opensource Project build error FAILED: out/soong/build.ninja

  8. CLion调试Android 11 Native代码(blog.csdn.net/iamdy/artic…)

  9. AOSP Native代码导入IDE(CLion)(blog.csdn.net/iamdy/artic…)

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

六、收获

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

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

感谢你的阅读
下一篇我们分析学习H264的编码技术之帧内预测,欢迎关注公众号“音视频开发之旅”,一起学习成长。
欢迎交流