Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions .github/workflows/release-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,38 @@ jobs:
cp target/release-max/gb-desktop "${package_dir}/"
cp README.md LICENSE-MIT LICENSE-APACHE "${package_dir}/"

sdl_libs=(target/release-max/libSDL3*.so*)
if ((${#sdl_libs[@]} == 0)); then
echo "expected SDL3 shared libraries under target/release-max" >&2
exit 1
sdl_libs=()
sdl_lib_names=()
while IFS= read -r sdl_lib; do
sdl_name="$(basename "${sdl_lib}")"
sdl_seen=false
for existing_name in "${sdl_lib_names[@]}"; do
if [[ "${existing_name}" == "${sdl_name}" ]]; then
sdl_seen=true
break
fi
done
if [[ "${sdl_seen}" == false ]]; then
sdl_lib_names+=("${sdl_name}")
sdl_libs+=("${sdl_lib}")
fi
done < <(
find target/release-max \( -type f -o -type l \) -name 'libSDL3*.so*' -print |
sort -u
)
if ((${#sdl_libs[@]} > 0)); then
cp "${sdl_libs[@]}" "${package_dir}/"
patchelf --set-rpath '$ORIGIN' "${package_dir}/gb-desktop"
else
ldd_output="$(ldd "${package_dir}/gb-desktop" 2>&1 || true)"
if grep -q 'libSDL3' <<<"${ldd_output}"; then
printf '%s\n' "${ldd_output}"
echo "gb-desktop dynamically links SDL3 but no bundled libSDL3 shared object was emitted" >&2
exit 1
fi
fi
Comment thread
pakitovic marked this conversation as resolved.
cp "${sdl_libs[@]}" "${package_dir}/"

chmod +x "${package_dir}/gb-desktop"
patchelf --set-rpath '$ORIGIN' "${package_dir}/gb-desktop"
"${package_dir}/gb-desktop" --help

tar -C dist -czf "${tar_path}" "${package_name}"
Expand Down
56 changes: 38 additions & 18 deletions .github/workflows/release-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,26 +48,46 @@ jobs:
printf 'APPL????' > "${app_root}/Contents/PkgInfo"
cp README.md LICENSE-MIT LICENSE-APACHE "${package_dir}/"

sdl_libs=(target/release-max/libSDL3*.dylib)
if ((${#sdl_libs[@]} == 0)); then
echo "expected SDL3 dylibs under target/release-max" >&2
sdl_libs=()
sdl_lib_names=()
while IFS= read -r sdl_lib; do
sdl_name="$(basename "${sdl_lib}")"
sdl_seen=false
for existing_name in "${sdl_lib_names[@]}"; do
if [[ "${existing_name}" == "${sdl_name}" ]]; then
sdl_seen=true
break
fi
done
if [[ "${sdl_seen}" == false ]]; then
sdl_lib_names+=("${sdl_name}")
sdl_libs+=("${sdl_lib}")
fi
done < <(
find target/release-max \( -type f -o -type l \) -name 'libSDL3*.dylib' -print |
sort -u
)
if ((${#sdl_libs[@]} > 0)); then
Comment thread
pakitovic marked this conversation as resolved.
for dylib in "${sdl_libs[@]}"; do
dylib_name="$(basename "${dylib}")"
cp "${dylib}" "${macos_dir}/${dylib_name}"
chmod +w "${macos_dir}/${dylib_name}"
install_name_tool -id "@executable_path/${dylib_name}" "${macos_dir}/${dylib_name}"
done

bundled_sdl="$(basename "${sdl_libs[0]}")"
while IFS= read -r dependency; do
case "${dependency}" in
*libSDL3*.dylib*)
install_name_tool -change "${dependency}" "@executable_path/${bundled_sdl}" "${macos_dir}/gb-desktop"
;;
esac
done < <(otool -L "${macos_dir}/gb-desktop" | tail -n +2 | awk '{print $1}')
elif otool -L "${macos_dir}/gb-desktop" | grep -q 'libSDL3'; then
otool -L "${macos_dir}/gb-desktop"
echo "gb-desktop dynamically links SDL3 but no bundled libSDL3 dylib was emitted" >&2
exit 1
fi
for dylib in "${sdl_libs[@]}"; do
dylib_name="$(basename "${dylib}")"
cp "${dylib}" "${macos_dir}/${dylib_name}"
chmod +w "${macos_dir}/${dylib_name}"
install_name_tool -id "@executable_path/${dylib_name}" "${macos_dir}/${dylib_name}"
done

bundled_sdl="$(basename "${sdl_libs[0]}")"
while IFS= read -r dependency; do
case "${dependency}" in
*libSDL3*.dylib*)
install_name_tool -change "${dependency}" "@executable_path/${bundled_sdl}" "${macos_dir}/gb-desktop"
;;
esac
done < <(otool -L "${macos_dir}/gb-desktop" | tail -n +2 | awk '{print $1}')

chmod +x "${macos_dir}/gb-desktop"
codesign --force --deep --sign - "${app_root}"
Expand Down
15 changes: 9 additions & 6 deletions .github/workflows/release-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ jobs:
- name: Build desktop release
run: cargo build --profile release-max -p gb-desktop --features gb-desktop/sdl3-build-from-source

- name: Smoke test desktop CLI
run: target\release-max\gb-desktop.exe --help

- name: Package Windows binary
shell: pwsh
run: |
Expand All @@ -42,9 +39,15 @@ jobs:
Copy-Item -Path "target\release-max\gb-desktop.exe" -Destination $packageDir -Force
Copy-Item -Path "README.md", "LICENSE-MIT", "LICENSE-APACHE" -Destination $packageDir -Force

Get-ChildItem -Path "target\release-max" -Recurse -Filter "*.dll" -File |
Sort-Object -Property FullName -Unique |
Copy-Item -Destination $packageDir -Force
$packageDlls = @(
Get-ChildItem -Path "target\release-max" -Recurse -Filter "*.dll" -File |
Sort-Object -Property FullName -Unique
)
if ($packageDlls.Count -gt 0) {
$packageDlls | Copy-Item -Destination $packageDir -Force
}

& (Join-Path $packageDir "gb-desktop.exe") --help

Compress-Archive -Path (Join-Path $packageDir "*") -DestinationPath $zipPath -Force

Expand Down
8 changes: 4 additions & 4 deletions docs/frontends/DESKTOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ cargo run --profile release-max -p gb-desktop -- [path/to/rom.gb]

## Release packages

The GitHub release workflows package only the SDL3 desktop frontend. They all build `gb-desktop` with `cargo build --profile release-max -p gb-desktop --features gb-desktop/sdl3-build-from-source`, then run `gb-desktop --help` from the packaged runtime layout so the artifact proves that the executable can find its bundled SDL3 runtime before upload.
The GitHub release workflows package only the SDL3 desktop frontend. They all build `gb-desktop` with `cargo build --profile release-max -p gb-desktop --features gb-desktop/sdl3-build-from-source`, then run `gb-desktop --help` from the packaged runtime layout so the artifact proves that the executable can start with whatever SDL3 runtime form the source-build path emitted before upload.

The workflows live under `.github/workflows/`:

- `release-windows.yml` creates `gb-cycle-windows-x86_64.zip` on `windows-latest`, containing `gb-desktop.exe`, `README.md`, both license files, and every SDL3 `.dll` copied by the source-build path under `target/release-max`.
- `release-linux.yml` creates `gb-cycle-linux-x86_64.tar.gz` on `ubuntu-latest`, containing `gb-desktop`, `README.md`, both license files, and `libSDL3*.so*` from `target/release-max`; the binary is patched with an `$ORIGIN` rpath so it loads the bundled SDL3 shared object from the unpacked artifact directory without requiring `LD_LIBRARY_PATH`.
- `release-macos.yml` creates only the Apple Silicon `gb-cycle-macos-aarch64.zip` package on `macos-latest`, containing `GB Cycle.app`, `README.md`, both license files, and `libSDL3*.dylib` inside `Contents/MacOS`; the dylib install names are rewritten to `@executable_path`, the app is ad-hoc signed after that rewrite, and the bundle reuses `crates/gb-desktop/macos/Info.plist` so the release artifact carries the same Pocket Camera usage string as the local macOS launcher.
- `release-windows.yml` creates `gb-cycle-windows-x86_64.zip` on `windows-latest`, containing `gb-desktop.exe`, `README.md`, both license files, and every `.dll` emitted recursively by the source-build path under `target/release-max`.
- `release-linux.yml` creates `gb-cycle-linux-x86_64.tar.gz` on `ubuntu-latest`, containing `gb-desktop`, `README.md`, both license files, and any `libSDL3*.so*` found recursively under `target/release-max` and deduplicated by library filename; when a shared object is present, the binary is patched with an `$ORIGIN` rpath so it loads the bundled SDL3 shared object from the unpacked artifact directory without requiring `LD_LIBRARY_PATH`, and when no shared object is present the workflow fails if `ldd` still reports an SDL3 dynamic dependency.
- `release-macos.yml` creates only the Apple Silicon `gb-cycle-macos-aarch64.zip` package on `macos-latest`, containing `GB Cycle.app`, `README.md`, both license files, and any `libSDL3*.dylib` found recursively under `target/release-max` and deduplicated by library filename inside `Contents/MacOS`; when a dylib is present, the dylib install names are rewritten to `@executable_path` before ad-hoc signing, when no dylib is present the workflow fails if `otool -L` still reports an SDL3 dynamic dependency, and the bundle reuses `crates/gb-desktop/macos/Info.plist` so the release artifact carries the same Pocket Camera usage string as the local macOS launcher.

Manual `workflow_dispatch` runs are for artifact validation and upload the package through `actions/upload-artifact`. Tag pushes matching `v*` additionally attach the same package to the GitHub Release via `softprops/action-gh-release`; do not use a non-release branch tag unless you intentionally want to test the release-asset path and then clean up the temporary release/tag afterward.

Expand Down