diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-03-26 20:46:56 +0100 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2022-03-30 15:12:21 +0200 |
commit | 79365d6f5a3706da8464d564deee6bb54422c3d0 (patch) | |
tree | d3b89f7b5875759ef96d3a1125234bb531a57ba1 | |
parent | 21c24aa4fdea118ddda0b60e17486458c739375f (diff) |
WASM fix native EH build since Emscripten 3.1.6
Building LO with WASM native EH and Emscripten 3.1.6+, the link
fails with a missing "emscripten_longjmp" symbol. Actually the
old build was simply wrong, because the emscripten_longjmp
function is just used for the Emscripten SjLj and not the native
WASM SjLj implementation. Linking just worked, because the used
libcompiler_rt-wasm-sjlj-mt.a lib was incorrectly providing that
symbol, which 3.1.6 removed.
But since running the NEH build still fails early in the same way
then before in FF nightly 100 and Chrome (= failure in the LO job
scheduler calling Task::UpdateMinPeriod for the "desktop::Desktop
m_firstRunTimer" timer, resulting in a WASM VM "RuntimeError:
indirect call signature mismatch"), there is still no way to know,
if nothing else it missing. The Emscripten / JS EH build still
works without any code changes. And it's not the first call on
a job object that fails...
And unfortunatly, because Qt itself also uses libpng, it also uses
SjLj for error handling, like LO in the image import, so the Qt
build must also be patched to build with "-s SUPPORT_LONGJMP=wasm".
Simply enough to do (see README.wasm.md). LO's configure now
detects that symbol and will bail out on incompatible Qt and LO
build setup.
See https://github.com/emscripten-core/emscripten/issues/16572
Change-Id: I3a1877f3aeb77873906176b9d3cd1ea92973f1f6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132139
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
-rw-r--r-- | configure.ac | 21 | ||||
-rw-r--r-- | external/cairo/ExternalProject_cairo.mk | 2 | ||||
-rw-r--r-- | external/cppunit/ExternalProject_cppunit.mk | 4 | ||||
-rw-r--r-- | external/freetype/ExternalProject_freetype.mk | 2 | ||||
-rw-r--r-- | external/libnumbertext/ExternalProject_libnumbertext.mk | 4 | ||||
-rw-r--r-- | solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk | 3 | ||||
-rw-r--r-- | static/README.wasm.md | 22 |
7 files changed, 45 insertions, 13 deletions
diff --git a/configure.ac b/configure.ac index 9d97f42c4030..224faea12abf 100644 --- a/configure.ac +++ b/configure.ac @@ -4625,10 +4625,10 @@ check_use_ld() fi else # I tried to use gcc's '-B<path>' and a directory + symlink setup in - # $BUILDDIR, but libtool always filtered-out that option, so gcc wouldn't - # pickup the alternative linker, when called by libtool for linking. + # $BUILDDIR, but libtool always filtered-out that option, so gcc wouldn't + # pickup the alternative linker, when called by libtool for linking. # For mold, one can use LD_PRELOAD=/usr/lib/mold/mold-wrapper.so instead. - AC_MSG_ERROR([A linker path is just supported with clang, because of libtool's -B filtering!]) + AC_MSG_ERROR([A linker path is just supported with clang, because of libtool's -B filtering!]) fi fi use_ld_fail_if_error=$2 @@ -12966,6 +12966,21 @@ then if test ! -f "${qt5_platformsdir}"/libqwasm.a -o ! -f "$QT5_PLATFORMS_SRCDIR"/wasm_shell.html; then AC_MSG_ERROR([No Qt5 WASM QPA plugin found in ${qt5_platformsdir} or ${QT5_PLATFORMS_SRCDIR}]) fi + + EMSDK_LLVM_NM="$(em-config EMSCRIPTEN_ROOT)"/../bin/llvm-nm + if ! test -x "$EMSDK_LLVM_NM"; then + AC_MSG_ERROR([Missing llvm-nm expected to be found at "$EMSDK_LLVM_NM".]) + fi + if test ! -f "${qt5_libdir}"/libQt5Gui.a; then + AC_MSG_ERROR([No Qt5 WASM libQt5Gui.a in ${qt5_libdir}]) + fi + QT5_WASM_SJLJ="`${EMSDK_LLVM_NM} "${qt5_libdir}"/libQt5Gui.a 2>/dev/null | $GREP emscripten_longjmp`" + if test "$ENABLE_WASM_EXCEPTIONS" = TRUE -a -n "$QT5_WASM_SJLJ"; then + AC_MSG_ERROR(['emscripten_longjmp' symbol found in libQt5Gui.a (missing '-s SUPPORT_LONGJMP=wasm'). See static/README.wasm.md.]) + fi + if test "$ENABLE_WASM_EXCEPTIONS" != TRUE -a -z "$QT5_WASM_SJLJ"; then + AC_MSG_ERROR(['emscripten_longjmp' symbol not found in libQt5Gui.a. You probably use an incompatible Qt build with '-s SUPPORT_LONGJMP=wasm'.]) + fi fi QT5_CFLAGS="-I$qt5_incdir -DQT_CLEAN_NAMESPACE -DQT_THREAD_SUPPORT -DQT_NO_VERSION_TAGGING" diff --git a/external/cairo/ExternalProject_cairo.mk b/external/cairo/ExternalProject_cairo.mk index f1bf3ddbd1b2..0996572d63ba 100644 --- a/external/cairo/ExternalProject_cairo.mk +++ b/external/cairo/ExternalProject_cairo.mk @@ -48,7 +48,7 @@ $(call gb_ExternalProject_get_state_target,cairo,build) : $(gb_RUN_CONFIGURE) ./configure \ $(if $(debug),STRIP=" ") \ $(if $(filter ANDROID iOS,$(OS)),CFLAGS="$(if $(debug),-g) $(ZLIB_CFLAGS) $(gb_VISIBILITY_FLAGS)") \ - $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS=" $(ZLIB_CFLAGS) -Wno-enum-conversion" --enable-pthread=yes PTHREAD_LIBS="") \ + $(if $(filter EMSCRIPTEN,$(OS)),CFLAGS=" $(ZLIB_CFLAGS) -Wno-enum-conversion $(gb_EMSCRIPTEN_CPPFLAGS)" --enable-pthread=yes PTHREAD_LIBS="") \ $(if $(filter-out EMSCRIPTEN ANDROID iOS,$(OS)),CFLAGS="$(CFLAGS) $(if $(debug),-g) $(ZLIB_CFLAGS)" ) \ $(if $(filter ANDROID iOS,$(OS)),PKG_CONFIG=./dummy_pkg_config) \ LIBS="$(ZLIB_LIBS)" \ diff --git a/external/cppunit/ExternalProject_cppunit.mk b/external/cppunit/ExternalProject_cppunit.mk index 3c6e18af71d2..f0b4ff06acce 100644 --- a/external/cppunit/ExternalProject_cppunit.mk +++ b/external/cppunit/ExternalProject_cppunit.mk @@ -28,7 +28,7 @@ $(call gb_ExternalProject_get_state_target,cppunit,build) : $(call gb_Trace_EndRange,cppunit,EXTERNAL) else -cppunit_CXXFLAGS=$(CXXFLAGS) +cppunit_CXXFLAGS=$(CXXFLAGS) $(gb_EMSCRIPTEN_CXXFLAGS) cppunit_CXXFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG) @@ -52,7 +52,7 @@ $(call gb_ExternalProject_get_state_target,cppunit,build) : $(if $(filter SOLARIS,$(OS)),LIBS="-lm") \ $(if $(filter ANDROID,$(OS)),LIBS="$(gb_STDLIBS)") \ $(if $(verbose),--disable-silent-rules,--enable-silent-rules) \ - CXXFLAGS="$(cppunit_CXXFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS)" \ + CXXFLAGS="$(cppunit_CXXFLAGS)" \ && cd src \ && $(MAKE) \ ) diff --git a/external/freetype/ExternalProject_freetype.mk b/external/freetype/ExternalProject_freetype.mk index 57e7df357de4..7f3faca416ca 100644 --- a/external/freetype/ExternalProject_freetype.mk +++ b/external/freetype/ExternalProject_freetype.mk @@ -26,7 +26,7 @@ $(call gb_ExternalProject_get_state_target,freetype,build) : --without-png \ --prefix=$(call gb_UnpackedTarball_get_dir,freetype/instdir) \ $(gb_CONFIGURE_PLATFORMS) \ - CFLAGS="$(CFLAGS) $(if $(debug),-g) $(gb_VISIBILITY_FLAGS)" \ + CFLAGS="$(CFLAGS) $(if $(debug),-g) $(gb_VISIBILITY_FLAGS) $(gb_EMSCRIPTEN_CPPFLAGS)" \ && $(MAKE) install \ && touch $@ ) $(call gb_Trace_EndRange,freetype,EXTERNAL) diff --git a/external/libnumbertext/ExternalProject_libnumbertext.mk b/external/libnumbertext/ExternalProject_libnumbertext.mk index 976d1772c4b0..1716f9db8a12 100644 --- a/external/libnumbertext/ExternalProject_libnumbertext.mk +++ b/external/libnumbertext/ExternalProject_libnumbertext.mk @@ -16,9 +16,9 @@ $(eval $(call gb_ExternalProject_register_targets,libnumbertext,\ build \ )) -libnumbertext_CXXFLAGS=$(CXXFLAGS) $(CXXFLAGS_CXX11) $(gb_EMSCRIPTEN_CPPFLAGS) +libnumbertext_CXXFLAGS=$(CXXFLAGS) $(CXXFLAGS_CXX11) $(gb_EMSCRIPTEN_CXXFLAGS) -libnumbertext_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG) +libnumbertext_CPPFLAGS+=$(gb_COMPILERDEFS_STDLIB_DEBUG) $(gb_EMSCRIPTEN_CPPFLAGS) $(call gb_ExternalProject_get_state_target,libnumbertext,build): $(call gb_Trace_StartRange,libnumbertext,EXTERNAL) diff --git a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk index 83e850a95f9f..61424f72c44f 100644 --- a/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk +++ b/solenv/gbuild/platform/EMSCRIPTEN_INTEL_GCC.mk @@ -33,6 +33,7 @@ gb_EMSCRIPTEN_QTDEFS := -DQT_NO_LINKED_LIST -DQT_NO_JAVA_STYLE_ITERATORS -DQT_NO gb_Executable_EXT := .html ifeq ($(ENABLE_WASM_EXCEPTIONS),TRUE) gb_EMSCRIPTEN_EXCEPT = -fwasm-exceptions -s SUPPORT_LONGJMP=wasm +gb_EMSCRIPTEN_CPPFLAGS += -s SUPPORT_LONGJMP=wasm else gb_EMSCRIPTEN_EXCEPT = -s DISABLE_EXCEPTION_CATCHING=0 endif @@ -40,7 +41,7 @@ endif gb_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) gb_LinkTarget_EXCEPTIONFLAGS += $(gb_EMSCRIPTEN_EXCEPT) gb_LinkTarget_CFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS) -gb_LinkTarget_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS) +gb_LinkTarget_CXXFLAGS += $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_QTDEFS) $(gb_EMSCRIPTEN_EXCEPT) gb_LinkTarget_LDFLAGS += $(gb_EMSCRIPTEN_LDFLAGS) $(gb_EMSCRIPTEN_CPPFLAGS) $(gb_EMSCRIPTEN_EXCEPT) # Linker and compiler optimize + debug flags are handled in LinkTarget.mk diff --git a/static/README.wasm.md b/static/README.wasm.md index 4ea67ad03e6e..4624e87605b7 100644 --- a/static/README.wasm.md +++ b/static/README.wasm.md @@ -87,9 +87,10 @@ Use `emrun --serve_after_close` to run Qt WASM demos. environment vars, especially `EMMAKEN_JUST_CONFIGURE`, which will create the correct output file names, checked by `configure` (`a.out`). -There's a distro config for WASM (work in progress), that gets your -defaults right (and currently disables a ton of 3rd party stuff which -is not essential). +There's a distro config for WASM, but it just provides --host=wasm32-local-emscripten, which +should be enough setup. The build itself is a cross build and the cross-toolset just depends +on a minimal toolset (gcc, libc-dev, flex, bison); all else is build from source, because the +final result is not depending on the build system at all. Recommended configure setup is thusly: @@ -107,6 +108,21 @@ FWIW: it's also possible to build an almost static Linux LibreOffice by just usi --disable-dynloading --enable-customtarget-components. System externals are still linked dynamically, but everything else is static. +#### Experimental (AKA currently broken) WASM exception + SjLj build + +You can build LO with WASM exceptions, which should be "much" faster then the JS +based Emscripten EH handling. For setjmp / longjmp (SjLj) used by the PNG and JPEG +libraries error handling, this needs Emscripten 3.1.3+. That builds, but execution +still fails early with a signature mismatch call to Task::UpdateMinPeriod in LO's +job scheduler code. Unfortunatly the build also needs a Qt build with +"-s SUPPORT_LONGJMP=wasm", which is incompatible with the JS EH + SjLj. + +The LO configure flag is simply an additional --enable-wasm-exceptions. Qt5 can +be patched in qtbase/mkspecs/wasm-emscripten/qmake.conf with the addition of + + QMAKE_CFLAGS += -s SUPPORT_LONGJMP=wasm + QMAKE_CXXFLAGS += -s SUPPORT_LONGJMP=wasm + ### "Deploying" soffice.wasm tar -chf wasm.tar --xform 's/.*program/lo-wasm/' instdir/program/soffice.* \ |