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

2021-09-09 10:35:30 浏览数 (1)

目录

  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导入
代码语言:javascript复制
export SOONG_GEN_CMAKEFILES=1
export SOONG_GEN_CMAKEFILES_DEBUG=1
  1. 然后执行envsetup.sh脚本 进行配置
代码语言:javascript复制
. 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时报如下错误

代码语言:javascript复制
% 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上建立区分大小的文件系统

代码语言:javascript复制
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS ' -size 40g ~/android.dmg

然后进行挂载

代码语言:javascript复制
hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android;

对应的detach命令如下:

代码语言:javascript复制
hdiutil detach /Volumes/android;

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

代码语言:javascript复制
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过去之后不再报上面的错误了,但是出现如下错误

代码语言:javascript复制
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: 提示文件描述超过了上限(具体错误信息忘记保存了)

代码语言:javascript复制
# 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

代码语言:javascript复制
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分钟左右终于编译完成。哈哈哈

代码语言:javascript复制
#### 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'

代码语言:javascript复制
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这里找了个解决方案

代码语言:javascript复制
---> 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

代码语言:javascript复制
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

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

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

代码语言:javascript复制
[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. 搭建编译环境 (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. 解决编译中遇到的各种问题

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

0 人点赞