Windows Build (MinGW64) #94
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Windows Build (MinGW64) | |
| # Builds interchainedd.exe on Windows via MSYS2 MinGW64. | |
| # BDB comes from the MSYS2 package (mingw-w64-x86_64-db) — no from-source | |
| # build needed; the MSYS2 package ships Windows-patched headers and static | |
| # libs at /mingw64/{include,lib}. --with-incompatible-bdb handles the | |
| # version mismatch vs 4.8. | |
| on: | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| windows-x86_64: | |
| name: Windows x86_64 — interchainedd.exe | |
| runs-on: windows-latest | |
| defaults: | |
| run: | |
| shell: msys2 {0} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| submodules: recursive | |
| - name: Set up MSYS2 (MinGW64) | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: MINGW64 | |
| update: true | |
| install: >- | |
| git | |
| make | |
| autoconf | |
| automake | |
| libtool | |
| pkg-config | |
| mingw-w64-x86_64-gcc | |
| mingw-w64-x86_64-boost | |
| mingw-w64-x86_64-libevent | |
| mingw-w64-x86_64-sqlite3 | |
| mingw-w64-x86_64-zeromq | |
| mingw-w64-x86_64-miniupnpc | |
| mingw-w64-x86_64-openssl | |
| mingw-w64-x86_64-zlib | |
| mingw-w64-x86_64-db | |
| perl | |
| - name: Verify BDB and Boost from MSYS2 | |
| run: | | |
| echo "=== BDB headers ===" | |
| ls -lah /mingw64/include/db*.h | |
| echo "=== BDB libs ===" | |
| ls -lah /mingw64/lib/libdb*.a /mingw64/lib/libdb*.dll.a 2>/dev/null || true | |
| echo "=== BDB version ===" | |
| grep DB_VERSION_STRING /mingw64/include/db.h | head -3 | |
| echo "=== Boost static libs ===" | |
| ls /mingw64/lib/libboost_*.a 2>/dev/null | sort | |
| - name: Install Rust stable + x86_64-pc-windows-gnu target | |
| shell: pwsh | |
| run: | | |
| # Install rustup + stable toolchain (idempotent) | |
| $env:RUSTUP_INIT_SKIP_PATH_CHECK = "yes" | |
| Invoke-WebRequest "https://win.rustup.rs/x86_64" -OutFile "$env:TEMP\rustup-init.exe" | |
| & "$env:TEMP\rustup-init.exe" -y --default-toolchain stable --profile minimal 2>&1 | |
| $env:PATH = "$env:USERPROFILE\.cargo\bin;$env:PATH" | |
| rustup target add x86_64-pc-windows-gnu | |
| Write-Host "Rust: $(rustc --version)" | |
| Write-Host "Cargo: $(cargo --version)" | |
| - name: Build NEDB FFI (x86_64-pc-windows-gnu) | |
| run: | | |
| export PATH="$(cygpath "$USERPROFILE")/.cargo/bin:$PATH" | |
| sed -i 's/^lto[[:space:]]*=.*/lto = false/' nedb-ffi/Cargo.toml | |
| cd nedb-ffi | |
| RUSTFLAGS="-C embed-bitcode=no" \ | |
| cargo rustc --release --crate-type=staticlib \ | |
| --target x86_64-pc-windows-gnu | |
| echo "libnedb_ffi.a size: $(du -sh target/x86_64-pc-windows-gnu/release/libnedb_ffi.a | cut -f1)" | |
| # Windows PE/COFF 64-bit symbols have no leading underscore — grep without it | |
| SYMS=$(nm target/x86_64-pc-windows-gnu/release/libnedb_ffi.a 2>/dev/null \ | |
| | grep -c 'nedb_' || true) | |
| echo "nedb_* symbols: $SYMS" | |
| [ "${SYMS:-0}" -gt 0 ] || { echo "ERROR: no nedb_* symbols found"; exit 1; } | |
| - name: Stage NEDB FFI .la at native release path | |
| run: | | |
| NEDB_X64="$(pwd)/nedb-ffi/target/x86_64-pc-windows-gnu/release/libnedb_ffi.a" | |
| NEDB_NATIVE_DIR="$(pwd)/nedb-ffi/target/release" | |
| mkdir -p "$NEDB_NATIVE_DIR" | |
| cp "$NEDB_X64" "$NEDB_NATIVE_DIR/libnedb_ffi.a" | |
| printf '%s\n' \ | |
| "# Generated by libtool (GNU libtool) 2.4.6" \ | |
| "dlname=''" \ | |
| "library_names=''" \ | |
| "old_library='libnedb_ffi.a'" \ | |
| "inherited_linker_flags=''" \ | |
| "dependency_libs='-lpthread -lws2_32 -lbcrypt -lntdll'" \ | |
| "weak_library_names=''" \ | |
| "current=0" "age=0" "revision=0" \ | |
| "installed=no" "shouldnotlink=no" \ | |
| "dlopen=''" "dlpreopen=''" \ | |
| "libdir='$NEDB_NATIVE_DIR'" \ | |
| > "$NEDB_NATIVE_DIR/libnedb_ffi.la" | |
| echo "Staged: $NEDB_NATIVE_DIR/libnedb_ffi.la" | |
| cat "$NEDB_NATIVE_DIR/libnedb_ffi.la" | |
| - name: Configure & Build interchainedd.exe | |
| run: | | |
| export PATH="$(cygpath "$USERPROFILE")/.cargo/bin:$PATH" | |
| J=$(nproc || echo 4) | |
| # Use BDB from MSYS2 package — headers and static libs at /mingw64 | |
| BDB_PREFIX="/mingw64" | |
| ./autogen.sh | |
| # Boost 1.74+ / MSYS2 MinGW64: the AX_BOOST_* macros have a two-step | |
| # guard in the generated configure: | |
| # 1) "Could not find a version" — fires when ax_lib="" (ls glob empty) | |
| # 2) "Could not link against $ax_lib !" — fires when link_X != yes | |
| # We patch step-1 to set ax_lib + link_X=yes + BOOST_X_LIB, and | |
| # neutralise step-2 entirely. The real .a files are at /mingw64/lib | |
| # and will be linked at make time via BOOST_LIBS. | |
| # Boost 1.91 MSYS2 MinGW64 quirks: | |
| # - boost::system is fully header-only (no libboost_system.a shipped) | |
| # → BOOST_SYSTEM_LIB must be empty or the linker errors | |
| # - boost::filesystem and boost::thread DO have static libs | |
| # Patch both AX_BOOST_* guards (find + link) for each library. | |
| # MSYS2 MinGW64 Boost 1.91: static libs use -mt suffix | |
| # (e.g. libboost_filesystem-mt.a, libboost_thread-mt.a). | |
| # boost::system is fully header-only — no lib file at all. | |
| sed -i \ | |
| -e 's/as_fn_error.*Could not find a version of the Boost::System library.*/ax_lib=; link_system=yes; BOOST_SYSTEM_LIB=""/' \ | |
| -e 's/as_fn_error.*Could not find a version of the Boost::Filesystem library.*/ax_lib=boost_filesystem-mt; link_filesystem=yes; BOOST_FILESYSTEM_LIB="-lboost_filesystem-mt"/' \ | |
| -e 's/as_fn_error.*Could not find a version of the Boost::Thread library.*/ax_lib=boost_thread-mt; link_thread=yes; BOOST_THREAD_LIB="-lboost_thread-mt"/' \ | |
| -e 's/as_fn_error.*Could not find a version of the Boost::Chrono library.*/ax_lib=boost_chrono-mt; link_chrono=yes; BOOST_CHRONO_LIB="-lboost_chrono-mt"/' \ | |
| -e 's/as_fn_error.*Could not link against \$ax_lib.*/true # MinGW64 Boost link-test bypassed/' \ | |
| configure | |
| # Use versioned static archives — the unversioned libdb.a / libdb_cxx.a | |
| # are thin import libs (DLL stubs, ~1MB). The full static archives are | |
| # libdb-6.2.a / libdb_cxx-6.2.a (~2-2.5MB). Pass as direct paths so | |
| # the configure link test picks up real code, not the DLL shims. | |
| BDB_CFLAGS="-I${BDB_PREFIX}/include" \ | |
| BDB_LIBS="${BDB_PREFIX}/lib/libdb_cxx-6.2.a ${BDB_PREFIX}/lib/libdb-6.2.a" \ | |
| ./configure \ | |
| --enable-wallet \ | |
| --with-incompatible-bdb \ | |
| --without-gui \ | |
| --disable-bench \ | |
| --disable-tests \ | |
| --without-zmq \ | |
| --without-miniupnpc \ | |
| || { cat config.log; exit 1; } | |
| # Scope NEDB + its Windows deps to interchainedd only. | |
| # Using LIBS += injects NEDB into every target (cli, tx, etc.) which | |
| # then all need to satisfy Rust stdlib Windows API deps — unnecessary | |
| # and fragile. interchainedd_LDADD targets just the daemon binary. | |
| # | |
| # --allow-multiple-definition: Rust staticlib bundles Windows API | |
| # import stubs that conflict with MinGW's own stubs. | |
| # -lbcrypt: BCryptGenRandom (Rust getrandom crate) | |
| # -lntdll: NtCreateNamedPipeFile (Rust std process pipes) | |
| # -luserenv: GetUserProfileDirectoryW (Rust std home dir) | |
| # -lsodium: libzmq CURVE support | |
| # | |
| # Boost is still in LIBS so cli/tx/wallet can find it. | |
| NEDB_LIB="$(pwd)/nedb-ffi/target/release/libnedb_ffi.a" | |
| # --whole-archive only on interchainedd (force-load all NEDB symbols). | |
| # Windows API deps go in LIBS so every NEDB-linked target gets them | |
| # (interchainedd + interchained-wallet both link libnedb_ffi). | |
| echo "interchainedd_LDADD += -Wl,--allow-multiple-definition -Wl,--whole-archive,${NEDB_LIB},--no-whole-archive" \ | |
| >> src/Makefile | |
| # -lntdll removed: explicit ntdll import causes Windows to eagerly resolve | |
| # ntdll's own kernel deps (ksecdd.sys) at load time — "ksecdd.sys not found". | |
| # ntdll is always implicitly loaded; never link it explicitly. | |
| echo "LIBS += -lboost_thread-mt -lboost_chrono-mt -lboost_filesystem-mt -lws2_32 -lbcrypt -luserenv -lsodium" \ | |
| >> src/Makefile | |
| make -j"$J" src/interchainedd.exe src/interchained-cli.exe | |
| test -f src/interchainedd.exe && file src/interchainedd.exe | |
| test -f src/interchained-cli.exe && file src/interchained-cli.exe | |
| - name: Package Windows binary | |
| run: | | |
| REF="${GITHUB_REF_NAME:-${GITHUB_SHA:0:8}}" | |
| mkdir -p out | |
| cp src/interchainedd.exe out/ 2>/dev/null || true | |
| cp src/interchained-cli.exe out/ 2>/dev/null || true | |
| [ -f README.md ] && cp README.md out/ || true | |
| sha256sum out/* > out/SHA256SUMS | |
| tar -C out -czf "interchained-windows-x86_64-${REF}.tar.gz" . | |
| echo "Binary size: $(du -sh out/interchainedd.exe 2>/dev/null || echo 'not found')" | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: interchained-windows-x86_64 | |
| path: interchained-windows-x86_64-*.tar.gz | |
| if-no-files-found: error |