From 2f32b65755dace449293fb0ec5fcca61054b9e31 Mon Sep 17 00:00:00 2001 From: Mark Elvers Date: Mon, 7 Sep 2026 09:39:06 +0000 Subject: [PATCH 1/2] perf: Link dllbinaryen.so from libbinaryen.a instead of compiling Binaryen twice --- dune | 110 ++++++++++++++++++++++------------------------------------- 1 file changed, 40 insertions(+), 70 deletions(-) diff --git a/dune b/dune index b902926..17ff7a9 100644 --- a/dune +++ b/dune @@ -51,92 +51,62 @@ (rule (target dllbinaryen.so) - (locks binaryen) - (deps - (source_tree binaryen)) + (deps libbinaryen.a) (enabled_if (= %{system} macosx)) (action - (no-infer - (progn - (run - cmake - -S - binaryen - -B - binaryen - -G - "Unix Makefiles" - ; GCC 7 (shipped with esy) doesn't like _ for unused variables - "-DCMAKE_CXX_FLAGS=-Wno-unused-variable -Wno-maybe-uninitialized -Wno-deprecated-declarations -Wno-restrict" - -DBUILD_TESTS=OFF - -DBUILD_TOOLS=OFF - -DBUILD_SHARED_LIBS=ON - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=binaryen) - (run cmake --build binaryen --config Release -- -j4) - (copy binaryen/lib/libbinaryen.dylib dllbinaryen.so))))) + ; See the comment on the rule below; -all_load is the macOS linker's + ; equivalent of --whole-archive. + (run + c++ + -dynamiclib + -o + %{target} + -Wl,-all_load + %{dep:libbinaryen.a} + -lpthread))) (rule (target dllbinaryen.so) - (locks binaryen) - (deps - (source_tree binaryen)) + (deps libbinaryen.a) (enabled_if (and (<> %{system} macosx) (<> %{system} mingw64))) (action - (no-infer - (progn - (run - cmake - -S - binaryen - -B - binaryen - -G - "Unix Makefiles" - ; GCC 7 (shipped with esy) doesn't like _ for unused variables - "-DCMAKE_CXX_FLAGS=-Wno-unused-variable -Wno-maybe-uninitialized -Wno-restrict" - -DBUILD_TESTS=OFF - -DBUILD_TOOLS=OFF - -DBUILD_SHARED_LIBS=ON - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=binaryen) - (run cmake --build binaryen --config Release -- -j4) - (copy binaryen/lib/libbinaryen.so dllbinaryen.so))))) + ; Binaryen's CMake always compiles with -fPIC on these platforms, so the + ; shared library can be linked directly from the objects in the static + ; archive instead of configuring and compiling the whole tree a second + ; time. `c++` is the compiler CMake picks by default, so this links with + ; the same C++ runtime the objects were built against. + (run + c++ + -shared + -o + %{target} + -Wl,--whole-archive + %{dep:libbinaryen.a} + -Wl,--no-whole-archive + -Wl,-Bsymbolic + -Wl,--no-undefined + -lpthread))) (rule (target dllbinaryen.dll) - (locks binaryen) - (deps - (source_tree binaryen)) + (deps libbinaryen.a) (enabled_if (= %{system} mingw64)) (action - (no-infer - (progn - (run - cmake - -S - binaryen - -B - binaryen - -G - "Unix Makefiles" - -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc - -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ - "-DCMAKE_SYSTEM_NAME=Windows" - ; GCC 7 (shipped with esy) doesn't like _ for unused variables - "-DCMAKE_CXX_FLAGS=-Wno-unused-variable -Wno-maybe-uninitialized -Wno-restrict" - -DBUILD_TESTS=OFF - -DBUILD_TOOLS=OFF - -DCMAKE_SHARED_LIBRARY_PREFIX_CXX=lib - -DBUILD_SHARED_LIBS=ON - -DCMAKE_BUILD_TYPE=Release - -DCMAKE_INSTALL_PREFIX=binaryen) - (run cmake --build binaryen --config Release -- -j4) - (copy binaryen/bin/libbinaryen.dll dllbinaryen.dll))))) + ; Same idea as the dllbinaryen.so rule above, using the MinGW compiler + ; the previous version of this rule passed to CMake. + (run + x86_64-w64-mingw32-g++ + -shared + -o + %{target} + -Wl,--whole-archive + %{dep:libbinaryen.a} + -Wl,--no-whole-archive + -lpthread))) (data_only_dirs node_modules) \ No newline at end of file From 2eaaa22d3c011d98f91bcbd74084f31af3855fc9 Mon Sep 17 00:00:00 2001 From: Mark Elvers Date: Mon, 7 Sep 2026 16:09:10 +0000 Subject: [PATCH 2/2] fix: Pass the MinGW toolchain to the static Binaryen build explicitly Under Cygwin/MSYS2 CMake cannot find a usable C/C++ compiler on its own. Previously the shared-library rule configured the same build directory first with -DCMAKE_C_COMPILER/-DCMAKE_CXX_COMPILER/-DCMAKE_SYSTEM_NAME, and the static rule inherited them from CMakeCache.txt. Now that the shared library is linked from the static archive nothing seeds the cache, so give the static rule the same settings on mingw64. --- dune | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/dune b/dune index 17ff7a9..6dd03d6 100644 --- a/dune +++ b/dune @@ -28,6 +28,36 @@ (locks binaryen) (deps (source_tree binaryen)) + (enabled_if + (<> %{system} mingw64)) + (action + (no-infer + (progn + (run + cmake + -S + binaryen + -B + binaryen + -G + "Unix Makefiles" + ; GCC 7 (shipped with esy) doesn't like _ for unused variables + "-DCMAKE_CXX_FLAGS=-Wno-unused-variable -Wno-maybe-uninitialized -Wno-deprecated-declarations -Wno-restrict" + -DBUILD_TESTS=OFF + -DBUILD_TOOLS=OFF + -DBUILD_SHARED_LIBS=OFF + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_INSTALL_PREFIX=binaryen) + (run cmake --build binaryen --config Release -- -j4) + (copy binaryen/lib/libbinaryen.a libbinaryen.a))))) + +(rule + (targets libbinaryen.a) + (locks binaryen) + (deps + (source_tree binaryen)) + (enabled_if + (= %{system} mingw64)) (action (no-infer (progn @@ -39,6 +69,13 @@ binaryen -G "Unix Makefiles" + ; CMake cannot find a usable compiler on its own under Cygwin/MSYS2, so + ; point it at the MinGW toolchain explicitly (this used to happen as a + ; side effect of the shared-library build configuring the same directory + ; first). + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ + "-DCMAKE_SYSTEM_NAME=Windows" ; GCC 7 (shipped with esy) doesn't like _ for unused variables "-DCMAKE_CXX_FLAGS=-Wno-unused-variable -Wno-maybe-uninitialized -Wno-deprecated-declarations -Wno-restrict" -DBUILD_TESTS=OFF