diff options
| author | Kaydax <kaydax@kaydax.xyz> | 2026-10-31 05:40:40 -0400 |
|---|---|---|
| committer | kraibse <33869366+kraibse@users.noreply.github.com> | 2026-10-31 11:29:48 +0100 |
| commit | f6298e2eb67012cc9e93bc68b4894ee62e0b5f48 (patch) | |
| tree | 2a13ba717c21da34c7b8f56dd9f977d0fb9be874 /.github | |
| parent | b7575b0305dcd5d312a12cdb1c04bf163034a395 (diff) | |
Add PGO builds to workflows
Diffstat (limited to '.github')
| -rw-r--r-- | .github/workflows/release-binaries.yml | 207 |
1 files changed, 181 insertions, 26 deletions
diff --git a/.github/workflows/release-binaries.yml b/.github/workflows/release-binaries.yml index e3314cedb2..bc305a47b2 100644 --- a/.github/workflows/release-binaries.yml +++ b/.github/workflows/release-binaries.yml @@ -29,15 +29,25 @@ jobs: include: - platform: linux-x86_64 runner: ubuntu-24.04 + # The two -pgo builds are the same programs compiled by clang against Eden's periodically + # updated profile (https://github.com/Eden-CI/PGO). Windows uses MSYS2's MinGW clang like + # Eden does; MSVC cannot read an LLVM .profdata file. + - platform: linux-x86_64-pgo + runner: ubuntu-24.04 + pgo: true - platform: windows-x86_64 runner: windows-2022 + - platform: windows-x86_64-pgo + runner: windows-2022 + pgo: true + mingw: true steps: - name: Check out source uses: actions/checkout@v4 - name: Install Linux dependencies - if: matrix.platform == 'linux-x86_64' + if: startsWith(matrix.platform, 'linux') shell: bash run: | sudo apt-get update @@ -52,7 +62,7 @@ jobs: libopus-dev libasound2-dev - name: Install Qt on Linux - if: matrix.platform == 'linux-x86_64' + if: startsWith(matrix.platform, 'linux') uses: jurplel/install-qt-action@v4 with: version: '6.8.3' @@ -62,6 +72,32 @@ jobs: modules: qtcharts cache: true + # The profile is written by a current clang, so use the newest clang from the LLVM apt repo + # rather than Ubuntu's; an older reader rejects a newer profile. + - name: Install clang for PGO + if: startsWith(matrix.platform, 'linux') && matrix.pgo + shell: bash + run: | + set -euo pipefail + curl -fsSL https://apt.llvm.org/llvm-snapshot.gpg.key | + sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc > /dev/null + echo 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble main' | + sudo tee /etc/apt/sources.list.d/llvm.list > /dev/null + sudo apt-get update + sudo apt-get install -y --no-install-recommends clang lld + clang --version + + # Fetched into the source tree so both the Linux and MSYS2 configure steps can read it from a + # path their clang understands. + - name: Download PGO profile + if: matrix.pgo + shell: bash + run: | + set -euo pipefail + curl -fsSL -o eden.profdata \ + https://github.com/Eden-CI/PGO/releases/latest/download/eden.profdata + test -s eden.profdata + - name: Set up MSVC if: matrix.platform == 'windows-x86_64' uses: ilammy/msvc-dev-cmd@v1 @@ -87,6 +123,24 @@ jobs: shell: pwsh run: glslangValidator --version + # Eden builds its Windows PGO binaries with MSYS2's clang toolchain, so we do the same. The + # package list is docs/Deps.md (MSYS2) plus what the bundled FFmpeg needs to compile. + - name: Set up MSYS2 + if: matrix.mingw + uses: msys2/setup-msys2@v2 + with: + msystem: UCRT64 + update: true + install: >- + git make autoconf libtool automake-wrapper patch jq pactoys ninja + pacboy: >- + toolchain:p clang:p lld:p cmake:p python-pip:p + qt6-base:p qt6-charts:p qt6-tools:p qt6-translations:p qt6-svg:p + openssl:p boost:p fmt:p lz4:p nlohmann-json:p zlib:p zstd:p + vulkan-memory-allocator:p vulkan-devel:p glslang:p enet:p opus:p + libusb:p unordered_dense:p jbigkit:p xz:p libdeflate:p bzip2:p + lerc:p graphite2:p libwebp:p libtiff:p brotli:p + - name: Cache CPM downloads uses: actions/cache@v4 with: @@ -96,23 +150,38 @@ jobs: cpm-${{ runner.os }}- - name: Configure Linux - if: matrix.platform == 'linux-x86_64' + if: startsWith(matrix.platform, 'linux') shell: bash - run: >- - cmake -S . -B build/release -G Ninja - -DCMAKE_BUILD_TYPE=Release - -DBUILD_TESTING=OFF - -DYUZU_TESTS=OFF - -DYUZU_CMD=ON - -DYUZU_ROOM=OFF - -DYUZU_ROOM_STANDALONE=OFF - -DYUZU_USE_BUNDLED_QT=OFF - -DCMAKE_PREFIX_PATH="$QT_ROOT_DIR" - -DYUZU_USE_BUNDLED_SDL3=ON - -DVulkanHeaders_FORCE_BUNDLED=ON - -DVulkanUtilityLibraries_FORCE_BUNDLED=ON - -DENABLE_UPDATE_CHECKER=OFF - -DUSE_DISCORD_PRESENCE=OFF + run: | + set -euo pipefail + flags=( + -DCMAKE_BUILD_TYPE=Release + -DBUILD_TESTING=OFF + -DYUZU_TESTS=OFF + -DYUZU_CMD=ON + -DYUZU_ROOM=OFF + -DYUZU_ROOM_STANDALONE=OFF + -DYUZU_USE_BUNDLED_QT=OFF + "-DCMAKE_PREFIX_PATH=$QT_ROOT_DIR" + -DYUZU_USE_BUNDLED_SDL3=ON + -DVulkanHeaders_FORCE_BUNDLED=ON + -DVulkanUtilityLibraries_FORCE_BUNDLED=ON + -DENABLE_UPDATE_CHECKER=OFF + -DUSE_DISCORD_PRESENCE=OFF + ) + if [ '${{ matrix.pgo }}' = 'true' ]; then + # Same flags Eden's CI passes for its clang PGO build. + profile="-fprofile-use=$PWD/eden.profdata -Wno-backend-plugin \ + -Wno-profile-instr-unprofiled -Wno-profile-instr-out-of-date" + flags+=( + -DCMAKE_C_COMPILER=clang + -DCMAKE_CXX_COMPILER=clang++ + -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld + "-DCMAKE_C_FLAGS=$profile" + "-DCMAKE_CXX_FLAGS=$profile" + ) + fi + cmake -S . -B build/release -G Ninja "${flags[@]}" - name: Configure Windows if: matrix.platform == 'windows-x86_64' @@ -130,15 +199,49 @@ jobs: -DENABLE_UPDATE_CHECKER=OFF -DUSE_DISCORD_PRESENCE=OFF + # MinGW build: system Qt and libraries from MSYS2, clang plus Eden's PGO profile. The profile + # path is converted to its Windows form because clang runs with the MSYS mount underneath. + - name: Configure MinGW PGO + if: matrix.mingw + shell: msys2 {0} + run: | + set -euo pipefail + profile="-fprofile-use=$(cygpath -m "$PWD/eden.profdata") -Wno-backend-plugin \ + -Wno-profile-instr-unprofiled -Wno-profile-instr-out-of-date" + cmake -S . -B build/release -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_TESTING=OFF \ + -DYUZU_TESTS=OFF \ + -DYUZU_CMD=ON \ + -DYUZU_ROOM=OFF \ + -DYUZU_ROOM_STANDALONE=OFF \ + -DYUZU_USE_BUNDLED_QT=OFF \ + -DYUZU_USE_BUNDLED_SDL3=ON \ + -DVulkanHeaders_FORCE_BUNDLED=ON \ + -DVulkanUtilityLibraries_FORCE_BUNDLED=ON \ + -DENABLE_UPDATE_CHECKER=OFF \ + -DUSE_DISCORD_PRESENCE=OFF \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld \ + "-DCMAKE_C_FLAGS=$profile" \ + "-DCMAKE_CXX_FLAGS=$profile" + - name: Build + if: ${{ ! matrix.mingw }} shell: bash run: cmake --build build/release --target yuzu yuzu-cmd --parallel + - name: Build MinGW PGO + if: matrix.mingw + shell: msys2 {0} + run: cmake --build build/release --target yuzu yuzu-cmd --parallel + # A self-contained AppImage: linuxdeploy bundles every library the two programs need except # the base system ones (glibc, X11/Wayland client libraries, the GPU driver and Vulkan loader), # and its Qt plugin adds the Qt libraries and platform plugins. Runs on glibc 2.39+ systems. - name: Package Linux AppImage - if: matrix.platform == 'linux-x86_64' + if: startsWith(matrix.platform, 'linux') shell: bash run: | set -euo pipefail @@ -159,7 +262,7 @@ jobs: cp dist/Eglantine.png "$icon" export APPIMAGE_EXTRACT_AND_RUN=1 export QMAKE="$QT_ROOT_DIR/bin/qmake" - export LDAI_OUTPUT="eglantine-${GITHUB_SHA}-linux-x86_64.AppImage" + export LDAI_OUTPUT="eglantine-${GITHUB_SHA}-${{ matrix.platform }}.AppImage" export OUTPUT="$LDAI_OUTPUT" "$tools/linuxdeploy-x86_64.AppImage" --appdir AppDir \ --executable build/release/bin/eglantine \ @@ -182,6 +285,42 @@ jobs: } windeployqt --release --no-translations build/release/bin/eglantine.exe + # A dynamic MinGW build is not portable on its own: windeployqt6 brings the Qt libraries and + # plugins, then every non-system DLL the binaries and those plugins pull in gets copied next to + # them (docs/Caveats.md#msys2). + - name: Package MinGW binary + if: matrix.mingw + shell: msys2 {0} + run: | + set -euo pipefail + export PATH="/ucrt64/bin:$PATH" + cd build/release/bin + test -f eglantine.exe + test -f eden-cli.exe + windeployqt6 --no-translations --no-compiler-runtime --no-opengl-sw \ + --no-system-dxc-compiler --no-system-d3d-compiler eglantine.exe + deps() { + objdump -p "$1" | awk '/DLL Name:/ {print $3}' | while read -r dll; do + [ -z "$dll" ] && continue + source=$(command -v "$dll" 2>/dev/null || true) + [ -z "$source" ] && continue + # The system DLLs ship with Windows, so they never need bundling. + case "$source" in + *System32* | *SysWOW64*) continue ;; + esac + if [ ! -f "$dll" ]; then + cp "$source" "$dll" + deps "$source" + fi + done + } + for exe in eglantine.exe eden-cli.exe; do + deps "$exe" + done + find . -name '*.dll' | while read -r dll; do + deps "$dll" + done + # The artifact is the bin folder itself: GitHub zips artifacts on download, and uploading a # zip gave a zip inside a zip. The release job zips it once for the release. - name: Upload Windows binary @@ -193,8 +332,17 @@ jobs: if-no-files-found: error retention-days: 7 + - name: Upload MinGW binary + if: matrix.mingw + uses: actions/upload-artifact@v4 + with: + name: eglantine-${{ matrix.platform }}-${{ github.sha }} + path: build/release/bin/ + if-no-files-found: error + retention-days: 7 + - name: Upload Linux binary - if: matrix.platform == 'linux-x86_64' + if: startsWith(matrix.platform, 'linux') uses: actions/upload-artifact@v4 with: name: eglantine-${{ matrix.platform }}-${{ github.sha }} @@ -203,7 +351,7 @@ jobs: compression-level: 0 retention-days: 7 - # Publishes both binaries as a GitHub pre-release once every platform built: on pushes to nx2 + # Publishes every binary as a GitHub pre-release once every platform built: on pushes to nx2 # and nx2-experimental, and on manual runs unless "Publish the binaries as a GitHub release" is # unticked. release: @@ -223,10 +371,16 @@ jobs: - name: Package release files shell: bash run: | + set -euo pipefail mkdir dist - (cd "artifacts/eglantine-windows-x86_64-${GITHUB_SHA}" && - zip -qr "${GITHUB_WORKSPACE}/dist/eglantine-${GITHUB_SHA}-windows-x86_64.zip" .) - cp "artifacts/eglantine-linux-x86_64-${GITHUB_SHA}/eglantine-${GITHUB_SHA}-linux-x86_64.AppImage" dist/ + for artifact in artifacts/*/; do + name=$(basename "$artifact") + if compgen -G "$artifact*.AppImage" > /dev/null; then + cp "$artifact"/*.AppImage dist/ + else + (cd "$artifact" && zip -qr "${GITHUB_WORKSPACE}/dist/${name}.zip" .) + fi + done - name: Create release shell: bash @@ -242,4 +396,5 @@ jobs: --notes "Automatic build of ${GITHUB_REF_NAME} at ${GITHUB_SHA}. Windows: extract the zip and run eglantine.exe, or eden-cli.exe from a terminal. - Linux: make the AppImage executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch)." + Linux: make the AppImage executable (chmod +x) and run it; it bundles its libraries and needs glibc 2.39 or newer (Ubuntu 24.04, Fedora 40, Debian 13, Arch). + The -pgo builds are the same programs compiled with profile-guided optimization (clang plus Eden's profile); prefer them when your CPU supports it. The Windows PGO build is a MinGW build, so it carries its own DLLs and needs no Visual C++ redistributable." |
