编译环境
在Windows或者Mac下编译Android客户端是不支持的,官方推荐的是使用Ubuntu来进行编译,因此我们的编译采用的是Ubuntu服务器,版本为14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)
。需提前安装Git(拉代码)和Python(GN中的所有外部脚本都在Python中执行)
安装depot_tools
Chromium使用depot_tools
的脚本包来管理checkout和审查代码,因此拉代码前需要安装好此工具。首先拉取代码:
1 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git |
添加路径到PATH环境变量中,或者直接添加到配置文件:~/.bashrc
或 ~/.zshrc
1 | export PATH="$PATH:/path/to/depot_tools" |
拉取Chromium源码
新建目录然后拉取代码,这里过程非常长,看大家网速了。如果想快点拉完,可以在fetch的时候添加--no-history
指令不拉取历史记录,这样会快很多。
1 | mkdir ~/chromium && cd ~/chromium |
PS:通过
fetch android
指令拉取代码,会自动帮我们在.gclient
文件下配置好target_os = [ 'android' ]
属性,并自动执行gclient sync
指令去拉取Android相关的依赖。
下载Android依赖
拉完源码后,执行以下指令安装编译Android APK所需的依赖及下载其他所需的二进制文件。
1 | build/install-build-deps-android.sh |
配置GN编译脚本
Chromium使用Ninja作为主要的构建工具,并通过GN来生成.ninja
配置文件。对于Chromium这种航母级的源码编译,使用Ninja能大大的加快编译速度。通过gn args out/Default
指令,会启动系统的默认编辑器进入配置文件编辑模式,并在out/Default
目录下初始化此版本的编译,生成args.gn
文件(可以同时配置多个构建版本,生成的产物互不影响)。这个时候输入以下的配置参数并保存,GN会帮我们初始化好所有的.ninja
配置文件。
1 | target_os = "android" |
当然你也可以使用以下指令快速完成配置文件的初始化:
1 | gn gen --args='target_os="android" target_cpu="arm"' out/Default |
关于target_cpu
与本机代码指令集的对应关系,可以参照下列表格:
abi | target_cpu |
---|---|
arm64-v8a | arm64 |
armeabi-v7a | arm |
x86 | x86 |
x86_64 | x64 |
除了target_os
和target_cpu
之外,我们还可以根据编译类型(如debug、release)设置一些其他的参数:
- is_debug: 设置true时编译debug版本,false时编译release版本。
- is_component_build: 设置true时会把声明为
components
的目标作为共享库动态加载,一般在编译debug版本时,会设置为true,这样每次改动编译链接花费的时间就会减少很多。若为false,则组件将采用静态链接,详细介绍可参考官方文档:component_build.md。 - use_jumbo_build: 设置true时会启动jumbo编译模式,该模式下编译与链接速度都会快很多,在调试的时候可以提高效率。但是因为jumbo的原理是合并多文件一起进行编译,因此编译时可能会产生额外的symbols冲突,详细介绍可参考官方文档:jumbo.md。
GN常用指令
查看构建环境的默认参数
通过args --list
命令还可以查看当前构建环境的所有配置参数与详细说明,并且可以看到当前的默认值是多少,通过以下指令我们可以把参数输出到文件中进行查看。
1 | gn args --list out/Default > env.txt |
对历史构建进行清理
通过clean
指令可以对编译环境进行清理,会删除所有编译的中间产物,仅保留args.gn
、build.ninja
等基础的配置文件,以便我们进行一次完整的重编译。
1 | gn clean out/Default |
查看给定target或config的详细信息
通过desc
指令可以查看某个target的所有详细信息,包括所有包含的sources
源码、cflags
参数、依赖的libs
等等…通过以下指令我们可以把结果输出到文件中进行查看。
1 | gn desc out/Default //net:net > desc.txt |
查看指令帮助信息
通过help
指令可快速查看某个command
的详细使用文档,包括支持参数、输出结果、Examples等:
1 | gn help <command> |
关于GN的更多使用方式可参考官方文档:Quick Start guide
编译Chromium APK
通过以下命令我们可以编译Chromium的APK:
1 | autoninja -C out/Default chrome_public_apk |
其中autoninja
为ninja
的包装器,会自动提供最佳的参数给到ninja
;out/Default
为我们生成配置文件的目录;最后的chrome_public_apk
为ninja
已经配置好的编译target,其中还包含了chrome_modern_public_apk
、monochrome_public_apk
等特性target。
经过漫长的等待后,看到下面的log,并且没有任何报错,就证明已经编译完成了,APK产物ChromePublic.apk
在out/Default/apks
目录下面:
1 | ninja: Entering directory `out/Default' |
单独编译模块与使用
除了编译完整的APK,其实在Chromium
中还有很多实用的模块与so库我们可以抽出来在项目中进行使用。单独编译模块的方式也很简单,假设我们需要编译net模块到项目中使用,可通过如下的命令进行编译:
1 | autoninja -C out/Default net |
此命令会编译net模块以及所依赖的其他模块,如:base
、boringssl
、crcrypto
等模块。顺利编译完成后,在out/Default/
目录下即可找到我们所需的so库文件:
1 | ls -l | grep so$ |
将上面编译生成的so拷贝到项目的src/main/jniLibs/armeabi-v7a
目录下,并抽取相关头文件拷贝至src/main/cpp/include
中(可通过gn desc
中返回的相关信息进行查找)。最终在CMakeLists.txt
中设置include_directories
与link_directories
后即可进行调用。
1 | set(libs_dir src/main/jniLibs/${ANDROID_ABI}) |