Can't get GMP lib compiling with Emscripten

emscripten, gmp, llvm

Solution

I got this working in the end. (And indeed for MPFR as well).

The biggest issue was making sure one used 32 bit options and headers.

Problem

I've tried the instructions here with the latest version of Emscripten: https://github.com/kripken/gmp.js/blob/master/README.markdown The .a file seems to be correctly created. I then try to compile against that library (in debug mode), and that seems to work: ``` 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 ``` However, when I try to run the generated Javascript, I get this error: ``` 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) ``` Alon (the creator of Emscripten), over on the Emscripten Google Group, says that means the function is not there, and to check with llvm-vm, which it does appear to be: ``` 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 ``` So I'm completely at a loss! It might be worth noting that compiling the test against the library when building with the regular compiler works fine. EDIT: Got further with this. In version 5.1.1 of this lib they introduced a new configure option '--dissable-assembly', which does a generic C compilation. The issue now is that while the test runs, it never stops. It is suggested that I 'disable' the LIKELY and UNLIKELY options in the gmp.h: https://github.com/kripken/gmp.js/blob/master/gmp-h.in But I don't see how to 'disable' them as such. Normally there's a 0 or 1 option, but I don't see that here. I don't understand even what this particular option does. Thanks Marcos

Original source