使用 Emscripten 编译 GMP/MPFR
Compiling GMP/MPFR with Emscripten
好吧,这让我发疯了。我已经尝试了至少一个月,但互联网上没有任何帮助。
我遵循了 this 的步骤。当我执行这些步骤时,甚至示例都不起作用,因为当我这样做时,我得到了这个。
bitcode ==> javascript
warning: unresolved symbol: __gmpz_cmp
warning: unresolved symbol: __gmpz_mul_ui
warning: unresolved symbol: __gmpz_submul_ui
warning: unresolved symbol: __gmpz_init_set_ui
warning: unresolved symbol: __gmpz_mul_2exp
warning: unresolved symbol: __gmpz_init
warning: unresolved symbol: __gmpz_fdiv_qr
warning: unresolved symbol: __gmpz_add
当我 运行 生成 complete.js 文件时 -
missing function: __gmpz_init
-1
-1
/home/ubuntu/workspace/gmp.js/complete.js:117
throw ex;
^
abort(-1) at Error
at jsStackTrace (/home/ubuntu/workspace/gmp.js/complete.js:1045:13)
at stackTrace (/home/ubuntu/workspace/gmp.js/complete.js:1062:22)
at abort (/home/ubuntu/workspace/gmp.js/complete.js:6743:44)
at ___gmpz_init (/home/ubuntu/workspace/gmp.js/complete.js:1744:56)
at Object._main (/home/ubuntu/workspace/gmp.js/complete.js:4978:2)
at Object.callMain (/home/ubuntu/workspace/gmp.js/complete.js:6627:30)
at doRun (/home/ubuntu/workspace/gmp.js/complete.js:6681:60)
at run (/home/ubuntu/workspace/gmp.js/complete.js:6695:5)
at Object.<anonymous> (/home/ubuntu/workspace/gmp.js/complete.js:6769:1)
at Module._compile (module.js:541:32)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.
我发现要这样做,你需要使用 32 位机器。我有一台 64 位机器,所以我使用 this tutorial.
chroot 进入了 32 位文件系统
之后一切正常。我正在使用 GMP 和 MPFR 制作一个 Mandelbrot 程序,我在 GitHub 上在线发布了编译脚本(连同程序本身)。 Here 是的。将其改编为您自己的项目。
这些说明适用于主机 运行 amd64 Debian Buster。似乎 GMP 不再需要 32 位来与 Emscripten 一起工作(并且在任何情况下似乎不再支持 32 位 Emscripten?),但我使用 chroot 来清洁环境。安装后,我的 chroot 有 1.6GB 大。但如果可以避免,我不建议将它用于计算密集型代码,在一个基准测试中,我的本机代码比在 nodejs 中使用 Emscripten 运行 编译的相同代码快 15 倍...
Debian 克星 chroot
mkdir emscripten
sudo debootstrap buster emscripten
sudo chroot emscripten /bin/bash
echo "deb http://security.debian.org/debian-security buster/updates main" >> /etc/apt/sources.list
apt update
apt install python cmake g++ git lzip wget nodejs m4
echo "none /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0" >> /etc/fstab
mount /dev/shm
echo "none /proc proc defaults 0 0" >> /etc/fstab
mount /proc
adduser emscripten
su - emscripten
emsdk 最新
撰写本文时已安装
releases-upstream-b024b71038d1291ed7ec23ecd553bf2c0c8d6da6-64bit
和 node-12.9.1-64bit
:
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
mkdir -p ${HOME}/opt/src
cd ${HOME}/opt/src
gmp 6.1.2
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz
tar xf gmp-6.1.2.tar.lz
cd gmp-6.1.2
emconfigure ./configure --disable-assembly --host none --enable-cxx --prefix=${HOME}/opt
make
make install
cd ..
mpfr 4.0.2
wget https://www.mpfr.org/mpfr-current/mpfr-4.0.2.tar.xz
wget https://www.mpfr.org/mpfr-current/allpatches
tar xf mpfr-4.0.2.tar.xz
cd mpfr-4.0.2
patch -N -Z -p1 < ../allpatches
emconfigure ./configure --host none --prefix=${HOME}/opt --with-gmp=${HOME}/opt
make
make install
cd ..
mpc 1.1.0
wget https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz
tar xf mpc-1.1.0.tar.gz
cd mpc-1.1.0
emconfigure ./configure --host none --prefix=${HOME}/opt --with-gmp=${HOME}/opt --with-mpfr=${HOME}/opt
make
make install
cd ..
你好世界
你最喜欢的节目使用GMP/MPFR/MPC:
emcc -o hello.js hello.c \
${HOME}/opt/lib/libmpc.a ${HOME}/opt/lib/libmpfr.a ${HOME}/opt/lib/libgmp.a
nodejs hello.js
我将它打包到一个名为 gmp-wasm. You can find a Dockerized code which builds the library within the source 的 NPM 库中。它导出低级函数和不可变的高级包装器:
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>
<script>
gmp.init().then(({
calculate
}) => {
// calculate() automatically deallocates all objects
// created within the callback function
const result = calculate((g) => {
const six = g.Float(1).add(5);
const res = g.Pi().div(six).sin();
return res;
});
document.write(`sin(Pi/6) = ` + result);
});
</script>
使用低级函数:
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>
<script>
gmp.init().then(({
calculate, binding
}) => {
const result = calculate((g) => {
const a = g.Float(1);
const b = g.Float(2);
const c = g.Float(0);
// c = a + b
binding.mpfr_add(c.mpfr_t, a.mpfr_t, b.mpfr_t, 0);
return c;
});
document.write(`1 + 2 = ` + result);
});
</script>
好吧,这让我发疯了。我已经尝试了至少一个月,但互联网上没有任何帮助。
我遵循了 this 的步骤。当我执行这些步骤时,甚至示例都不起作用,因为当我这样做时,我得到了这个。
bitcode ==> javascript
warning: unresolved symbol: __gmpz_cmp
warning: unresolved symbol: __gmpz_mul_ui
warning: unresolved symbol: __gmpz_submul_ui
warning: unresolved symbol: __gmpz_init_set_ui
warning: unresolved symbol: __gmpz_mul_2exp
warning: unresolved symbol: __gmpz_init
warning: unresolved symbol: __gmpz_fdiv_qr
warning: unresolved symbol: __gmpz_add
当我 运行 生成 complete.js 文件时 -
missing function: __gmpz_init
-1
-1
/home/ubuntu/workspace/gmp.js/complete.js:117
throw ex;
^
abort(-1) at Error
at jsStackTrace (/home/ubuntu/workspace/gmp.js/complete.js:1045:13)
at stackTrace (/home/ubuntu/workspace/gmp.js/complete.js:1062:22)
at abort (/home/ubuntu/workspace/gmp.js/complete.js:6743:44)
at ___gmpz_init (/home/ubuntu/workspace/gmp.js/complete.js:1744:56)
at Object._main (/home/ubuntu/workspace/gmp.js/complete.js:4978:2)
at Object.callMain (/home/ubuntu/workspace/gmp.js/complete.js:6627:30)
at doRun (/home/ubuntu/workspace/gmp.js/complete.js:6681:60)
at run (/home/ubuntu/workspace/gmp.js/complete.js:6695:5)
at Object.<anonymous> (/home/ubuntu/workspace/gmp.js/complete.js:6769:1)
at Module._compile (module.js:541:32)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.
我发现要这样做,你需要使用 32 位机器。我有一台 64 位机器,所以我使用 this tutorial.
chroot 进入了 32 位文件系统之后一切正常。我正在使用 GMP 和 MPFR 制作一个 Mandelbrot 程序,我在 GitHub 上在线发布了编译脚本(连同程序本身)。 Here 是的。将其改编为您自己的项目。
这些说明适用于主机 运行 amd64 Debian Buster。似乎 GMP 不再需要 32 位来与 Emscripten 一起工作(并且在任何情况下似乎不再支持 32 位 Emscripten?),但我使用 chroot 来清洁环境。安装后,我的 chroot 有 1.6GB 大。但如果可以避免,我不建议将它用于计算密集型代码,在一个基准测试中,我的本机代码比在 nodejs 中使用 Emscripten 运行 编译的相同代码快 15 倍...
Debian 克星 chroot
mkdir emscripten
sudo debootstrap buster emscripten
sudo chroot emscripten /bin/bash
echo "deb http://security.debian.org/debian-security buster/updates main" >> /etc/apt/sources.list
apt update
apt install python cmake g++ git lzip wget nodejs m4
echo "none /dev/shm tmpfs rw,nosuid,nodev,noexec 0 0" >> /etc/fstab
mount /dev/shm
echo "none /proc proc defaults 0 0" >> /etc/fstab
mount /proc
adduser emscripten
su - emscripten
emsdk 最新
撰写本文时已安装
releases-upstream-b024b71038d1291ed7ec23ecd553bf2c0c8d6da6-64bit
和 node-12.9.1-64bit
:
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
mkdir -p ${HOME}/opt/src
cd ${HOME}/opt/src
gmp 6.1.2
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz
tar xf gmp-6.1.2.tar.lz
cd gmp-6.1.2
emconfigure ./configure --disable-assembly --host none --enable-cxx --prefix=${HOME}/opt
make
make install
cd ..
mpfr 4.0.2
wget https://www.mpfr.org/mpfr-current/mpfr-4.0.2.tar.xz
wget https://www.mpfr.org/mpfr-current/allpatches
tar xf mpfr-4.0.2.tar.xz
cd mpfr-4.0.2
patch -N -Z -p1 < ../allpatches
emconfigure ./configure --host none --prefix=${HOME}/opt --with-gmp=${HOME}/opt
make
make install
cd ..
mpc 1.1.0
wget https://ftp.gnu.org/gnu/mpc/mpc-1.1.0.tar.gz
tar xf mpc-1.1.0.tar.gz
cd mpc-1.1.0
emconfigure ./configure --host none --prefix=${HOME}/opt --with-gmp=${HOME}/opt --with-mpfr=${HOME}/opt
make
make install
cd ..
你好世界
你最喜欢的节目使用GMP/MPFR/MPC:
emcc -o hello.js hello.c \
${HOME}/opt/lib/libmpc.a ${HOME}/opt/lib/libmpfr.a ${HOME}/opt/lib/libgmp.a
nodejs hello.js
我将它打包到一个名为 gmp-wasm. You can find a Dockerized code which builds the library within the source 的 NPM 库中。它导出低级函数和不可变的高级包装器:
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>
<script>
gmp.init().then(({
calculate
}) => {
// calculate() automatically deallocates all objects
// created within the callback function
const result = calculate((g) => {
const six = g.Float(1).add(5);
const res = g.Pi().div(six).sin();
return res;
});
document.write(`sin(Pi/6) = ` + result);
});
</script>
使用低级函数:
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>
<script>
gmp.init().then(({
calculate, binding
}) => {
const result = calculate((g) => {
const a = g.Float(1);
const b = g.Float(2);
const c = g.Float(0);
// c = a + b
binding.mpfr_add(c.mpfr_t, a.mpfr_t, b.mpfr_t, 0);
return c;
});
document.write(`1 + 2 = ` + result);
});
</script>