Skip to content

windows: support independent MSVC and MinGW profiles (R9, depends on goplus/lib#26) - #2440

Merged
xushiwei merged 57 commits into
xgo-dev:mainfrom
cpunion:codex/windows-r9-native-toolchain-20260827
Aug 29, 2026
Merged

windows: support independent MSVC and MinGW profiles (R9, depends on goplus/lib#26)#2440
xushiwei merged 57 commits into
xgo-dev:mainfrom
cpunion:codex/windows-r9-native-toolchain-20260827

Conversation

@cpunion

@cpunion cpunion commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Part of xgo-dev/llgo#2325.

R8 (xgo-dev/llgo#2425) and the native Windows calling-convention support (xgo-dev/llgo#2433) are merged. This R9 contribution still depends on the minimal Windows C bindings in goplus/lib#26; only the five demo/test/tool modules that consume those bindings use the temporary fork revision, while LLGo's root compiler module no longer depends on goplus/lib.

Summary

  • add independent native windows/amd64 MSVC and GNU/MinGW profiles without changing GOOS, GOARCH, Go flags, or LLGo's existing -target meaning;
  • when CC is unset, probe the effective target of the default clang: official standalone LLVM selects x86_64-pc-windows-msvc, while MSYS2 CLANG64 selects x86_64-w64-windows-gnu;
  • keep optional CC, CXX, and -ldflags=-extld=... overrides Go-compatible, including quoted compiler commands and empty external-linker flag values;
  • propagate the resolved physical triple and ABI through SSA code generation, C ABI lowering, libffi selection, linker/archive/import-library handling, dependency discovery, and package-cache fingerprints;
  • reject non-Clang drivers, unsupported clang-cl syntax, architecture/ABI mismatches, and MSYS/Cygwin output targets rather than inferring the ABI from executable paths or the invoking shell;
  • make the MSVC profile use official full-target LLVM 19.1.3, the Visual Studio SDK/UCRT, and native x64-windows dependencies without resolving compiler libraries from MSYS2;
  • make the MinGW profile use pinned CLANG64 LLVM 19.1.7, its GNU/UCRT C++ runtime, and its own dependencies without inheriting Visual Studio SDK/toolset identity;
  • provide profile-local pkg-config discovery for PowerShell/cmd and POSIX-style shells, so normal installed use requires no profile-selection environment variables;
  • run both profiles through the existing Windows Go, LLGo, hello, demo, GOROOT, docs-local, build-cache, benchmark, runtime, and relevant coverage matrices;
  • keep native exe, c-archive, and c-shared artifacts interoperable within each profile, including explicit MinGW COFF import-library generation;
  • audit artifacts and environment identity so the MSVC lane cannot acquire msys-2.0.dll, cygwin1.dll, or libwinpthread, and the MinGW lane cannot silently reuse MSVC SDK/vcpkg state.

User-facing selection

No LLGo-specific profile variable is required:

GOOS=windows GOARCH=amd64 llgo build ./...

LLGo probes the default Clang target and appends the matching canonical target internally. Explicit CC, CXX, and external-linker settings remain optional Go-compatible overrides. CI verifies installed llgo.exe again with CC, CXX, PKG_CONFIG, and PKG_CONFIG_PATH unset from the profile's normal shell.

Dependency boundary

The temporary github.com/cpunion/lib replacement is limited to _demo/c, _xtool, cl/_testlibc, cl/_testpy, and cl/_testrt. It will be replaced with the released github.com/goplus/lib version after goplus/lib#26 merges. The root module, compiler, SSA, C ABI, runtime, and build system do not import that fork.

Validation

  • Parallels Windows 11 ARM64 VM under x64 emulation:
    • native MSVC-profile llgo install ./... passes;
    • MinGW profile resolution, native executable/C archive/DLL/import-library generation, and execution pass;
    • a compiler command containing MSVC target/runtime flags is preserved as separate arguments and emits a COFF-x86-64 fixture;
    • installed use succeeds without user-supplied profile-selection variables.
  • macOS ARM64:
    • focused compiler, build, cross-toolchain, quoting, and environment tests pass;
    • the LLDB fixture compiler-command regression passes with a multi-argument CC.
  • cpunion/llgo#202 CI: 57 checks pass, 0 fail; the only skipped job is the PR-only release publication step.
    • both Windows profiles pass the shared Go and LLGo test matrices, GOROOT, demos, LLDB, local install, build-cache, coverage, and benchmark jobs;
    • Linux/macOS regressions, cross compilation, WASM runtime, docs, artifacts, and compatibility lanes pass;
    • benchmark collection includes separate Windows MSVC and MinGW data and reports no non-Windows binary-size change attributable to the R9 toolchain split.

Deliberate boundaries

  • R9 qualifies both amd64 profiles. Native Windows ARM64 and WoW64 386 MSVC execution remain R10; their remaining GNU/MinGW qualification remains R11.
  • MSYS2 and Cygwin are invocation shells, not target ABIs. Full Cygwin shell smoke and clean release packaging remain R12.
  • clang-cl syntax and non-Clang drivers fail clearly until a complete driver-dialect implementation exists.
  • Remote installation remains outside the Windows matrix; Windows docs coverage continues to use the local installation paths established by R8.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review: Windows native (MinGW/GNU) toolchain support

Solid, well-structured change. The NativeToolchain abstraction is clean, toolchain-identity fields are consistently threaded through the fingerprint (empty() + collectCommonInputs + TestNativeToolchainIdentityParticipatesInFingerprint), and the tricky bits are handled correctly:

  • GNU vs Windows response-file quoting (clang.go writeGNUResponseArg/writeWindowsResponseArg) implements the CommandLineToArgvW backslash-doubling rule rather than escaping naively.
  • usesWindowsCABI (cabi.go) correctly reclassifies MinGW as native Windows C ABI while excluding MSYS/Cygwin, with matching table-driven tests.
  • CI archive handling in setup-deps/action.yml is properly hardened (SHA-256 pinned LLVM/FileCheck, pinned vcpkg baseline, --fail/--retry, HTTPS, windows-abi allowlisted to msvc|mingw).

No blocking correctness bugs found. A few maintainability/robustness items are inline. One out-of-scope note:

  • Pre-existing zip-slip in internal/crosscompile/fetch.go extractZip (~line 400): unlike extractTarGz (line 280), extractZip joins dest+file.Name and writes with no path-containment check, so a crafted .zip entry (../..) can escape dest. Not touched by this PR and the download URLs are HTTPS constants, but the native-Windows work continues to rely on this shared extractor. Worth adding the same strings.HasPrefix(target, filepath.Clean(dest)+sep) guard that extractTarGz already has.

Findings without inline locations

  • internal/crosscompile/crosscompile.go:461: getESPClangRoot(forceEspClang) runs unconditionally here and can perform a download or return an error. For the native-Windows path below (goos == "windows"), the entire export struct is reassigned wholesale by resolveWindowsToolchain and clangRoot/export.ClangRoot are then cleared. That means the ESP-clang resolution above is wasted work for native Windows and, worse, a spurious failure path: a download hiccup in getESPClangRoot can fail a build that never uses ESP clang. Consider short-circuiting the ESP-clang resolution when the native Windows toolchain will be selected.

Comment thread internal/crosscompile/windows_toolchain.go
Comment thread xtool/env/env.go
@codecov

codecov Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.12207% with 8 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/crosscompile/fetch.go 93.02% 3 Missing ⚠️
internal/build/build.go 96.87% 2 Missing ⚠️
internal/crosscompile/crosscompile.go 93.75% 2 Missing ⚠️
internal/crosscompile/windows_toolchain.go 99.41% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

LLGo baseline benchmarks

0b66e0c90e9d | workflow run | long-term charts

Program measurements

Platform Workload File size vs base Text size vs base Build vs base Run vs base
Linux cprintf 19496 B 0 B / +0.0% 387 B 0 B / +0.0% 336.564 ms -1.243 ms / -0.4% (better) 1.340 ms -25.7 us / -1.9% (better)
Linux cprintf-lto 19328 B 0 B / +0.0% 368 B 0 B / +0.0% 340.638 ms +788.8 us / +0.2% (worse) 1.380 ms -7.59 us / -0.5% (better)
Linux fmtprintf 1652680 B 0 B / +0.0% 501874 B 0 B / +0.0% 2.489 s +20.17 ms / +0.8% (worse) 3.712 ms +13.37 us / +0.4% (worse)
Linux fmtprintf-lto 1524632 B 0 B / +0.0% 460334 B 0 B / +0.0% 8.369 s +42.17 ms / +0.5% (worse) 3.535 ms -45.69 us / -1.3% (better)
Linux println 62328 B 0 B / +0.0% 15286 B 0 B / +0.0% 346.845 ms +4.928 ms / +1.4% (worse) 1.740 ms +29.14 us / +1.7% (worse)
Linux println-lto 54160 B 0 B / +0.0% 12914 B 0 B / +0.0% 515.672 ms -2.979 ms / -0.6% (better) 1.747 ms -16.53 us / -0.9% (better)
macOS cprintf 84480 B 0 B / +0.0% 16733 B 0 B / +0.0% 598.527 ms +240.2 ms / +67.0% (worse) 3.958 ms +1.602 ms / +68.0% (worse)
macOS cprintf-lto 100704 B 0 B / +0.0% 16713 B 0 B / +0.0% 849.653 ms +482 ms / +131.1% (worse) 3.858 ms +1.393 ms / +56.5% (worse)
macOS fmtprintf 1512800 B 0 B / +0.0% 883280 B 0 B / +0.0% 2.053 s -545.2 ms / -21.0% (better) 7.026 ms -1.872 ms / -21.0% (better)
macOS fmtprintf-lto 1208464 B 0 B / +0.0% 876316 B 0 B / +0.0% 10.000 s +2.224 s / +28.6% (worse) 13.336 ms +7.452 ms / +126.7% (worse)
macOS println 114784 B 0 B / +0.0% 35165 B 0 B / +0.0% 532.380 ms +187.2 ms / +54.2% (worse) 3.603 ms +391.4 us / +12.2% (worse)
macOS println-lto 118656 B 0 B / +0.0% 32817 B 0 B / +0.0% 633.059 ms +182.8 ms / +40.6% (worse) 6.175 ms +3.294 ms / +114.3% (worse)
Windows MinGW cprintf 20480 B new 4662 B new 889.702 ms new 4.087 ms new
Windows MinGW cprintf-lto 18432 B new 4582 B new 879.923 ms new 3.721 ms new
Windows MinGW fmtprintf 1918976 B new 591718 B new 3.593 s new 7.691 ms new
Windows MinGW fmtprintf-lto 1968128 B new 583190 B new 9.459 s new 7.967 ms new
Windows MinGW println 74240 B new 25062 B new 837.363 ms new 6.472 ms new
Windows MinGW println-lto 67584 B new 21734 B new 1.062 s new 6.490 ms new
Windows MSVC cprintf 12288 B new 4438 B new 804.633 ms new 4.084 ms new
Windows MSVC cprintf-lto 11776 B new 4278 B new 1.012 s new 5.225 ms new
Windows MSVC fmtprintf 1460224 B new 591286 B new 3.535 s new 9.000 ms new
Windows MSVC fmtprintf-lto 1503232 B new 589734 B new 10.788 s new 9.241 ms new
Windows MSVC println 47104 B new 25062 B new 793.535 ms new 6.973 ms new
Windows MSVC println-lto 44032 B new 22102 B new 1.042 s new 6.927 ms new
Core language and compiler benchmarks
Platform Benchmark ns/op vs base
Linux BenchmarkLookupPCRandom 12.250 ns/op +0.01 ns/op / +0.1% (worse)
Linux BenchmarkMergeCompilerFlags 144.600 ns/op +0.7 ns/op / +0.5% (worse)
Linux BenchmarkMergeLinkerFlags 94.610 ns/op +0.22 ns/op / +0.2% (worse)
Linux BenchmarkChannelBuffered 38.160 ns/op -9.71 ns/op / -20.3% (better)
Linux BenchmarkChannelHandoff 23883 ns/op -315 ns/op / -1.3% (better)
Linux BenchmarkDefer 45.660 ns/op -0.32 ns/op / -0.7% (better)
Linux BenchmarkDirectCall 1.760 ns/op +0.003 ns/op / +0.2% (worse)
Linux BenchmarkGlobalRead 1.762 ns/op +0.002 ns/op / +0.1% (worse)
Linux BenchmarkGlobalWrite 2.809 ns/op -0.001 ns/op / -0.03559% (better)
Linux BenchmarkGoroutine 29638 ns/op -358 ns/op / -1.2% (better)
Linux BenchmarkInterfaceCall 9.148 ns/op +0.001 ns/op / +0.01093% (worse)
Linux BenchmarkRuntimeGetG 1.760 ns/op +0.001 ns/op / +0.1% (worse)
macOS BenchmarkLookupPCRandom 14.380 ns/op +1 ns/op / +7.5% (worse)
macOS BenchmarkMergeCompilerFlags 184.600 ns/op +26.8 ns/op / +17.0% (worse)
macOS BenchmarkMergeLinkerFlags 102.400 ns/op +3.76 ns/op / +3.8% (worse)
macOS BenchmarkChannelBuffered 25.050 ns/op -9.91 ns/op / -28.3% (better)
macOS BenchmarkChannelHandoff 8894 ns/op +3131 ns/op / +54.3% (worse)
macOS BenchmarkDefer 34.420 ns/op -17.1 ns/op / -33.2% (better)
macOS BenchmarkDirectCall 1.201 ns/op -0.067 ns/op / -5.3% (better)
macOS BenchmarkGlobalRead 1.348 ns/op -0.016 ns/op / -1.2% (better)
macOS BenchmarkGlobalWrite 1.310 ns/op -0.157 ns/op / -10.7% (better)
macOS BenchmarkGoroutine 29882 ns/op -6990 ns/op / -19.0% (better)
macOS BenchmarkInterfaceCall 4.946 ns/op -1.674 ns/op / -25.3% (better)
macOS BenchmarkRuntimeGetG 2.189 ns/op -0.816 ns/op / -27.2% (better)
Windows MinGW BenchmarkLookupPCRandom 16.450 ns/op new
Windows MinGW BenchmarkMergeCompilerFlags 813.300 ns/op new
Windows MinGW BenchmarkMergeLinkerFlags 622.700 ns/op new
Windows MinGW BenchmarkChannelBuffered 34.410 ns/op new
Windows MinGW BenchmarkChannelHandoff 866.500 ns/op new
Windows MinGW BenchmarkDefer 52.780 ns/op new
Windows MinGW BenchmarkDirectCall 1.859 ns/op new
Windows MinGW BenchmarkGlobalRead 1.860 ns/op new
Windows MinGW BenchmarkGlobalWrite 2.453 ns/op new
Windows MinGW BenchmarkGoroutine 95736 ns/op new
Windows MinGW BenchmarkInterfaceCall 9.336 ns/op new
Windows MinGW BenchmarkRuntimeGetG 2.175 ns/op new
Windows MSVC BenchmarkLookupPCRandom 15.950 ns/op new
Windows MSVC BenchmarkMergeCompilerFlags 599.700 ns/op new
Windows MSVC BenchmarkMergeLinkerFlags 537.300 ns/op new
Windows MSVC BenchmarkChannelBuffered 34.860 ns/op new
Windows MSVC BenchmarkChannelHandoff 1097 ns/op new
Windows MSVC BenchmarkDefer 58.870 ns/op new
Windows MSVC BenchmarkDirectCall 1.546 ns/op new
Windows MSVC BenchmarkGlobalRead 1.858 ns/op new
Windows MSVC BenchmarkGlobalWrite 2.451 ns/op new
Windows MSVC BenchmarkGoroutine 91347 ns/op new
Windows MSVC BenchmarkInterfaceCall 9.015 ns/op new
Windows MSVC BenchmarkRuntimeGetG 2.483 ns/op new

Compared with c6857d23fec4 measured in the same runner job. Platforms without a paired baseline are marked new.

@cpunion

cpunion commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author

已按评审修正:d813a2503 在 native Windows profile 解析前不再触发无关的 ESP Clang 查找或下载,同时补充了分支判定测试;NativeToolchainInput 的注释也已明确 ExternalFlags-extldflags 参数列表。

@cpunion
cpunion force-pushed the codex/windows-r9-native-toolchain-20260827 branch from d813a25 to 0b66e0c Compare August 29, 2026 12:42
@xushiwei
xushiwei merged commit c680861 into xgo-dev:main Aug 29, 2026
73 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants