Skip to content

fix(ci): statically link MinGW runtime for Windows builds#769

Merged
lklimek merged 3 commits into
v1.0-devfrom
fix/windows-static-linking
Mar 18, 2026
Merged

fix(ci): statically link MinGW runtime for Windows builds#769
lklimek merged 3 commits into
v1.0-devfrom
fix/windows-static-linking

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented Mar 18, 2026

Summary

Fixes #768 — Windows users get "The code execution cannot proceed because (null).DLL was not found" when running dash-evo-tool.

Root cause: Two issues in the Windows cross-compilation setup:

  1. The binary dynamically linked MinGW runtime DLLs (libgcc_s_seh-1.dll, libwinpthread-1.dll, libstdc++-6.dll) that don't exist on normal Windows machines
  2. The sqlite3.dll import library was generated by dlltool without the -D flag, producing a null DLL name in the PE import table — the direct cause of the (null).DLL error

Fix:

  • Add rustflags to .cargo/config.toml for x86_64-pc-windows-gnu that statically links GCC runtime, C++ stdlib, and pthreads
  • Add bundled feature to rusqlite so SQLite is compiled from C source and statically linked — eliminates sqlite3.dll dependency entirely
  • Remove the Windows libsql CI step that downloaded and created the broken import library
  • Set OPENSSL_STATIC=1 in CI build step to statically link OpenSSL
  • Add a post-build sanity check that inspects the PE import table and fails the build if null DLL imports or MinGW runtime DLLs are found

Test plan

  • Trigger release workflow manually on this branch
  • Verify all 5 platform builds complete successfully
  • Verify Windows sanity check step passes (no null DLLs, no MinGW runtime DLLs)
  • Download Windows artifact and verify it runs on a clean Windows machine

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

  • Chores

    • Optimized Windows build to produce self-contained executables and bundle the SQLite runtime.
    • Added CI verification to ensure Windows binaries have no external DLL dependencies.
  • Tests

    • Updated a test helper to persist wallet state before registering test addresses for more reliable test behavior.

Adds -static-libgcc, -static-libstdc++, and static winpthread rustflags
for the x86_64-pc-windows-gnu target so the Windows binary no longer
depends on MinGW runtime DLLs absent on user machines. Also sets
OPENSSL_STATIC=1 on the build step to statically link OpenSSL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 18, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0455f09f-5e4b-439a-9211-9841ea735db9

📥 Commits

Reviewing files that changed from the base of the PR and between 48ca8a6 and 73fe1a9.

📒 Files selected for processing (1)
  • src/model/wallet/mod.rs

📝 Walkthrough

Walkthrough

Configures Windows GNU builds for static linking (MinGW runtimes, OpenSSL) and enables bundled SQLite; updates CI to verify the produced Windows binary is self-contained and removes the prior Windows DLL fetch step.

Changes

Cohort / File(s) Summary
Build config
\.cargo/config.toml, Cargo.toml
Added rustflags for Windows GNU target to pass static linking args (static-libgcc, static-libstdc++, pthread, etc.). Enabled rusqlite "bundled" feature.
CI/CD pipeline
.github/workflows/release.yml
Removed Windows libsql DLL fetch/registration step. Added OPENSSL_STATIC=1 and a Windows-only verification step that inspects the produced dash-evo-tool.exe for null imports and disallowed MinGW runtime DLLs, failing the job if any are found. Adjusted build environment for static OpenSSL.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 Hooray, I hop with glee and cheer,

No stray DLLs are hopping near,
Bundled SQLite snug and tight,
A self-contained exe takes flight,
Thump-thump—builds that sleep at night.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: enabling static linking of MinGW runtime libraries for Windows builds to resolve a DLL dependency issue.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #768 by statically linking MinGW runtime DLLs, bundling SQLite, enabling static OpenSSL, and adding a verification check to prevent null DLL imports.
Out of Scope Changes check ✅ Passed All changes are directly related to resolving the Windows DLL linking issue: rustflags for static compilation, bundled SQLite, static OpenSSL, CI verification step, and no unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-static-linking
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Add `bundled` feature to rusqlite so SQLite is compiled from source
  and statically linked, eliminating the sqlite3.dll dependency
- Remove the Windows libsql CI step that downloaded sqlite3.dll and
  created an import library with a broken (null) DLL name entry
- Add post-build verification step that inspects the PE import table
  and fails if null DLL imports or MinGW runtime DLLs are found

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek requested a review from Copilot March 18, 2026 16:25
@lklimek lklimek marked this pull request as ready for review March 18, 2026 16:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Windows release artifacts failing on clean machines due to unintended dynamic DLL dependencies and a broken SQLite import library that produced (null).DLL in the PE import table.

Changes:

  • Enable rusqlite’s bundled feature so SQLite is compiled and statically linked (removing the external sqlite3.dll dependency).
  • Update Windows GNU target rustflags to statically link MinGW runtime components.
  • Simplify the release workflow by removing the SQLite DLL/import-lib step, enabling static OpenSSL linking, and adding a PE import-table sanity check for Windows artifacts.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.

