Skip to content

Commit bcbeb9c

Browse files
committed
fix(openssl/windows): run vcvars in a CHILD cmd — it terminates its caller
Three runs in a row ended the same way, and the CRLF change did not move it: [bat] vspath=C:\Program Files\Microsoft Visual Studio\18\Enterprise ** Visual Studio 2026 Developer Command Prompt v18.8.2 [vcvarsall.bat] Environment initialized for: 'x64' <nothing> vcvars SUCCEEDS and then the script is gone: no further echo, no RESULT, exit 0. Visual Studio's developer-prompt script terminates the batch that calls it, so no amount of error handling after the `call` can ever run — the previous commit blamed line endings, and this run disproves that (it ran with CRLF and behaved identically). The fix is structural rather than another guess at how vcvars exits: the build moves into a second script invoked as `cmd /c <inner.bat>`. vcvars can then only take that CHILD process down, while the outer script survives to record RESULT=%errorlevel%. The vcvars path travels by environment variable instead of as an argument, because a child cmd inherits the environment and that avoids another layer of quoting around a path containing spaces. The inner script keeps the same exit codes (13 vcvars, 14 cd, 20/21/22 Configure/nmake/install_sw) and the same per-step logging, so the next failure — if there is one — still names itself.
1 parent eae9fed commit bcbeb9c

1 file changed

Lines changed: 41 additions & 17 deletions

File tree

pkgs/c/compat.openssl.lua

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ local function _install_windows_impl()
412412
os.mkdir(prefix)
413413
local logf = path.join(prefix, "mcpp_openssl_build.log")
414414
local bat = path.join(prefix, "mcpp_openssl_build.bat")
415+
local inner = path.join(prefix, "mcpp_openssl_inner.bat")
415416

