Skip to content

Add shared dependency verification and fix Docker fontconfig pins#3510

Merged
mattleibow merged 4 commits intomainfrom
dev/issue-3346-static-crt-angle
Feb 11, 2026
Merged

Add shared dependency verification and fix Docker fontconfig pins#3510
mattleibow merged 4 commits intomainfrom
dev/issue-3346-static-crt-angle

Conversation

@mattleibow
Copy link
Contributor

@mattleibow mattleibow commented Feb 10, 2026

Summary

Adds build-time verification that native Windows DLLs do not dynamically link against the C runtime, and fixes broken fontconfig version pins in Linux Docker cross-compilation images.

Related to #3346 — ARM64 Windows crash in published MAUI apps when VC++ Redistributable is not installed. CI confirms all Windows native binaries (including ANGLE) are already statically linked — this PR adds verification to prevent regressions.

Changes

1. Shared dependency verification functions (scripts/cake/native-shared.cake)

  • CheckWindowsDependencies(dll, excluded, included) — uses dumpbin /dependents to verify Windows DLLs
  • CheckLinuxDependencies(so, excluded, included, maxGlibc) — uses readelf -dV to verify Linux shared objects
  • Replaces duplicated CheckDeps() implementations across build files

2. Windows dependency verification coverage

Build Before After
ANGLE (winui-angle) ❌ No verification ✅ Rejects VCRUNTIME/MSVCP
libSkiaSharp (windows) ❌ No verification ✅ Rejects VCRUNTIME/MSVCP
libHarfBuzzSharp (windows) ❌ No verification ✅ Rejects VCRUNTIME/MSVCP
WinUI Native (winui) ✅ Local CheckDeps ✅ Uses shared function
Linux (linux) ✅ Local CheckDeps ✅ Uses shared function

3. Fix Docker fontconfig version pins

Debian removed old fontconfig packages from deb.debian.org, breaking cross-compilation Docker builds. Updated to the oldest available version for each Debian release:

Dockerfile Old version New version Notes
Debian 11 2.13.1-2 (404) 2.13.1-4.2 Oldest 2.13.x on deb.debian.org
Debian 12 2.13.1-2 (404) 2.13.1-4.2 Oldest 2.13.x on deb.debian.org
Debian 13 * 2.13.1-2 (404) 2.13.1-4.2 Oldest 2.13.x on deb.debian.org
Debian 13 loong64 2.17.1-3 (404) 2.17.1-4 Oldest available for loong64
Debian 10 2.13.1-2 (unchanged) Uses archive.debian.org (retains old packages)
All riscv64 2.15.0-2.3 (unchanged) Still available

CI Results

All 62 native build jobs pass, including:

  • ANGLE WinUI arm64/x64/x86 — dependency verification confirms no VCRUNTIME/MSVCP linkage
  • libSkiaSharp and libHarfBuzzSharp Windows builds — same verification
  • Linux loongarch64 (both with and without deps) — previously failing due to fontconfig 404, now fixed
  • ✅ All other Linux, macOS, WASM, and Android builds

…ation

- Add explicit /MT to ANGLE extra_cflags to ensure static CRT linking,
  preventing potential crashes on Windows machines without VC++ Redistributable
- Extract CheckWindowsDependencies() and CheckLinuxDependencies() into
  scripts/cake/native-shared.cake for reuse across all native builds
- Add dependency verification to ANGLE, libSkiaSharp, and libHarfBuzzSharp
  Windows builds (reject VCRUNTIME/MSVCP dependencies)
- Simplify native/winui/build.cake and native/linux/build.cake to delegate
  to the shared functions

CI verified all DLLs pass the dependency check (no VCRUNTIME/MSVCP deps).

Fixes #3346
See also: #136 (original static CRT fix for libSkiaSharp)
Copy link
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 aims to fix Windows ARM64 publish-time crashes in MAUI apps by ensuring native Windows binaries don’t depend on the VC++ Redistributable, and by adding shared build-time dependency verification across native build scripts.

Changes:

  • Introduces shared CheckWindowsDependencies() / CheckLinuxDependencies() helpers in scripts/cake/native-shared.cake.
  • Replaces duplicated per-platform dependency checks in Windows/WinUI/Linux native build scripts with the shared helpers.
  • Adds Windows dependency verification (rejecting VCRUNTIME/MSVCP) to the WinUI ANGLE build output.

Reviewed changes

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

Show a summary per file
File Description
scripts/cake/native-shared.cake Adds shared Windows (dumpbin) and Linux (readelf + optional GLIBC max) dependency verification helpers.
native/winui/build.cake Switches WinUI native DLL dependency verification to use CheckWindowsDependencies().
native/winui-angle/build.cake Adds excluded dependency list and runs Windows dependency verification on produced ANGLE DLLs.
native/windows/build.cake Adds Windows dependency verification for libSkiaSharp.dll and libHarfBuzzSharp.dll.
native/linux/build.cake Refactors Linux dependency verification to call CheckLinuxDependencies() and passes verifyGlibcMax through.

