diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 3c33f8d8c..9371d3bcd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -40,11 +40,12 @@ jobs: with: fetch-depth: 0 - - uses: actions/cache@main - id: cache + - name: Cache premake5 + id: cache-premake5 + uses: actions/cache@main with: - key: ${{ hashFiles('tools/build/bin/premake5.exe') }} path: tools/build/bin/premake5 + key: ${{ runner.os }}-premake5-${{ hashFiles('third_party/premake-core/**') }} - name: Cache Qt6 id: cache-qt-linux @@ -55,13 +56,29 @@ jobs: restore-keys: | ${{ runner.os }}-qt6- + - 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: Cache submodules + id: cache-submodules + uses: actions/cache@v3 + with: + path: third_party + key: ${{ runner.os }}-submodules-${{ hashFiles('.gitmodules') }} + - 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}-20 main" sudo apt-get -y update - sudo apt-get -y install mesa-vulkan-drivers valgrind libc++-dev libc++abi-dev libgtk-3-dev libsdl2-dev libvulkan-dev libx11-xcb-dev clang-20 ninja-build spirv-tools libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-cursor0 + sudo apt-get -y install mesa-vulkan-drivers valgrind libc++-dev libc++abi-dev libgtk-3-dev libsdl2-dev libvulkan-dev libx11-xcb-dev clang-20 ninja-build spirv-tools libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-cursor0 libxcb-shape0 # Install Qt 6.9.2 via aqtinstall if [ '${{ steps.cache-qt-linux.outputs.cache-hit }}' != 'true' ]; then @@ -79,10 +96,25 @@ jobs: echo "PKG_CONFIG_PATH=/opt/Qt/6.9.2/gcc_64/lib/pkgconfig" >> $GITHUB_ENV echo "QT_DIR=/opt/Qt/6.9.2/gcc_64" >> $GITHUB_ENV + # Download linuxdeploy tools 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-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage -O ~/linuxdeploy/linuxdeploy-plugin-qt + 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-qt ~/linuxdeploy/linuxdeploy-plugin-appimage + fi + echo "$HOME/linuxdeploy" >> $GITHUB_PATH + # Verify spirv-opt is available which spirv-opt && spirv-opt --version || echo "Warning: spirv-opt not found in PATH" - git submodule update --init --depth=1 -j$(getconf _NPROCESSORS_ONLN) $(grep -oP '(?<=path = )(?!third_party\/(DirectXShaderCompiler|FidelityFX-(CAS|FSR)|premake-(androidndk|export-compile-commands))).+' .gitmodules) - if [ '${{ steps.cache.outputs.cache-hit }}' != 'true' ]; then + + # Update submodules if not cached + if [ '${{ steps.cache-submodules.outputs.cache-hit }}' != 'true' ]; then + git submodule update --init --depth=1 -j$(getconf _NPROCESSORS_ONLN) $(grep -oP '(?<=path = )(?!third_party\/(DirectXShaderCompiler|FidelityFX-(CAS|FSR)|premake-(androidndk|export-compile-commands))).+' .gitmodules) + fi + + if [ '${{ steps.cache-premake5.outputs.cache-hit }}' != 'true' ]; then ./xenia-build.py premake cp third_party/premake-core/bin/release/premake5 tools/build/bin fi @@ -100,14 +132,59 @@ jobs: fi chmod +x $binary mkdir -p artifacts/xenia_edge - cp $binary artifacts/xenia_edge/ - cp LICENSE artifacts/xenia_edge/ + + # Use linuxdeploy to bundle Qt dependencies + export QMAKE=/opt/Qt/6.9.2/gcc_64/bin/qmake + export LD_LIBRARY_PATH=/opt/Qt/6.9.2/gcc_64/lib:$LD_LIBRARY_PATH + + # 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 + + # Run linuxdeploy with Qt plugin to deploy all Qt dependencies and create AppImage + ~/linuxdeploy/linuxdeploy --appdir artifacts/xenia_edge \ + --executable $binary \ + --desktop-file assets/xenia_edge.desktop \ + --icon-file assets/icon/256.png \ + --plugin qt \ + --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/xenia_edge + path: artifacts/release if-no-files-found: error build-windows: @@ -230,12 +307,13 @@ jobs: run: | # Create zips cd linux_artifacts - 7z a ../xenia_edge_linux.zip * -xr!'*.pdb' -mx9 -bb3 + # For Linux, just rename the AppImage (no need to zip a single file) + mv xenia_edge.AppImage ../xenia_edge_linux.AppImage cd ../windows_artifacts 7z a ../xenia_edge_windows.zip * -xr!'*.pdb' -mx9 -bb3 cd .. # Create release tag=${GITHUB_SHA::7} - gh release create $tag xenia_edge_linux.zip xenia_edge_windows.zip \ + gh release create $tag xenia_edge_linux.AppImage xenia_edge_windows.zip \ --target $GITHUB_SHA -t "xenia_edge" --generate-notes diff --git a/assets/xenia_edge.desktop b/assets/xenia_edge.desktop new file mode 100644 index 000000000..eaa929c5f --- /dev/null +++ b/assets/xenia_edge.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Name=Xenia Edge +GenericName=Xbox 360 Emulator +Comment=Xbox 360 Research Emulator +Exec=xenia_edge %f +Icon=xenia_edge +Terminal=false +Categories=Game;Emulator; +MimeType=application/x-xbox360-executable;application/x-xbox360-iso; +StartupNotify=true \ No newline at end of file