无法使用Emscripten编译GMP库

4
我已经尝试了这里的指示,使用最新版本的Emscripten:https://github.com/kripken/gmp.js/blob/master/README.markdown 看起来 .a 文件已经正确创建。然后我尝试针对该库进行编译(以调试模式),似乎也是可以的:
emcc invocation:  /home/marcosscriven/sources/emscripten/emcc -O0 --closure 0 test.c .libs/libgmp.a -o complete.js 
(Emscripten: Running sanity checks)
emcc: compiling to bitcode
emcc: compiling source file:  test.c
emcc running: /usr/local/bin/clang -m32 -U__i386__ -U__x86_64__ -U__i386 -U__x86_64 -Ui386 -Ux86_64 -U__SSE__ -U__SSE2__ -U__MMX__ -UX87_DOUBLE_ROUNDING -UHAVE_GCC_ASM_FOR_X87 -DEMSCRIPTEN -U__STRICT_ANSI__ -U__CYGWIN__ -D__STDC__ -Xclang -triple=i386-pc-linux-gnu -D__IEEE_LITTLE_ENDIAN -fno-math-errno -fno-ms-compatibility -nostdinc -Xclang -nobuiltininc -Xclang -nostdsysteminc -Xclang -isystem/home/marcosscriven/sources/emscripten/system/local/include -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/emscripten -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/bsd -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/libc -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/libcxx -Xclang -isystem/home/marcosscriven/sources/emscripten/system/lib/libcxxabi/include -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/gfx -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/net -Xclang -isystem/home/marcosscriven/sources/emscripten/system/include/SDL -U__APPLE__ -U__linux__ -D_LIBCPP_HAS_NO_DELETED_FUNCTIONS -emit-llvm -c test.c -o /tmp/tmp_pOV54/test_0.o
emcc: copying library file:  .libs/libgmp.a
emcc: will generate JavaScript
emcc: considering including libcxx: we need set([]) and have set([])
emcc: considering including libcxxabi: we need set([]) and have set([])
emcc: considering including libc: we need set(['realloc', 'malloc', 'memcpy', 'free']) and have set([])
emcc: including libc
emcc: linking:  ['/tmp/tmp_pOV54/test_0.o', '/tmp/tmp_pOV54/libgmp_1.a', '/home/marcosscriven/.emscripten_cache/libc.bc']
emcc: llvm-linking: ['/tmp/tmp_pOV54/test_0.o', '/home/marcosscriven/.emscripten_cache/libc.bc']
emcc: saving intermediate processing steps to /tmp/emscripten_temp
emcc: LLVM opts: ['-internalize', '-internalize-public-api-list=main', '-globaldce']
emcc:    step took 0.01 seconds
emcc:    step took 0.00 seconds
emcc: LLVM => JS
emscript: ll=>js
  emscript: scan took 0.000277042388916 seconds
  emscript: split took 0.000169038772583 seconds
  emscript: phase 1 took 0.173984050751 seconds
  emscript: phase 2 working on 1 chunks  (intended chunk size: 1.00 MB, meta: 0.00 MB, forwarded: 0.01 MB, total: 0.01 MB)
  emscript: phase 2 took 0.206316947937 seconds
  emscript: phase 2b took 0.000115871429443 seconds
  emscript: phase 2c took 0.00135588645935 seconds
  emscript: phase 3 took 0.170216083527 seconds
emcc:    step took 0.60 seconds
emcc: total time: 1.62 seconds

然而,当我尝试运行生成的Javascript时,我遇到了这个错误:
marcosscriven@ubuntu-laptop:~/sources/gmp-5.0.2$ node complete.js 

/home/marcosscriven/sources/gmp-5.0.2/complete.js:2452
      ___gmpz_init(((5242892)|0));
      ^
TypeError: undefined is not a function
    at _pidigits (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2452:7)
    at Object._main (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2429:7)
    at Object.callMain (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2644:24)
    at doRun (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2679:20)
    at run (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2703:12)
    at Object.<anonymous> (/home/marcosscriven/sources/gmp-5.0.2/complete.js:2725:13)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)

在 Emscripten 的 Google 组上,Emscripten 的创建者 Alon 表示这意味着该函数不存在,请检查 llvm-vm,而事实证明该函数确实存在:

marcosscriven@ubuntu-laptop:~/sources/gmp-5.0.2$ !llvm-nm
llvm-nm .libs/libgmp.a | grep gmpz_init
00000000 T __gmpz_init
00000000 T __gmpz_init2
         U __gmpz_init
00000000 T __gmpz_inits
00000000 T __gmpz_init_set
00000000 T __gmpz_init_set_d
00000000 T __gmpz_init_set_si
00000000 T __gmpz_init_set_str
00000000 T __gmpz_init_set_ui
         U __gmpz_init
         U __gmpz_init_set_ui
         U __gmpz_init2
         U __gmpz_init_set_ui
         U __gmpz_init
         U __gmpz_init_set_str
         U __gmpz_init
         U __gmpz_init2
         U __gmpz_init_set
         U __gmpz_init
         U __gmpz_init_set

我完全不知道该怎么办!

值得注意的是,使用常规编译器构建时针对库进行测试可以正常工作。

编辑:在此版本5.1.1中,他们引入了一个新的配置选项“--dissable-assembly”,它执行通用的C编译。

现在的问题是,虽然测试运行,但永远不会停止。

建议在gmp.h中“禁用”LIKELY和UNLIKELY选项:

https://github.com/kripken/gmp.js/blob/master/gmp-h.in

但我不知道如何“禁用”它们。通常有0或1选项,但我在这里找不到。我甚至不了解这个特定选项的作用。

谢谢

Marcos


前导下划线的数量是否匹配? - Marc Glisse
根据制作Emscripten的Alon所说,额外的下划线是预期的。 - Marcos Scriven
1个回答

5
我最终成功解决了这个问题 (MPFR 也是如此)。最大的问题是确保使用32位选项和头文件。

1
你愿意写一份详细的指南来说明如何构建它吗?我担心我遇到了与你相同的问题(使用gmp),但似乎无法解决...>< - Nikkolasg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接