Can't build wasm

I tried following the instructions at SWI-Prolog in the browser using WASM , and I’ve made a few edits to the instructions where I had problems; but now I’m stuck.

The error message is a bit suspicious because it points to “ply=…” in var _main=Module["_main"]=function(){return(_main=Module["_main"]=Module["asm"]["ba"]).apply(null,arguments)};
I’ve had to truncate the error message because of Discourse limitations. The full output is SWIPL wasm build with error · GitHub (I haven’t included the outputs of the various preliminary steps, such as getting and building GMP; if those outputs are needed, I can re-do everything from the beginning).

$ uname -a
Linux penguin 5.15.103-17409-g07029265d738 #1 SMP PREEMPT Thu May 4 18:32:41 PDT 2023 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux 11 (bullseye)
Release:	11
Codename:	bullseye
$ node --version
[552/575] Linking C static library src/libswipl.a
[553/575] Linking C executable src/swipl.js
[554/575] Linking C executable src/swipl-bundle-no-data.js
[555/575] Generating ../home/boot.prc
FAILED: home/boot.prc 
cd /home/peter/src/swipl-devel/build.wasm/src && /usr/bin/cmake -E remove -f /home/peter/src/swipl-devel/build.wasm/home/boot.prc && /usr/bin/nodejs /home/peter/src/swipl-devel/build.wasm/src/swipl.js -q -O -o /home/peter/src/swipl-devel/build.wasm/home/boot.prc -b /home/peter/src/swipl-devel/build.wasm/home/boot/
var Module=typeof Module!="undefined"?Module:{};var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program"; ...

TypeError: wasm function signature contains illegal type
    at wasm-function[1508]:0xf76ba
    at wasm-function[2773]:0x1a8a19
    at wasm-function[630]:0x584d1
    at wasm-function[3219]:0x1c06c9
    at wasm-function[331]:0x23c18
    at wasm-function[1743]:0x13a027
    at wasm-function[1742]:0x139f55
    at wasm-function[862]:0x74c50
    at wasm-function[3328]:0x1ca55b
    at Module._main (/home/peter/src/swipl-devel/build.wasm/src/swipl.js:1:93149)
ninja: build stopped: subcommand failed.

Compilation exited abnormally with code 1 at Sat May 27 17:53:03

I just noticed that “WASM updates” says that a recent version of Node.js is needed (v18.16 has been tested), and mine is pretty old, so I’ll try installing that and see what happens. (This information was left out of the build instructions)

EDIT: I updated to Node.js v18.16.0, and get essentially the same result. (It takes a few hours to build Node.js)
I’ve updated the build instructions to include the Node.JS version.

This is still a version issue. The WASM toolchain is still pretty sensitive to versions, both wrt. Emscripten and Node.js. Luckily, once built, most browsers seem to have sufficiently up-to-date WASM/JavaScript support to run the result.

Note that Emscripten also ships with a node.js that is currently (3.1.37?) too old to run the code it generates. The configuration may pick up that version. You can avoid that by adding -DNODE_JS_EXECUTABLE=/bin/node to the CMake flags.

There are also binaries :slight_smile:

Unfortunately, my ChromeBook doesn’t like PPAs for installing newer versions of Node.js than are part of Debian. If there’s a cheat-sheet on how to work around this, please tell me.

Anyway, adding -DNODE_JS_EXECUTABLE=$(type -p node) to the configure script seems to have fixed things. I’ve updated the SWI-Prolog in the browser using WASM page, but I’ve noticed that there’s also Building SWI-Prolog using Emscripten for WebAssembly (WASM) … should the latter also be updated, or is it obsolete?

I don’t know. Its long ago I had a Chromebook.

I do hope this is a temporary hack. If you don’t do anything it picks the node version that comes with Emscripten. You’d assume that is compatible with the code produced by the Emscripten compiler. At the moment that doesn’t seem to be the case. Emscripten develops quite fast, getting better each time but occasionally suffering from some regression.

Probably one should go. I’m tempted to use the website as the leading place. Note that you can edit the page using the repo GitHub - SWI-Prolog/plweb-www: Submodule of plweb.git that contains the (wiki) web-pages. We could also host all build instructions on Discourse. These instruction are a but complicated compromise between conciseness and trying to cover all cases. And, they are always a moving target. The idea is to take care of most problems in CMake, so the user only has to decide on packages and options (threads, GMP/BF, etc.)

Note that the NPM version is built using GitHub - SWI-Prolog/npm-swipl-wasm: SWI-Prolog WebAssembly build as a NPM package.

A similar problem exist when trying to build SWI-Prolog from source for Windows. There are so many places one lands at the start from a Google search depending upon the query that it takes hours to days to just to sort out what is current and even more importantly what is valid and works.

While I don’t expect the situation for a Windows build from source to be fixed, now would be the time to nip the problem for WASM. :slightly_smiling_face:

I don’t see much hope :frowning: The Windows version is extremely complicated as we have many different build routes (MinGW, MSYS2, Cygwin, MSVC, WSL2, …) and it is relatively hard to get all dependencies in place.

Then, people put their own build experience in a blog, gist, YouTube, … They probably worked when written, but get outdated.

I fear there is little we can do about that except for trying to keep the build instructions up-to-date on Build SWI-Prolog from source as good as we can.


All the tests now pass except one. I’ve put the full error output here: SWIPL wasm build with error · GitHub

(I built with GMP, following the instructions; I tried building without GMP but that didn’t work and I haven’t tried to figure out why)

Running test set "gmp" ...................../home/peter/src/swipl-devel/build.wasm/src/swipl.js:1
var Module=typeof Module!="undefined"?Module:{}; ...

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Infinity".] {

Node.js v18.16.0
1/1 Test #2: swipl:basic ......................***Failed    2.03 sec

It used to work … The default build for WASM is these days without GMP as that is a lot smaller and avoids the tricky license conditions.