QuickJs交叉编译arm64,替换路由器上笨重的nodejs

QuickJs交叉编译arm64,替换路由器上笨重的nodejs

0x0 前言

新年快乐!

最近在新闻上刷到一个叫QuickJs的js引擎,主打的就是一个轻量,于是想到自己路由器上之前有一个别人用js写的奇葩所谓sm4加密库。

这个库虽然标榜是sm4,但是加密结果跟其他人的实现都完全不一样,我去看了半天它的代码也没看出哪里写的不标准,喂给ai也没解决。反正是就结果来说是独此一家,只能用它。

然后我为了用这个库,只好在我的路由器上装了个nodejs,测试下来那叫一个慢,不过也凑活能用,就一直没动他,今天看到了如此快速高效的实现,直接换掉它!

0x1 交叉编译

本人环境:wsl ubuntu24.04。

安装交叉编译工具链

1
sudo apt install gcc-aarch64-linux-gnu

去QuickJs的release下载源代码解压:https://github.com/quickjs-zh/QuickJS/releases/tag/v20250426

然后修改它的Makefile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#CONFIG_M32=y
# cosmopolitan build (see https://github.com/jart/cosmopolitan)
#CONFIG_COSMO=y
# -----------40行左右添加------------
CONFIG_AARCH64=y #40行左右添加如下两行
LDFLAGS+=-static #静态编译
# ----------------------------------

# [...]

ifdef CONFIG_WIN32
ifdef CONFIG_M32
CROSS_PREFIX?=i686-w64-mingw32-
else
CROSS_PREFIX?=x86_64-w64-mingw32-
endif
EXE=.exe
#------------80行左右添加--------------
else ifdef CONFIG_AARCH64
CROSS_PREFIX?=aarch64-linux-gnu-
EXE=
#-------------------------------------
else
CROSS_PREFIX?=
EXE=
endif
# installation directory

# [...]

#--------可选,277行左右修改-----------
#给qjsc用的,可以直接把js编译成直接可用的ELF二进制文件,如果你想在x86_64上交叉编译出arm64的js二进制ELF可以修改
#如果没有qjsc的需求可以直接忽略
QJSC_DEFINES:=-DCONFIG_CC=\"$(CROSS_PREFIX)gcc\" -DCONFIG_PREFIX=\"$(PREFIX)\"
ifdef CONFIG_LTO
QJSC_DEFINES+=-DCONFIG_LTO
endif
QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(CROSS_PREFIX)gcc\" -DCONFIG_PREFIX=\"$(PREFIX)\"
#-------------------------------------

直接编译

1
make -j$(nproc)

如果没有报错的话就没问题了

把生成的qjs上传到openwrt就可以使用了。

1
2
./qjs demo.js
./qjs --help

0x2延申:命令行参数适配

在之前的nodejs脚本里获取命令行参数的方法是

1
process.argv;

quickjs里没有process包,但是有一个全局变量scriptArgs,参考examples/pi_bigint.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// ....前略....

var args;
if (typeof scriptArgs != "undefined") {
args = scriptArgs;
args.shift();
} else if (typeof arguments != "undefined") {
args = arguments;
} else {
/* default: 1000 digits */
args=[1000];
}

main(args);

它是一个string Array,特别的,scriptArgs[0]是脚本自身的文件名,从1开始则是用户给定的输入。

举一例:

1
2
3
const args = process.argv.slice(2); //nodejs写法,在quickjs无法使用

const args = scriptArgs.slice(1); //quickjs写法。

QuickJs交叉编译arm64,替换路由器上笨重的nodejs
https://www.hakurei.org.cn/2026/01/01/quickjs-on-openwrt/
作者
zjkimin
发布于
2026年1月1日
更新于
2026年1月1日
许可协议