]> vilimpoc.org git repositories - dotfiles/blobdiff - setup-windows.bat
setup-windows: Msys2 step - MSYS2 with MinGW-w64 GCC, per-user, no elevation
[dotfiles] / setup-windows.bat
index 7445de5aa8ef4e6abe25a5898eec3cb421d8bdc9..eb145ec0433ee6de33202ac53c509c8070fbb5d3 100644 (file)
@@ -95,6 +95,8 @@ if "%ELEV%"=="NOLUA" (
 @rem   VS Clang/LLVM component          with-uac  see $ClangComponents\r
 @rem   Windows Driver Kit               with-uac  see the WDK step\r
 @rem   BinSkim                          no-uac    NuGet publishes win-x64 only\r
+@rem   Google.AndroidStudio             here      no Windows ARM64 build\r
+@rem   Android SDK                      no-uac    Windows build tools are x86/x64 only\r
 @rem\r
 @rem The decision itself is made in ONE place, setup-windows-steps.ps1, which\r
 @rem marks each of these -X64Only with its reason. The plan shows them as [-]\r
@@ -211,7 +213,44 @@ call :winget ProcessExplorer Microsoft.Sysinternals.ProcessExplorer
 call :winget ProcessMonitor Microsoft.Sysinternals.ProcessMonitor\r
 call :winget SDelete Microsoft.Sysinternals.SDelete\r
 call :winget VSCode Microsoft.VisualStudioCode\r
+\r
+@rem --- Windows Terminal, after registering the framework package it needs ---\r
+@rem\r
+@rem Terminal is an MSIX, and its manifest depends on the Microsoft.UI.Xaml.2.8\r
+@rem framework package (>= 8.2306.22001.0), which winget installs first, from the\r
+@rem 8.2310.30001.0 appx. That goes wrong when a NEWER build of the framework is\r
+@rem already on the machine but not registered for this account - measured on\r
+@rem the Windows 10 box, winget 1.29.380, with 8.2501.31001.0 staged and none\r
+@rem registered for the account running this:\r
+@rem   - Windows stages nothing ("A higher version 8.2501.31001.0 of this package\r
+@rem     is already installed", AppXDeploymentServer event 735) and reports the\r
+@rem     stage as a success;\r
+@rem   - winget then registers the 8.2310 package it believes it staged, by full\r
+@rem     name, and there is no such package (0x80073CF1);\r
+@rem   - which it prints as\r
+@rem         Installer failed with exit code: 0x80070002 : The system cannot\r
+@rem         find the file specified.\r
+@rem     and Terminal itself is never attempted. On every run, since a failed\r
+@rem     run changes nothing.\r
+@rem\r
+@rem So register the build that is already there for this account first - by\r
+@rem family name, which takes no version and no elevation. winget then finds the\r
+@rem dependency met and installs Terminal alone. Asked only when this account\r
+@rem has none registered, the case measured, so a re-run - Terminal and its\r
+@rem framework both in place - changes nothing.\r
+@rem\r
+@rem With none on the machine either, the registration fails with that same\r
+@rem 0x80073CF1, and that is not worth a line: it is the fresh box, where nothing\r
+@rem is in winget's way and it installs the framework itself. Any other failure\r
+@rem is reported, and winget still gets its turn.\r
+@rem\r
+@rem %PS64% because it is Windows PowerShell: the Appx module does not load in\r
+@rem PowerShell 7 here ("Operation is not supported on this platform").\r
+call :want WindowsTerminal || goto :after_terminal\r
+"%PS64%" -NoProfile -ExecutionPolicy Bypass -Command "$f = 'Microsoft.UI.Xaml.2.8'; if (-not (Get-AppxPackage $f)) { try { Add-AppxPackage -RegisterByFamilyName -MainPackage ($f + '_8wekyb3d8bbwe') -ErrorAction Stop; Write-Host ('[setup-windows] WindowsTerminal: registered ' + $f + ' ' + @(Get-AppxPackage $f)[0].Version + ', already on this machine, for this account.') } catch { if ($_.Exception.Message -notmatch '0x80073CF1') { Write-Host ('[setup-windows] WARNING: could not register ' + $f + ' for this account: ' + ($_.Exception.Message -split '\r?\n')[0]) } } }"\r
 call :winget WindowsTerminal Microsoft.WindowsTerminal\r
+:after_terminal\r
+\r
 call :winget Python Python.Python.3.13\r
 \r
 @rem WinMerge is the one package here where winget's own preference order picks\r
@@ -337,6 +376,46 @@ call :want NASM || goto :after_nasm
 if not "%ERRORLEVEL%"=="0" call :winget NASM NASM.NASM\r
 :after_nasm\r
 \r
+@rem MSYS2, per-user, for the MinGW-w64 GCC toolchains - the same ones GitHub's\r
+@rem windows-latest runner carries under C:\msys64, so a build that works here\r
+@rem works there. Two environments are installed:\r
+@rem   ucrt64   x86_64, links the UCRT        - the modern target\r
+@rem   mingw32  i686, links msvcrt.dll        - the one that can still target\r
+@rem                                            Windows XP\r
+@rem\r
+@rem Not through winget: the MSYS2.MSYS2 package runs the GUI installer, which\r
+@rem installs machine-wide into C:\msys64 by default. The self-extracting\r
+@rem archive (7-Zip SFX) needs no elevation and unpacks wherever it is pointed,\r
+@rem here %LOCALAPPDATA%\msys64. Nothing is put on the PATH on purpose: the\r
+@rem environments' bin directories carry same-named exes (gcc, ld, windres) and\r
+@rem a project picks one by its full path, e.g. %LOCALAPPDATA%\msys64\mingw32\bin.\r
+@rem\r
+@rem Re-running: the archive is downloaded only when pacman is missing; otherwise\r
+@rem `pacman -Syu` updates what is there and `--needed` leaves installed packages\r
+@rem alone. The first -Syu after a fresh unpack may replace the MSYS2 runtime and\r
+@rem end the shell on purpose, which is why it runs twice.\r
+call :want Msys2 || goto :after_msys2\r
+set "MSYS2_ROOT=%LOCALAPPDATA%\msys64"\r
+if exist "%MSYS2_ROOT%\usr\bin\pacman.exe" goto :msys2_packages\r
+echo [setup-windows] Msys2: downloading the MSYS2 base archive\r
+"%PS64%" -NoProfile -ExecutionPolicy Bypass -Command "$ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri 'https://github.com/msys2/msys2-installer/releases/latest/download/msys2-base-x86_64-latest.sfx.exe' -OutFile \"$env:TEMP\msys2-base.sfx.exe\""\r
+if not exist "%TEMP%\msys2-base.sfx.exe" ( echo [setup-windows] Msys2: download failed & goto :after_msys2 )\r
+echo [setup-windows] Msys2: unpacking into %MSYS2_ROOT%\r
+"%TEMP%\msys2-base.sfx.exe" -y -o"%LOCALAPPDATA%" >nul\r
+del /q "%TEMP%\msys2-base.sfx.exe" 2>nul\r
+if not exist "%MSYS2_ROOT%\usr\bin\pacman.exe" ( echo [setup-windows] Msys2: unpack failed & goto :after_msys2 )\r
+@rem First start: creates the home directory and the key ring.\r
+"%MSYS2_ROOT%\usr\bin\bash.exe" -lc "true"\r
+:msys2_packages\r
+echo [setup-windows] Msys2: updating the base system\r
+"%MSYS2_ROOT%\usr\bin\bash.exe" -lc "pacman -Syuu --noconfirm"\r
+"%MSYS2_ROOT%\usr\bin\bash.exe" -lc "pacman -Syuu --noconfirm"\r
+echo [setup-windows] Msys2: MinGW-w64 GCC for ucrt64 and mingw32\r
+"%MSYS2_ROOT%\usr\bin\bash.exe" -lc "pacman -S --noconfirm --needed mingw-w64-ucrt-x86_64-gcc mingw-w64-i686-gcc"\r
+"%MSYS2_ROOT%\mingw32\bin\gcc.exe" --version | findstr /i "gcc" && echo [setup-windows] Msys2: mingw32 gcc ready in %MSYS2_ROOT%\mingw32\bin\r
+"%MSYS2_ROOT%\ucrt64\bin\gcc.exe" --version | findstr /i "gcc" && echo [setup-windows] Msys2: ucrt64 gcc ready in %MSYS2_ROOT%\ucrt64\bin\r
+:after_msys2\r
+\r
 @rem VirtualBox has no ARM64 Windows host build, and the x64 one cannot be made to\r
 @rem work by emulation: a hypervisor is kernel-mode, and its x64 driver will not\r
 @rem load on an ARM64 kernel. Installing it on ARM64 gets you a broken product and\r
@@ -345,6 +424,12 @@ if not "%ERRORLEVEL%"=="0" call :winget NASM NASM.NASM
 @rem This is also what makes setup-windows-7-test-env.bat unreachable from an\r
 @rem ARM64 host: it prepares a Windows 7 *x86* guest, and neither VirtualBox nor\r
 @rem Hyper-V on ARM64 can run one.\r
+@rem\r
+@rem Nor is it installed when this Windows is itself a virtual machine, which the\r
+@rem planner reads from the firmware's SMBIOS strings: the test VMs belong on the\r
+@rem physical host, and nesting VirtualBox inside a guest needs nested\r
+@rem virtualization the outer hypervisor usually does not offer. The plan marks it\r
+@rem -NotInVM, with that reason, and names the hypervisor it found.\r
 call :winget VirtualBox Oracle.VirtualBox\r
 \r
 @rem ---------------------------------------------------------------------------\r
@@ -378,6 +463,27 @@ call :winget DotNetSdk Microsoft.DotNet.SDK.10
 call :winget CMake Kitware.CMake\r
 call :winget AndroidGPUInspector Google.AndroidGPUInspector\r
 \r
+@rem --- Android Studio ---\r
+@rem\r
+@rem Machine-wide: the manifest's NSIS installer elevates itself and installs to\r
+@rem %ProgramFiles%\Android\Android Studio. x64 only - there is no ARM64 build -\r
+@rem so the plan keeps it off ARM64.\r
+@rem\r
+@rem Installed only when it is missing, which setup-windows-current.ps1 decides.\r
+@rem Android Studio updates itself, in the app, and the winget package is published\r
+@rem with UpgradeBehavior: deny and RequireExplicitUpgrade, so winget would never\r
+@rem upgrade it anyway. What the check prevents is the other case: a Studio that\r
+@rem was installed some other way - as on the x64 laptop, where winget lists it\r
+@rem only by its Add/Remove Programs key - is one winget cannot match to the\r
+@rem package, so `winget install` would run the installer over it.\r
+@rem\r
+@rem It is also where the per-user Android SDK step gets its JDK: Studio bundles\r
+@rem one (jbr), and the SDK's sdkmanager and Gradle both need Java.\r
+call :want AndroidStudio || goto :after_studio\r
+"%PS64%" -NoProfile -ExecutionPolicy Bypass -File "%~dp0setup-windows-current.ps1" -Step AndroidStudio -HostArch "%HOST_ARCH%"\r
+if not "%ERRORLEVEL%"=="0" call :winget AndroidStudio Google.AndroidStudio\r
+:after_studio\r
+\r
 @rem OpenCppCoverage: native (PE) line coverage for the C++ binaries. run-coverage-occ.py drives the\r
 @rem pytest suite under it to produce an HTML report (the binaries under test build with PDBs,\r
 @rem which it reads). The installer elevates via UAC.\r
@@ -687,9 +793,9 @@ if "%IS_ARM64%"=="1" (
     echo [setup-windows]                 compiler by design; clang-cl and upstream LLVM are x64-box only.\r
     echo [setup-windows]                 Rust stable-aarch64-pc-windows-msvc, native, linking through MSVC.\r
     echo [setup-windows]   emulated    : iperf3 ^(x64^) and adb ^(x86^), both bound by their link, not the CPU.\r
-    echo [setup-windows]   not here    : Brave, WinMerge, LLVM, NASM, AGI, OpenCppCoverage, BinSkim\r
-    echo [setup-windows]                 and the WDK - dropped on ARM64; the plan above says why.\r
-    echo [setup-windows]   unavailable : VirtualBox, the Windows 7 x86 test VM, Intel VTune,\r
+    echo [setup-windows]   not here    : Brave, WinMerge, LLVM, NASM, AGI, OpenCppCoverage, BinSkim,\r
+    echo [setup-windows]                 the WDK and the Android SDK - dropped on ARM64; the plan above says why.\r
+    echo [setup-windows]   unavailable : VirtualBox, the Windows 7 x86 test VM, Intel VTune, Android Studio,\r
     echo [setup-windows]                 and the v141 / Windows XP targeting toolset.\r
 )\r
 @rem The list above is what this script PROVIDES on ARM64, not necessarily what\r