目录
- 背景
- Android源码下载
- 源码编译及遇到的问题
- 使用CLion 导入
- 资料
- 收获
一、背景
对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步,
- 下载安装repo 启动器
- 下载mainfest
- 开始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 配置和编译命令
- 编译前配置下生成cmakelist文件这样后面才可以使用CLion导入
export SOONG_GEN_CMAKEFILES=1
export SOONG_GEN_CMAKEFILES_DEBUG=1
- 然后执行envsetup.sh脚本 进行配置
. envsetup.sh
再执行 choosecombo ,这个命令用阿里选择编译目标,比如硬件平台、开发者还是使用者等,一般默认配置就好。
最后开始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 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
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 导入
具体步骤如下
- 打开CLion
- 选择「New CMake Project from Sources」
- 指定包含 CMakeLists.txt 的目录out/development/ide/clion
- 选择「Open Existing Project」
然后就可以很愉快的进行Android Native源码的跳转查看。
其中在 androidsource/out/development/ide/clion/CMakeLists.txt如下(目前主要是看 av相关的代码,所有只加了相关的子路径)
五、资料
- 搭建编译环境
- https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment
- Move Android source into case-sensitive image
- 清华大学 android source 镜像站
- http://blog.hanschen.site/2019/10/11/aosp-native-ide/
- 自己动手调试Android源码
- Android Opensource Project build error
FAILED: out/soong/build.ninja
- CLion调试Android 11 Native代码
- AOSP Native代码导入IDE(CLion)
六、收获
- 源码的下载、编译以及通过CLion导入方便的查看Native源码
- 解决编译中遇到的各种问题
感谢你的阅读
下一篇我们分析学习H264的编码技术之帧内预测,欢迎关注公众号“音视频开发之旅”,一起学习成长。
欢迎交流