diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index ed63a64..989034a 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -71,9 +71,6 @@ jobs: if: needs.check-version.outputs.should_build == 'true' runs-on: ${{ matrix.os }} timeout-minutes: 120 - env: - CPM_SOURCE_CACHE: ${{ github.workspace }}/.cpm-cache - strategy: fail-fast: false matrix: @@ -82,86 +79,92 @@ jobs: os: ubuntu-latest artifact_suffix: "_x86_64" script_suffix: "" - arch_arg: "" + build_arg: "" - name: "Citron Build (Optimized x86_64)" os: ubuntu-latest artifact_suffix: "_v3" script_suffix: "_v3" - arch_arg: "--arch v3" + build_arg: "v3" - name: "Citron Build (aarch64)" os: ubuntu-24.04-arm artifact_suffix: "_aarch64" script_suffix: "" - arch_arg: "" + build_arg: "" + + container: ghcr.io/pkgforge-dev/archlinux:latest steps: - - name: Checkout CI Scripts - uses: actions/checkout@v4 - with: - persist-credentials: false + - name: Install Git + run: pacman -Syu --noconfirm --needed git - - name: Clone Citron Source - # No --recursive: build-citron-linux.sh uses CPM to fetch all library - # dependencies at cmake configure time. No submodule init is required. + - name: Checkout Workflow Scripts + uses: actions/checkout@v4 + + - name: Clone Citron Source Code shell: bash run: | REPO_URL="https://github.com/citron-neo/emulator.git" + ATTEMPT=0 MAX_ATTEMPTS=999 + while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do ATTEMPT=$((ATTEMPT + 1)) - echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning..." - rm -rf citron - if git clone "$REPO_URL" citron; then + echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning repository..." + + # 1. CRITICAL: Wipe the directory before every attempt + rm -rf emulator + + if git clone --recursive "https://github.com/citron-neo/emulator.git" emulator; then echo "✅ Clone successful on attempt $ATTEMPT." exit 0 fi + echo "⚠️ Clone failed. Retrying in 15 seconds..." sleep 15 done + echo "❌ Failed to clone after $MAX_ATTEMPTS attempts." exit 1 - - name: Set Git Safe Directory - working-directory: ./citron + - name: Prepare Build Environment + run: | + mv get-dependencies.sh emulator/ + mv build-citron.sh emulator/ + mv package-citron.sh emulator/ + + - name: Add Git Safe Directory + working-directory: ./emulator run: git config --global --add safe.directory "$PWD" - - name: Cache CPM Sources - uses: actions/cache@v4 - with: - path: ${{ github.workspace }}/.cpm-cache - key: cpm-linux-${{ runner.os }}-${{ matrix.os }}-${{ hashFiles('citron/CMakeModules/dependencies.cmake') }} - restore-keys: | - cpm-linux-${{ runner.os }}-${{ matrix.os }}- + - name: Install dependencies + working-directory: ./emulator + run: chmod +x ./get-dependencies.sh && ./get-dependencies.sh - - name: Setup Build Environment - working-directory: ./citron - run: | - chmod +x ./build-citron-linux.sh - ./build-citron-linux.sh setup - - - name: Get Version - id: version - working-directory: ./citron - run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - - name: Build Citron - working-directory: ./citron - env: - CITRON_BUILD_TYPE: Release - APP_VERSION: ${{ steps.version.outputs.sha }} - ARCH_SUFFIX: ${{ matrix.script_suffix }} + - name: Build Citron from source + working-directory: ./emulator run: | NPROC_VAL=$(nproc --all) JOBS_VAL=$((NPROC_VAL > 4 ? 4 : NPROC_VAL)) - JOBS=${JOBS_VAL} ./build-citron-linux.sh use --pgo none --lto full ${{ matrix.arch_arg }} + chmod +x ./build-citron.sh + JOBS=${JOBS_VAL} DEVEL=false ./build-citron.sh ${{ matrix.build_arg }} + + - name: Package AppImage with Correct Name + working-directory: ./emulator + run: | + GIT_SHA=$(git rev-parse --short HEAD) + export APP_VERSION="${GIT_SHA}" + export VERSION="${GIT_SHA}" + export ARCH_SUFFIX="${{ matrix.script_suffix }}" + export DEVEL="false" + chmod +x ./package-citron.sh + ./package-citron.sh - name: Upload Artifacts uses: actions/upload-artifact@v4 with: name: Artifacts${{ matrix.artifact_suffix }} - path: citron/build/use-nopgo/AppImage/ - + path: emulator/dist/ release: if: ${{ github.ref_name == 'main' }} @@ -220,7 +223,7 @@ jobs: **Build Details:** - Platform: Linux (x86_64, x86_64_v3, aarch64) - Format: AppImage + tar.zst packages - - Build Type: Release with LTO + - Build Type: Release with optimizations - Date: ${{ env.BUILD_DATE }} - name: Update LATEST_VERSION diff --git a/.github/workflows/build_nightly.yml b/.github/workflows/build_nightly.yml index a2e6bbd..71eee5c 100644 --- a/.github/workflows/build_nightly.yml +++ b/.github/workflows/build_nightly.yml @@ -343,15 +343,13 @@ jobs: # =========================================================================== # LINUX + # =========================================================================== build-linux: name: "${{ matrix.name }}" needs: [check-version] if: needs.check-version.outputs.should_build == 'true' runs-on: ${{ matrix.os }} timeout-minutes: 120 - env: - CPM_SOURCE_CACHE: ${{ github.workspace }}/.cpm-cache - strategy: fail-fast: false matrix: @@ -360,27 +358,28 @@ jobs: os: ubuntu-latest artifact_suffix: "_x86_64" script_suffix: "" - arch_arg: "" + build_arg: "" - name: "Citron Build (Optimized x86_64)" os: ubuntu-latest artifact_suffix: "_v3" script_suffix: "_v3" - arch_arg: "--arch v3" + build_arg: "v3" - name: "Citron Build (aarch64)" os: ubuntu-24.04-arm artifact_suffix: "_aarch64" script_suffix: "" - arch_arg: "" + build_arg: "" + + container: ghcr.io/pkgforge-dev/archlinux:latest steps: - - name: Checkout CI Scripts - uses: actions/checkout@v4 - with: - persist-credentials: false + - name: Install Git + run: pacman -Syu --noconfirm --needed git - - name: Clone Citron Source - # No --recursive: build-citron-linux.sh uses CPM to fetch all library - # dependencies at cmake configure time. No submodule init is required. + - name: Checkout Workflow Scripts + uses: actions/checkout@v4 + + - name: Clone Citron Source Code shell: bash run: | REPO_URL="https://github.com/citron-neo/emulator.git" @@ -388,9 +387,9 @@ jobs: MAX_ATTEMPTS=999 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do ATTEMPT=$((ATTEMPT + 1)) - echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning..." - rm -rf citron - if git clone "$REPO_URL" citron; then + echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning repository..." + rm -rf emulator + if git clone --recursive "$REPO_URL" emulator; then echo "✅ Clone successful on attempt $ATTEMPT." exit 0 fi @@ -400,45 +399,44 @@ jobs: echo "❌ Failed to clone after $MAX_ATTEMPTS attempts." exit 1 - - name: Set Git Safe Directory - working-directory: ./citron + - name: Prepare Build Environment + run: | + mv get-dependencies.sh emulator/ + mv build-citron.sh emulator/ + mv package-citron.sh emulator/ + + - name: Add Git Safe Directory + working-directory: ./emulator run: git config --global --add safe.directory "$PWD" - - name: Cache CPM Sources - uses: actions/cache@v4 - with: - path: ${{ github.workspace }}/.cpm-cache - key: cpm-linux-${{ runner.os }}-${{ matrix.os }}-${{ hashFiles('citron/CMakeModules/dependencies.cmake') }} - restore-keys: | - cpm-linux-${{ runner.os }}-${{ matrix.os }}- + - name: Install dependencies + working-directory: ./emulator + run: chmod +x ./get-dependencies.sh && ./get-dependencies.sh - - name: Setup Build Environment - working-directory: ./citron - run: | - chmod +x ./build-citron-linux.sh - ./build-citron-linux.sh setup - - - name: Get Version - id: version - working-directory: ./citron - run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - - name: Build Citron - working-directory: ./citron - env: - CITRON_BUILD_TYPE: Nightly - APP_VERSION: ${{ steps.version.outputs.sha }} - ARCH_SUFFIX: ${{ matrix.script_suffix }} + - name: Build Citron from source + working-directory: ./emulator run: | NPROC_VAL=$(nproc --all) JOBS_VAL=$((NPROC_VAL > 4 ? 4 : NPROC_VAL)) - JOBS=${JOBS_VAL} ./build-citron-linux.sh use --pgo none --lto full ${{ matrix.arch_arg }} + chmod +x ./build-citron.sh + JOBS=${JOBS_VAL} DEVEL=false BUILD_TYPE=Nightly ./build-citron.sh ${{ matrix.build_arg }} + + - name: Package AppImage with Correct Name + working-directory: ./emulator + run: | + GIT_SHA=$(git rev-parse --short HEAD) + export APP_VERSION="${GIT_SHA}" + export VERSION="${GIT_SHA}" + export ARCH_SUFFIX="${{ matrix.script_suffix }}" + export DEVEL="false" + chmod +x ./package-citron.sh + ./package-citron.sh - name: Upload Artifacts uses: actions/upload-artifact@v4 with: name: Artifacts${{ matrix.artifact_suffix }} - path: citron/build/use-nopgo/AppImage/ + path: emulator/dist/ # =========================================================================== # macOS diff --git a/.github/workflows/build_stable.yml b/.github/workflows/build_stable.yml index becca7e..2edad94 100644 --- a/.github/workflows/build_stable.yml +++ b/.github/workflows/build_stable.yml @@ -342,15 +342,13 @@ jobs: # =========================================================================== # LINUX + # =========================================================================== build-linux: name: "${{ matrix.name }}" needs: [check-version] if: needs.check-version.outputs.should_build == 'true' runs-on: ${{ matrix.os }} timeout-minutes: 120 - env: - CPM_SOURCE_CACHE: ${{ github.workspace }}/.cpm-cache - strategy: fail-fast: false matrix: @@ -359,27 +357,28 @@ jobs: os: ubuntu-latest artifact_suffix: "_x86_64" script_suffix: "" - arch_arg: "" + build_arg: "" - name: "Citron Build (Optimized x86_64)" os: ubuntu-latest artifact_suffix: "_v3" script_suffix: "_v3" - arch_arg: "--arch v3" + build_arg: "v3" - name: "Citron Build (aarch64)" os: ubuntu-24.04-arm artifact_suffix: "_aarch64" script_suffix: "" - arch_arg: "" + build_arg: "" + + container: ghcr.io/pkgforge-dev/archlinux:latest steps: - - name: Checkout CI Scripts - uses: actions/checkout@v4 - with: - persist-credentials: false + - name: Install Git + run: pacman -Syu --noconfirm --needed git - - name: Clone Citron Source - # No --recursive: build-citron-linux.sh uses CPM to fetch all library - # dependencies at cmake configure time. No submodule init is required. + - name: Checkout Workflow Scripts + uses: actions/checkout@v4 + + - name: Clone Citron Source Code shell: bash run: | REPO_URL="https://github.com/citron-neo/emulator.git" @@ -387,9 +386,9 @@ jobs: MAX_ATTEMPTS=999 while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do ATTEMPT=$((ATTEMPT + 1)) - echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning..." - rm -rf citron - if git clone "$REPO_URL" citron; then + echo "Attempt $ATTEMPT of $MAX_ATTEMPTS: Cloning repository..." + rm -rf emulator + if git clone --recursive "$REPO_URL" emulator; then echo "✅ Clone successful on attempt $ATTEMPT." exit 0 fi @@ -399,45 +398,44 @@ jobs: echo "❌ Failed to clone after $MAX_ATTEMPTS attempts." exit 1 - - name: Set Git Safe Directory - working-directory: ./citron + - name: Prepare Build Environment + run: | + mv get-dependencies.sh emulator/ + mv build-citron.sh emulator/ + mv package-citron.sh emulator/ + + - name: Add Git Safe Directory + working-directory: ./emulator run: git config --global --add safe.directory "$PWD" - - name: Cache CPM Sources - uses: actions/cache@v4 - with: - path: ${{ github.workspace }}/.cpm-cache - key: cpm-linux-${{ runner.os }}-${{ matrix.os }}-${{ hashFiles('citron/CMakeModules/dependencies.cmake') }} - restore-keys: | - cpm-linux-${{ runner.os }}-${{ matrix.os }}- + - name: Install dependencies + working-directory: ./emulator + run: chmod +x ./get-dependencies.sh && ./get-dependencies.sh - - name: Setup Build Environment - working-directory: ./citron - run: | - chmod +x ./build-citron-linux.sh - ./build-citron-linux.sh setup - - - name: Get Version - id: version - working-directory: ./citron - run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - - name: Build Citron - working-directory: ./citron - env: - CITRON_BUILD_TYPE: Stable - APP_VERSION: ${{ steps.version.outputs.sha }} - ARCH_SUFFIX: ${{ matrix.script_suffix }} + - name: Build Citron from source + working-directory: ./emulator run: | NPROC_VAL=$(nproc --all) JOBS_VAL=$((NPROC_VAL > 4 ? 4 : NPROC_VAL)) - JOBS=${JOBS_VAL} ./build-citron-linux.sh use --pgo none --lto full ${{ matrix.arch_arg }} + chmod +x ./build-citron.sh + JOBS=${JOBS_VAL} DEVEL=false BUILD_TYPE=Stable ./build-citron.sh ${{ matrix.build_arg }} + + - name: Package AppImage with Correct Name + working-directory: ./emulator + run: | + GIT_SHA=$(git rev-parse --short HEAD) + export APP_VERSION="${GIT_SHA}" + export VERSION="${GIT_SHA}" + export ARCH_SUFFIX="${{ matrix.script_suffix }}" + export DEVEL="false" + chmod +x ./package-citron.sh + ./package-citron.sh - name: Upload Artifacts uses: actions/upload-artifact@v4 with: name: Artifacts${{ matrix.artifact_suffix }} - path: citron/build/use-nopgo/AppImage/ + path: emulator/dist/ # =========================================================================== # macOS diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..9f1c57e --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,69 @@ +# Maintainer: Collecting + +# The '-git' suffix signifies this is a bleeding-edge build from the git repo +pkgname=citron-git +pkgver=0.1.r0.g1a2b3c4 # This will be replaced by the pkgver() function +pkgrel=1 +pkgdesc="A Nintendo Switch emulator" +arch=('x86_64' 'aarch64') +url="https://citron-emu.org/" +license=('GPL2') + +# Dependencies needed to run the emulator +depends=( + 'boost-libs' 'enet' 'fmt' 'ffmpeg' 'gamemode' 'glslang' 'hicolor-icon-theme' + 'libdecor' 'libxkbcommon-x11' 'mbedtls2' 'nlohmann-json' 'qt6-base' + 'qt6-multimedia' 'sdl2' 'vulkan-icd-loader' +) + +# Dependencies needed only to build the emulator from source +makedepends=( + 'boost' 'catch2' 'cmake' 'git' 'ninja' 'nasm' 'qt6-tools' 'vulkan-headers' +) + +# This points to the source code repository +source=("git+https://git.citron-emu.org/citron/emulator.git") +sha256sums=('SKIP') + +# This function automatically generates a version string based on the latest git commit +pkgver() { + cd "$pkgname" + git describe --long --tags | sed 's/\([^-]*-g\)/r\1/;s/-/./g' +} + +# This function runs before the build and is used to apply patches +prepare() { + cd "$pkgname" + # Apply compatibility patches for newer Boost versions + find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::asio::io_service\b/boost::asio::io_context/g' + find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::asio::io_service::strand\b/boost::asio::strand/g' + find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's|#include *|#include |g' + find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::process::async_pipe\b/boost::process::v1::async_pipe/g' +} + +# This function contains the build commands +build() { + cd "$pkgname" + # makepkg sets CFLAGS and CXXFLAGS, so we don't need to specify arch flags + cmake -B build -S . -GNinja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCITRON_USE_BUNDLED_VCPKG=OFF \ + -DCITRON_USE_BUNDLED_QT=OFF \ + -DUSE_SYSTEM_QT=ON \ + -DCITRON_USE_BUNDLED_FFMPEG=OFF \ + -DCITRON_USE_BUNDLED_SDL2=OFF \ + -DCITRON_TESTS=OFF \ + -DCITRON_CHECK_SUBMODULES=OFF \ + -DCITRON_ENABLE_LTO=ON \ + -DCITRON_USE_QT_MULTIMEDIA=ON \ + -DENABLE_QT_TRANSLATION=ON + + ninja -C build +} + +# This function installs the built files into a temporary directory +package() { + cd "$pkgname" + DESTDIR="$pkgdir/" ninja -C build install +} diff --git a/README.md b/README.md index 75ca138..1c077cc 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -# 🍋 The Official Citron Neo CI +# 🍋 The Official Citron-CI -[![GitHub Downloads](https://camo.githubusercontent.com/f7d99771b8c7be2c26f2ae567342d0f6224a81daf7362bad19031525d68ecbd8/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f646f776e6c6f6164732f636974726f6e2d6e656f2f43492f746f74616c3f6c6f676f3d676974687562266c6162656c3d476974487562253230446f776e6c6f616473)](https://github.com/citron-neo/CI/releases/latest) [![Build Citron Neo (Nightly)](https://github.com/citron-neo/CI/actions/workflows/build_nightly.yml/badge.svg)](https://github.com/citron-neo/CI/actions/workflows/build_nightly.yml) [![Build Citron Neo (Stable)](https://github.com/citron-neo/CI/actions/workflows/build_stable.yml/badge.svg)](https://github.com/citron-neo/CI/actions/workflows/build_stable.yml) +[![GitHub Downloads](https://img.shields.io/github/downloads/citron-neo/CI/total?logo=github&label=GitHub%20Downloads)](https://github.com/citron-neo/CI/releases/latest) +[![Build Citron (Nightly)](https://github.com/citron-neo/CI/actions/workflows/build_nightly.yml/badge.svg)](https://github.com/citron-neo/CI/actions/workflows/build_nightly.yml) +[![Build Citron (Stable)](https://github.com/citron-neo/CI/actions/workflows/build_stable.yml/badge.svg)](https://github.com/citron-neo/CI/actions/workflows/build_stable.yml) ## Star History @@ -18,45 +20,57 @@ This repository makes Nightly builds for **x86_64** (Standard), **x86_64_v3** (C Would you like to submit a compatibility report for the emulator? You can do so here: -- [Submit Compatibility Report](https://github.com/citron-neo/Citron-Compatability) +* [Submit Compatibility Report](https://github.com/citron-neo/Citron-Compatability) --- Direct links for other information you may need can also be found below: -- [Latest Commits Can Be Found Here](https://github.com/citron-neo/emulator/commits/main) +* [Latest Commits Can Be Found Here](https://github.com/citron-neo/emulator/commits/main) -- [Latest Android Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-android) +* [Latest Android Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-android) -- [Latest Linux Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-linux) +* [Latest Linux Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-linux) -- [Latest Windows Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-windows) +* [Latest Windows Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-windows) -- [Latest macOS Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-macos) +* [Latest macOS Nightly Release](https://github.com/citron-neo/CI/releases/tag/nightly-macos) --- # READ THIS IF YOU HAVE ISSUES -If you are on wayland (specially GNOME wayland) and get freezes or crashes, you are likely affected by this issue that affects all Qt6 apps: [citron-neo#50](https://github.com/citron-neo/CI/pull/50) +If you are on wayland (specially GNOME wayland) and get freezes or crashes, you are likely affected by this issue that affects all Qt6 apps: https://github.com/citron-neo/CI/issues/50 To fix it simply set the env variable `QT_QPA_PLATFORM=xcb` -**Also, are you looking for AppImages of other emulators? Check:** [AnyLinux-AppImages](https://pkgforge-dev.github.io/Anylinux-AppImages/) +**Also, are you looking for AppImages of other emulators? Check:** [AnyLinux-AppImages](https://pkgforge-dev.github.io/Anylinux-AppImages/) ---- +---- AppImage made using [sharun](https://github.com/VHSgunzo/sharun), which makes it extremely easy to turn any binary into a portable package without using containers or similar tricks. **These AppImages bundle everything and should work on any Linux distro, even on musl based ones.** -A `tar.zst` portable archive of the same build is also published alongside the AppImage on each Linux release, for users who prefer an install-free tarball over the AppImage format. +It is possible that the AppImages may fail to work with appimagelauncher, we recommend these alternatives instead: -These AppImages work without fuse2 as it can use fuse3 instead, it can also work without fuse at all thanks to the [uruntime](https://github.com/VHSgunzo/uruntime) +* [AM](https://github.com/ivan-hc/AM) `am -i citron` or `appman -i citron` +* [dbin](https://github.com/xplshn/dbin) `dbin install citron.appimage` + +* [soar](https://github.com/pkgforge/soar) `soar install citron` + +These AppImages works without fuse2 as it can use fuse3 instead, it can also work without fuse at all thanks to the [uruntime](https://github.com/VHSgunzo/uruntime) + +
+ raison d'être + Inspiration Image + +
+ +**The following information above and the creation of the AppImages Citron currently creates & distributes derives from Pkgforges previous work. You can find their repository here: https://github.com/pkgforge-dev/Citron-AppImage** --- -Thank-you for being apart of & using Citron Neo, we value all members of the community whom help shape the emulator into what it is today! - -- The Citron Neo Team +Thank-you for being apart of & using Citron, we value all members of the community whom help shape the emulator into what it is today! +- The Citron Team diff --git a/build-citron.sh b/build-citron.sh new file mode 100644 index 0000000..92a5748 --- /dev/null +++ b/build-citron.sh @@ -0,0 +1,93 @@ +#!/bin/sh +set -ex + +# --- Architecture and Compiler Flag Setup --- +ARCH="${ARCH:-$(uname -m)}" + +if [ "$1" = 'v3' ] && [ "$ARCH" = 'x86_64' ]; then + ARCH_FLAGS="-march=x86-64-v3 -O3 -USuccess -UNone -fuse-ld=lld" +elif [ "$ARCH" = 'x86_64' ]; then + ARCH_FLAGS="-march=x86-64 -mtune=generic -O3 -USuccess -UNone -fuse-ld=lld" +else + ARCH_FLAGS="-march=armv8-a -mtune=generic -O3 -USuccess -UNone -fuse-ld=lld" +fi + +# --- Source Code Checkout and Versioning --- +git clone --recursive "https://github.com/citron-neo/emulator.git" ./citron +cd ./citron + +if [ "$DEVEL" = 'true' ]; then + CITRON_TAG="$(git rev-parse --short HEAD)" + VERSION="$CITRON_TAG" +else + if CITRON_TAG="$(git describe --tags 2>/dev/null)"; then + git checkout "$CITRON_TAG" + VERSION="$(echo "$CITRON_TAG" | awk -F'-' '{print $1}')" + else + # Fallback for repositories without tags (or shallow history without reachable tags) + VERSION="$(git rev-parse --short HEAD)" + echo "No tags found, falling back to commit version: $VERSION" + fi +fi + +# --- Apply Necessary Source Code Patches for Compatibility --- +find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::asio::io_service\b/boost::asio::io_context/g' +find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::asio::io_service::strand\b/boost::asio::strand/g' +find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's|#include *|#include |g' +find . -type f \( -name '*.cpp' -o -name '*.h' \) | xargs sed -i 's/\bboost::process::async_pipe\b/boost::process::v1::async_pipe/g' +sed -i '/sse2neon/d' ./src/video_core/CMakeLists.txt +sed -i 's/cmake_minimum_required(VERSION 2.8)/cmake_minimum_required(VERSION 3.5)/' externals/xbyak/CMakeLists.txt + +# --- Find Qt6 Private Headers --- +HEADER_PATH=$(pacman -Ql qt6-base | grep 'qpa/qplatformnativeinterface.h$' | awk '{print $2}') +if [ -z "$HEADER_PATH" ]; then + echo "ERROR: Could not find qplatformnativeinterface.h path." >&2 + exit 1 +fi +QT_PRIVATE_INCLUDE_DIR=$(dirname "$(dirname "$HEADER_PATH")") +CXX_FLAGS_EXTRA="-I${QT_PRIVATE_INCLUDE_DIR}" + +# --- Build Process --- +JOBS=$(nproc --all) + +mkdir build && cd build + +# Configure the build using CMake +cmake .. -GNinja \ + -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ + -DCITRON_USE_BUNDLED_VCPKG=OFF \ + -DCITRON_USE_BUNDLED_QT=OFF \ + -DUSE_SYSTEM_QT=ON \ + -DENABLE_QT6=ON \ + -DCITRON_USE_BUNDLED_FFMPEG=OFF \ + -DCITRON_USE_BUNDLED_SDL2=ON \ + -DCITRON_USE_EXTERNAL_SDL2=OFF \ + -DCITRON_TESTS=OFF \ + -DCITRON_CHECK_SUBMODULES=OFF \ + -DCITRON_USE_LLVM_DEMANGLE=OFF \ + -DCITRON_ENABLE_LTO=ON \ + -DCITRON_USE_QT_MULTIMEDIA=ON \ + -DCITRON_USE_QT_WEB_ENGINE=OFF \ + -DENABLE_QT_TRANSLATION=ON \ + -DUSE_DISCORD_PRESENCE=ON \ + -DENABLE_WEB_SERVICE=ON \ + -DENABLE_OPENSSL=ON \ + -DBUNDLE_SPEEX=ON \ + -DCITRON_USE_FASTER_LD=OFF \ + -DCITRON_USE_EXTERNAL_Vulkan_HEADERS=ON \ + -DCITRON_USE_EXTERNAL_VULKAN_UTILITY_LIBRARIES=ON \ + -DCITRON_USE_AUTO_UPDATER=ON \ + -DCMAKE_INSTALL_PREFIX=/usr \ + -DCMAKE_CXX_FLAGS="$ARCH_FLAGS -Wno-error -w ${CXX_FLAGS_EXTRA}" \ + -DCMAKE_C_FLAGS="$ARCH_FLAGS" \ + -DCMAKE_SYSTEM_PROCESSOR="$(uname -m)" \ + -DCITRON_BUILD_TYPE=Release \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + +# Compile and install the project +ninja -j${JOBS} +sudo ninja install + +# --- Output Version Info --- +echo "$VERSION" >~/version diff --git a/get-dependencies.sh b/get-dependencies.sh new file mode 100644 index 0000000..c63a212 --- /dev/null +++ b/get-dependencies.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +set -ex +ARCH="$(uname -m)" +EXTRA_PACKAGES="https://raw.githubusercontent.com/pkgforge-dev/Anylinux-AppImages/refs/heads/main/useful-tools/get-debloated-pkgs.sh" + +pacman -Syu --noconfirm --needed \ + base-devel \ + boost \ + boost-libs \ + catch2 \ + clang \ + cmake \ + curl \ + enet \ + fmt \ + gamemode \ + gcc \ + git \ + glslang \ + glu \ + hidapi \ + libvpx \ + libxi \ + libxkbcommon-x11 \ + libxss \ + lld \ + llvm \ + rapidjson \ + mesa \ + nasm \ + ninja \ + nlohmann-json \ + numactl \ + openal \ + patchelf \ + pulseaudio \ + pulseaudio-alsa \ + qt6-networkauth \ + qt6-multimedia \ + qt6-svg \ + qt6-tools \ + qt6-translations \ + sdl2 \ + unzip \ + vulkan-headers \ + vulkan-mesa-layers \ + wget \ + xcb-util-cursor \ + xcb-util-image \ + xcb-util-renderutil \ + xcb-util-wm \ + xorg-server-xvfb \ + zip \ + zsync + +wget --retry-connrefused --tries=30 "$EXTRA_PACKAGES" -O ./get-debloated-pkgs.sh +chmod +x ./get-debloated-pkgs.sh +./get-debloated-pkgs.sh --add-mesa ffmpeg-mini qt6-base-mini libxml2-mini opus-mini icu-mini diff --git a/package-citron.sh b/package-citron.sh new file mode 100644 index 0000000..5766640 --- /dev/null +++ b/package-citron.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -ex +ARCH="${ARCH:-$(uname -m)}" + +# The VERSION is now passed as an environment variable from the workflow +if [ -z "$APP_VERSION" ]; then + echo "Error: APP_VERSION environment variable is not set." + exit 1 +fi + +# Construct unique names for the AppImage and tarball based on the build matrix. +OUTNAME_BASE="citron_nightly-${APP_VERSION}-linux-${ARCH}${ARCH_SUFFIX}" + +SHARUN="https://raw.githubusercontent.com/pkgforge-dev/Anylinux-AppImages/refs/heads/main/useful-tools/quick-sharun.sh" +export OUTNAME="${OUTNAME_BASE}.AppImage" +export OUTPATH="$PWD"/dist +export DESKTOP=/usr/share/applications/org.citron_emu.citron.desktop +export ICON=/usr/share/icons/hicolor/scalable/apps/org.citron_emu.citron.svg +export DEPLOY_OPENGL=1 +export DEPLOY_VULKAN=1 +export DEPLOY_PIPEWIRE=1 + +if [ "$DEVEL" = 'true' ]; then + export DEVEL_RELEASE=1 +fi + +wget --retry-connrefused --tries=30 "$SHARUN" -O ./quick-sharun +chmod +x ./quick-sharun +./quick-sharun /usr/bin/citron* /usr/lib/libgamemode.so* +./quick-sharun --make-appimage