1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
name: release-binaries
# Builds the Linux x86_64 PGO AppImage and publishes it as a GitHub pre-release.
on:
workflow_dispatch:
inputs:
publish_release:
description: Publish the AppImage as a GitHub release
type: boolean
default: true
push:
branches:
- nx2
# A binary only changes when build inputs change; docs-only pushes skip the build.
paths:
- "src/**"
- "CMakeLists.txt"
- "CMakeModules/**"
- "externals/**"
- "dist/**"
- "tools/**"
- ".patch/**"
- "cpmfile.json"
- ".github/workflows/release-binaries.yml"
permissions:
contents: read
# Clang major the PGO build uses, from apt.llvm.org. Eden's profile is written by a current clang
# and an older reader refuses it, so this has to stay at or above whatever produced eden.profdata;
# bump it when a refreshed profile needs a newer LLVM.
env:
PGO_LLVM_VERSION: '23'
PLATFORM: linux-x86_64-pgo
# A running build is never cancelled: it finishes and publishes. A push meanwhile queues one build;
# a later push replaces it, so the newest commit builds as soon as the running one is done.
concurrency:
group: release-binaries-${{ github.ref }}
cancel-in-progress: false
jobs:
build:
name: Linux x86_64 PGO AppImage
runs-on: ubuntu-24.04
env:
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 3000M
steps:
- name: Check out source
uses: actions/checkout@v5
- name: Install dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
autoconf cmake g++ gcc git glslang-tools libglu1-mesa-dev \
libpulse-dev libtool libudev-dev libxkbcommon-x11-0 \
mesa-common-dev nasm ninja-build qt6-base-private-dev \
qt6-charts-dev qt6-tools-dev libavfilter-dev libavcodec-dev \
libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev \
spirv-tools spirv-headers libusb-1.0-0-dev \
libboost-dev libboost-fiber-dev libboost-context-dev \
libopus-dev libasound2-dev ccache \
libxcb-cursor0 libxcb-icccm4 libxcb-image0 \
libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-shape0 libxcb-xinerama0 libxcb-xkb1
- name: Install Qt
uses: jurplel/install-qt-action@v4
with:
version: '6.8.3'
host: linux
target: desktop
arch: linux_gcc_64
modules: qtcharts
cache: true
# Ubuntu's own clang 18 cannot read a profile from a current LLVM, so take clang from the LLVM
# apt repo. The versioned packages are named explicitly: that repo's unversioned clang/lld
# metapackages can lag the binaries they depend on and then resolve to nothing. lld-23 only
# ships ld.lld under /usr/lib/llvm-23/bin, so -B points the linker search there.
- name: Install clang for 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-$PGO_LLVM_VERSION 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-$PGO_LLVM_VERSION" "lld-$PGO_LLVM_VERSION"
"clang-$PGO_LLVM_VERSION" --version
# Eden's periodically updated profile: https://github.com/Eden-CI/PGO
- name: Download PGO profile
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: Cache CPM downloads
uses: actions/cache@v5
with:
path: .cache/cpm
key: cpm-${{ runner.os }}-${{ hashFiles('cpmfile.json', 'CMakeLists.txt', 'src/**/CMakeLists.txt') }}
restore-keys: |
cpm-${{ runner.os }}-
# The sha in the key makes every run save a fresh cache (actions/cache never saves over an
# exact hit), and restore-keys seeds it from the newest one.
- name: Cache compiler objects
uses: actions/cache@v5
with:
path: .ccache
key: objects-${{ env.PLATFORM }}-${{ github.sha }}
restore-keys: |
objects-${{ env.PLATFORM }}-
# Same flags Eden's CI passes for its clang PGO build.
- name: Configure
shell: bash
run: |
set -euo pipefail
profile="-fprofile-use=$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 \
"-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 \
-DUSE_CCACHE=ON \
"-DCMAKE_C_COMPILER=clang-$PGO_LLVM_VERSION" \
"-DCMAKE_CXX_COMPILER=clang++-$PGO_LLVM_VERSION" \
"-DCMAKE_EXE_LINKER_FLAGS=-B/usr/lib/llvm-$PGO_LLVM_VERSION/bin -fuse-ld=lld" \
"-DCMAKE_C_FLAGS=$profile" \
"-DCMAKE_CXX_FLAGS=$profile"
- name: Build
shell: bash
run: |
cmake --build build/release --target yuzu yuzu-cmd --parallel
ccache --show-stats
# 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 AppImage
shell: bash
run: |
set -euo pipefail
test -x build/release/bin/eglantine
test -x build/release/bin/eden-cli
strip build/release/bin/eglantine build/release/bin/eden-cli
tools="$RUNNER_TEMP/linuxdeploy"
mkdir -p "$tools"
curl -fsSL -o "$tools/linuxdeploy-x86_64.AppImage" \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
curl -fsSL -o "$tools/linuxdeploy-plugin-qt-x86_64.AppImage" \
https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x "$tools"/*.AppImage
# The desktop file names its icon dev.eglantine.eglantine.
icon="$RUNNER_TEMP/dev.eglantine.eglantine.png"
cp dist/Eglantine.png "$icon"
export APPIMAGE_EXTRACT_AND_RUN=1
export QMAKE="$QT_ROOT_DIR/bin/qmake"
export LDAI_OUTPUT="eglantine-${GITHUB_SHA}-${PLATFORM}.AppImage"
export OUTPUT="$LDAI_OUTPUT"
export ARCH=x86_64
"$tools/linuxdeploy-x86_64.AppImage" --appdir AppDir \
--executable build/release/bin/eglantine \
--executable build/release/bin/eden-cli \
--desktop-file dist/dev.eden_emu.eden.desktop \
--icon-file "$icon" \
--plugin qt \
--output appimage
test -s "$LDAI_OUTPUT"
sha256sum "$LDAI_OUTPUT" | tee "$LDAI_OUTPUT.sha256"
- name: Upload AppImage
uses: actions/upload-artifact@v7
with:
name: eglantine-${{ env.PLATFORM }}-${{ github.sha }}
path: |
eglantine-${{ github.sha }}-${{ env.PLATFORM }}.AppImage
eglantine-${{ github.sha }}-${{ env.PLATFORM }}.AppImage.sha256
if-no-files-found: error
compression-level: 0
retention-days: 7
# Publishes the AppImage as a GitHub pre-release: on pushes to nx2, and on manual runs unless
# "Publish the AppImage as a GitHub release" is unticked.
release:
name: Publish release
needs: build
if: github.event_name == 'push' || inputs.publish_release
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- name: Download AppImage
uses: actions/download-artifact@v7
with:
name: eglantine-${{ env.PLATFORM }}-${{ github.sha }}
path: dist
- name: Create release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
ls -la dist
gh release create "build-${GITHUB_RUN_NUMBER}" dist/* \
--repo "${GITHUB_REPOSITORY}" \
--target "${GITHUB_SHA}" \
--prerelease \
--title "Eglantine ${GITHUB_REF_NAME} build ${GITHUB_RUN_NUMBER} (${GITHUB_SHA::7})" \
--notes "Automatic Linux x86_64 PGO build of ${GITHUB_REF_NAME} at ${GITHUB_SHA}.
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).
It is compiled with profile-guided optimization (clang plus Eden's profile). The .sha256 file holds its checksum."
|