fix(compile): Windows staticlib without MSVC, actionable dylib error, .dll default, /STACK comment - #6643
Conversation
… .dll default, /STACK comment
|
Warning Review limit reached
Next review available in: 33 seconds Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Fixes the four Windows toolchain holes from the 2026-07-18 audit (main @ 58e555e). All changes in
crates/perry/src/commands/compile/.(a)
--output-type staticlibno longer hard-requires MSVClib.exerun_pipeline.rsunconditionally spawnedCommand::new("lib.exe"), so a lightweight-toolchain user (LLVM + xwin viaperry setup windows, no Visual Studio) got a raw spawn error.Now the archiver is selected with the established lookup precedence (
library_search.rs):lib.exe— vswhere-located MSVC bin dir (the same dirfind_msvc_link_exepicks), then PATH (covers vcvars prompts);llvm-lib— drop-in lib.exe replacement, ships withwinget install LLVM.LLVM, resolved viafind_llvm_tool(soPERRY_LLVM_LIB, rustup sysroot, and PATH all work);llvm-ar --format=coff crs— last resort (rustup's llvm-tools component carries llvm-ar but not llvm-lib).If none resolve, the compile fails with the same two-toolchain install hint style as the executable linker path (LLVM winget line + VS Build Tools workload line), instead of an opaque spawn error.
(b)
--output-type dylibon Windows: actionable failure + the link.exe /DLL investigationInvestigation result (required by the audit)
The code comment claimed MSVC link.exe "returns 0 without writing the DLL" under
/DLL /FORCE:UNRESOLVED, which is why it was deliberately excluded. This no longer reproduces. Tested on this box with MSVC 14.50.35717 (VS 2026 Build Tools) against a clang-built COFF object with an unresolvedjs_*symbol, using Perry's exact dylib link line (/NOLOGO /DLL /FORCE:UNRESOLVED /DEF:... /OUT:... /defaultlib:libcmt):LoadLibrary; both.defexports resolve viaGetProcAddress;perry_plugin_abi_version()callable and returns the right value.Caveat: verified on MSVC 14.50 only — older toolsets may still exhibit the silent-drop behavior, which shaped the fix below.
Fix
Per the audit's guidance ("if it actually works now, wiring MSVC link.exe as fallback is the better fix"):
find_lld_link(), plusfind_llvm_tool("lld-link")so Unix cross-hosts get awhichprobe too — same reach as the oldPathBuf::from("lld-link")PATH-at-spawn fallback, but resolved up front).find_msvc_link_exe) is wired as the fallback when lld-link is absent.PERRY_LLD_LINK, VS Build Tools alternative) instead of the raw spawn failure.LIB(xwin sysroot first, then vswhere — mirroringselect_linker_command) when the user hasn't, so/defaultlib:libcmtresolves from a plain shell for both linkers.(c)
/STACKcomment correctedlink/platform_cmd.rssaid "Reserve 8MB" next to/STACK:67108864, which is 64 MiB. The comment now says 64 MiB and why it's that large (deep recursion in compiled TS + game workloads; bakes in the old manualeditbin /STACKpost-link step this replaced).(d) Extension-less
--output-type dylibdefaults to.dllon Windowsoutput_path.rspicked.dylib(host-macOS cfg) else.so— no Windows branch, so a no--odylib build on Windows producedapp.so. The dylib arm is now target-keyed like the rest of the file (host cfg only as the no---targetfallback):windows/windows-winui→.dll, Apple family →.dylib, else.so. Matcheswindows_default_output_extension, which already handled the-o NAMEpath. Finishes #4771.Verification
cargo check -p perrypasses (0 errors; the only warnings are pre-existing ones in untouched files). Note: origin/main's perry-runtime doesn't compile on Windows (pre-existingExitProcessdivergence, fix in PR fix(runtime): declare ExitProcess as never-returning on Windows (build break) #6609); verified with that one-line local overlay applied — the overlay is not part of this PR.windows_link_tests.rs(archiver precedence lib.exe → llvm-lib → llvm-ar → None;/OUT:vs--format=coff crscommand shapes) andoutput_path.rs(target-keyed dylib extension incl..dll, host-fallback matrix): all 29 matching tests pass (cargo test -p perry --bin perry -- output_path windows_link). Running them on Windows needed a local, uncommitted link shim for a second pre-existing Windows hole: the perry (test) binary fails to link withLNK2019: js_crypto_ed25519_verify— a perry-updater extern defined in perry-stdlib, which the perry CLI bin does not depend on (release-profile CGU partitioning is why release builds don't hit it). Not introduced by this PR; may be worth its own issue.perry hello.ts --output-type staticlib -o hello.lib→ exit 0; the MSVC "Library Manager 14.50" banner confirms the new selector picked lib.exe via the vswhere rung;lib.exe /LIST hello.libshows the member;hello.linkdeps.jsonsidecar written. The other two rungs were validated manually against the same object: both thellvm-lib-built and thellvm-ar --format=coff crs-built archives are readable by MSVC lib.exe (exit 0). (The perry-dev bin build itself required the same local shim for the pre-existing LNK2019 above.)cargo fmt -p perryclean; diff touches only the intended files.No version bump / changelog per maintainer instruction (folded in at merge time).