File Description
Cargo.toml Enables rusqlite bundled SQLite to avoid shipping sqlite3.dll.
Cargo.lock Lockfile updates consistent with enabling bundled SQLite (e.g., cc added).
.github/workflows/release.yml Removes Windows SQLite download/import-lib step; adds static OpenSSL env and a Windows import-table self-containment check.
.cargo/config.toml Adds Windows GNU target rustflags to statically link MinGW runtimes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/release.yml (1)

104-122: Solid verification step with explicit failure — well done.

The sanity check correctly:

  • Inspects the PE import table using objdump
  • Fails explicitly with descriptive error messages when null imports or MinGW runtime DLLs are found
  • Provides clear success output

Consider expanding DLL checks (optional):

For additional assurance, you could also verify that sqlite3.dll and OpenSSL DLLs (libssl-*.dll, libcrypto-*.dll) are not in the import table, confirming the bundled SQLite and static OpenSSL are working as expected.

,

💡 Optional: expand DLL verification
           # Fail if MinGW runtime DLLs are dynamically linked
-          for dll in libgcc_s_seh-1.dll libwinpthread-1.dll libstdc++-6.dll; do
+          for dll in libgcc_s_seh-1.dll libwinpthread-1.dll libstdc++-6.dll sqlite3.dll libssl libcrypto; do
             if echo "$IMPORTS" | grep -qi "$dll"; then
               echo "::error::Binary dynamically links $dll — must be statically linked"
               exit 1
             fi
           done
-          echo "✅ Binary is self-contained — no MinGW runtime or null DLL dependencies"
+          echo "✅ Binary is self-contained — no MinGW runtime, SQLite, OpenSSL, or null DLL dependencies"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 104 - 122, Update the "Verify
Windows binary is self-contained" step to also reject imports of sqlite3 and
OpenSSL DLLs by extending the IMPORTS checks: after computing IMPORTS, add
checks that fail if any case-insensitive match for "sqlite3.dll" or wildcard
OpenSSL names like "libssl-" or "libcrypto-" appears (use grep -qi with patterns
such as "sqlite3.dll" and "libssl-\\|libcrypto-"), referencing the existing
IMPORTS variable and reusing the same error/exit pattern used for the MinGW DLL
checks so the step fails with a descriptive message if these DLLs are
dynamically linked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/release.yml:
- Around line 104-122: Update the "Verify Windows binary is self-contained" step
to also reject imports of sqlite3 and OpenSSL DLLs by extending the IMPORTS
checks: after computing IMPORTS, add checks that fail if any case-insensitive
match for "sqlite3.dll" or wildcard OpenSSL names like "libssl-" or "libcrypto-"
appears (use grep -qi with patterns such as "sqlite3.dll" and
"libssl-\\|libcrypto-"), referencing the existing IMPORTS variable and reusing
the same error/exit pattern used for the MinGW DLL checks so the step fails with
a descriptive message if these DLLs are dynamically linked.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d4c0eab6-74a2-4628-a48f-97dc939b62e3

📥 Commits

Reviewing files that changed from the base of the PR and between 26be625 and 48ca8a6.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .cargo/config.toml
  • .github/workflows/release.yml
  • Cargo.toml

Insert the wallet record before the address row in `register_test_address`
so the `addresses.seed_hash` FK (enforced when SQLite is compiled with
`SQLITE_DEFAULT_FOREIGN_KEYS=1` via the `bundled` feature) is satisfied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lklimek lklimek enabled auto-merge (squash) March 18, 2026 17:00
@lklimek lklimek disabled auto-merge March 18, 2026 17:00
@lklimek lklimek enabled auto-merge (squash) March 18, 2026 17:01
@lklimek lklimek merged commit c8700bb into v1.0-dev Mar 18, 2026
4 checks passed
@lklimek lklimek deleted the fix/windows-static-linking branch March 18, 2026 17:04
lklimek added a commit that referenced this pull request Mar 18, 2026
…770)

* ci: add binary dependency verification for Linux, macOS, and Flatpak

Add post-build sanity checks to catch missing or unexpected shared
library dependencies before release artifacts are published:

- Linux: ldd check with allowlist, fail on "not found"
- macOS (ARM64 + x86): otool -L check, fail on non-system libs
- Flatpak: ldd check inside build-dir, fail on "not found"

Complements the Windows PE verification from #769.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): prevent grep exit code 1 from failing dependency checks

When all binary dependencies are valid system libraries, `grep -Ev`
filters out all lines and returns exit code 1 (no matches). Under
`bash -e` (GitHub Actions default), this kills the script before it
can report success. Add `|| true` to all grep commands inside command
substitutions across Linux and macOS verification steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(ci): run Flatpak ldd check inside sandbox, not on host

The ldd check was running against the host runner's libraries, which
don't match the Flatpak runtime. Use `flatpak build build-dir` to
execute ldd inside the sandbox where libraries resolve against the
Flatpak runtime (/usr) and app (/app) directories.

Addresses review comment from copilot-pull-request-reviewer on PR #770.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows install error

2 participants