collabora-online/wasm
Michael Meeks c117d87bb4 nearly pure re-factor: split out code into its own modules.
StateRecorder.hpp split from ChildSession.cpp
KitWebSocketHandler.[ch]pp split from Kit.cpp.
ThreadPool.hpp split from RenderTiles.hpp

Expose headers for KitSocketPoll and Document
at the same time.

Not clear we need the DocumentManagerInterface anymore.

Conditionally compile out Document::createSession for unittest
dependency breaking, and avoid Rlimit::handleSetrlimitCommand
likewise.

Make makePropertyValue a private method of Kit.cpp.

clang-format new files.

Change-Id: I47a1d6afe20165f156b477a931b94c916cff4b9d
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
2024-03-06 20:56:55 -05:00
..
Makefile.am nearly pure re-factor: split out code into its own modules. 2024-03-06 20:56:55 -05:00
README update wasm.README for distro-config 2023-12-08 14:08:30 +00:00
README.no-container.md wasm: readme update 2023-11-27 10:48:44 +00:00
base64.hpp spdx: improve machine and human readability of headers. 2023-11-20 14:30:02 +00:00
poco-1.12.4-emscripten.patch Drop POCO_HAVE_FD_EPOLL for Emscripten 2023-02-22 09:00:39 +01:00
poco-devel-emscripten.patch WASM document how to build dependencies in wasm/README 2023-01-09 15:21:37 +02:00
poco-no-special-expat-sauce.diff Add patch that prevents expat in Poco from causing trouble with WASM 2023-01-16 18:43:21 +02:00
wasmapp.cpp wasm often doesn't get tiles after invalidates 2023-12-12 16:23:00 +00:00
wasmapp.hpp wasm: header include cleanup 2023-12-09 19:22:24 +00:00

README

NOTE: For instructions on how to build and run it without the
Allotropia-supplied container, see wasm/README.no-container.md.

= WASM with emscripten =

Building for WASM with emscripten is still a bit immature and many projects
need patching to work.

Note that there are wrapper tools like "emconfigure", "emmake", "emcmake" that
tend to set up environment variables like CC properly, although some project's
build system unfortunately override that.

Linking WASM executable uses a lot of memory; without optimisations or with -O1
in LDFLAGS, /usr/bin/time prints "1660068maxresident" which should work
anywhere, but with -O2 in LDFLAGS (which is the default) some LTO happens that
uses about 8x as much RAM, "12261016maxresident" or ~12 GiB... so append
CXXFLAGS='-g -O1' or similar to the configure invocation if out of memory.

For convenience it's recommended to build with a docker container that has the
required build tools.

    podman pull public.ecr.aws/allotropia/libo-builders/wasm

== Build LO core ==

First you need to build LibreOffice core with emscripten.
Currently best to use "feature/wasm" branch.

It can be good to create an environment file you can source in new shells eg.

export GITREPO=$HOME/lo/feature_wasm
export EXTSOURCES=$HOME/lo/ext_sources
export BUILDDIR=/data/lo/build_feature_wasm
export ONLINEGITREPO=$HOME/lo/online
export ONLINEBUILDDIR=/data/lo/build_online_wasm

These examples assume that the git repo is in $GITREPO, the build
directory in $BUILDDIR and the tarball download cache in
$EXTSOURCES - adjust these to your preferences.

    podman run -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR -v $EXTSOURCES:/ext_sources:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $BUILDDIR/ && $GITREPO/autogen.sh --with-external-tar=/ext_sources --with-distro=CPWASM-LOKit"

    podman run -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR -v $EXTSOURCES:/ext_sources:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $BUILDDIR/ && make -rj8"

== Build Online using dependencies from container ==

The container contains prebuilt libzstd and POCO for convenience.

Note that here the LO core (and builddir, if separate) must be mapped to the
same directory in the container as it was when building core, due to files
containing absolute paths.

    podman run -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR:ro -v $ONLINEGITREPO:$ONLINEGITREPO:rw -v $ONLINEBUILDDIR:$ONLINEBUILDDIR:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $ONLINEBUILDDIR/ && $ONLINEGITREPO/autogen.sh && emconfigure $ONLINEGITREPO/configure --disable-werror --with-lokit-path=$GITREPO/include --with-lo-path=$BUILDDIR/instdir --with-lo-builddir=$BUILDDIR --with-zstd-includes=/usr/local/include --with-zstd-libs=/usr/local/lib --with-poco-includes=/usr/local/include --with-poco-libs=/usr/local/lib --host=wasm32-local-emscripten"
    podman run -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR:ro -v $ONLINEGITREPO:$ONLINEGITREPO:rw -v $ONLINEBUILDDIR:$ONLINEBUILDDIR:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $ONLINEBUILDDIR/ && emmake make -rj8"

== Build Online dependencies manually ==