416417
local function note(msg)
417418
local fh = io.open(logf, "a")
@@ -474,34 +475,57 @@ local function _install_windows_impl()
474475
-- script that "succeeds" having done nothing after the first call.
475476
local logw = tostring(logf):gsub("/", "\\")
476477
local prefw = tostring(prefix):gsub("/", "\\")
477-
io.writefile(bat, table.concat({
478+
local innerw = tostring(inner):gsub("/", "\\")
479+
io.writefile(inner, table.concat({
478480
"@echo off",
479-
'echo [bat] started >> "' .. logw .. '" 2>&1',
480-
'set "VSWHERE=%ProgramFiles(x86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe"',
481-
'echo [bat] vswhere=%VSWHERE% >> "' .. logw .. '" 2>&1',
482-
'if not exist "%VSWHERE%" ( echo [bat] RESULT=10 vswhere missing >> "' .. logw .. '" & exit /b 0 )',
483-
'for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"',
484-
'echo [bat] vspath=%VSPATH% >> "' .. logw .. '" 2>&1',
485-
'if not defined VSPATH ( echo [bat] RESULT=11 no VC toolset >> "' .. logw .. '" & exit /b 0 )',
486-
'set "VCVARS=%VSPATH%\\VC\\Auxiliary\\Build\\vcvars64.bat"',
487-
'if not exist "%VCVARS%" ( echo [bat] RESULT=12 no vcvars64 >> "' .. logw .. '" & exit /b 0 )',
488-
'call "%VCVARS%" >> "' .. logw .. '" 2>&1',
489-
'if errorlevel 1 ( echo [bat] RESULT=13 vcvars failed >> "' .. logw .. '" & exit /b 0 )',
481+
-- vcvars runs HERE, in a child cmd, so whatever it does to its caller
482+
-- cannot reach the outer script.
483+
'call "%MCPP_VCVARS%" >> "' .. logw .. '" 2>&1',
484+
'if errorlevel 1 exit /b 13',
490485
'echo [bat] toolset ready >> "' .. logw .. '" 2>&1',
491486
'cd /d "' .. srcroot .. '"',
492-
'if errorlevel 1 ( echo [bat] RESULT=14 cd failed >> "' .. logw .. '" & exit /b 0 )',
487+
'if errorlevel 1 exit /b 14',
493488
'where perl >> "' .. logw .. '" 2>&1',
494489
'where nmake >> "' .. logw .. '" 2>&1',
495490
'echo [bat] configuring >> "' .. logw .. '" 2>&1',
496491
'perl Configure VC-WIN64A no-shared no-tests no-apps no-engine no-dso --prefix="' .. prefw .. '" --openssldir="' .. prefw .. '\\ssl" >> "' .. logw .. '" 2>&1',
497-
'if errorlevel 1 ( echo [bat] RESULT=20 Configure failed >> "' .. logw .. '" & exit /b 0 )',
492+
'if errorlevel 1 exit /b 20',
498493
'echo [bat] building >> "' .. logw .. '" 2>&1',
499494
'nmake >> "' .. logw .. '" 2>&1',
500-
'if errorlevel 1 ( echo [bat] RESULT=21 nmake failed >> "' .. logw .. '" & exit /b 0 )',
495+
'if errorlevel 1 exit /b 21',
501496
'echo [bat] installing >> "' .. logw .. '" 2>&1',
502497
'nmake install_sw >> "' .. logw .. '" 2>&1',
503-
'if errorlevel 1 ( echo [bat] RESULT=22 nmake install_sw failed >> "' .. logw .. '" & exit /b 0 )',
504-
'echo [bat] RESULT=0 >> "' .. logw .. '" 2>&1',
498+
'if errorlevel 1 exit /b 22',
499+
"exit /b 0",
500+
}, "\r\n") .. "\r\n")
501+
502+
-- Outer script: find the toolset, then hand the actual build to the inner
503+
-- script in a CHILD cmd and record its exit code.
504+
--
505+
-- The child process is the whole point. Three runs in a row died silently
506+
-- right after `call "%VCVARS%"` succeeded — the log even showed
507+
-- "[vcvarsall.bat] Environment initialized for: 'x64'" — and then nothing:
508+
-- no further echo, no RESULT, exit 0. Visual Studio's developer-prompt
509+
-- script terminates the batch that calls it. Running it inside `cmd /c
510+
-- <inner.bat>` means it can only take that child down, and the outer
511+
-- script still runs to write RESULT. The vcvars path travels by ENVIRONMENT
512+
-- VARIABLE rather than as an argument, because a child cmd inherits the
513+
-- environment and that avoids another layer of quoting around a path with
514+
-- spaces.
515+
io.writefile(bat, table.concat({
516+
"@echo off",
517+
'echo [bat] started >> "' .. logw .. '" 2>&1',
518+
'set "VSWHERE=%ProgramFiles(x86)%\\Microsoft Visual Studio\\Installer\\vswhere.exe"',
519+
'echo [bat] vswhere=%VSWHERE% >> "' .. logw .. '" 2>&1',
520+
'if not exist "%VSWHERE%" ( echo [bat] RESULT=10 vswhere missing >> "' .. logw .. '" & exit /b 0 )',
521+
'for /f "usebackq tokens=*" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VSPATH=%%i"',
522+
'echo [bat] vspath=%VSPATH% >> "' .. logw .. '" 2>&1',
523+
'if not defined VSPATH ( echo [bat] RESULT=11 no VC toolset >> "' .. logw .. '" & exit /b 0 )',
524+
'set "MCPP_VCVARS=%VSPATH%\\VC\\Auxiliary\\Build\\vcvars64.bat"',
525+
'if not exist "%MCPP_VCVARS%" ( echo [bat] RESULT=12 no vcvars64 >> "' .. logw .. '" & exit /b 0 )',
526+
'echo [bat] handing build to child cmd >> "' .. logw .. '" 2>&1',
527+
'cmd /c "' .. innerw .. '"',
528+
'echo [bat] RESULT=%errorlevel% >> "' .. logw .. '" 2>&1',
505529
"exit /b 0",
506530
}, "\r\n") .. "\r\n")
507531

0 commit comments

Comments
 (0)