throw new Exception("Could not find dumpbin.exe, please ensure that --vsinstall is used or the envvar VS_INSTALL is set.");
}

RunProcess(dumpbins.First(), $"/dependents {dll}", out var stdoutEnum);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

RunProcess(dumpbins.First(), $"/dependents {dll}", ...) does not quote the DLL path. If the repo path (or output path) contains spaces, dumpbin will receive a truncated argument and dependency verification will fail. Use a ProcessSettings/argument builder and quote/escape dll when building the arguments.

Suggested change
RunProcess(dumpbins.First(), $"/dependents {dll}", out var stdoutEnum);
var processSettings = new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append("/dependents")
.AppendQuoted(dll.FullPath)
};
RunProcess(dumpbins.First(), processSettings, out var stdoutEnum);

Copilot uses AI. Check for mistakes.
if (included.Length > 0)
Information($"Making sure that there ARE dependencies on: {string.Join(", ", included)}");

RunProcess("readelf", $"-dV {so}", out var stdoutEnum);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

RunProcess("readelf", $"-dV {so}", ...) does not quote the .so path. If the path contains spaces, the command line will be parsed incorrectly and dependency/GLIBC verification will fail. Quote/escape so (preferably via ProcessSettings/argument builder).

Suggested change
RunProcess("readelf", $"-dV {so}", out var stdoutEnum);
RunProcess("readelf", $"-dV \"{so.FullPath}\"", out var stdoutEnum);

Copilot uses AI. Check for mistakes.
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// HELPERS
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

native-shared.cake now has two separate "// HELPERS" section headers (one before dependency verification and another immediately after). This makes the file structure confusing—consider removing one header or renaming sections so each header uniquely describes the block that follows.

Suggested change
// HELPERS
// BUILD HELPERS

Copilot uses AI. Check for mistakes.
EnsureDirectoryExists(outDir);
CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui{suffix}/{arch}/{target}.dll"), outDir);
CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui{suffix}/{arch}/{target}.pdb"), outDir);
CheckWindowsDependencies($"{outDir}/{target}.dll", excluded: VERIFY_EXCLUDED);
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The ANGLE build args still don’t include the static CRT flag (/MT). With the new CheckWindowsDependencies(..., excluded: { "VCRUNTIME", "MSVCP" }) call, /MD builds will keep depending on VCRUNTIME/MSVCP and this task will fail (and it also doesn’t address the ARM64 publish crash described in the PR). Add /MT (or /MTd for debug, if applicable) to the extra_cflags passed to RunGn for ANGLE.

Copilot uses AI. Check for mistakes.
@mattleibow
Copy link
Contributor Author

mattleibow commented Feb 11, 2026

CI Results (Build #155844)

All 62 native build jobs passed ✅ — zero failures.

What this PR proves

Windows dependency verification works: The new CheckWindowsDependencies calls confirm that all produced Windows DLLs — ANGLE (libEGL.dll, libGLESv2.dll), libSkiaSharp.dll, and libHarfBuzzSharp.dll — do not link against VCRUNTIME or MSVCP. ANGLE already produces statically-linked CRT binaries when is_component_build=false, so no /MT flag was needed. The verification catches any future regression at build time.

Fontconfig fix works: The loongarch64 Docker builds (previously failing with ar: libfontconfig1.deb: file format not recognized because Debian removed 2.17.1-3 from their pool) now succeed with 2.17.1-4. Also proactively fixed Debian 11/12/13 wildcard pins (2.13.1-22.13.1-4.2, the oldest still available on deb.debian.org).

@mattleibow mattleibow changed the title Statically link CRT in ANGLE builds and add shared dependency verification Add shared dependency verification for native Windows and Linux builds Feb 11, 2026
libfontconfig1_2.17.1-3_loong64.deb was removed from deb.debian.org
when version -4 (Feb 3) and -5 (Feb 9) were published, causing the
Docker image build to fail with 'file format not recognized' (curl
silently downloaded a 404 HTML page instead of the .deb).
Debian removed fontconfig 2.13.1-2 from deb.debian.org pool. Update
each Dockerfile to use the version that matches its Debian release:
- Debian 11 (bullseye): 2.13.1-2 → 2.13.1-4.2
- Debian 12 (bookworm): 2.13.1-2 → 2.14.1-4
- Debian 13 (trixie) *: 2.13.1-2 → 2.17.1-5

Debian 10 is unaffected (uses archive.debian.org which retains old
packages).
Use the minimum available version on deb.debian.org to avoid pulling
in newer fontconfig behavior:
- Debian 12/13 wildcard: 2.13.1-4.2 (oldest on deb.debian.org)
- Debian 13 loong64: 2.17.1-4 (oldest available for loong64)
@mattleibow mattleibow changed the title Add shared dependency verification for native Windows and Linux builds Add shared dependency verification and fix Docker fontconfig pins Feb 11, 2026
@mattleibow mattleibow merged commit 06a0c3d into main Feb 11, 2026
1 of 2 checks passed
@mattleibow mattleibow deleted the dev/issue-3346-static-crt-angle branch February 11, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants