Repository navigation
Description
Summary
build.rs unconditionally emits cargo:rustc-link-arg=/STACK:8388608 inside #[cfg(windows)], assuming the linker is always MSVC's link.exe. On the x86_64-pc-windows-gnu target the linker is GNU ld (via x86_64-w64-mingw32-gcc), which doesn't understand /STACK: syntax, so the build fails at the link step. This breaks cargo install --git ... (and any local build) for anyone whose default/active Rust toolchain targets *-pc-windows-gnu — not just MSVC-less setups, since rustup's per-project or rustup default toolchain selection can point at the GNU target even on a machine that otherwise reports x86_64-pc-windows-msvc as its default host.
Environment
- OS: Windows 11 Pro (10.0.26100)
- Rust:
rustc 1.93.0 (254b59607 2026-01-19), hostx86_64-pc-windows-gnu - Active toolchain:
1.93.0-x86_64-pc-windows-gnu - rtk commit:
23d1e899ce89bef54dfa7f3b6f66374c24f311e7(build.rs last touched in12276c174378d5fdbd7deb37f921bd8a46806cd4, 2026-03-26)
Steps to reproduce
- On Windows, have an active/default Rust toolchain targeting
x86_64-pc-windows-gnu(e.g.rustup default stable-x86_64-pc-windows-gnu). - Run
cargo install --git https://github.com/rtk-ai/rtk.
Expected
Build succeeds and installs rtk.exe.
Actual
Link step fails:
error: linking with `x86_64-w64-mingw32-gcc` failed: exit code: 1
|
= note: "x86_64-w64-mingw32-gcc" ... "/STACK:8388608"
= note: ...\ld.exe: cannot find /STACK:8388608: No such file or directory
collect2.exe: error: ld returned 1 exit status
error: failed to compile `rtk v0.42.4 (...)`, intermediate artifacts can be found at `...`
ld treats /STACK:8388608 as a positional filename argument (not recognizing the MSVC flag syntax), so it errors out looking for a file by that name.
Root cause
Lines 6 to 13 in 23d1e89
| #[cfg(windows)] | |
| { | |
| // Clap + the full command graph can exceed the default 1 MiB Windows | |
| // main-thread stack during process startup. Reserve a larger stack for | |
| // the CLI binary so `rtk.exe --version`, `--help`, and hook entry | |
| // points start reliably without requiring ad-hoc RUSTFLAGS. | |
| println!("cargo:rustc-link-arg=/STACK:8388608"); | |
| } |
#[cfg(windows)]
{
// Clap + the full command graph can exceed the default 1 MiB Windows
// main-thread stack during process startup. Reserve a larger stack for
// the CLI binary so `rtk.exe --version`, `--help`, and hook entry
// points start reliably without requiring ad-hoc RUSTFLAGS.
println!("cargo:rustc-link-arg=/STACK:8388608");
}The /STACK: syntax is specific to MSVC's link.exe. GNU ld (used on the *-pc-windows-gnu target) expects --stack=<size> / -Wl,--stack,<size>.
Suggested fix
Branch on CARGO_CFG_TARGET_ENV (set by Cargo for build scripts; "msvc" or "gnu" on Windows targets) and emit the linker-appropriate flag:
#[cfg(windows)]
{
// Clap + the full command graph can exceed the default 1 MiB Windows
// main-thread stack during process startup. Reserve a larger stack for
// the CLI binary so `rtk.exe --version`, `--help`, and hook entry
// points start reliably without requiring ad-hoc RUSTFLAGS.
// MSVC's link.exe and GNU/mingw's ld use different flag syntax for this.
if std::env::var("CARGO_CFG_TARGET_ENV").as_deref() == Ok("msvc") {
println!("cargo:rustc-link-arg=/STACK:8388608");
} else {
println!("cargo:rustc-link-arg=-Wl,--stack,8388608");
}
}I applied exactly this patch locally, built with cargo +stable-x86_64-pc-windows-gnu install --path ., and confirmed rtk.exe builds and runs correctly (rtk --version, rtk hook claude, rtk gain all work as expected) on the GNU target. Happy to open a PR with this change if useful.
Activity
pszymkowiak commentedon Jul 26, 2026
🔍 Automated Triage
bughighSummary
build.rs unconditionally emits MSVC-only /STACK: linker flag on cfg(windows), breaking builds on x86_64-pc-windows-gnu; fix by branching on CARGO_CFG_TARGET_ENV (patch provided and verified by reporter).
📁 Relevant files
build.rsTriaged automatically by wshm · This is an automated analysis, not a human review.
esidorenko-sl commentedon Aug 27, 2026
Still reproduces on develop (322db4d):
cargo buildunderstable-x86_64-pc-windows-gnudies at the link step withld.exe: cannot find /STACK:8388608.Gating the block on
cfg(all(windows, target_env = "msvc"))is enough for a working build, in case emitting the-Wl,--stackequivalent for ld needs more thought than the MSVC-only guard.bharvey42 commentedon Sep 1, 2026
This still reproduces on
develop@ aa40853 —cargo buildunderstable-x86_64-pc-windows-gnudies at the link step, so the target is unbuildable on mainline today. Confirming esidorenko-sl's report from 2026-08-27.There are now six open PRs fixing this one line, and I don't think any of them is being read, because from this issue only one of the six is even visible — #3778 is the only one that says
Fixes #3215. I went through all six against the current tree; posting the comparison here so the decision is cheap for whoever picks.#[cfg(windows)]+TARGETstringcontains("gnu")#[cfg(windows)]+CARGO_CFG_TARGET_ENVCARGO_CFG_TARGET_OS+_ENVCARGO_CFG_TARGET_OS+_ENVCARGO_CFG_TARGET_OS+_ENV#[cfg(windows)]+CARGO_CFG_TARGET_ENVTwo things separate them.
1. Host gating vs target gating. #2539, #2895 and #3778 fix the flag spelling but leave the
#[cfg(windows)]block in place. In a build script that attribute describes the machine compiling build.rs, not the target being built, so it is wrong in both directions: cross-compiling to Windows from Linux skips the flag entirely (the stack fix silently disappears), and cross-compiling from a Windows host to a non-Windows target enters the block and emits a PE-only linker option into an ELF link. Theelsebranch makes that concrete — on a Windows host targetingx86_64-unknown-linux-gnu, #2895/#3778 emit-Wl,--stack,8388608, and #2539'scontains("gnu")matches that target too. #3239, #3547 and #3613 readCARGO_CFG_TARGET_OS, which is target-accurate.2. Which way the non-msvc branch defaults. #3613 is the only one that inverts it:
Anything that isn't literally
gnugets MSVC syntax, so*-pc-windows-gnullvm(aarch64 Windows) hits exactly the bug this issue is about. The others default the other way — unknown env gets the GNU flag — which is the safer default, since msvc is the one that needs the special spelling. #3613 otherwise has the nicest structure of the six (an extracted, documentedset_windows_stack_size()); flipping that match arm would make it fully correct.Recommendation: #3239 or #3547. They are behaviourally identical — target-gated, GNU default — and differ only in style: #3239 spells out the reasoning in a comment (including why
#[cfg(windows)]is the wrong gate, which is the trap the other three fell into), #3547 is the more compact expression of the same logic. Either closes this.Disclosure so you can weigh it: I've been running #3239 in a local fork build since 2026-08-08 on
x86_64-pc-windows-gnu, daily, no issues. I have no stake in which one lands — #3547 is equally correct and I'd be just as happy to see it merged. What I care about is that one of them does, because until then anyone on this target can't build rtk at all, which also means they can't build a baseline to validate any other Windows PR against. That's a quiet multiplier on the rest of the Windows backlog.One structural note. This issue is labelled
good first issue, and the duplicates arrive almost on a schedule — Jun 22, Jul 8, Jul 27, Aug 12, Aug 20, Aug 30, roughly one a fortnight. #2895 and #3778 are the same code, differing only in the wording of one comment. Each new duplicate raises the cost of picking, which delays the merge, which leaves the label up. Droppinggood first issueonce a candidate is chosen would stop the inflow.Also worth knowing when you do pick: none of these six has had CI run — they show
check-target: SKIPPED, so a maintainer needs to approve the workflow before there's any signal to review.KuSh commentedon Oct 31, 2026
Fixed by #3613, shipped in v1.1.0: build.rs now passes
-Wl,--stackto the MinGW linker and keeps/STACK:for MSVC only, and CI builds and tests the x86_64-pc-windows-gnu target. If the GNU build still fails for you on v1.1.0 or later, please comment and we will reopen.