Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build failures with Emscripten image > 3.1.12 (when building from source) #9

Closed
Jaifroid opened this issue Nov 18, 2022 · 30 comments · Fixed by #53 or #54
Closed

Build failures with Emscripten image > 3.1.12 (when building from source) #9

Jaifroid opened this issue Nov 18, 2022 · 30 comments · Fixed by #53 or #54
Labels
help wanted Extra attention is needed

Comments

@Jaifroid
Copy link
Collaborator

Jaifroid commented Nov 18, 2022

@kelson42 @mossroy I've tried to reproduce a build based on the instructions in the README.

I encountered two errors. The first was easy to fix: zlib v1.2.12 no longer exists, so I had to update the reference to it in Makefile to v1.2.13.

The second is much harder (for me) to fix. I consistently get the following error(s) -- I tried three times -- when running the docker / make command, which occurs towards what I believe is the end of the build (it takes a very long time to get to that point before it bombs out):

/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__memory/uninitialized_algorithms.h:628:21: 
error: use of overloaded operator '!=' is ambiguous (with operand types 'std::reverse_iterator<zim::offset_t *>' and 'std::reverse_iterator<zim::offset_t *>')
    while (__first1 != __last1) {

Easier to see in screenshot:

image

@Jaifroid
Copy link
Collaborator Author

My goal was to generate the a.out.js Web Worker that is not being built in kiwix/kiwix-build#548. Although it seems to me that this Worker is an integral part of the wasm. The wasm binary is useless by itself: it is by definition intended to be run in JavaScript, and the Web Worker that initializes it and provides the interface to the binary is an essential part of the package built by Emscripten SDK. It can't be built separately as far as I can see, as the Worker is tied to the specific WASM at build time. @kelson42 do you agree that they should be built together in kiwix-build?

@kelson42
Copy link

@Jaifroid I'm not skilled to answer this question. I can only say that this is not needed in usual bindings. For the wrapping you should mostly need (from the libzim): the wasm version of the code and the headers. @mgautierfr @mossroy to be confirmed.

@Jaifroid
Copy link
Collaborator Author

Thanks @kelson42. I think -- but hopefully others will confirm -- that becaause Emscripten builds the WASM and the Web Worker together (and ties them together with a "magic number"), if we don't include the Web Worker at build time, then all the effort to build WASM as a target will be useless for Kiwix JS, because it will be necessary for me to run the build myself in order to get the Worker and WASM pair. I hope I'm wrong, and there is a simple add-on command that will allow me to derive the Worker from the WASM without re-building from scratch...

@mossroy
Copy link

mossroy commented Nov 18, 2022

After switching to zlib v1.2.13 (you're right, v1.2.12 can not be downloaded any more), I managed to recompile and use this prototype.
Did you use the Docker image to do that? It might come from the emscripten version. The docker image uses emsdk 3.1.12.

There are various ways to build and use WASM.
In our case, we need to use the https://emscripten.org/docs/api_reference/Filesystem-API.html#filesystem-api-workerfs to let it access the ZIM files from the browser engine. Which, indeed, seems to work only inside a WebWorker.
At the time I worked on that, there was no other way to read a very big file (without putting it all in memory), and without embedding it inside the binary.

However, it would certainly be possible to bind the libzim.a file with a different method (like https://emscripten.org/docs/api_reference/Filesystem-API.html#memfs), that would be able to run unit test on it (and could be included in the CI) with a file included in it.

@mossroy
Copy link

mossroy commented Nov 18, 2022

It should be possible to build this prototype using the libzim.a produced by kiwix/kiwix-build#548 , although I did not check.

In the Makefile, you could remove the steps that generate libzim.a, and provide this file directly in the directory where the demo_file_api.js expects it.

However, I see in kiwix/kiwix-build#548 that the emsdk version used to compile libzim.a is 3.1.24, while we currently use 3.1.12 here. I suppose it should work anyway, but if you have problems, you might upgrade emsdk here too.

@mossroy
Copy link

mossroy commented Nov 18, 2022

Trying to recompile the whole Makefile with emsdk 3.1.24 fails with:

wasm-ld: error: /src/build/lib/libzim.a: archive has no index; run ranlib to add one

@Jaifroid
Copy link
Collaborator Author

Thank you very much @mossroy. That helps a lot, specifically hints about how to derive the wasm and worker from the libzim.a binary. I was compiling with a later version of Emscripten, and hit that error about the ambiguous operator (when I got the zlib error, I first tried upgrading Emscripten in the dockerfile).

Slightly worrying that later versions of Emscripten are failing...

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Nov 18, 2022

Trying to recompile the whole Makefile with emsdk 3.1.24 fails with:

wasm-ld: error: /src/build/lib/libzim.a: archive has no index; run ranlib to add one

I just started everything from scratch, deleting the docker image and rebuilding with the original SDK specified in this repo (and deleting the /tmp/emscripten_cache directory), and I ran into the same error very quickly in the build process:

wasm-ld: error: /src/build/lib/libzim.a: archive has no index; run ranlib to add one
wasm-ld: error: /src/build/lib/libzstd.a: archive has no index; run ranlib to add one
em++: error: '/emsdk/upstream/bin/wasm-ld 

Maybe it's not related to the Emscripten SDK version?

@mossroy
Copy link

mossroy commented Nov 18, 2022

I do think this "archive has no index" error is related to the emsdk version.
If I run a make clean then re-run the emscripten compilation (with version 3.1.12), it works for me.

@Jaifroid
Copy link
Collaborator Author

I ran the make clean command (in the docker), then the docker make command. It built this time for a pretty long time, but then stopped with the same errors:

wasm-ld: error: /src/build/lib/libzim.a: archive has no index; run ranlib to add one
wasm-ld: error: /src/build/lib/libzstd.a: archive has no index; run ranlib to add one

☹️

@mossroy
Copy link

mossroy commented Nov 19, 2022

The make clean command can be run outside docker.

I tried again from a fresh checkout (and after switching to the update-zlib-and-netbeans-conf branch I just created, to update zlib). It generated the a.out.wasm with no error (with the Docker image, based on emsdk 3.1.12, and compiling everything from scratch)

About the compilation time, you can add a -j4 or -j6 at the end of the docker run command to speed up the process (depending on how many cores your device has). It enables compiling several steps in parallel

@Jaifroid
Copy link
Collaborator Author

Thanks, @mossroy I'll try again now.

@Jaifroid
Copy link
Collaborator Author

I tried this procedure twice in an Ubuntu 20.04.5 LTS terminal:

  • Deleted / reverted all changes I had made to the master branch
  • Deleted the docker-emscripten-libzim image in Docker
  • Stopped docker, rebooted machine fully, restarted Docker, re-opened terminal, cd to this Repo
  • Pulled origin to get the new branch update-zlib-and-netbeans-conf
  • Checked out new branch
  • Ran make clean
  • Ran sudo make clean for good measure
  • Ran docker build -t "docker-emscripten-libzim:v3" ./docker to rebuild the image -- note that it rebuilt very quickly, seemed to pull the packages from a cache somewhere, however the EMSDK version very clearly says 3.1.12
  • Ran make clean inside the docker with docker run --rm -v $(pwd):/src -v /tmp/emscripten_cache/:/home/emscripten/.emscripten_cache -u $(id -u):$(id -g) -it docker-emscripten-libzim:v3 make clean
  • Finally I ran docker run --rm -v $(pwd):/src -v /tmp/emscripten_cache/:/home/emscripten/.emscripten_cache -u $(id -u):$(id -g) -it docker-emscripten-libzim:v3 make -j6

Each time, after running for a fairly long time (faster than before due to the -j6) and outputting thousands of lines of text/log, I get:

image

Is there anything else I can try to get this working and avoid the archive has no index error?

@mossroy
Copy link

mossroy commented Nov 19, 2022

Puzzling...

A few ideas to test:

  • Try to remove the -v /tmp/emscripten_cache/:/home/emscripten/.emscripten_cache from the command-line
  • Check the emsdk version inside your docker image, with docker run --rm -it docker-emscripten-libzim:v3 emsdk list (the first lines should say The *recommended* precompiled SDK download is 3.1.12 (a8c3b314d61e2bb98581d522f858132b2fc21488))
  • Maybe you can try to apply the hints from wasm-ld: error: archive has no index; run ranlib to add one emscripten-core/emscripten#9329 (but I don't understand why it already works for me)

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Nov 20, 2022

@kelson42 @mgautierfr I've tried mossroy's hints above, have confirmed that the correct SDK is being used, but I'm afraid I still get the same error as shown in screenshot above towards the end of the build. I also had a look at emscripten-core/emscripten#9329 and emscripten-core/emscripten#9705, but I can't work out where to add the suggested solutions, and in any case across the two issues there appear to be three suggested solutions:

  • Add a setting AR=emar, but I've no idea where to add this
  • Another option is to configure with --ar=emar, but where?
  • Add --ranlib="emranlib", but again, no clue where

This is an area in which I'm going to need some help! For me, the ideal situation would be if nightly builds could build the actual WASM plus the JS Web Worker required to run it (which could be done, I guess, through a nightly job on this repo, which would take the libzim.a binary as one of its inputs as suggested in #12). I think only then would I know how to use and incorporate this WASM into Kiwix JS.

@mgautierfr
Copy link
Collaborator

mgautierfr commented Nov 22, 2022

I have succeded to build a.out.js (and a.out.wasm) using the libzim compile with kiwix-build.

  • Use the wasm branch of kiwix-build repository (https://github.com/kiwix/kiwix-build/tree/wasm) Now merged, use master
  • Install kiwix-build (pip install .).
  • Compile libzim (kiwix-build libzim --target-platform wasm)
  • Libraries are installed in BUILD_wasm/INSTALL/lib64 (on fedora, may be */lib/x86_64-foo-bar elsewhere). Includes are in BUILD_wasm/INSTALL/include
  • In the make file, remove the dependency to build/lib/libzim.a for demo_file_api.js and change -I and -L flags to point to the installed files by kiwix-build.
  • In EXPORTED_RUNTIME_METHODS argument replace printErr by err and print by out (I'm not sure about this change but else em++ complains about deprecated exported methods)
  • Follow the readme (install emsdk, run make,...) (It should be possible to use the emsdk installed by kiwix-build but I have not tested that)
  • a.out.js and a.out.wasm are compiled.
  • Run a local server python -m http.server and access the file at localhost:8000/index.html.
  • Library seems to be loaded but I have error when trying to read zim file :
new files selected [index.html:20:21](http://localhost:8000/index.html)
WebWorker called with action=init [a.out.js:29:13](http://localhost:8000/a.out.js)
baseZimFileName = wikipedia_en_ray_charles_2018-09.zim [a.out.js:106:17](http://localhost:8000/a.out.js)
Module["arguments"] = /work/wikipedia_en_ray_charles_2018-09.zim [a.out.js:107:17](http://localhost:8000/a.out.js)
runtime initialized [a.out.js:92:21](http://localhost:8000/a.out.js)
uncaught exception: 5516400
WebWorker called with action=getArticleCount [a.out.js:29:13](http://localhost:8000/a.out.js)
RuntimeError: index out of bounds

Local compilation is needed (for now) as we need .a of all the dependencies and kiwix-build packaged include only libzim.a (to fix)

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Nov 22, 2022

@mgautierfr Thank you for the instructions to compile manually. I was compiling using the docker version of Emscripten and mossroy's makefile, which ought to replicate the steps required to do it manually. Is there something obvious that is missing from the dockerfile or the makefile in that case?

@Jaifroid Jaifroid changed the title Build failure: use of overloaded operator '!=' is ambiguous Build failures Nov 23, 2022
@Jaifroid
Copy link
Collaborator Author

I've tested the a.out.js and a.out.wasm compiled by mossroy three days ago (20th Nov) using our test branch https://github.com/kiwix/kiwix-js/tree/libzim-experiments. These versions work fine. However, they are not built with the libzim.a compiled at kiwix-build. Instead, they use the libzim.a generated by the complete build process here (when/if it can be got to run without the build failures I am getting in the docker).

@Jaifroid
Copy link
Collaborator Author

One of the issues documented here (archive has no index) seems to be fixed by #14. The other issue still needs testing by running the build with the latest Emscripten SDK. The error is: use of overloaded operator '!=' is ambiguous.

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Nov 28, 2022

Update: I still can't compile locally, using Docker, without getting wasm-ld: error: /src/build/lib/libzstd.a: archive has no index; run ranlib to add one, despite the crosscompile option am=emar. However, it works in GitHub actions. Very weird.

It turned out there were some residual files pre-compiled in my FS. Thorough cleaning fixed this.

@Jaifroid
Copy link
Collaborator Author

I confirm that the error with use of overloaded operator is still present if attempting to compile the full toolchain (including generating libzim.a) in the latest Emscripten 3.1.26: Action#step:4:9300.

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Dec 4, 2022

Once #14 is merged, the remaining two build errors are:

  • Error when building from scratch use of overloaded operator '!=' is ambiguous occurs with Emscripten image > 3.1.2;
  • When attempting to build using the libzim.a and linked dependencies provided by kiwix-build, the WASMs and wrappers appear to build correctly, but we get both index and memory out of bound errors when testing the artefacts (Use the libzim.a generated by kiwix-build #12).

@Jaifroid Jaifroid changed the title Build failures Build failures with Emscripten image > 3.1.12 and when building from kiwix-build binaries Dec 4, 2022
@kelson42
Copy link

kelson42 commented Dec 8, 2022

Not sure anymore if this ticket is still valid, we can compile and run this repo code against https://download.openzim.org/release/libzim/ wasm release AFAIK. So #12 needs to be implemented in CI/CD ans we will be good.

@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Dec 8, 2022

@kelson42 Last night I tested building the most recent dependencies with the latest Emscripten image, and I still got use of overloaded operator '!=' is ambiguous. However, I need to do the same with libzim.a and dependencies from kiwix-build to see if this issue is only present when building from source files or not. I'll test this as part of #12.

@Jaifroid Jaifroid changed the title Build failures with Emscripten image > 3.1.12 and when building from kiwix-build binaries Build failures with Emscripten image > 3.1.12 Dec 12, 2022
@stale
Copy link

stale bot commented May 26, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be now be reviewed manually. Thank you for your contributions.

@stale stale bot added the stale label May 26, 2023
@Jaifroid Jaifroid removed the stale label Jun 12, 2023
@kelson42 kelson42 pinned this issue Jun 21, 2023
@Jaifroid Jaifroid linked a pull request Jun 22, 2023 that will close this issue
@Jaifroid Jaifroid changed the title Build failures with Emscripten image > 3.1.12 Build failures with Emscripten image > 3.1.12 (when building from source) Jun 22, 2023
@Jaifroid
Copy link
Collaborator Author

Jaifroid commented Jun 22, 2023

This is still an issue when building libzim from source rather than from pre-compiled binaries. We can build using Emscripten emsdk 3.1.41 (current latest) if building using a pre-compiled binary, but building from source still requires 3.1.12, due to the error:

/emsdk/upstream/emscripten/cache/sysroot/include/c++/v1/__memory/uninitialized_algorithms.h:632:21: error: use of
overloaded operator '!=' is ambiguous (with operand types 'std::reverse_iterator<zim::offset_t *>' and
'std::reverse_iterator<zim::offset_t *>')
  632 |     while (__first1 != __last1) {
      |            ~~~~~~~~ ^  ~~~~~~~

For the relevant workflow run, see https://github.com/openzim/javascript-libzim/actions/runs/5351035516/jobs/9704382137.

@Jaifroid
Copy link
Collaborator Author

While the issue is not actually fixed, at least we can now successfully build BOTH nightly/release versions AND source versions. We are having to use a different Emscripten SDK for each scenario due to the error detailed above if we build from source using anything higher than 3.1.12. On the other hand, we can no longer build nightlies with enaything lower than 3.1.41, so this is a workaround. Expect source building to break at some future point...

@mgautierfr
Copy link
Collaborator

but building from source still requires 3.1.12, due to the error: [...]

This errors are already fixed.

From your workflow, it seems you are using libzim 8.1.0, you'd better use 8.2.0

@Jaifroid
Copy link
Collaborator Author

OK, thanks for spotting that. It's actually hard-coded in the make file for building from source. I'll update and test if this "properly" solves this issue.

@Jaifroid
Copy link
Collaborator Author

Building libzim 8.2.0 with EMSDK 3.1.41 (latest) now works fine: see https://github.com/openzim/javascript-libzim/actions/runs/5355400958/jobs/9713639586. So this issue is finally solved "properly" by #54.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
4 participants