Repository navigation
makev.bat: fix -msvc bootstrap order and a noisy benign cleanup failure - #29100
Conversation
Two issues found while diagnosing an -msvc build failure caused by the vlang/vc snapshot's stale small/char bug (see #29025, #29098): 1. -msvc's bootstrap stage (building v_win_bootstrap.exe from vc/v_win.c, before compiling the real v.exe) never tried MSVC at all - it went straight to Clang, then GCC, then the bundled TCC, even though MSVC is what -msvc explicitly asked for and is already confirmed present at that point (vsdevcmd.bat has already run). Reordered to: TCC first (fastest, no external toolchain needed), then MSVC, then Clang, then GCC - each is still tried in turn, since any one of them can fail to compile a given vc/v_win.c snapshot on its own (two concrete examples so far: TCC needs vlang/tccbin#96's intrin.h/dbghelp.h headers; MSVC and TCC both hit the small/char macro collision differently, depending on whether their own windows.h chain happens to pull in rpcndr.h). 2. Every "%V_STAGE%" cleanup (`if exist "%V_STAGE%" del "%V_STAGE%"`, 5 call sites) could intermittently print a native, unhandled "Access is denied." - Windows (or a real-time antivirus scanner, which the script's own success message already warns about) can briefly hold a lock on an executable right after the process running it exits. The delete's own exit code was never checked (build success/failure is determined by the compile step's saved errorlevel beforehand), so this was always harmless, just noisy. Replaced all 5 sites with a new :try_delete helper that retries twice with short waits (matching the existing ping-based sleep trick already used in :move_updated_to_v) before giving up silently. In the common case (no lock), this adds no delay at all - the retries only ever run when the file was still locked, which is exactly the case that used to hang around and fail visibly anyway. Verified end-to-end on Windows across several rebuilds: MSVC (or TCC, depending on which fixes are locally present) bootstraps successfully, the final v.exe is genuinely MSVC-built via -cc msvc, and the cleanup message no longer appears. Co-Authored-By: WOZCODE <contact@withwoz.com>
medvednikov
left a comment
There was a problem hiding this comment.
Reviewed 4420fc186de40cb4af04eefedd496c6cfd378e1d; CI status/results were not considered.
One bootstrap correctness concern is noted inline: the new MSVC compilation command omits the compatibility-compiler define that all three existing C-bootstrap commands pass. Please preserve that bootstrap contract in the new branch.
I also traced the five cleanup replacements: callers either preserve the compilation result in stage_error/msvc_error or are already taking the explicit failure branch, so the best-effort helper's successful return does not replace those compilation decisions.
Validation: source review of the diff, bootstrap selection/stage flow, cleanup call sites, and the shared bootstrap-define setup. No Windows build was run here; the missing-define finding is based on the script's documented portable-snapshot requirement and the other bootstrap commands, not a claimed runtime reproduction.
Per review on #29100: the new build_bootstrap_with_msvc's cl invocation omitted VC_BOOTSTRAP_DEFINE (-DCUSTOM_DEFINE_v1_fallback), which the existing TCC/Clang/GCC bootstrap commands all pass, and which the script's own top-of-file comment documents as required to keep portable vc/v_win.c snapshots on the full compatibility-compiler path until the new compiler has been built. cl.exe accepts the same -D syntax already used for the other three compilers (verified: a minimal #ifdef/#error test file compiles successfully with `cl -DCUSTOM_DEFINE_v1_fallback`), so no MSVC-specific /D translation is needed. Verified: exercised the reviewer's suggested regression scenario end-to-end (TCC forced to fail, Clang hidden from PATH, so msvc_strap's MSVC bootstrap actually runs) - the full build, through compiling v_stage.exe and the final v.exe, still succeeds with the define present. I was not able to force a concrete failure without the define in this environment (my local vc/v_win.c snapshot may not exercise the -cross-specific behavior this define guards against), matching the reviewer's own note that this finding wasn't backed by a local runtime reproduction either - the fix restores consistency with the other three bootstrap commands and the documented contract regardless. Co-Authored-By: WOZCODE <contact@withwoz.com>
…verage Two findings from an adversarial review of #29100: 1. try_delete was only applied to the 5 %V_STAGE% cleanup sites; the sibling %ObjFile% (.v.c.obj) cleanups (4 sites) and the %V_STAGE_C% cleanup in build_stage_with_clang were left as plain 'if exist ... del', which can hit the exact same transient-lock "Access is denied" noise try_delete was written to eliminate, just under different filenames. Converted all 5 remaining sites. 2. cmd/tools/makev_test.py's test_all_portable_bootstraps_select_v1 only checked VC_BOOTSTRAP_DEFINE is passed for tcc/clang/gcc, never extended to msvc (the new bootstrap this PR adds) - added test_msvc_bootstrap_selects_v1 as a separate test, since MSVC's cl.exe is invoked directly (no "!msvc_exe!" variable the way the other three have) and doesn't fit the existing loop's line-matching pattern. Also added three BatchExecutionTests exercising try_delete itself for real (unlocked file gets deleted, missing file is a no-op, and - genuinely verified, not just asserted - a file held open by another process stays undeleted but try_delete still returns 0), since it previously had zero automated coverage. Verified: `python cmd/tools/makev_test.py -v` - all 15 tests pass. `./makev.bat -msvc --local` still builds a working v.exe with all changes combined. A third finding from the same review - windows_ci_msvc.yml's real CI job never forces the bundled TCC to fail, so it never actually exercises the new build_bootstrap_with_msvc branch in practice (TCC succeeds first) - is a CI workflow change and is left for a separate, explicit ask rather than bundled here. Co-Authored-By: WOZCODE <contact@withwoz.com>
|
Ran an adversarial review pass on this PR (4 lenses, 3 adversarial refuters per candidate). 3 of 7 candidates survived:
Verified: |
…ression risk Per adversarial review of #29100 (commit 9683eda): no test exercises msvc_strap/build_bootstrap_with_msvc/build_stage_with_clang's actual control flow with a failing compiler, so a future edit that reads !ERRORLEVEL! after a `call :try_delete` (instead of a variable saved before it) would silently swallow a real compile failure - try_delete always exits 0 by design. Confirmed empirically: a reviewer deliberately reintroduced exactly that bug and the full `python cmd/tools/makev_test.py -v` suite still passed 15/15. Documenting the caller contract and this known gap directly at try_delete's definition for now, rather than adding a harder-to-get- right execution-level test (these routines need real MSVC/Clang/TCC, which the existing test harness's V-command-stubbing approach doesn't reach) or refactoring the build script's structure. Co-Authored-By: WOZCODE <contact@withwoz.com>
|
Ran another adversarial review pass on 9683eda. 1 finding survived - and unusually well-verified: one of the adversarial refuters didn't just reason about it, they deliberately reintroduced the exact regression (reading The gap: no test exercises Per direction, documenting this as a known limitation rather than building a harder execution-level test right now (these routines need real MSVC/Clang/TCC, which the existing test harness's V-command-stubbing approach can't reach without a larger change). Added the caller contract and this gap directly as a comment at |
medvednikov
left a comment
There was a problem hiding this comment.
Re-reviewed the fixups since 4420fc186de40cb4af04eefedd496c6cfd378e1d, at head 86cf97ba7640f84541e45bd90f2b52b4162698b2. CI status/results were not considered.
The previous P2 about the missing portable-bootstrap define is addressed. No new actionable correctness issue found in these fixups.
build_bootstrap_with_msvc now passes %VC_BOOTSTRAP_DEFINE% to cl before %V_C_FILE%, matching the other bootstrap paths. Using the shared -D spelling is valid: Microsoft's compiler command-line documentation explicitly permits either / or - for options. The new test_msvc_bootstrap_selects_v1 specifically checks the direct cl invocation, which the existing TCC/Clang/GCC loop did not cover.
I also checked the expanded cleanup changes. build_bootstrap_with_msvc preserves msvc_bootstrap_error, build_stage_with_clang preserves stage_error, and the final MSVC build preserves msvc_error before calling try_delete. The other changed cleanup sites are already on explicit failure branches. Thus the helper's unconditional success does not mask the compilation decisions in the current code. The new deletion tests cover an unlocked file, a missing file, and a persistently locked file.
Validation limits: source-level re-review of the updated script, its callers, and the complete Python test file; I did not execute the Python suite or Windows bootstrap/locked-file tests. This environment has neither a V compiler nor a Windows command interpreter, and direct checkout downloads fail DNS resolution. The source-contract test is not an end-to-end MSVC-bootstrap test; I have not independently reproduced the author's reported Windows run. The original finding is resolved as a bootstrap-contract inconsistency, not as a newly claimed reproduction of the old failure.
Reference: https://learn.microsoft.com/en-us/cpp/build/reference/compiler-command-line-syntax?view=msvc-170
|
Closing the loop on @medvednikov's disclosed validation limit from the last review ("I have not independently reproduced the author's reported Windows run" - they have no Windows/V-compiler access, so that review was source-level only). Re-verified on real Windows at current head (86cf97b):
This is a genuine reproduction of the bootstrap path the previous review could only assess from source, not a claim carried over from an earlier commit. No issues found - MSVC bootstrap works as intended when TCC is unavailable. |
|
Previous P2 resolved. The MSVC invocation passes %VC_BOOTSTRAP_DEFINE%, the regression test checks it, and the cleanup callers preserve compiler exit codes. The posted follow-up found no new actionable correctness issue. |
Summary
Two issues found while diagnosing an
-msvcbuild failure caused bythe
vlang/vcsnapshot's stalesmall/charbug (see #29025,#29098).
1.
-msvc's bootstrap stage never tried MSVC at all. Buildingv_win_bootstrap.exefromvc/v_win.c(before compiling the realv.exe) went straight to Clang, then GCC, then the bundled TCC - eventhough MSVC is what
-msvcexplicitly asked for and is alreadyconfirmed present at that point (
vsdevcmd.bathas already run).Reordered to TCC → MSVC → Clang → GCC: TCC first since it's
fastest and needs no external toolchain, then MSVC (the explicit
request), then the remaining fallbacks. Each is still tried in turn,
since any one of them can fail to compile a given
vc/v_win.csnapshot on its own - two concrete examples hit this session: TCC
needs vlang/tccbin#96's
intrin.h/dbghelp.hheaders; MSVC and TCChit the
small/charmacro collision differently depending onwhether their own
windows.hchain happens to pull inrpcndr.h.2. A noisy, benign cleanup failure. Every
"%V_STAGE%"cleanup(
if exist "%V_STAGE%" del "%V_STAGE%", 5 call sites) couldintermittently print a native, unhandled
Access is denied.-Windows (or a real-time antivirus scanner, which the script's own
success message already warns about) can briefly hold a lock on an
executable right after the process running it exits. The delete's own
exit code was never checked (build success/failure is determined by
the compile step's saved errorlevel beforehand), so this was always
harmless, just confusing. Replaced all 5 sites with a new
:try_deletehelper that retries twice with short waits (matching theexisting ping-based sleep trick already used in
:move_updated_to_v)before giving up silently. In the common case (no lock), this adds no
delay - the retries only run when the file was actually still locked,
which is exactly the case that used to fail visibly anyway.
Test plan
./makev.bat -msvc --localnow bootstraps via TCC first(falling back to MSVC/Clang/GCC as needed depending on which
toolchain-specific fixes are locally present), and the final
v.exeis genuinely MSVC-built (-cc msvc).Access is denied.message no longer appears across multiple consecutive runs.
normal (unlocked) case by inspection of its early-exit branches.
🧙 Built with WOZCODE