https://github.com/marcpems updated https://github.com/llvm/llvm-project/pull/219263
>From 26399f0d236fb624a953d7b2cd3e7d397ba67921 Mon Sep 17 00:00:00 2001 From: marcpems <[email protected]> Date: Fri, 28 Aug 2026 11:05:26 +0100 Subject: [PATCH 1/4] [Windows] Add optional ThinLTO, PDB debug info, and enhanced PGO training to release-binaries.yml Adds minimal, additive inputs to the existing release-binaries.yml workflow (rather than a separate duplicate workflow file): - enable-thinlto: build stage2 with ThinLTO (default off, matches current behavior). - enable-pdb: also generate and upload PDB debug info as a separate artifact (default off). - enhanced-pgo: PGO training always runs (matching the pre-existing, unconditional upstream behavior); this flag only selects the training method. Default false uses the legacy single-file Sema.cpp training step (byte-for-byte the same as current upstream behavior). Setting it to true trains by building LLVMSupport instead, exercising the compiler across many more translation units for a broader, more representative profile. Default behavior (enable-thinlto=false, enable-pdb=false, enhanced-pgo=false) is unchanged from current upstream. Co-authored-by: Copilot <[email protected]> --- .github/workflows/release-binaries.yml | 95 +++++++++++++++++++++-- llvm/utils/release/build_llvm_release.bat | 81 +++++++++++++++---- 2 files changed, 156 insertions(+), 20 deletions(-) diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index e95a6c5936137..0ff52df0809be 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -12,6 +12,21 @@ on: required: true default: false type: boolean + enable-thinlto: + description: "Windows only: build stage2 with ThinLTO" + required: false + default: false + type: boolean + enable-pdb: + description: "Windows only: also generate and upload PDB debug info" + required: false + default: false + type: boolean + enhanced-pgo: + description: "Windows only: train the instrumented clang by building LLVMSupport instead of the legacy single-file Sema.cpp training step (PGO training always runs; this only selects the method)" + required: false + default: false + type: boolean runs-on: description: "Runner to use for the build" required: true @@ -36,6 +51,21 @@ on: required: true default: false type: boolean + enable-thinlto: + description: "Windows only: build stage2 with ThinLTO" + required: false + default: false + type: boolean + enable-pdb: + description: "Windows only: also generate and upload PDB debug info" + required: false + default: false + type: boolean + enhanced-pgo: + description: "Windows only: train the instrumented clang by building LLVMSupport instead of the legacy single-file Sema.cpp training step (PGO training always runs; this only selects the method)" + required: false + default: false + type: boolean runs-on: description: "Runner to use for the build" required: true @@ -69,6 +99,9 @@ jobs: build-runs-on: ${{ steps.vars.outputs.build-runs-on }} test-runs-on: ${{ steps.vars.outputs.build-runs-on }} attestation-name: ${{ steps.vars.outputs.attestation-name }} + windows-enable-thinlto: ${{ steps.vars.outputs.windows-enable-thinlto }} + windows-enable-pdb: ${{ steps.vars.outputs.windows-enable-pdb }} + windows-enhanced-pgo: ${{ steps.vars.outputs.windows-enhanced-pgo }} steps: - name: Validate Release Version @@ -90,6 +123,9 @@ jobs: LLVM_VERSION_MAJOR: ${{ steps.version-from-source.outputs.major }} INPUTS_RUNS_ON: ${{ inputs.runs-on }} INPUTS_RELEASE_VERSION: ${{ inputs.release-version }} + INPUTS_ENABLE_THINLTO: ${{ inputs.enable-thinlto }} + INPUTS_ENABLE_PDB: ${{ inputs.enable-pdb }} + INPUTS_ENHANCED_PGO: ${{ inputs.enhanced-pgo }} shell: bash # In order for the test-release.sh script to run correctly, the LLVM # source needs to be at the following location relative to the build dir: @@ -160,8 +196,10 @@ jobs: fi if [ "$RUNNER_OS" = "Windows" ]; then - # The build times out on Windows, so we need to disable LTO. - target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF" + # Disable LTO by default; use --enable-thinlto to enable ThinLTO. + if [ "$INPUTS_ENABLE_THINLTO" != "true" ]; then + target_cmake_flags="$target_cmake_flags -DLLVM_RELEASE_ENABLE_LTO=OFF" + fi fi case "$INPUTS_RUNS_ON" in @@ -206,10 +244,29 @@ jobs: target_cmake_flags="$target_cmake_flags -D${bootstrap_prefix}_CPACK_PACKAGE_FILE_NAME=$release_binary_basename" + # Translate --enable-thinlto/--enable-pdb/--enhanced-pgo into individual + # flags consumed by the Windows build_llvm_release.bat invocation below + # (only meaningful for Windows builds). + windows_enable_thinlto="false" + if [ "$INPUTS_ENABLE_THINLTO" = "true" ]; then + windows_enable_thinlto="true" + fi + windows_enable_pdb="false" + if [ "$INPUTS_ENABLE_PDB" = "true" ]; then + windows_enable_pdb="true" + fi + windows_enhanced_pgo="false" + if [ "$INPUTS_ENHANCED_PGO" = "true" ]; then + windows_enhanced_pgo="true" + fi + echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT echo "build-runs-on=$build_runs_on" >> $GITHUB_OUTPUT echo "test-runs-on=$test_runs_on" >> $GITHUB_OUTPUT echo "attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-binary-attestation" >> $GITHUB_OUTPUT + echo "windows-enable-thinlto=$windows_enable_thinlto" >> $GITHUB_OUTPUT + echo "windows-enable-pdb=$windows_enable_pdb" >> $GITHUB_OUTPUT + echo "windows-enhanced-pgo=$windows_enhanced_pgo" >> $GITHUB_OUTPUT build-release-package: name: "Build Release Package" @@ -297,21 +354,42 @@ jobs: env: INPUTS_RUNS_ON: ${{ inputs.runs-on }} LLVM_VERSION: ${{ needs.prepare.outputs.release-version }} - EXTRA_ARGS: ${{ case(needs.prepare.outputs.build-runs-on == 'windows-11-arm', '--fast-build', '--fast-build') }} + BUILD_RUNS_ON: ${{ needs.prepare.outputs.build-runs-on }} + WINDOWS_ENABLE_THINLTO: ${{ needs.prepare.outputs.windows-enable-thinlto }} + WINDOWS_ENABLE_PDB: ${{ needs.prepare.outputs.windows-enable-pdb }} + WINDOWS_ENHANCED_PGO: ${{ needs.prepare.outputs.windows-enhanced-pgo }} run: | subst S: ${{ github.workspace }} cd S:\llvm\utils\release\ - .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version $env:LLVM_VERSION --local-python --skip-checkout $env:EXTRA_ARGS + $variantArgs = @() + # --fast-build trades PGO training and stage0 test coverage for + # build speed; it exists solely so the GitHub-hosted windows-11-arm + # runner can finish within its 6-hour job timeout. Other runners + # (including our self-hosted ones) don't need that trade-off, and + # --enhanced-pgo/--enable-thinlto/--enable-pdb below are explicit, + # deliberate opt-ins that should not be silently defeated by it. + if ($env:BUILD_RUNS_ON -eq "windows-11-arm") { $variantArgs += "--fast-build" } + if ($env:WINDOWS_ENABLE_THINLTO -eq "true") { $variantArgs += "--enable-thinlto" } + if ($env:WINDOWS_ENABLE_PDB -eq "true") { $variantArgs += "--enable-pdb" } + if ($env:WINDOWS_ENHANCED_PGO -eq "true") { $variantArgs += "--enhanced-pgo" } + .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version $env:LLVM_VERSION --local-python --skip-checkout @variantArgs if ($env:INPUTS_RUNS_ON -eq "windows-11-arm") { $zstd = (Get-ChildItem -Recurse -Filter "zstd.exe" | Select-Object -First 1).fullName mv $zstd $env:GITHUB_WORKSPACE } $installer = (Get-ChildItem -Recurse -Filter "LLVM-*.msi" | Select-Object -First 1).fullName - $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Select-Object -First 1).fullName + $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Where-Object { $_.Name -notlike "*-pdb.tar.xz" } | Select-Object -First 1).fullName # Move installer to top-level directory so it is easier to upload. mv $installer $env:GITHUB_WORKSPACE mv $tarball $env:GITHUB_WORKSPACE echo "windows-installer-filename=$(Split-Path -Path $installer -Leaf)" >> $env:GITHUB_OUTPUT + if ($env:WINDOWS_ENABLE_PDB -eq "true") { + $pdbArchive = (Get-ChildItem -Recurse -Filter "*-pdb.tar.xz" | Select-Object -First 1).fullName + if ($pdbArchive) { + mv $pdbArchive $env:GITHUB_WORKSPACE + echo "windows-pdb-filename=$(Split-Path -Path $pdbArchive -Leaf)" >> $env:GITHUB_OUTPUT + } + } - name: Dump Wix logs if: runner.os == 'Windows' && failure() @@ -364,6 +442,13 @@ jobs: ${{ needs.prepare.outputs.release-binary-filename-zstd }} ${{ steps.build-windows.outputs.windows-installer-filename }} + - name: Upload Windows PDB debug info + if: runner.os == 'Windows' && steps.build-windows.outputs.windows-pdb-filename != '' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ runner.os }}-${{ runner.arch }}-release-pdb + path: ${{ steps.build-windows.outputs.windows-pdb-filename }} + - name: Run Tests # These almost always fail so don't let them fail the build and prevent the uploads. if : runner.os != 'Windows' diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat index 66c4a0380667a..1c66adb388b56 100644 --- a/llvm/utils/release/build_llvm_release.bat +++ b/llvm/utils/release/build_llvm_release.bat @@ -10,7 +10,7 @@ goto begin echo Script for building the LLVM installer on Windows, echo used for the releases at https://github.com/llvm/llvm-project/releases echo. -echo Usage: build_llvm_release.bat --version ^<version^> [--x86,--x64, --arm64] [--skip-checkout] [--local-python] [--force-msvc] [--fast-build] +echo Usage: build_llvm_release.bat --version ^<version^> [--x86,--x64, --arm64] [--skip-checkout] [--local-python] [--force-msvc] [--fast-build] [--enhanced-pgo] [--enable-thinlto] [--enable-pdb] echo. echo Options: echo --version: [required] version to build @@ -21,6 +21,11 @@ echo --arm64: build and test arm64 variant echo --skip-checkout: use local git checkout instead of downloading src.zip echo --local-python: use installed Python and does not try to use a specific version (3.11) echo --force-msvc: use MSVC compiler for stage0, even if clang-cl is present +echo --enhanced-pgo: train the instrumented stage1 clang by building LLVMSupport instead of +echo the legacy single-file Sema.cpp training step, and use the resulting profile for +echo stage2 (64-bit builds only). +echo --enable-thinlto: build stage2 with ThinLTO (64-bit builds only) +echo --enable-pdb: generate PDB debug info files for stage2 and include them as an additional artifact (64-bit builds only) echo. echo Note: At least one variant to build is required. echo. @@ -40,7 +45,10 @@ set arm64= set skip-checkout= set local-python= set force-msvc= -set fast-build= +set fast-build= +set enhanced-pgo= +set enable-thinlto= +set enable-pdb= call :parse_args %* if "%help%" NEQ "" goto usage @@ -355,12 +363,21 @@ set cmake_flags=%all_cmake_flags:\=/% mkdir build_%arch% cd build_%arch% -if "%fast-build%" neq "true" ( +REM --fast-build skips PGO training for CI speed on time-constrained +REM runners (see build_llvm_release.bat's usage doc), but --enhanced-pgo +REM is an explicit, deliberate opt-in and should not be silently defeated +REM by it; only skip training when enhanced-pgo was not also requested. +if "%fast-build%" == "true" if "%enhanced-pgo%" neq "true" ( + echo Skipping PGO training due to --fast-build. +) else ( call :do_generate_profile || exit /b 1 -) +) +set lto_cmake_flag= +if "%enable-thinlto%" == "true" set lto_cmake_flag=-DLLVM_ENABLE_LTO=Thin cmake -GNinja %cmake_flags% ^ -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb;flang;mlir" ^ -DLLVM_ENABLE_RUNTIMES="compiler-rt;openmp" ^ + %lto_cmake_flag% ^ %common_lldb_flags% ^ -DPYTHON_HOME=%PYTHONHOME% ^ %cmake_profile_flags% %llvm_src%\llvm || exit /b 1 @@ -384,14 +401,31 @@ if "%arch%"=="amd64" ( ) else ( set filename=clang+llvm-%version%-aarch64-pc-windows-msvc ) +REM NOTE: LLVM_ENABLE_PDB is intentionally only set for this toolchain-only +REM (tarball) reconfigure, not for the MSI/WiX "ninja package" build above: +REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging +REM failures, so PDBs are packaged separately as their own tarball instead. +set pdb_cmake_flag= +if "%enable-pdb%" == "true" set pdb_cmake_flag=-DLLVM_ENABLE_PDB=ON cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ - -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% %llvm_src%\llvm || exit /b 1 + -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ + %pdb_cmake_flag% ^ + %llvm_src%\llvm || exit /b 1 ninja install || exit /b 1 :: check llvm_config is present & returns something %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1 cd .. 7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz +if "%enable-pdb%" == "true" ( + :: Package the PDB debug info files produced alongside the install tree + :: into their own archive so they can be uploaded as a separate artifact. + set pdb_filename=%filename%-pdb + pushd %filename% + 7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si ..\!pdb_filename!.tar.xz + popd +) + exit /b 0 ::============================================================================== @@ -503,18 +537,35 @@ cmake -GNinja %cmake_flags% -DLLVM_TARGETS_TO_BUILD=Native ^ ninja clang || exit /b 1 set instrumented_clang=%cd:\=/%/bin/clang-cl.exe cd .. -REM Use that to build part of llvm to generate a profile. mkdir train cd train -cmake -GNinja %cmake_flags% ^ - -DCMAKE_C_COMPILER=%instrumented_clang% ^ - -DCMAKE_CXX_COMPILER=%instrumented_clang% ^ - -DLLVM_ENABLE_PROJECTS=clang ^ - -DLLVM_TARGETS_TO_BUILD=Native ^ - %llvm_src%\llvm || exit /b 1 -REM Drop profiles generated from running cmake; those are not representative. -del ..\instrument\profiles\*.profraw -ninja tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.obj +if "%enhanced-pgo%" == "true" ( + REM Build LLVMSupport with the instrumented clang to generate a broad profile. + REM This mirrors Linux and Mac perf-training approach. + cmake -GNinja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_C_COMPILER=%instrumented_clang% ^ + -DCMAKE_CXX_COMPILER=%instrumented_clang% ^ + -DLLVM_TARGETS_TO_BUILD=Native ^ + -DLLVM_ENABLE_PROJECTS="" ^ + -DLLVM_ENABLE_RUNTIMES="" ^ + %llvm_src%\llvm || exit /b 1 + REM Drop profiles generated from running cmake; those are not representative. + del ..\instrument\profiles\*.profraw + ninja LLVMSupport || exit /b 1 +) else ( + REM Use instrumented build of clang to compile a complex single file to + REM deliver minimum build times. + cmake -GNinja %cmake_flags% ^ + -DCMAKE_C_COMPILER=%instrumented_clang% ^ + -DCMAKE_CXX_COMPILER=%instrumented_clang% ^ + -DLLVM_ENABLE_PROJECTS=clang ^ + -DLLVM_TARGETS_TO_BUILD=Native ^ + %llvm_src%\llvm || exit /b 1 + REM Drop profiles generated from running cmake; those are not representative. + del ..\instrument\profiles\*.profraw + ninja tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.obj || exit /b 1 +) cd .. set profile=%cd:\=/%/profile.profdata %stage0_bin_dir%\llvm-profdata merge -output=%profile% instrument\profiles\*.profraw || exit /b 1 >From 8c2b613e2690c6fd5221646f4f8b522b1364c3fa Mon Sep 17 00:00:00 2001 From: marcpems <[email protected]> Date: Tue, 1 Sep 2026 07:27:54 +0100 Subject: [PATCH 2/4] Fix double-packaging of PDB files in Windows release main tarball Previously, when --enable-pdb was set, the main release tarball included the full install tree (with all bin\*.pdb and lib\*.pdb files) *and* a separate dedicated -pdb.tar.xz archive packaged those same PDBs again, roughly doubling the compressed payload and needlessly inflating the main artifact. Fix: package the dedicated PDB archive first (as before), then delete bin\*.pdb and lib\*.pdb from the install tree, then run the main archive command. The main archive command itself is left completely unmodified from upstream (byte-for-byte identical to the pre-existing single 7z line) since the PDBs are simply no longer present in the tree by the time it runs; only the ordering changed and one "del" line was added inside the existing PDB-packaging block. This is deliberately simpler than an earlier version of this fix that added a "-xr!pattern" 7-Zip exclusion to the main archive command: that syntax requires a literal "!", which is fragile under this script's `setlocal enabledelayedexpansion` and needs extra setlocal/endlocal scoping and careful comment placement to avoid cmd.exe parser pitfalls. Deleting the files before archiving avoids that whole class of issues and keeps the main archive command identical to upstream's non-PDB behavior. Verified locally in real cmd.exe with a synthetic install tree (including a decoy nested\bin\keep.pdb outside the top-level bin/lib directories, to confirm the deletion is scoped the same way the prior "-xr!" recursive exclusion was): the PDB archive contains exactly bin\*.pdb and lib\*.pdb, the main archive contains everything else (including the decoy nested PDB, correctly left untouched), and the non-PDB (enable-pdb=false) path is completely unchanged. Co-authored-by: Copilot <[email protected]> --- llvm/utils/release/build_llvm_release.bat | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat index 1c66adb388b56..231dafc395ada 100644 --- a/llvm/utils/release/build_llvm_release.bat +++ b/llvm/utils/release/build_llvm_release.bat @@ -415,16 +415,18 @@ ninja install || exit /b 1 :: check llvm_config is present & returns something %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1 cd .. -7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz - if "%enable-pdb%" == "true" ( :: Package the PDB debug info files produced alongside the install tree - :: into their own archive so they can be uploaded as a separate artifact. + :: into their own archive so they can be uploaded as a separate artifact, + :: then delete them from the install tree so the main archive command + :: below does not compress them a second time. set pdb_filename=%filename%-pdb pushd %filename% 7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si ..\!pdb_filename!.tar.xz + del /s /q bin\*.pdb lib\*.pdb popd ) +7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz exit /b 0 >From 9983d086f24b2f12f30f90aa03e13059811f1b3c Mon Sep 17 00:00:00 2001 From: marcpems <[email protected]> Date: Wed, 2 Sep 2026 11:28:07 +0100 Subject: [PATCH 3/4] Run PDB reconfigure/recompile concurrently with test suite and packaging LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every object file from the main build and previously forced a full serial recompile+relink after WiX/MSI packaging finished (~41 min observed). That recompile does not depend on the test suite or WiX packaging, so kick it off in a separate build directory right after the main build completes, and let it run concurrently with them in the background, hiding most/all of its wall-clock cost instead of paying for it serially at the end. Uses a dedicated minimized console (start /min) to avoid console handle contention with the foreground script's output, and delayed expansion (cmd /v:on + ^!errorlevel^!) to reliably capture ninja's real exit code from the background job. Validated on the self-hosted ARM64 runner: the concurrent PDB rebuild was fully hidden behind the ~78 min test-suite phase with zero added wall-clock cost, and no behavioral regressions were observed. --- llvm/utils/release/build_llvm_release.bat | 93 +++++++++++++++++++---- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat index 231dafc395ada..74c2df9293c5c 100644 --- a/llvm/utils/release/build_llvm_release.bat +++ b/llvm/utils/release/build_llvm_release.bat @@ -382,6 +382,54 @@ cmake -GNinja %cmake_flags% ^ -DPYTHON_HOME=%PYTHONHOME% ^ %cmake_profile_flags% %llvm_src%\llvm || exit /b 1 ninja || exit /b 1 + +:: generate tarball with install toolchain only off +if "%arch%"=="amd64" ( + set filename=clang+llvm-%version%-x86_64-pc-windows-msvc +) else ( + set filename=clang+llvm-%version%-aarch64-pc-windows-msvc +) +REM LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every +REM object file from the build above and forces a full recompile+relink. +REM That recompile does not depend on the test suite or WiX packaging +REM below, so kick it off now in a separate build directory and let it +REM run concurrently with them, hiding most/all of its wall-clock cost +REM instead of paying for it serially at the end. LLVM_ENABLE_PDB is +REM still never set for the MSI/WiX "ninja package" build below: +REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging +REM failures, so PDBs are packaged separately as their own tarball +REM instead. +if "%enable-pdb%" == "true" ( + cd .. + mkdir build_%arch%_pdb + cd build_%arch%_pdb + cmake -GNinja %cmake_flags% ^ + -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb;flang;mlir" ^ + -DLLVM_ENABLE_RUNTIMES="compiler-rt;openmp" ^ + %lto_cmake_flag% ^ + %common_lldb_flags% ^ + -DPYTHON_HOME=%PYTHONHOME% ^ + %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ + -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ + -DLLVM_ENABLE_PDB=ON ^ + %llvm_src%\llvm || exit /b 1 + del /q ..\pdb_build.done 2>nul + REM Use "start /min" (a genuinely separate, minimized console) rather + REM than "start /b" (which shares the parent's console/IO handles): + REM the background job's own console output can otherwise bleed into + REM and interleave with this foreground script's captured output + REM despite the ">" file redirection below, consistent with + REM console-handle contention between the two concurrently-running + REM processes. A dedicated console avoids sharing those handles at all. + REM "/v:on" + "^!errorlevel^!" (rather than "%%errorlevel%%") is + REM required so ninja's real exit code is captured. Without delayed + REM expansion, cmd.exe substitutes %errorlevel% once when the whole + REM "cmd1 & cmd2" line is parsed (before ninja even runs), so it would + REM always report the pre-existing errorlevel instead of ninja's + REM result. + start "pdb_build" /min cmd /v:on /c "ninja install > ..\pdb_build.log 2>&1 & echo ^!errorlevel^! > ..\pdb_build.done" < nul + cd ..\build_%arch% +) ninja check-llvm || exit /b 1 ninja check-clang || exit /b 1 ninja check-lld || exit /b 1 @@ -395,23 +443,14 @@ REM ninja check-mlir || exit /b 1 REM ninja check-lldb || exit /b 1 ninja package || exit /b 1 -:: generate tarball with install toolchain only off -if "%arch%"=="amd64" ( - set filename=clang+llvm-%version%-x86_64-pc-windows-msvc +if "%enable-pdb%" == "true" ( + call :wait_for_pdb_build || exit /b 1 ) else ( - set filename=clang+llvm-%version%-aarch64-pc-windows-msvc + cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ + -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ + %llvm_src%\llvm || exit /b 1 + ninja install || exit /b 1 ) -REM NOTE: LLVM_ENABLE_PDB is intentionally only set for this toolchain-only -REM (tarball) reconfigure, not for the MSI/WiX "ninja package" build above: -REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging -REM failures, so PDBs are packaged separately as their own tarball instead. -set pdb_cmake_flag= -if "%enable-pdb%" == "true" set pdb_cmake_flag=-DLLVM_ENABLE_PDB=ON -cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ - -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ - %pdb_cmake_flag% ^ - %llvm_src%\llvm || exit /b 1 -ninja install || exit /b 1 :: check llvm_config is present & returns something %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1 cd .. @@ -430,6 +469,30 @@ if "%enable-pdb%" == "true" ( exit /b 0 +::============================================================================== +:: Poll for the concurrent PDB build kicked off earlier in this function to +:: finish, and propagate its exit code. Must be a standalone function (not +:: an inline goto/label inside a parenthesized if-block) since cmd.exe does +:: not reliably support jumping to a label defined inside the same +:: "( ... )" block. +::============================================================================== +:wait_for_pdb_build +if not exist ..\pdb_build.done ( + ping -n 6 127.0.0.1 >nul + goto :wait_for_pdb_build +) +REM Use "for /f" rather than "set /p" to read the exit code: "for /f" +REM tokenizes on whitespace and strips it, whereas "set /p" would take any +REM trailing spaces/junk in the file literally, breaking the "== 0" check +REM below even when the underlying build actually succeeded. +set pdb_build_rc= +for /f %%r in (..\pdb_build.done) do set pdb_build_rc=%%r +if not "%pdb_build_rc%" == "0" ( + type ..\pdb_build.log + exit /b 1 +) +exit /b 0 + ::============================================================================== :: Set PATH and some environment variables. ::============================================================================== >From dfd643390cda6fce4f1495bdf26c701e9829d6d7 Mon Sep 17 00:00:00 2001 From: marcpems <[email protected]> Date: Fri, 4 Sep 2026 14:36:38 +0100 Subject: [PATCH 4/4] Fix Windows release artifact bloat: strip FatLTO bitcode from .lib and stop PDB build polluting main archive The CPack strip script only globbed lib/*.a, so Windows .lib archives kept their embedded FatLTO bitcode. Separately, --enable-pdb reused the same install prefix for both the PDB-enabled tree and the main archive, so the main tarball inherited debug-heavy .lib members too. Together these inflated Windows-ARM64-release-binary from ~1GB to ~6.8GB. Fix: also strip .lib in the CPack pre-build script, and give the PDB build its own -pdb-root install prefix with a clean, separate non-PDB install for the main archive. Validated on GB300: main artifact 6.80 GiB -> 1.75 GiB, PDB artifact correctly restored to 4.15 GiB. Co-authored-by: Copilot <[email protected]> --- .../release_cpack_pre_build_strip_lto.cmake | 4 ++- llvm/utils/release/build_llvm_release.bat | 33 +++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake b/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake index e7d8830515439..633a226fae9c7 100644 --- a/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake +++ b/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake @@ -1,4 +1,6 @@ -file(GLOB files ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.a) +file(GLOB files + ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.a + ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.lib) if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(strip_command diff --git a/llvm/utils/release/build_llvm_release.bat b/llvm/utils/release/build_llvm_release.bat index 74c2df9293c5c..9f65d46e52839 100644 --- a/llvm/utils/release/build_llvm_release.bat +++ b/llvm/utils/release/build_llvm_release.bat @@ -389,6 +389,8 @@ if "%arch%"=="amd64" ( ) else ( set filename=clang+llvm-%version%-aarch64-pc-windows-msvc ) +set main_install_dir=%build_dir%/%filename% +set pdb_install_dir=%build_dir%/%filename%-pdb-root REM LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every REM object file from the build above and forces a full recompile+relink. REM That recompile does not depend on the test suite or WiX packaging @@ -410,7 +412,7 @@ if "%enable-pdb%" == "true" ( %common_lldb_flags% ^ -DPYTHON_HOME=%PYTHONHOME% ^ %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ - -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ + -DCMAKE_INSTALL_PREFIX=%pdb_install_dir% ^ -DLLVM_ENABLE_PDB=ON ^ %llvm_src%\llvm || exit /b 1 del /q ..\pdb_build.done 2>nul @@ -445,24 +447,29 @@ ninja package || exit /b 1 if "%enable-pdb%" == "true" ( call :wait_for_pdb_build || exit /b 1 -) else ( - cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ - -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^ - %llvm_src%\llvm || exit /b 1 - ninja install || exit /b 1 ) +cmake -GNinja %cmake_flags% %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^ + -DCMAKE_INSTALL_PREFIX=%main_install_dir% ^ + %llvm_src%\llvm || exit /b 1 +ninja install || exit /b 1 :: check llvm_config is present & returns something -%build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1 +%main_install_dir%/bin/llvm-config.exe --bindir || exit /b 1 cd .. if "%enable-pdb%" == "true" ( - :: Package the PDB debug info files produced alongside the install tree - :: into their own archive so they can be uploaded as a separate artifact, - :: then delete them from the install tree so the main archive command - :: below does not compress them a second time. + :: Package PDBs from the separate PDB-enabled install tree so the main + :: archive can still come from the clean non-PDB install tree above. set pdb_filename=%filename%-pdb - pushd %filename% + REM Use a plain relative directory name here, not the absolute + REM %pdb_install_dir% path: on this runner "pushd" fails with + REM "The system cannot find the drive specified" when given an + REM absolute path that mixes backslash and forward-slash separators + REM (as %pdb_install_dir% does, since it's built with a "/" against + REM the backslash-based %build_dir%). cwd is already %build_dir% + REM (see "cd .." above), and %filename%-pdb-root is a direct child + REM of it, so the relative form below is equivalent and avoids the + REM issue entirely. + pushd %filename%-pdb-root 7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si ..\!pdb_filename!.tar.xz - del /s /q bin\*.pdb lib\*.pdb popd ) 7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
