@echo off setlocal EnableExtensions EnableDelayedExpansion :: ============================================================================= :: build.bat — portable build for loader (Release|x64 by default) :: :: Usage: :: build.bat Build Release x64 :: build.bat debug Build Debug x64 :: build.bat clean Clean intermediate + output :: build.bat --install If no MSVC found, install VS Build Tools (minimal) :: build.bat --install debug Install tools then Debug build :: :: What it needs (auto if --install): :: - Visual Studio 2019/2022/18 Build Tools OR full VS :: workload: Desktop development with C++ (VCTools) :: - Windows 10/11 SDK (pulled with workload) :: :: True zero-install is not possible: MSVC is ~1–3 GB. This script only :: downloads the official Build Tools bootstrapper when you pass --install. :: :: Runtime: project links STATIC CRT (/MT Release, /MTd Debug) so loader.exe :: does NOT need vcruntime140.dll / msvcp140.dll next to it on target PCs. :: Prefer: build.bat (Release) for drop-and-run lab use. :: ============================================================================= cd /d "%~dp0" set "ROOT=%CD%" set "SLN=%ROOT%\loader.sln" set "CONFIG=Release" set "PLATFORM=x64" set "DO_INSTALL=0" set "DO_CLEAN=0" set "MSBUILD=" set "VSWHERE=" set "TOOLSET=" set "VSINSTALL=" set "VCVARS=" for %%A in (%*) do ( if /I "%%~A"=="--install" set "DO_INSTALL=1" if /I "%%~A"=="/install" set "DO_INSTALL=1" if /I "%%~A"=="install" set "DO_INSTALL=1" if /I "%%~A"=="debug" set "CONFIG=Debug" if /I "%%~A"=="Debug" set "CONFIG=Debug" if /I "%%~A"=="release" set "CONFIG=Release" if /I "%%~A"=="Release" set "CONFIG=Release" if /I "%%~A"=="clean" set "DO_CLEAN=1" if /I "%%~A"=="Clean" set "DO_CLEAN=1" ) if not exist "%SLN%" ( echo [x] loader.sln not found in "%ROOT%" exit /b 1 ) echo. echo ============================================ echo loader build ^| %CONFIG%^|%PLATFORM% echo ============================================ echo. call :FindVsWhere call :FindMsBuild if defined MSBUILD goto :HaveToolchain if "%DO_INSTALL%"=="1" ( call :InstallBuildTools call :FindVsWhere call :FindMsBuild ) if not defined MSBUILD ( echo [x] MSBuild / C++ toolset not found. echo. echo Install options: echo 1^) Re-run: build.bat --install echo ^(downloads VS Build Tools + C++ workload, needs admin + internet^) echo 2^) Manual: https://visualstudio.microsoft.com/visual-cpp-build-tools/ echo Select "Desktop development with C++" echo. exit /b 1 ) :HaveToolchain call :DetectToolset echo [+] MSBuild : %MSBUILD% if defined TOOLSET ( echo [+] Toolset: %TOOLSET% ) else ( echo [!] Toolset: ^(project default / auto^) ) echo [+] Config : %CONFIG%^|%PLATFORM% echo. if "%DO_CLEAN%"=="1" ( echo [*] Cleaning... "%MSBUILD%" "%SLN%" /t:Clean /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% /m /nologo /v:minimal if errorlevel 1 exit /b 1 echo [+] Clean done. exit /b 0 ) set "EXTRA_PROPS=" if defined TOOLSET set "EXTRA_PROPS=/p:PlatformToolset=%TOOLSET%" echo [*] Building... "%MSBUILD%" "%SLN%" /t:Build /p:Configuration=%CONFIG% /p:Platform=%PLATFORM% %EXTRA_PROPS% /m /nologo /v:minimal if errorlevel 1 ( echo. echo [x] Build FAILED. echo If the exe is locked: close loader.exe and rebuild. echo If toolset missing: build.bat --install exit /b 1 ) set "OUT=%ROOT%\x64\%CONFIG%\loader.exe" if exist "%OUT%" ( echo. echo [+] SUCCESS echo [+] Output: %OUT% for %%F in ("%OUT%") do echo [+] Size : %%~zF bytes ) else ( echo. echo [!] Build reported success but "%OUT%" not found. echo Check loader\x64\%CONFIG%\ or project OutDir. ) echo. exit /b 0 :: --------------------------------------------------------------------------- :: Find vswhere.exe (ships with VS Installer) :: --------------------------------------------------------------------------- :FindVsWhere set "VSWHERE=" if exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" ( set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" exit /b 0 ) if exist "%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" ( set "VSWHERE=%ProgramFiles%\Microsoft Visual Studio\Installer\vswhere.exe" ) exit /b 0 :: --------------------------------------------------------------------------- :: Locate MSBuild that can build C++ (prefers latest with VC tools) :: --------------------------------------------------------------------------- :FindMsBuild set "MSBUILD=" set "VSINSTALL=" if defined VSWHERE ( :: Prefer install with Microsoft.VisualStudio.Component.VC.Tools.x86.x64 for /f "usebackq delims=" %%I in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath 2^>nul`) do ( set "VSINSTALL=%%I" ) if not defined VSINSTALL ( for /f "usebackq delims=" %%I in (`"%VSWHERE%" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath 2^>nul`) do ( set "VSINSTALL=%%I" ) ) ) if defined VSINSTALL ( if exist "!VSINSTALL!\MSBuild\Current\Bin\amd64\MSBuild.exe" ( set "MSBUILD=!VSINSTALL!\MSBuild\Current\Bin\amd64\MSBuild.exe" exit /b 0 ) if exist "!VSINSTALL!\MSBuild\Current\Bin\MSBuild.exe" ( set "MSBUILD=!VSINSTALL!\MSBuild\Current\Bin\MSBuild.exe" exit /b 0 ) ) :: Fallback: common fixed paths (VS 18 / 2022 / 2019 Build Tools + Community) for %%P in ( "%ProgramFiles%\Microsoft Visual Studio\18\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\18\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\18\Professional\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\18\Enterprise\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\2022\BuildTools\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\amd64\MSBuild.exe" "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe" "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" ) do ( if exist %%~P ( set "MSBUILD=%%~P" exit /b 0 ) ) :: PATH where msbuild.exe >nul 2>&1 if not errorlevel 1 ( for /f "delims=" %%I in ('where msbuild.exe') do ( set "MSBUILD=%%I" exit /b 0 ) ) exit /b 0 :: --------------------------------------------------------------------------- :: Pick PlatformToolset matching installed VS (project file says v145) :: --------------------------------------------------------------------------- :DetectToolset set "TOOLSET=" :: Map VS major version from vswhere when possible if defined VSWHERE ( for /f "usebackq delims=" %%I in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationVersion 2^>nul`) do ( set "VSVER=%%I" ) if defined VSVER ( for /f "tokens=1 delims=." %%M in ("!VSVER!") do set "VSMAJOR=%%M" if "!VSMAJOR!"=="18" set "TOOLSET=v145" if "!VSMAJOR!"=="17" set "TOOLSET=v143" if "!VSMAJOR!"=="16" set "TOOLSET=v142" if defined TOOLSET exit /b 0 ) ) :: Fallback: MSVC folder names under the install if defined VSINSTALL if exist "!VSINSTALL!\VC\Tools\MSVC" ( for /f "delims=" %%V in ('dir /b /ad /o-n "!VSINSTALL!\VC\Tools\MSVC" 2^>nul') do ( set "VER=%%V" set "MAJ=!VER:~0,4!" if "!MAJ!"=="14.5" ( set "TOOLSET=v145" & exit /b 0 ) if "!MAJ!"=="14.4" ( set "TOOLSET=v143" & exit /b 0 ) if "!MAJ!"=="14.3" ( set "TOOLSET=v143" & exit /b 0 ) if "!MAJ!"=="14.2" ( set "TOOLSET=v142" & exit /b 0 ) ) ) :: Last resort: leave empty so .vcxproj PlatformToolset is used exit /b 0 :: --------------------------------------------------------------------------- :: Download + install minimal VS Build Tools (C++ desktop workload) :: --------------------------------------------------------------------------- :InstallBuildTools echo. echo [!] No C++ toolchain found. Installing Visual Studio Build Tools... echo Workload: Desktop development with C++ (VCTools) echo This needs Administrator rights and internet. Size ~1.5–3 GB. echo. :: Prefer winget if present (cleanest) where winget.exe >nul 2>&1 if not errorlevel 1 ( echo [*] Trying winget install of VS 2022 Build Tools... winget install -e --id Microsoft.VisualStudio.2022.BuildTools --accept-package-agreements --accept-source-agreements --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --add Microsoft.VisualStudio.Component.Windows11SDK.22621" if not errorlevel 1 ( echo [+] winget install finished. exit /b 0 ) echo [!] winget install failed or cancelled — falling back to bootstrapper. ) set "BT_DIR=%ROOT%\.build-tools" set "BT_EXE=%BT_DIR%\vs_BuildTools.exe" if not exist "%BT_DIR%" mkdir "%BT_DIR%" if not exist "%BT_EXE%" ( echo [*] Downloading VS Build Tools bootstrapper... :: Official ever-green bootstrapper (VS 2022 Build Tools) powershell -NoProfile -ExecutionPolicy Bypass -Command ^ "try { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vs_BuildTools.exe' -OutFile '%BT_EXE%' -UseBasicParsing } catch { Write-Error $_; exit 1 }" if errorlevel 1 ( echo [x] Download failed. exit /b 1 ) ) echo [*] Running installer (passive). Approve UAC if prompted... "%BT_EXE%" --wait --passive --norestart ^ --add Microsoft.VisualStudio.Workload.VCTools ^ --includeRecommended ^ --add Microsoft.VisualStudio.Component.Windows11SDK.22621 if errorlevel 1 ( echo [x] Build Tools install failed (exit %ERRORLEVEL%). echo Run this .bat as Administrator, or install manually: echo https://visualstudio.microsoft.com/visual-cpp-build-tools/ exit /b 1 ) echo [+] Build Tools install finished. exit /b 0