1. V8编译历程
1.1 前言
- 编译V8第一步就是保证能访问Google,当然不仅仅是为了查阅资料,最最重要的是V8源码下载的需要。
- 访问 https://v8.dev/docs ,V8官网可查看到Building V8 from source 根据所写一步步来就好。
1.2 编译环境搭建
V8源码通过depot_tools工具来管理,首先下载这个工具,作者以/Users/*/Documents/test/v8
目录为工作目录。
由于需要访问国外站,在获取depot_tools前需要做一些不可描述的事情:
1 | export http_proxy="http://127.0.0.1:8001"; export HTTP_PROXY="http://127.0.0.1:8001"; export https_proxy="http://127.0.0.1:8001"; export HTTPS_PROXY="http://127.0.0.1:8001" |
开启代理后,将其假如环境变量。
进入/Users/*/Documents/test/v8
目录下:
1 | git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git |
通过git下载depot_tools
。
将工具集假如环境变量:
1 | export PATH=$PATH:/Users/*/Documents/test/v8/depot_tools |
fetch V8源码,并同步,fetch命令即depot_tools中的命令:
1 | fetch v8 |
作者使用Mac,Xcode 为10.2.1,Xcode在10以后不支持32位的编译,一次需要同时安装10一下的版本。
到苹果下载官网 https://developer.apple.com/download/more/ 找到Xcode 10一下的版本并下载,我采用的是9.4.1。由于Xcode 体积比较大,通过浏览器下载比较慢。直接复制下载地址到下载器无法下载,需要将下载地址的请求头一并复制:打开chrome 开发者工具,点击下载后在Network可看到下载地址,右键下载地址,选择Copy-Copy as cURL,在终端粘贴后假如 -O
即可通过curl下载。
笔者将Xcode9.4.1 安装到:/Applications/Xcode9.4.1/Xcode.app
查看xcode的版本:
1 | xcode-select -p |
切换xcode的版本:
1 | sudo xcode-select -s /Applications/Xcode9.4.1/Xcode.app/Contents/Developer |
接下来进入编译的坑。
1.3 编译
1.3.1 编译V8可执行文件
通过 https://v8.dev/docs/cross-compile-arm 官网介绍的,在.gclient
中添加target_os = ['android']
,再次执行gclient sync
,拉取与Android编译想过的模块,主要是NDK,如果本地有ndk,可以不用添加target_os = ['android']
,以节约时间。即是加上,拉下来的NDK也是linux的,里面缺少很多Mac下的工具,因此,我单独自己下载的。
1 | cd /Users/*/Documents/test/v8 |
通过 gm
工具编译
1 | cd v8 # 进入v8代码目录 |
执行完后,会生成 unittests cctest d8
三个执行文件,并需要电脑通过ADB连接Android手机,以测试生存文件是否存在问题。这里有个巨坑,在生成d8的最后一步,需要用到一个工具eu-strip,这个工具是linux的,导致最后一步无法通过。除此之外,在构建静态库时,需要用到llvm-ar工具,但是v8工具库里缺少这个文件,需要从ndk中拷贝一份。
1 | cd /Users/*/Documents/test/v8 |
在链接过程中可能会报clang: error: invalid linker name in argument '-fuse-ld=lld'
这是因为缺少ld.lld
文件。
编译完成后,会自动通过adb下载到手机做测试。如果不想测试执行gm android_arm.release
,另外gm
命令会自动上传编译报告给google,如果link完后,提示ninjalog_uploader_wrapper.py
相关的错误可能时代理没设置,不过没关系,前面的那步一脚编译完成。
如果需要测试v8编译是否成功,可参考官方文档 https://v8.dev/docs/cross-compile-arm 自己上传d8及需要的文件至手机测试。
如果自定测试提示adb未找到,需要将adb添加到下面目录(v8下载的android_tools中的adb为linux版的):
1 | /Users/*/Documents/test/v8/v8/third_party/android_tools/sdk/platform-tools/adb |
如果不行,直接改代码
/Users/*/Documents/test/v8/v8/third_party/catapult/devil/devil/android/sdk/adb_wrapper.py:
1 | def _FindAdb(): |
自己简单测一下;
1 | adb shell 'mkdir -p /data/local/tmp/v8/bin' |
1.3.2 编译配置
可按自己的需求修改编译配置,通过v8gen.py工具可查看内置默认编译配置
1 | cd /Users/*/Documents/test/v8/v8 |
通过tools/dev/v8gen.py arm.release
命令可以生存对应的问价,文件在 out.gn
目录内,通过gm
生成的文件在 out
内。
1 | is_component_build = false |
is_component_build
true 生存动态库,false 生成可执行文件
v8_static_library=true
生成静态库
v8_enable_i18n_support=false
是否支持i18n
1.3.3 编译静态库
出了通过配置编译外,还可以自己通过llvm-ar 命令来生存静态库。
1 | cd /Users/*/Documents/test/v8/v8/out/android_arm.release/obj |
得到的libv8all.a 即为链接了所有.o 的静态库。
1.3.4 其他问题
“stddef.h: No such file or directory”
这个是clang++ 的一个bug,在拷贝llvm-ar时,确保
v8/third_party/llvm-build/Release+Asserts/bin/
目录中的clang++ 没被替换,用v8自己的。在Android项目中引入v8静态库做开发时,出现
std::__ndk1::
想关错误- NDK的libc++的C++11命名空间为std::__ndk1
- NDK的gnustl的C++11命名空间为std
- 安卓系统的libc++的C++11命名空间为std::__1
https://zhuanlan.zhihu.com/p/31025055
需要将obj下的libc++相关的库一起引入,通过ar命令打包时,需要一起打包。
发现v8下的内容被玩坏了?
删掉对应内容的git仓库,
gclient sync
一下 。gclient sync
提示其他库有内容未提交,删掉其他库,一起gclient sync
😋。怎么都不行?
请使用ubuntu!!!