目标是将最新稳定的 GSL 编译为 web assembly 并使其作为 Node.js 模块使用。
我尝试了以下程序,灵感来自于emscripten手册的这一部分:
git clone git://git.savannah.gnu.org/gsl.git
cd gsl
git checkout tags/release-2-6
autoreconf -i
emconfigure ./configure
emmake make
不幸的是,我得到了多个
wasm-ld: error: duplicate symbol
。
但是编译 GSL (
make
) 效果非常好。
我在 Ubuntu 18.04 上使用
emsdk version 2.0.16
。
有谁知道如何解决这个问题吗?
非常感谢您的帮助。
终于找到了受这个要点启发的解决方案。该问题与动态链接和共享库有关。
无论如何,以下代码成功地将 GSL 编译为 Node.js 模块:
git clone git://git.savannah.gnu.org/gsl.git
cd gsl
git checkout tags/release-2-6
autoreconf -i
emconfigure ./configure
# Note the flag indicating STATIC linking:
# -------------------------======---------
emmake make LDFLAGS=-all-static
emcc -g -O2 -o .libs/gsl.js -s MODULARIZE -s EXPORTED_RUNTIME_METHODS=\[ccall\] -s LINKABLE=1 -s EXPORT_ALL=1 ./.libs/libgsl.a -lm
上面创建了节点模块
./.libs/gsl.js
,可以按以下示例脚本所示使用:
// test_gsl.js
var factory = require('./.libs/gsl.js');
factory().then((instance) => {
// Compute the value of the Bessel function for x = 5.0:
var besselRes = instance._gsl_sf_bessel_J0(5.0);
// Calculate the hypergeometric cumulative probability distribution for:
// 4: Number of successes (white balls among the taken)
// 7: Number of white balls in the urn
// 19: Number of black balls in the urn
// 13: Number of balls taken
var hg = instance._gsl_cdf_hypergeometric_P(4, 7, 19, 13);
// Do the same using `ccall`
var hg_ccal = instance.ccall("gsl_cdf_hypergeometric_P",
"number",
["number", "number", "number", "number" ],
[4, 7, 19, 13]);
console.log(`besselRes is: ${besselRes}`);
console.log(`gsl_cdf_hypergeometric_P(4,7,19,13): ${hg}`);
console.log(`ccall("gsl_cdf_hypergeometric_P",4,7,19,13): ${hg_ccal}`);
});
请注意,在生成的 Node.js 模块中,所有 GSL 函数都带有下划线 (
_
) 前缀。
上面的脚本 (
node ./test_gsl.js
) 生成以下输出:
besselRes is: -0.17759677131433826
gsl_cdf_hypergeometric_P(4,7,19,13): 0.8108695652173905
ccall("gsl_cdf_hypergeometric_P",4,7,19,13): 0.8108695652173905
我真诚地希望这篇文章对任何人都有帮助。 祝你玩得开心,干杯!
补充网友3139868的答案:
如果您在运行最后一个命令时遇到有关 cblas 符号的错误:
emcc -g -O2 -o .libs/gsl.js -s MODULARIZE -s EXPORTED_RUNTIME_METHODS=\[ccall\] -s LINKABLE=1 -s EXPORT_ALL=1 ./.libs/libgsl.a -lm
运行以下命令:
emcc -g -O2 -o .libs/gsl.js -s MODULARIZE -s EXPORTED_RUNTIME_METHODS=\[ccall\] -s LINKABLE=1 -s EXPORT_ALL=1 ./cblas/.libs/libgslcblas.a .libs/libgsl.a -lm