【推荐】获取 aarch64 版本 libv8_monolith.a 静态库的三种方法

前言

前不久,为了搞定 OpenRASP for linux aarch64 版本,中间最关键的一个东西就是 Chromium 的开源 v8 引擎(俗称 libv8),通过静态库(libv8_monolith.a)的形式引入,官方提供的预编译版本是 7.8.279.19,相对较老,尝试从 V8 官方源码编译这个版本,运行总是 OOM(不知道是否编译环境的问题),含泪放弃~~~
以下为过程中的报错信息:

mvn install

OOM

gdb ../build64/java/libopenrasp_v8_java.so core.xxxxx # xxxxx 为 coredump 的进程号

调用堆栈

后来经过反复尝试(网络上的文章是真简短,但最终都是指向失败,求助 GPT 基本也是一顿胡说,让我走了不少弯路),发现 8.6.395.17 版本的 hello-world 可以正常运行,遂在这个版本基础上进行 OpenRASP 更新的后续工作。
这篇文章就讲一讲我这三周摸索出的三种获取 libv8_monolith.a 静态库的方法,供读者参考。

方法一:使用 Libv8 官方代码

  • 优点:原生代码,干净;生成的库体积小、参数配置方便
  • 缺点:需要梯子才能访问、工具链庞大,编译环境搭建贼慢
  • 参考:https://github.com/tanjelly/openrasp-v8/blob/master/vendors/build-libv8.sh

PS: 刚开始不知道项目中有这个脚本,走了不少弯路!!!

安装系统

  • Ubuntu22.04 X86_64

安装必要组件

sed -i 's#/archive.ubuntu.com#/mirrors.ustc.edu.cn#g' /etc/apt/sources.list
sed -i 's#/security.ubuntu.com#/mirrors.ustc.edu.cn#g' /etc/apt/sources.list

apt-get update
apt-get upgrade
apt-get install vim git python2 python3 python3-pip ninja-build clang-14
apt-get install pkg-config libglib2.0-dev
ln -s /usr/bin/python2 /usr/bin/python
export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/share/pkgconfig:/usr/lib/$(uname -p)-linux-gnu/pkgconfig

拉取编译 libv8 相关代码

cd /opt/
# 拉取编译工具
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=/opt/depot_tools:$PATH

# 初始化编译环境(如果有报错需要根据错误处理)
python3 /opt/depot_tools/gclient.py

# 拉取v8代码
fetch v8

# 拉取相关依赖(漫长的等待...)
cd v8
git checkout 8.6.395.17
gclient sync -v
# 或执行 python3 /opt/depot_tools/gclient.py sync -v

安装 aarch64 编译环境

cd /opt/v8/
python build/linux/sysroot_scripts/install-sysroot.py --arch=arm64

构建

cd /opt/v8/

# 构建配置
mkdir -p out/arm64.release
cat > out/arm64.release/args.gn <<EOF
is_debug = false
target_cpu = "arm64"
symbol_level = 0
is_component_build = false
treat_warnings_as_errors = false
use_custom_libcxx = false
libcxx_abi_unstable = false
v8_embedder_string = " <OpenRASP>"
v8_monolithic = true
v8_enable_i18n_support = false
v8_use_snapshot = true
v8_use_external_startup_data = false
v8_enable_shared_ro_heap = true
EOF

# 生成构建相关文件(过程中可能会提示 libcxx_abi_unstable 问题,直接忽略)
gn gen out/arm64.release

# 构建(16为CPU数量)
/usr/bin/ninja -C out/arm64.release -j 16 v8_monolith

# 最终生成的库文件(大小为40M左右)
out/arm64.release/obj/libv8_monolith.a

其它版本 libv8_monolith.a 生成方法与 aarch64 版本基本相同,只需要修改 args.gn 文件中的 target_cpu 参数为 x64(编译成功) 或 x86 (交叉编译失败,可能需要在 i386 系统环境下编译)即可。

方法二:使用 Nodejs 官方代码

  • 优点:使用系统默认的编译环境就可以进行,省却大量拉取工具链的时间
  • 缺点:想定制不太容易,怎么调参没研究透,最终生成的文件也比【方法一】大一些(约70M+)
  • 参考:https://github.com/rubyjs/libv8-node/blob/master/libexec/build-libv8

安装并启动系统

  • CentOS 7.9 Aarch64

安装必要组件

yum update -y
yum -y install cmake git wget vim python2 centos-release-scl
yum makecache

安装编译工具

yum -y install devtoolset-10
scl enable devtoolset-10 bash

拉取 Nodejs 代码

wget https://nodejs.org/dist/v15.14.0/node-v15.14.0.tar.gz
tar -xf node-v15.14.0.tar.xz

编译 Nodejs

cd node-v15.10.0/
CPUS=`cat /proc/cpuinfo | grep processor | wc -l`

# 配置
./configure --openssl-no-asm --without-npm --shared --without-intl --without-siphash
sed -i "56i \                 'v8_embedder_string': ' <OpenRASP>'," config.gypi

# 编译
make -j$CPUS

打包 libv8_monolith.a

首先在 nodejs 源码根目录下创建一个包含下列内容的脚本 build-monolith.sh(参考 node-v8-monolith 项目)

#!/bin/sh

BASEDIR=$(pwd)
BUILDTYPE=${BUILDTYPE:-Release}

cd out/${BUILDTYPE}/obj.target

if [ "$(uname)" = "SunOS" ]; then
  /usr/xpg4/bin/find . -path "**/*v8*/**/*.o" | xargs ar cqs libv8_monolith.a
  /usr/xpg4/bin/find . -path "**/*icu*/**/*.o" | xargs ar cqs libv8_monolith.a
elif [ "$(uname)" = "Linux" ]; then
  for lib in `find . -path './tools/v8_gypfiles/*.a'`;
    do ar -t $lib | xargs ar -q libv8_monolith.a;
  done;
  for lib in `find . -path './tools/icu/*.a'`;
    do ar -t $lib | xargs ar -q libv8_monolith.a;
  done;
else
  echo "Unsupported Platform"
  exit
fi

mv libv8_monolith.a $BASEDIR/out/${BUILDTYPE}

然后执行脚本,生成文件:

bash ./build-monolith.sh

# 生成的库文件位置
out/Release/libv8_monolith.a

方法三:使用 libv8-node 预编译库

  • 优点:此方法最省事,省却大量折腾 libv8 库的时间
  • 缺点:文件有点大,没法定制

下载 libv8-node

# 本来想找一个跟方法二一致的版本,发现官方没提供
wget https://rubygems.org/downloads/libv8-node-15.14.0.1-aarch64-linux.gem

从下载的文件包中使用 7zip 提取下列文件:

data.tar.gz/data.tar/vendor/v8/include
data.tar.gz/data.tar/vendor/v8/out.gn/libv8/obj/libv8_monolith.a

总结

综合对比来看,三种方法条件允许还是使用【方法一】比较好。如果为了节省时间,【方法三】是个不错的选择。【方法二】适合具备一定调参基础的同学。

参考

1: https://github.com/sqreen/node-v8-monolith
2: https://github.com/tanjelly/openrasp-v8
3: https://v8.dev/docs/compile-arm64
4: https://rubygems.org/gems/libv8-node/versions/15.14.0.1-aarch64-linux
5: https://nodejs.org/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值