美文网首页V8
Mac上如何编译Android可用的V8

Mac上如何编译Android可用的V8

作者: AndroidWorld | 来源:发表于2020-04-15 23:46 被阅读0次

    上篇文章我们尝试在Mac上成功编译了V8,不过编译生成的d8只能运行在Mac主机上运行,具体请参考「Mac上如何编译V8」。如果想要编译出能在Android上运行的d8该怎么做呢?这就要用到传说中的cross compile了。

    V8交叉编译

    请参考官方文档https://v8.dev/docs/cross-compile-arm

    修改gclient配置文件

    在.gclient文件里添加target_os=['android'],问题来了,这个.gclient文件在哪,笔者在V8源码文件夹下一顿找,居然没找到这货。假设你源码路径为/path/to/v8/v8,这货在/path/to/v8下,改完之后应该类似下图

    下载Android相关依赖

    在/path/to/v8下执行gclient sync命令

    生成ninja文件

    执行tools/dev/v8gen.py list,结果如下

    这里我选择arm64架构的,执行tools/dev/v8gen.py arm64.release,会生成out.gn/arm64.release文件夹,目录结构如下图

    执行gn args out.gn/arm64.release查看生成的默认参数配置,可根据需要修改默认参数,笔者的配置如下图

    执行gn args out.gn/arm64.release/ --list命令可以查看支持的所有参数及每个参数的说明,如果只想看某个参数的说明,例如只想看symbol_level参数的说明可执行gn args out.gn/arm64.release/ --list=symbol_level,结果如下图

    编译

    执行ninja -C out.gn/arm64.release/ d8,即可启动编译。

    编译过程碰到的问题

    1. fatal error: 'features.h' file not found

    我们搜下v8源码目录下是否有features.h文件,find . -name features.h,可以看到toolchains下只有linux-x86_64,但编译用的确是third_party/android_ndk/toolchains/llvm/prebuilt/darwin-x86_64/sysroot

    解决方法

    1. 先看下v8里的ndk的版本,cat third_party/android_ndk/source.properties

    2. 下载这个版本的ndk(如果本地有其他版本的ndk可先尝试),并在ndk目录下搜索features.h,find . -name features.h

    3. 把红框拷贝到v8下的ndk里,执行cp -rv 20.0.5594570/toolchains/llvm/prebuilt/darwin-x86_64/ /path/to/v8/v8/third_party/android_ndk/toolchains/llvm/prebuilt/darwin-x86_64/,darwin-x86_64已经有了

    4. 再启动编译

    2. llvm-ar: No such file or directory

    报错是因为llvm-ar这个文件不存在

    解决方法

    1. 同上一个问题,在ndk目录下搜索llvm-ar,find . -name llvm-ar

    2. 把红框文件拷贝过去,cp ./20.0.5594570/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar /path/to/v8/v8/third_party/llvm-build/Release+Asserts/bin/

    3. 再启动编译

    3. invalid linker name in argument '-fuse-ld=lld'

    解决方法

    参考https://lld.llvm.org/

    猜测应该是因为ld.lld这个文件找不到,在v8源码目录下执行find . -name ld.lld

    尝试拷贝这个文件,执行cp ./third_party/android_ndk/toolchains/llvm/prebuilt/darwin-x86_64/bin/ld.lld third_party/llvm-build/Release+Asserts/bin/

    再启动编译

    4. OSError: [Errno 8] Exec format error

    解决方法

    1. 调试gcc_link_wrapper.py发现是执行strip的时候出错了,错误显示「Exec format error」

    2. 看下eu-strip文件的格式,执行file buildtools/third_party/eu-strip/bin/eu-strip,可以看到这个文件是Linux上的可执行格式,Mac的可执行文件格式应该是「Mach-O」这种格式的。

    3. 在third_party/android_ndk/toolchains/llvm/prebuilt/darwin-x86_64下搜索stripe命令,find . -name *strip*

    4. 尝试把eu-strip换成llvm-strip试下,v8源码目录下搜索eu-strip,grep -nr 'eu-strip' *,strip工具应该是在build/toolchain/android/BUILD.gn里配置的。

    4. 修改build/toolchain/android/BUILD.gn,替换eu-strip为llvm-strip

    5. 再启动编译,终于编译成功。

    运行

    cd out.gn/arm64.release

    adb push d8 /data/local/tmp/v8/bin/,android上成功运行

    总结

    编译过程中碰到了4个问题,可以看到都是环境问题,而且网上相关的资料比较少,笔者在这里还折腾了不少时间,好在最终都成功解决了。难怪网上很多人都推荐用Linux去编译V8,如果用Linux编译的话应该不会有这些问题吧,但笔者手上只有Mac环境,也不想倒腾虚拟机,就硬着头皮在Mac上开干了。人生在于折腾,一分折腾一分收获,谨以此与大家共勉。

    相关文章

      网友评论

        本文标题:Mac上如何编译Android可用的V8

        本文链接:https://www.haomeiwen.com/subject/zfahvhtx.html