[llvm] 3e4b32a - workflows/release-binaries: Improve Windows installer (#220414)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 06:41:21 PDT 2026
Author: Alexandre Ganea
Date: 2026-09-21T13:41:15Z
New Revision: 3e4b32a108999591908ca254ac53aa81d7a1acb9
URL: https://github.com/llvm/llvm-project/commit/3e4b32a108999591908ca254ac53aa81d7a1acb9
DIFF: https://github.com/llvm/llvm-project/commit/3e4b32a108999591908ca254ac53aa81d7a1acb9.diff
LOG: workflows/release-binaries: Improve Windows installer (#220414)
The Windows WiX installer was missing two things for its setup:
1. The "product ID" which is used to uninstall any previous installed
LLVM versions. This avoids having versions living side-by-side with each
new release. I've reused the same GUID as the current 23.1.0 Win64
installer, to continue that "line" of product. The AArch64 installation
and any prior LLVM version (NSIS) before 23.1.0 will need to be
uninstalled manually, if we want to avoid side-by-side installatin.
2. A "per machine" scope which avoids messy installations which are
installed globally, but cannot be uninstalled globally, and available
only for the current user. After this PR, the installation is available
/ uninstallable to all users on the machine.
Since LLVM currently requires cmake 3.20 for building, and hasn't been
bumped yet to 3.31, also provide a workaround for the WiX scope setup.
Added a release note to signify that users would need to uninstall the
previous versions manually.
Assisted by Claude Opus 5.
Added:
llvm/cmake/WiXPerMachinePatch.xml
Modified:
llvm/CMakeLists.txt
llvm/docs/ReleaseNotes.md
llvm/utils/release/build_llvm_release.bat
Removed:
################################################################################
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 825dbce14d67c..07a2ec9bdfaf3 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -531,6 +531,21 @@ if(WIN32 AND NOT UNIX)
# cabinet itself, and CAB supports only MSZIP/LZX/Quantum, so an MSI cannot
# use LZMA the way the NSIS generator does.
set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-sval" "-dcl:high")
+ # Make the LLVM installation available for all users. CPack only gained
+ # CPACK_WIX_INSTALL_SCOPE in CMake 3.29, so inject the equivalent ALLUSERS
+ # property when packaging with an older CMake supported by LLVM.
+ # TODO: remove after transition to CMake 3.31.
+ if(CMAKE_VERSION VERSION_LESS "3.29")
+ list(APPEND CPACK_WIX_PATCH_FILE
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/WiXPerMachinePatch.xml")
+ else()
+ set(CPACK_WIX_INSTALL_SCOPE "perMachine")
+ endif()
+ # Permanent WiX UpgradeCode for official LLVM MSI packages. Windows Installer
+ # uses this value to recognize related releases and remove an older LLVM
+ # installation during an upgrade. It must remain identical across all future
+ # releases and release branches. DO NOT regenerate or change this GUID.
+ set(CPACK_WIX_UPGRADE_GUID "B08613CD-8BD0-4FB6-8937-621936604DE3")
endif()
endif()
include(CPack)
diff --git a/llvm/cmake/WiXPerMachinePatch.xml b/llvm/cmake/WiXPerMachinePatch.xml
new file mode 100644
index 0000000000000..6780214b0b696
--- /dev/null
+++ b/llvm/cmake/WiXPerMachinePatch.xml
@@ -0,0 +1,5 @@
+<CPackWiXPatch>
+ <CPackWiXFragment Id="#PRODUCT">
+ <Property Id="ALLUSERS" Value="1"/>
+ </CPackWiXFragment>
+</CPackWiXPatch>
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index 985117034e2be..ef6358b5ff711 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -186,6 +186,12 @@ Makes programs 10x faster by doing Special New Thing.
enabling Clang or MLIR retains the project's complete build, test, and
install behavior.
+### Changes to the Windows installer
+
+* The project has migrated to MSI installers. Previous installations of LLVM,
+ prior (and including) 23.1.0, must be manually uninstalled first, before
+ installing this new release.
+
### Changes to TableGen
* `!cond` operator short-circuits at the first `true` condition. Subsequent
diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat
index 12f54a5da3d5b..131de80bfe407 100644
--- a/llvm/utils/release/build_llvm_release.bat
+++ b/llvm/utils/release/build_llvm_release.bat
@@ -40,7 +40,7 @@ set arm64=
set skip-checkout=
set local-python=
set force-msvc=
-set fast-build=
+set fast-build=
call :parse_args %*
if "%help%" NEQ "" goto usage
@@ -286,6 +286,7 @@ ninja check-lld || exit /b 1
REM ninja check-runtimes || exit /b 1
REM ninja check-clang-tools || exit /b 1
ninja package || exit /b 1
+call :verify_msi_upgrade_code || exit /b 1
cd ..
exit /b 0
@@ -359,7 +360,7 @@ mkdir build_%arch%
cd build_%arch%
if "%fast-build%" neq "true" (
call :do_generate_profile || exit /b 1
-)
+)
cmake -GNinja %cmake_flags% ^
-DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb;flang;mlir" ^
-DLLVM_ENABLE_RUNTIMES="compiler-rt;openmp" ^
@@ -379,6 +380,7 @@ REM ninja check-flang || exit /b 1
REM ninja check-mlir || exit /b 1
REM ninja check-lldb || exit /b 1
ninja package || exit /b 1
+call :verify_msi_upgrade_code || exit /b 1
:: generate tarball with install toolchain only off
if "%arch%"=="amd64" (
@@ -432,6 +434,52 @@ exit /b 0
::=============================================================================
+::==============================================================================
+:: Verify that the generated MSI has LLVM's permanent UpgradeCode.
+::==============================================================================
+:verify_msi_upgrade_code
+:: This code has to match the value in llvm/CMakeLists.txt
+set "expected_upgrade_code=B08613CD-8BD0-4FB6-8937-621936604DE3"
+set "msi_path="
+for %%f in (*.msi) do (
+ if defined msi_path (
+ echo Found more than one MSI in %cd%; cannot determine which one to verify.
+ exit /b 1
+ )
+ set "msi_path=%%~ff"
+)
+if not defined msi_path (
+ echo No MSI found in %cd%.
+ exit /b 1
+)
+
+:: Query the MSI's UpgradeCode through the Windows Installer COM API. WiX's
+:: dark.exe would do this too, but it is deprecated and removed in newer WiX.
+set "msi_query=SELECT Value FROM Property WHERE Property='UpgradeCode'"
+set "ps_cmd=$i = New-Object -ComObject WindowsInstaller.Installer;"
+set "ps_cmd=%ps_cmd% $db = $i.OpenDatabase($env:msi_path, 0);"
+set "ps_cmd=%ps_cmd% $v = $db.OpenView($env:msi_query);"
+set "ps_cmd=%ps_cmd% $v.Execute();"
+set "ps_cmd=%ps_cmd% $v.Fetch().StringData(1).Trim('{', '}')"
+
+set "actual_upgrade_code="
+for /f %%i in ('powershell -NoProfile -Command "%ps_cmd%"') do (
+ set "actual_upgrade_code=%%i"
+)
+if not defined actual_upgrade_code (
+ echo Failed to read the UpgradeCode from "%msi_path%".
+ exit /b 1
+)
+if /i not "%actual_upgrade_code%"=="%expected_upgrade_code%" (
+ echo Unexpected UpgradeCode %actual_upgrade_code% in "%msi_path%".
+ echo Expected %expected_upgrade_code%.
+ exit /b 1
+)
+echo Verified MSI UpgradeCode: %expected_upgrade_code%
+exit /b 0
+
+::=============================================================================
+
::==============================================================================
:: Verify checksum.
::==============================================================================
More information about the llvm-commits
mailing list