Linux aarch64交叉编译之 nodejs js运行时环境

对于nodejs的交叉编译。该文章的目标是编译一套aarch64 Linux Debian嵌入式版本上可以运行的库,本来想在网上找些现成的,然而 交叉编译靠谱的资料也是少的一13,接下来就开始趟坑。老套路,先把linux桌面版搞好,然后 移植到嵌入式Linux Debian 板子上。

1 Nodejs简介

Node.js发布于2009年5月,由Ryan Dahl开发,是一个基于Chrome V8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式I/O模型,让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。

简单来说就是用来运行js的,基于v8引擎,效率更高,跑的更快。嵌入式Linux上运行js不可或缺的运行时runtime软件之一。

nodejs相关网站信息:

2 Linux 本地编译 & 交叉编译

2.1 Linux(ubuntu20.04)上 nodejs的编译

按照文档的指示,关注以下3个关键软件的版本:

* `gcc` and `g++` >= 6.3 or newer, or
* GNU Make 3.81 or newer
* Python (see note above)
  * Python 2.7
  * Python 3.5, 3.6, 3.7, and 3.8.

在linux上编译比较简单,按照README.md、BUILDING.md文档的说明,只需要执行命令:

$ ./configure
$ make -j4
$ make install

Linux桌面版的编译简单的一他糊涂,但是 嵌入式版的编译难度吗,相比之下,完全不是一个等级阿,坑还是比较多的,不过好在最终上岸。

2.2 使用clang编译nodejs

为了满足某些特殊需求,这使用clang编译而不是默认的gcc/g++编译器来编译,首先需要安装clang编译器体系,这里以clang-14(ubuntu20.04)为例,编辑/etc/apt/source.list文件,追加以下两行内容:

deb http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main
deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-14 main

执行命令集:

#安装前执行update
sudo apt update
#有时候会报key不识别的问题,直接记录key值,然后执行以下指令即可
#sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [key ID]
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 78BD65473CB3BD13
#install clang14 step process (order,step by step)
# LLVM
sudo apt-get install  -y libllvm-14-ocaml-dev libllvm14 llvm-14 llvm-14-dev llvm-14-doc llvm-14-examples llvm-14-runtime
# Clang and co
sudo apt-get install -y clang-14 clang-tools-14 clang-14-doc libclang-common-14-dev libclang-14-dev libclang1-14 clang-format-14 python3-clang-14 clangd-14 clang-tidy-14
# libfuzzer
sudo apt-get install -y libfuzzer-14-dev
# lldb
sudo apt-get install -y lldb-14
# lld (linker)
sudo apt-get install -y lld-14
# libc++
sudo apt-get install -y libc++-14-dev libc++abi-14-dev
# OpenMP
sudo apt-get install -y libomp-14-dev
# libclc
sudo apt-get install -y libclc-14-dev
# libunwind
sudo apt-get install -y libunwind-14-dev
# mlir
sudo apt-get install -y libmlir-14-dev mlir-14-tools

安装好后编译用到的编译工具链需要单独配置,这里就需要一个自定义的configure文件了,在nodejs的目录下创建一个文件clang-configure(和android-configure同级),内容如下:

#!/bin/bash

export CC=clang-14
export CXX=clang++-14
export LD=ld
export AS=llvm-as-14
export AR=llvm-ar-14
export STRIP=llvm-strip-14
export OBJCOPY=llvm-objcopy-14
export OBJDUMP=llvm-obidump-14
export RANLIB=llvm-ranlib-14
export NM=llvm-nm-14
export STRINGS=llvm-strings-14
export READELF=llvm-readelf-14

#execute configure
if [ -f "configure" ]; then
    ./configure --shared --debug --debug-node --debug-lib
fi

接下来创建一个目录clang(和clang-configure同级),在该目录下构建一个文件build-node-clang.sh脚本,内容如下:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
#MAKE_OPTS="-j8"

cd $DIR
rm -rf dist
mkdir -p dist

#检查编译结果,如果编译失败, 则退出
function CheckBuildResult() {
  if [ $? -ne 0 ]; then
    exit 1
  fi
}

cd ..
# build clang
./clang-configure
echo make start
make $MAKE_OPTS > /dev/null
CheckBuildResult
echo "make end"
rm -rf $DIR/tmp
mkdir $DIR/tmp
./tools/install.py install '' $DIR/tmp
cp -r $DIR/tmp/include $DIR/dist/

mkdir -p $DIR/dist/bin/clang
mkdir -p $DIR/dist/lib/clang
cp $DIR/tmp/lib/libnode.so.83 $DIR/dist/lib/clang
cp $DIR/../out/Release/node $DIR/dist/bin/clang
cd -

 到这里,脚本编写的相关工作就结束了,然后给build-node-clang.sh加权限:

