mirror of
https://github.com/xenios-jp/XeniOS.git
synced 2026-07-11 15:19:09 -07:00
356 lines
14 KiB
YAML
356 lines
14 KiB
YAML
name: Build (reusable)
|
|
|
|
# Callable from CI.yml. Permissions are set by the caller so one set of build
|
|
# logic can run either with write access to the sccache cache (from the trusted
|
|
# edge branch) or read-only (from feature branches and PRs, where sccache
|
|
# self-demotes to read-only on its startup write probe).
|
|
on:
|
|
workflow_call:
|
|
|
|
jobs:
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@main
|
|
- name: Setup
|
|
run: |
|
|
pipx install clang-format==21.1.8
|
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
|
- name: Lint
|
|
run: ./xenia-build.py lint --all
|
|
|
|
build-linux:
|
|
name: Build Linux
|
|
needs: lint
|
|
runs-on: ubuntu-24.04
|
|
steps:
|
|
- uses: actions/checkout@main
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Cache linuxdeploy tools
|
|
id: cache-linuxdeploy
|
|
uses: actions/cache@v3
|
|
with:
|
|
path: ~/linuxdeploy
|
|
key: ${{ runner.os }}-linuxdeploy-tools
|
|
restore-keys: |
|
|
${{ runner.os }}-linuxdeploy-
|
|
|
|
- name: Setup
|
|
run: |
|
|
UBUNTU_BASE=$(lsb_release -cs)
|
|
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
|
|
sudo apt-add-repository "deb http://apt.llvm.org/${UBUNTU_BASE}/ llvm-toolchain-${UBUNTU_BASE}-21 main"
|
|
|
|
sudo apt-get -y update
|
|
sudo apt-get -y install libc++-dev libc++abi-dev libgtk-3-dev libx11-xcb-dev clang-21 lld-21 ninja-build cmake libfontconfig1-dev libxtst-dev \
|
|
libasound2-dev libpulse-dev libudev-dev libdbus-1-dev \
|
|
libx11-dev libxext-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxss-dev libxkbcommon-dev libxfixes-dev
|
|
|
|
# Download linuxdeploy if not cached.
|
|
if [ '${{ steps.cache-linuxdeploy.outputs.cache-hit }}' != 'true' ]; then
|
|
mkdir -p ~/linuxdeploy
|
|
wget -q https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage -O ~/linuxdeploy/linuxdeploy
|
|
wget -q https://github.com/linuxdeploy/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-x86_64.AppImage -O ~/linuxdeploy/linuxdeploy-plugin-appimage
|
|
chmod +x ~/linuxdeploy/linuxdeploy ~/linuxdeploy/linuxdeploy-plugin-appimage
|
|
fi
|
|
echo "$HOME/linuxdeploy" >> $GITHUB_PATH
|
|
|
|
# Update submodules
|
|
git submodule update --init --depth=1 -j$(getconf _NPROCESSORS_ONLN) $(grep -oP '(?<=path = )(?!third_party\/DirectXShaderCompiler).+' .gitmodules)
|
|
|
|
# Fetch data repos (game-patches)
|
|
./xenia-build.py fetchdata
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@main
|
|
- name: Build
|
|
env:
|
|
CC: clang-21
|
|
CXX: clang++-21
|
|
SCCACHE_GHA_ENABLED: "true"
|
|
CMAKE_C_COMPILER_LAUNCHER: sccache
|
|
CMAKE_CXX_COMPILER_LAUNCHER: sccache
|
|
run: ./xenia-build.py build --config=Release
|
|
- name: sccache stats
|
|
if: always()
|
|
run: sccache --show-stats
|
|
- name: Prepare artifacts
|
|
id: prepare_artifacts
|
|
run: |
|
|
binary=build/bin/Linux/Release/xenia_edge
|
|
if [ $(stat -c%s $binary) -le 100000 ]; then
|
|
echo "::error::Binary is too small."
|
|
fi
|
|
chmod +x $binary
|
|
mkdir -p artifacts/xenia_edge
|
|
|
|
# Install icons with proper naming for linuxdeploy
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/16x16/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/32x32/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/48x48/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/64x64/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/128x128/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/256x256/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/512x512/apps
|
|
mkdir -p artifacts/xenia_edge/usr/share/icons/hicolor/1024x1024/apps
|
|
|
|
cp assets/icon/16.png artifacts/xenia_edge/usr/share/icons/hicolor/16x16/apps/xenia_edge.png
|
|
cp assets/icon/32.png artifacts/xenia_edge/usr/share/icons/hicolor/32x32/apps/xenia_edge.png
|
|
cp assets/icon/48.png artifacts/xenia_edge/usr/share/icons/hicolor/48x48/apps/xenia_edge.png
|
|
cp assets/icon/64.png artifacts/xenia_edge/usr/share/icons/hicolor/64x64/apps/xenia_edge.png
|
|
cp assets/icon/128.png artifacts/xenia_edge/usr/share/icons/hicolor/128x128/apps/xenia_edge.png
|
|
cp assets/icon/256.png artifacts/xenia_edge/usr/share/icons/hicolor/256x256/apps/xenia_edge.png
|
|
cp assets/icon/512.png artifacts/xenia_edge/usr/share/icons/hicolor/512x512/apps/xenia_edge.png
|
|
cp assets/icon/1024.png artifacts/xenia_edge/usr/share/icons/hicolor/1024x1024/apps/xenia_edge.png
|
|
|
|
mkdir -p artifacts/xenia_edge/usr/bin
|
|
|
|
~/linuxdeploy/linuxdeploy --appdir artifacts/xenia_edge \
|
|
--executable $binary \
|
|
--desktop-file assets/xenia_edge.desktop \
|
|
--icon-file assets/icon/256.png \
|
|
--output appimage
|
|
|
|
# linuxdeploy creates the AppImage in the current directory
|
|
# Find and rename it to a standard name
|
|
appimage_file=$(ls -1 *.AppImage | head -n1)
|
|
if [ -z "$appimage_file" ]; then
|
|
echo "::error::AppImage file not found after linuxdeploy"
|
|
exit 1
|
|
fi
|
|
|
|
# Create final artifacts directory and move the AppImage there
|
|
mkdir -p artifacts/release
|
|
mv "$appimage_file" artifacts/release/xenia_edge.AppImage
|
|
chmod +x artifacts/release/xenia_edge.AppImage
|
|
|
|
# Also copy LICENSE
|
|
cp LICENSE artifacts/release/
|
|
- name: Upload xenia edge artifacts
|
|
if: steps.prepare_artifacts.outcome == 'success'
|
|
uses: actions/upload-artifact@main
|
|
with:
|
|
name: xenia_edge_linux
|
|
path: artifacts/release
|
|
if-no-files-found: error
|
|
|
|
build-macos-arm64:
|
|
name: Build macOS ARM64
|
|
needs: lint
|
|
runs-on: macos-26
|
|
steps:
|
|
- uses: actions/checkout@main
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup
|
|
run: |
|
|
# Update submodules. Skip DirectXShaderCompiler (we don't use the
|
|
# Metal shader converter / dxilconv pipeline on edge).
|
|
git submodule update --init --depth=1 -j$(sysctl -n hw.ncpu) \
|
|
$(grep -oE 'path = .+' .gitmodules | sed 's/path = //' \
|
|
| grep -v 'DirectXShaderCompiler')
|
|
|
|
# wxWidgets has nested submodules (pcre, libpng, ...) needed when
|
|
# building from vendored source.
|
|
git submodule update --init --recursive --depth=1 \
|
|
-j$(sysctl -n hw.ncpu) third_party/wxWidgets
|
|
|
|
# Fetch data repos (game-patches)
|
|
./xenia-build.py fetchdata
|
|
|
|
- name: Install Metal Toolchain
|
|
# Apple's MobileAsset catalog fetch is flaky; retry with backoff.
|
|
run: |
|
|
for attempt in 1 2 3 4 5; do
|
|
if sudo xcodebuild -downloadComponent MetalToolchain; then
|
|
exit 0
|
|
fi
|
|
if [ $attempt -lt 5 ]; then
|
|
delay=$((attempt * 30))
|
|
echo "::warning::MetalToolchain download attempt $attempt failed; retrying in ${delay}s"
|
|
sleep $delay
|
|
fi
|
|
done
|
|
echo "::error::MetalToolchain download failed after 5 attempts"
|
|
exit 1
|
|
|
|
- name: Build
|
|
run: ./xenia-build.py build --config=Release --target=xenia-app
|
|
|
|
- name: Prepare artifacts
|
|
id: prepare_artifacts
|
|
run: |
|
|
app_bundle="build/bin/macOS/Release/Xenia-edge.app"
|
|
if [ ! -d "$app_bundle" ]; then
|
|
echo "::error::App bundle not found at $app_bundle"
|
|
ls -la build/bin/macOS/Release/ 2>&1 || true
|
|
exit 1
|
|
fi
|
|
main_exe="$app_bundle/Contents/MacOS/Xenia-edge"
|
|
if [ "$(stat -f%z "$main_exe")" -le 100000 ]; then
|
|
echo "::error::$main_exe is too small."
|
|
exit 1
|
|
fi
|
|
# Confirm we actually produced an arm64 binary (not x86_64).
|
|
if ! file "$main_exe" | grep -q "arm64"; then
|
|
echo "::error::$main_exe is not arm64:"
|
|
file "$main_exe"
|
|
exit 1
|
|
fi
|
|
|
|
# Tar the bundle so upload-artifact preserves the executable bit and
|
|
# any symlinks; the universal-merge job untars and lipos.
|
|
mkdir -p artifacts
|
|
tar -cf artifacts/Xenia-edge.app.tar -C "$(dirname "$app_bundle")" "$(basename "$app_bundle")"
|
|
|
|
- name: Upload xenia edge macOS arm64 app bundle
|
|
if: steps.prepare_artifacts.outcome == 'success'
|
|
uses: actions/upload-artifact@main
|
|
with:
|
|
name: xenia_edge_macos_arm64_app
|
|
path: artifacts/Xenia-edge.app.tar
|
|
if-no-files-found: error
|
|
|
|
build-macos-x86_64:
|
|
name: Build macOS x86_64 (cross from arm64)
|
|
needs: lint
|
|
# Cross-compiled on the arm64 runner — Apple's Intel runners are much
|
|
# slower, and Apple clang is universal so -arch x86_64 produces a native
|
|
# x86_64 binary either way.
|
|
runs-on: macos-26
|
|
steps:
|
|
- uses: actions/checkout@main
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup
|
|
run: |
|
|
git submodule update --init --depth=1 -j$(sysctl -n hw.ncpu) \
|
|
$(grep -oE 'path = .+' .gitmodules | sed 's/path = //' \
|
|
| grep -v 'DirectXShaderCompiler')
|
|
git submodule update --init --recursive --depth=1 \
|
|
-j$(sysctl -n hw.ncpu) third_party/wxWidgets
|
|
./xenia-build.py fetchdata
|
|
|
|
- name: Install Metal Toolchain
|
|
# Apple's MobileAsset catalog fetch is flaky; retry with backoff.
|
|
run: |
|
|
for attempt in 1 2 3 4 5; do
|
|
if sudo xcodebuild -downloadComponent MetalToolchain; then
|
|
exit 0
|
|
fi
|
|
if [ $attempt -lt 5 ]; then
|
|
delay=$((attempt * 30))
|
|
echo "::warning::MetalToolchain download attempt $attempt failed; retrying in ${delay}s"
|
|
sleep $delay
|
|
fi
|
|
done
|
|
echo "::error::MetalToolchain download failed after 5 attempts"
|
|
exit 1
|
|
|
|
- name: Build
|
|
run: ./xenia-build.py build --config=Release --target=xenia-app --target-arch=x64
|
|
|
|
- name: Prepare artifacts
|
|
id: prepare_artifacts
|
|
run: |
|
|
app_bundle="build-x64/bin/macOS/Release/Xenia-edge.app"
|
|
if [ ! -d "$app_bundle" ]; then
|
|
echo "::error::App bundle not found at $app_bundle"
|
|
ls -la build-x64/bin/macOS/Release/ 2>&1 || true
|
|
exit 1
|
|
fi
|
|
main_exe="$app_bundle/Contents/MacOS/Xenia-edge"
|
|
if [ "$(stat -f%z "$main_exe")" -le 100000 ]; then
|
|
echo "::error::$main_exe is too small."
|
|
exit 1
|
|
fi
|
|
# Confirm we actually produced an x86_64 binary (not arm64).
|
|
if ! file "$main_exe" | grep -q "x86_64"; then
|
|
echo "::error::$main_exe is not x86_64:"
|
|
file "$main_exe"
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p artifacts
|
|
tar -cf artifacts/Xenia-edge.app.tar -C "$(dirname "$app_bundle")" "$(basename "$app_bundle")"
|
|
|
|
- name: Upload xenia edge macOS x86_64 app bundle
|
|
if: steps.prepare_artifacts.outcome == 'success'
|
|
uses: actions/upload-artifact@main
|
|
with:
|
|
name: xenia_edge_macos_x86_64_app
|
|
path: artifacts/Xenia-edge.app.tar
|
|
if-no-files-found: error
|
|
|
|
build-windows:
|
|
name: Build Windows
|
|
needs: lint
|
|
runs-on: windows-2025
|
|
env:
|
|
POWERSHELL_TELEMETRY_OPTOUT: 1
|
|
steps:
|
|
- uses: actions/checkout@main
|
|
with:
|
|
fetch-depth: 0
|
|
submodules: false
|
|
|
|
- name: Disable Defender scanning for build paths
|
|
run: |
|
|
Add-MpPreference -ExclusionPath "$env:GITHUB_WORKSPACE"
|
|
Add-MpPreference -ExclusionPath "$env:RUNNER_TEMP"
|
|
shell: pwsh
|
|
|
|
- name: Setup
|
|
run: |
|
|
# Verify FXC is available (from Windows SDK)
|
|
$fxcPaths = Get-ChildItem -Path "${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64\fxc.exe" -ErrorAction SilentlyContinue | Sort-Object FullName
|
|
if ($fxcPaths) {
|
|
$fxcPath = $fxcPaths[-1].FullName
|
|
echo "FXC found at: $fxcPath"
|
|
} else {
|
|
echo "Warning: fxc.exe not found in Windows SDK"
|
|
}
|
|
|
|
git submodule update --init --depth=1 -j $env:NUMBER_OF_PROCESSORS (Select-String -CaseSensitive '(?<=path = ).+' .gitmodules).Matches.Value
|
|
# wxWidgets needs its own nested submodules (pcre, libpng, ...) when
|
|
# building from source on Windows.
|
|
git submodule update --init --recursive --depth=1 -j $env:NUMBER_OF_PROCESSORS third_party/wxWidgets
|
|
|
|
# Fetch data repos (game-patches)
|
|
python xenia-build.py fetchdata
|
|
|
|
- name: Setup sccache
|
|
uses: mozilla-actions/sccache-action@main
|
|
- name: Build
|
|
env:
|
|
SCCACHE_GHA_ENABLED: "true"
|
|
CMAKE_C_COMPILER_LAUNCHER: sccache
|
|
CMAKE_CXX_COMPILER_LAUNCHER: sccache
|
|
run: python xenia-build.py build --config=Release --target=xenia-app
|
|
- name: sccache stats
|
|
if: always()
|
|
run: sccache --show-stats
|
|
- name: Prepare artifacts
|
|
id: prepare_artifacts
|
|
run: |
|
|
$binary = 'build\bin\Windows\Release\xenia_edge.exe'
|
|
if ((get-item $binary).Length -le 100000) {
|
|
echo "::error::$binary is too small."
|
|
}
|
|
robocopy . build\bin\Windows\Release LICENSE /r:0 /w:0
|
|
# Copy all files and directories next to the binary, excluding
|
|
# build intermediates.
|
|
robocopy build\bin\Windows\Release artifacts\xenia_edge /MIR /r:0 /w:0 /XF *.lib *.idb *.exp
|
|
If ($LastExitCode -le 7) { echo "LastExitCode = $LastExitCode";$LastExitCode = 0 }
|
|
- name: Upload xenia edge artifacts
|
|
if: steps.prepare_artifacts.outcome == 'success'
|
|
uses: actions/upload-artifact@main
|
|
with:
|
|
name: xenia_edge_windows
|
|
path: artifacts\xenia_edge
|
|
if-no-files-found: error
|