Then build libzstd:
* with assembly code disabled
* using the Makefile (didn't try its other build systems)

    tar -xzvf ~/Downloads/zstd-1.5.2.tar.gz
    cd zstd-1.5.2/
    podman run -v /data/lo/zstd-1.5.2:/data/lo/zstd-1.5.2:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c 'source /home/builder/emsdk/emsdk_env.sh && cd /data/lo/zstd-1.5.2/ && emmake make -j8 lib-nomt ZSTD_NO_ASM=1'

Then build POCO:
* this requires two patches (currently exists patch for 1.12.4 and untested "devel"
  branch) plus renaming one source file (which actually is from expat but Poco includes)
* note that the header Poco/Platform.h maps EMSCRIPTEN to POCO_OS_LINUX
* it has both Makefiles and CMake but i couldn't get CMake to use CXXFLAGS to
  disable some Linux-specific code; i tried variations on:
    emcmake cmake -S .. -DENABLE_MONGODB=off -DENABLE_DATA_SQLITE=off -DENABLE_REDIS=off -DENABLE_PROMETHEUS=off -DENABLE_PDF=off -DENABLE_SEVENZIP=off -DENABLE_ZIP=off -DENABLE_CPPPARSER=off -DENABLE_POCODOC=off -DENABLE_PAGECOMPILER=off -DENABLE_PAGECOMPILER_FILE2PAGE=off -DENABLE_ACTIVERECORD=off -DENABLE_ACTIVERECORD_COMPILER=off -DENABLE_DATA=off -DENABLE_DATA_ODBC=off -DENABLE_DATA_POSTGRESQL=off -DENABLE_DATA_MYSQL=off -DENABLE_APACHECONNECTOR=off -DENABLE_JWT=off CXXFLAGS=-DPOCO_NO_LINUX_IF_PACKET_H
* Online requires a single include directory so "make install" must be used

    tar -xjvf ~/Downloads/poco-1.12.4-all.tar.bz2
    cd poco-1.12.4-all
    patch -p1 < $ONLINEGITREPO/wasm/poco-1.12.4-emscripten.patch
    mv XML/src/xmlparse.cpp XML/src/xmlparse.c
    patch -p0 < $ONLINEGITREPO/wasm/poco-no-special-expat-sauce.diff
    podman run -v /data/lo/poco-1.12.4-all:/data/lo/poco-1.12.4-all:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c 'source /home/builder/emsdk/emsdk_env.sh && cd /data/lo/poco-1.12.4-all && emconfigure ./configure --static --no-samples --no-tests --omit=Crypto,NetSSL_OpenSSL,JWT,Data,Data/SQLite,Data/ODBC,Data/MySQL,Data/PostgreSQL,Zip,PageCompiler,PageCompiler/File2Page,MongoDB,Redis,ActiveRecord,ActiveRecord/Compiler,Prometheus && emmake make -j8 CC=/home/builder/emsdk/upstream/emscripten/emcc CXX=/home/builder/emsdk/upstream/emscripten/em++ LD=/home/builder/emsdk/upstream/emscripten/em++ CXXFLAGS="-DPOCO_NO_LINUX_IF_PACKET_H -DPOCO_NO_INOTIFY -pthread -s USE_PTHREADS=1 -s DISABLE_EXCEPTION_CATCHING=0" && make -j8 install INSTALLDIR=/data/lo/poco-1.12.4-all/install'

== Build Online with manually built dependencies ==

Then build Online itself:

Note that here the LO core (and builddir, if separate) must be mapped to the
same directory in the container as it was when building core, due to files
containing absolute paths.

    podman run -v /data/lo/zstd-1.5.2:/data/lo/zstd-1.5.2:ro -v /data/lo/poco-1.12.4-all:/data/lo/poco-1.12.4-all:ro -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR:ro -v $ONLINEGITREPO:$ONLINEGITREPO:rw -v $ONLINEBUILDDIR:$ONLINEBUILDDIR:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $ONLINEBUILDDIR/ && $ONLINEGITREPO/autogen.sh && emconfigure $ONLINEGITREPO/configure --with-lokit-path=$GITREPO/include --with-lo-path=$BUILDDIR/instdir --with-lo-builddir=$BUILDDIR --with-zstd-includes=/data/lo/zstd-1.5.2/lib --with-zstd-libs=/data/lo/zstd-1.5.2/lib --with-poco-includes=/data/lo/poco-1.12.4-all/install/include --with-poco-libs=/data/lo/poco-1.12.4-all/install/lib --host=wasm32-local-emscripten"
    podman run -v /data/lo/zstd-1.5.2:/data/lo/zstd-1.5.2:ro -v /data/lo/poco-1.12.4-all:/data/lo/poco-1.12.4-all:ro -v $GITREPO:$GITREPO:ro -v $BUILDDIR:$BUILDDIR:ro -v $ONLINEGITREPO:$ONLINEGITREPO:rw -v $ONLINEBUILDDIR:$ONLINEBUILDDIR:rw --security-opt=label=disable -ti public.ecr.aws/allotropia/libo-builders/wasm /bin/bash -c "source /home/builder/emsdk/emsdk_env.sh && cd $ONLINEBUILDDIR/ && emmake make"