$chmod +x build-node-clang.sh

 然后在该目录下运行脚本build-node-clang.sh即刻开始编译即可。这里最终是要拿到libnode.so 和一个node二进制文件(用于运行js)

注意:在使用make -j多线程进行编译时有可能会报错,线程数量越少报错概率越低。

2.3 aarch64交叉编译nodejs

对于嵌入式Linux Debian,使用aarch64编译也需要提前安装好相关软件,aarch64相关软件apt安装如下:

sudo apt install binutils-aarch64-linux-gnu-dbg \ 
binutils-aarch64-linux-gnu cpp-aarch64-linux-gnu gcc-aarch64-linux-gnu \
g++-10-aarch64-linux-gnu g++-9-aarch64-linux-gnu g++-aarch64-linux-gnu g++ \
gcc-10-aarch64-linux-gnu-base gcc-9-aarch64-linux-gnu-base \
pkg-config-aarch64-linux-gnu qemu-efi-aarch64 gcc arch-test

同时编译用到的交叉编译工具链需要单独配置,这里就需要一个自定义的configure文件了,在nodejs的目录下创建一个文件aarch64-configure(和android-configure同级),内容如下:

#!/bin/bash

ARCH="aarch64"
DEST_CPU="arm64"

#linux host env
HOST_OS="linux"
HOST_ARCH="x86_64"
export LINK_host="g++"
export CXX_host="g++"
export CC_host="gcc"
export AR_host="ar"

#cross-compile env
export CC=aarch64-linux-gnu-gcc
export CXX=aarch64-linux-gnu-g++
export LD=aarch64-linux-gnu-ld
export RANLIB=aarch64-linux-gnu-l-ranlib
export AR=aarch64-linux-gnu-l-ar
export AS=aarch64-linux-gnu-l-as

#execute configure
if [ -f "configure" ]; then
    ./configure \
	 --dest-cpu=$DEST_CPU \
     --dest-os=linux \
	 --without-snapshot \
	 --openssl-no-asm \
	 --cross-compiling \
	 --shared \
	 --debug \
	 --debug-node \
	 --debug-lib
fi

接下来创建一个目录aarch64(和aarch64-configure同级),在该目录下构建一个文件build-node-aarch64.sh脚本,内容如下:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
MAKE_OPTS="-j24"

cd $DIR
rm -rf dist
mkdir -p dist

cd ..
# build arm64
./aarch64-configure
echo make start
make $MAKE_OPTS > /dev/null
echo "make end"
rm -rf $DIR/tmp
mkdir $DIR/tmp
./tools/install.py install '' $DIR/tmp
cp -r $DIR/tmp/include $DIR/dist/

mkdir -p $DIR/dist/bin/aarch64
mkdir -p $DIR/dist/lib/aarch64
cp $DIR/tmp/lib/libnode.so.83 $DIR/dist/lib/aarch64
cp $DIR/../out/Release/node $DIR/dist/bin/aarch64
cd -

到这里,脚本编写的相关工作就结束了,然后给build-node-aarch64.sh加权限:

$chmod +x build-node-aarch64.sh

 然后运行脚本build-node-aarch64.sh即刻开始编译,效果如下:

Node.js configure: Found Python 3.8.10...
WARNING: building --without-snapshot is no longer possible
WARNING: --openssl-no-asm will result in binaries that do not take advantage
         of modern CPU cryptographic instructions and will therefore be slower.
         Please refer to BUILDING.md
WARNING: warnings were emitted in the configure phase
INFO: configure completed successfully
make start
...
#一堆警告啥的忽略即可
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/source-text-module-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/source-text-module-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/stack-frame-info-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/stack-frame-info-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/string-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/string-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/struct-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/struct-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/synthetic-module-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/synthetic-module-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/template-objects-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/template-objects-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/template-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/objects/template-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/wasm/wasm-objects-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/src/wasm/wasm-objects-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/test/torque/test-torque-tq-csa.cc”的配方
tools/v8_gypfiles/run_torque.host.mk:13: 警告:忽略关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/test/torque/test-torque-tq-csa.cc”的旧配方
tools/v8_gypfiles/run_torque.target.mk:13: 警告:覆盖关于目标“/data/OpenSource/nodejs/out/Release/obj/gen/torque-output-root/torque-generated/../../deps/v8/third_party/v8/builtins/array-sort-tq-csa.cc”的配方
...

这里最终是要拿到libnode.so 和一个node二进制文件(用于运行js)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值