From 8b74365f2a6f693ebc74a55ebcf51900356e8f1b Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Sun, 14 Sep 2025 21:50:06 -0300 Subject: [PATCH 01/17] docs: Update dependencies on Ubuntu Signed-off-by: Caio Oliveira --- docs/build/Linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/Linux.md b/docs/build/Linux.md index a6b7b2dda7..9fc85a27e2 100644 --- a/docs/build/Linux.md +++ b/docs/build/Linux.md @@ -37,7 +37,7 @@ Dependencies are listed here as commands that can be copied/pasted. Of course, t - GCC 11 or later is required. - Ubuntu / Linux Mint / Debian: - - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev` + - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev` - Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. - Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF` From 9aa9ce5c36da4361a8c1508acb0f4c3984a59d63 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Sun, 14 Sep 2025 22:22:37 -0300 Subject: [PATCH 02/17] [docs] Refactor building with Linux * this a initial PR to improve documentation of building under linux based on updated windows doc Signed-off-by: Caio Oliveira --- docs/build/Linux.md | 227 +++++++++++++++++++++++++++--------------- docs/build/Windows.md | 2 +- 2 files changed, 146 insertions(+), 83 deletions(-) diff --git a/docs/build/Linux.md b/docs/build/Linux.md index 9fc85a27e2..5bbd2b1d4b 100644 --- a/docs/build/Linux.md +++ b/docs/build/Linux.md @@ -1,138 +1,201 @@ -### Dependencies +# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. + +## 📋 Index: + +* [Minimal Dependencies](#minimal-dependencies) +* [Cloning Eden with Git](#cloning-eden-with-git) +* [Arch / Manjaro](#arch-manjaro) +* [Ubuntu / Linux Mint / Debian](#ubuntu-linux-mint-debian) +* [Fedora](#fedora) +* [Building with Scripts](#building-with-scripts) +* [Running without Installing](#running-without-installing) + +--- + +## Minimal Dependencies You'll need to download and install the following to build Eden: - * [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc - * If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling - * [CMake](https://www.cmake.org/) 3.22+ +* [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc +* If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling +* [CMake](https://www.cmake.org/) 3.22+ +* [Git](https://git-scm.com/) for version control The following are handled by Eden's externals: - * [FFmpeg](https://ffmpeg.org/) - * [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ - * [opus](https://opus-codec.org/downloads/) 1.3+ - +* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) +* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON`) +* [opus](https://opus-codec.org/downloads/) 1.3+ + All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available: - * [Boost](https://www.boost.org/users/download/) 1.79.0+ - * [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 - * [fmt](https://fmt.dev/) 8.0.1+ - * [lz4](http://www.lz4.org) 1.8+ - * [nlohmann_json](https://github.com/nlohmann/json) 3.8+ - * [OpenSSL](https://www.openssl.org/source/) 1.1.1+ - * [ZLIB](https://www.zlib.net/) 1.2+ - * [zstd](https://facebook.github.io/zstd/) 1.5+ - * [enet](http://enet.bespin.org/) 1.3+ - * [cubeb](https://github.com/mozilla/cubeb) - * [SimpleIni](https://github.com/brofield/simpleini) +* [Boost](https://www.boost.org/users/download/) 1.79.0+ +* [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 +* [fmt](https://fmt.dev/) 8.0.1+ +* [lz4](http://www.lz4.org) 1.8+ +* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ +* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ +* [ZLIB](https://www.zlib.net/) 1.2+ +* [zstd](https://facebook.github.io/zstd/) 1.5+ +* [enet](http://enet.bespin.org/) 1.3+ +* [cubeb](https://github.com/mozilla/cubeb) +* [SimpleIni](https://github.com/brofield/simpleini) Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended. -Dependencies are listed here as commands that can be copied/pasted. Of course, they should be inspected before being run. +Dependencies are listed here as commands that can be copied/pasted. Inspect them before running. -- Arch / Manjaro: - - `sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip` - - Building with QT Web Engine requires `qt6-webengine` as well. - - Proper wayland support requires `qt6-wayland` - - GCC 11 or later is required. - -- Ubuntu / Linux Mint / Debian: - - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev` - - Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. - - Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - - Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF` - -```sh -git submodule update --init --recursive -cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -``` - -- Fedora: - - `sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel` - - Fedora 32 or later is required. - - Due to GCC 12, Fedora 36 or later users need to install `clang`, and configure CMake to use it via `-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang` - - CMake arguments to force system libraries: - - SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` - - FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` - - [RPM Fusion](https://rpmfusion.org/) (free) is required to install `ffmpeg-devel` - -### Cloning Eden with Git +## Cloning Eden with Git **Master:** ```bash -git clone --recursive https://git.eden-emu.dev/eden-emu/eden +git clone https://git.eden-emu.dev/eden-emu/eden cd eden ``` -The `--recursive` option automatically clones the required Git submodules. +## Arch / Manjaro -### Building Eden in Release Mode (Optimised) +```sh +sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip +``` +* Building with QT Web Engine requires `qt6-webengine` as well. +* Proper Wayland support requires `qt6-wayland` +* GCC 11 or later is required. -If you need to run ctests, you can disable `-DYUZU_TESTS=OFF` and install Catch2. +## Ubuntu / Linux Mint / Debian + +```sh +sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +``` +* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. + +```sh +# Make build dir and enter +mkdir build && cd build + +# Generate CMake Makefiles +cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 + +# Build +ninja +``` + +## Fedora + +```sh +sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel +``` +* Force system libraries via CMake arguments: + * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` +* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` +* Fedora 32 or later is required. +* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: +```sh +# Generate CMake Makefiles (for Clang compiler) +cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang +``` + +## Building Eden in Release Mode (Optimised) ```bash +# Make build dir and enter mkdir build && cd build + +# Generate CMake Makefiles cmake .. -GNinja -DYUZU_TESTS=OFF + +# Build ninja -sudo ninja install + +# Install! +sudo ninja install ``` -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` -`-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` might be needed if ninja command failed with `undefined reference to symbol 'spvOptimizerOptionsCreate`, reason currently unknown +* Enable Discord Rich Presence: +```bash +# ... -Optionally, you can use `cmake-gui ..` to adjust various options (e.g. disable the Qt GUI). +# Generate CMake Makefiles (with Discord Rich Presence) +cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -### Building Eden in Debug Mode (Slow) +# ... +``` + +* If ninja fails with `undefined reference to symbol 'spvOptimizerOptionsCreate'`, add `-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` +* Optionally use `cmake-gui ..` to adjust options (e.g., disable Qt GUI) + +## Building Eden in Debug Mode (Slow) ```bash +# Make build dir and enter mkdir build && cd build + +# Generate CMake Makefiles cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF + +# Build ninja ``` -### Building with debug symbols +## Building with Debug Symbols ```bash -mkdir build && cd build +# Make build dir and enter + +# Generate CMake Makefiles cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF + +# Build ninja ``` -### Building with Scripts -A convenience script for building is provided in `.ci/linux/build.sh`. You must provide an arch target for optimization, e.g. `.ci/linux/build.sh amd64`. Valid targets: -- `legacy`: x86_64 generic, only needed for CPUs older than 2013 or so -- `amd64`: x86_64-v3, for CPUs newer than 2013 or so -- `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) -- `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) -- `aarch64`: For armv8-a CPUs, older than mid-2021 or so -- `armv9`: For armv9-a CPUs, newer than mid-2021 or so -- `native`: Optimize to your native host architecture +## Building with Scripts -Extra flags to pass to CMake should be passed after the arch target. +* Provided script: `.ci/linux/build.sh` +* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` +* Valid targets: + * `native`: Optimize to your native host architecture + * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so + * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so + * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) + * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) + * `aarch64`: For armv8-a CPUs, older than mid-2021 or so + * `armv9`: For armv9-a CPUs, newer than mid-2021 or so +* Extra CMake flags go after the arch target. -Additional environment variables can be used to control building: -- `NPROC`: Number of threads to use for compilation (defaults to all) -- `TARGET`: Set to `appimage` to disable standalone `eden-cli` and `eden-room` executables -- `BUILD_TYPE`: Sets the build type to use. Defaults to `Release` +### Environment Variables -The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: -- `DEVEL` (default FALSE): Disable Qt update checker -- `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine -- `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia +* `NPROC`: Number of compilation threads (default: all cores) +* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` +* `BUILD_TYPE`: Build type (default: `Release`) -After building, an AppImage can be packaged via `.ci/linux/package.sh`. This script takes the same arch targets as the build script. If the build was created in a different directory, you can specify its path relative to the source directory, e.g. `.ci/linux/package.sh amd64 build-appimage`. Additionally, set the `DEVEL` environment variable to `true` to change the app name to `Eden Nightly`. +Boolean flags (set `true` to enable, `false` to disable): -### Running without installing +* `DEVEL` (default `FALSE`): Disable Qt update checker -After building, the binaries `eden` and `eden-cmd` (depending on your build options) will end up in `build/bin/`. +* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine + +* `USE_MULTIMEDIA` (default `TRUE`): Enable Qt Multimedia + +* AppImage packaging script: `.ci/linux/package.sh` + + * Accepts same arch targets as build script + * Use `DEVEL=true` to rename app to `Eden Nightly` + +## Running without Installing + +After building, binaries `eden` and `eden-cmd` will be in `build/bin/`. ```bash -# SDL +# Build Dir cd build/bin/ + +# SDL2 build ./eden-cmd -# Qt -cd build/bin/ +# Qt build ./eden ``` diff --git a/docs/build/Windows.md b/docs/build/Windows.md index 76602e6d69..93ee9fe551 100644 --- a/docs/build/Windows.md +++ b/docs/build/Windows.md @@ -157,7 +157,7 @@ make -j$(nproc) # Generate CMake Makefiles (withou QT) cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DENABLE_QT=no -$ ... +# ... ``` * Running programs from inside `MSYS2 MinGW x64` shell has a different `%PATH%` than directly from explorer. From 61a2a5b8143f7d01962e87252badc8efd4611926 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:16:55 -0400 Subject: [PATCH 03/17] [docs] refactor: full rewrite, generalization + dedup Combines most of the stuff that was repeated thrice over verbatim into a single common Build Instructions page, with additional caveats marked elsewhere. Prettifies some stuff too because why not. Signed-off-by: crueter --- docs/Build.md | 124 +++++++++++++++++++ docs/CPM.md | 2 +- docs/Caveats.md | 52 ++++++++ docs/Deps.md | 212 ++++++++++++++++++++++++++++++++ docs/Development.md | 24 +--- docs/Options.md | 67 +++++++++++ docs/README.md | 10 ++ docs/build/Android.md | 7 +- docs/build/FreeBSD.md | 81 ------------- docs/build/Linux.md | 201 ------------------------------- docs/build/OpenBSD.md | 10 -- docs/build/Solaris.md | 51 -------- docs/build/Windows.md | 259 ---------------------------------------- docs/build/macOS.md | 78 ------------ docs/img/creator-1.png | Bin 0 -> 64671 bytes docs/scripts/Linux.md | 31 +++++ docs/scripts/Windows.md | 76 ++++++++++++ 17 files changed, 579 insertions(+), 706 deletions(-) create mode 100644 docs/Build.md create mode 100644 docs/Caveats.md create mode 100644 docs/Deps.md create mode 100644 docs/Options.md create mode 100644 docs/README.md delete mode 100644 docs/build/FreeBSD.md delete mode 100644 docs/build/Linux.md delete mode 100644 docs/build/OpenBSD.md delete mode 100644 docs/build/Solaris.md delete mode 100644 docs/build/Windows.md delete mode 100644 docs/build/macOS.md create mode 100644 docs/img/creator-1.png create mode 100644 docs/scripts/Linux.md create mode 100644 docs/scripts/Windows.md diff --git a/docs/Build.md b/docs/Build.md new file mode 100644 index 0000000000..910f8b43e2 --- /dev/null +++ b/docs/Build.md @@ -0,0 +1,124 @@ +# Building Eden + +> [!WARNING] +> This guide is intended for developers ONLY. If you are not a developer or packager, you are unlikely to receive support. + +This is a full-fledged guide to build Eden on all supported platforms. + +## Dependencies +First, you must [install some dependencies](Deps.md). + +## Clone +Next, you will want to clone Eden via the terminal: + +```sh +git clone https://git.eden-emu.dev/eden-emu/eden.git +cd eden +``` + +Or use Qt Creator (Create Project -> Import Project -> Git Clone). + +## Android + +Android has a completely different build process than other platforms. See its [dedicated page](build/Android.md). + +## Initial Configuration + +If the configure phase fails, see the `Troubleshooting` section below. Usually, as long as you followed the dependencies guide, the defaults *should* successfully configure and build. + +### Qt Creator + +This is the recommended GUI method for Linux, macOS, and Windows. + +
+Click to Open + +> [!WARNING] +> On MSYS2, to use Qt Creator you are recommended to *also* install Qt from the online installer, ensuring to select the "MinGW" version. + +Open the CMakeLists.txt file in your cloned directory via File -> Open File or Project (Ctrl+O), if you didn't clone Eden via the project import tool. + +Select your desired "kit" (usually, the default is okay). RelWithDebInfo or Release is recommended: + +![Qt Creator kits](img/creator-1.png) + +Hit "Configure Project", then wait for CMake to finish configuring (may take a while on Windows). + +
+ +### Command Line + +This is recommended for *BSD, Solaris, Linux, and MSYS2. MSVC is possible, but not recommended. + +
+Click to Open + +Note that CMake must be in your PATH, and you must be in the cloned Eden directory. On Windows, you must also set up a Visual C++ development environment. This can be done by running `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat` in the same terminal. + +Recommended generators: +- MSYS2: `MSYS Makefiles` +- MSVC: Install **[ninja](https://ninja-build.org/)** and use `Ninja`, OR use `Visual Studio 17 2022` +- macOS: `Ninja` (preferred) or `Xcode` +- Others: `Ninja` (preferred) or `UNIX Makefiles` + +BUILD_TYPE should usually be `Release` or `RelWithDebInfo` (debug symbols--compiled executable will be large). If you are using a debugger and annoyed with stuff getting optimized out, try `Debug`. + +Also see the [Options](Options.md) page for additional CMake options. + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_BUILD_TYPE= -DYUZU_TESTS=OFF +``` + +If you are on Windows and prefer to use Clang: + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl +``` + +
+ +### CLion + +TODO + +## Troubleshooting + +If your initial configure failed: +- *Carefully* re-read the [dependencies guide](Deps.md) +- Clear the CPM cache (`.cache/cpm`) and CMake cache (`/CMakeCache.txt`) +- Evaluate the error and find any related settings +- See the [CPM docs](CPM.md) to see if you may need to forcefully bundle any packages + +Otherwise, feel free to ask for help in Revolt or Discord. + +## Caveats + +Many platforms have quirks, bugs, and other fun stuff that may cause issues when building OR running. See the [Caveats page](Caveats.md) before continuing. + +## Building & Running + +### Qt Creator + +Simply hit Ctrl+B, or the "hammer" icon in the bottom left. To run, hit the "play" icon, or Ctrl+R. + +### Command Line + +If you are not on Windows, and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. + +``` +cmake --build build +``` + +Your compiled executable will be in: +- `build/bin/eden.exe` for Windows, +- `build/bin/eden.app/Contents/MacOS/eden` for macOS, +- and `build/bin/eden` for others. + +## Scripts + +Some platforms have convenience scripts provided for building. + +- **[Linux](scripts/Linux.md)** +- **[Windows](scripts/Windows.md)** + +macOS scripts will come soon. Maybe. \ No newline at end of file diff --git a/docs/CPM.md b/docs/CPM.md index bce224da40..03d8a039f9 100644 --- a/docs/CPM.md +++ b/docs/CPM.md @@ -177,7 +177,7 @@ If `ci` is `true`: ### Examples -In order: OpenSSL CI, Boost (tag + artifact), discord-rpc (sha + options + patches), Opus (options + find_args) +In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches) ```json { diff --git a/docs/Caveats.md b/docs/Caveats.md new file mode 100644 index 0000000000..7bc2428bab --- /dev/null +++ b/docs/Caveats.md @@ -0,0 +1,52 @@ +# Caveats + +## Arch Linux + +- httplib AUR package is broken. Set `httplib_FORCE_BUNDLED=ON` if you have it installed. +- Eden is also available as an [AUR package](https://aur.archlinux.org/packages/eden-git). If you are unable to build, either use that or compare your process to the PKGBUILD. + +## Gentoo Linux + +Do not use the system sirit or xbyak packages. + +## macOS + +macOS is largely untested. Expect crashes, significant Vulkan issues, and other fun stuff. + +## Solaris + +Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configure command. In the meantime, a Qt Quick frontend is in the works--check back later! + +This is needed for some dependencies that call cc directly (tz): + +```sh +echo '#!/bin/sh' >cc +echo 'gcc $@' >>cc +chmod +x cc +export PATH="$PATH:$PWD" +``` + +Default MESA is a bit outdated, the following environment variables should be set for a smoother experience: +```sh +export MESA_GL_VERSION_OVERRIDE=4.6 +export MESA_GLSL_VERSION_OVERRIDE=460 +export MESA_EXTENSION_MAX_YEAR=2025 +export MESA_DEBUG=1 +export MESA_VK_VERSION_OVERRIDE=1.3 +# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance +export LIBGL_ALWAYS_SOFTWARE=1 +``` + +- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). +- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this. +- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source. + +## OpenBSD + +After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. + +## FreeBSD + +Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. + +The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_BUNDLED_OPENSSL=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md new file mode 100644 index 0000000000..cd875cd292 --- /dev/null +++ b/docs/Deps.md @@ -0,0 +1,212 @@ +# Dependencies + +To build Eden, you MUST have a C++ compiler. +* On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+ + - GCC 12 also requires Clang 14+ +* On Windows, this is either: + - **[MSVC](https://visualstudio.microsoft.com/downloads/)**, + * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* + - clang-cl - can be downloaded from the MSVC installer, + - or **[MSYS2](https://www.msys2.org)** +* On macOS, this is Apple Clang + - This can be installed with `xcode-select --install` + +The following additional tools are also required: + +* **[CMake](https://www.cmake.org/)** 3.22+ - already included with the Android SDK +* **[Git](https://git-scm.com/)** for version control + - **[Windows installer](https://gitforwindows.org)** +* On Windows, you must install the **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** as well + - *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* + +If you are on desktop and plan to use the Qt frontend, you *must* install Qt 6, and optionally Qt Creator (the recommended IDE for building) +* On Linux, *BSD and macOS, this can be done by the package manager + - If you wish to use Qt Creator, append `qtcreator` or `qt-creator` to the commands seen below. +* MSVC/clang-cl users on Windows must install through the [official installer](https://www.qt.io/download-qt-installer-oss) +* Linux and macOS users may choose to use the installer as well. +* MSYS2 can also install Qt 6 via the package manager + +If you are on Windows and NOT building with MSYS2, you may go [back home](Build.md) and continue. + +## Externals +The following are handled by Eden's externals: + +* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) +* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON` OR `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) + +All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available (UNIX-like only): + +* [Boost](https://www.boost.org/users/download/) 1.57.0+ +* [Catch2](https://github.com/catchorg/Catch2) 3.0.1 if `YUZU_TESTS` or `DYNARMIC_TESTS` are on +* [fmt](https://fmt.dev/) 8.0.1+ +* [lz4](http://www.lz4.org) +* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ +* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ +* [ZLIB](https://www.zlib.net/) 1.2+ +* [zstd](https://facebook.github.io/zstd/) 1.5+ +* [enet](http://enet.bespin.org/) 1.3+ +* [Opus](https://opus-codec.org/) 1.3+ +* [MbedTLS](https://github.com/Mbed-TLS/mbedtls) 3+ + +Vulkan 1.3.274+ is also needed: +* [VulkanUtilityLibraries](https://github.com/KhronosGroup/Vulkan-Utility-Libraries) +* [VulkanHeaders](https://github.com/KhronosGroup/Vulkan-Headers) +* [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) +* [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) + +Certain other dependencies will be fetched by CPM regardless. System packages *can* be used for these libraries, but many are either not packaged by most distributions OR have issues when used by the system: + +* [SimpleIni](https://github.com/brofield/simpleini) +* [DiscordRPC](https://github.com/eden-emulator/discord-rpc) +* [cubeb](https://github.com/mozilla/cubeb) +* [libusb](https://github.com/libusb/libusb) +* [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) +* [sirit](https://github.com/eden-emulator/sirit) +* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on +* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on +* [unordered-dense](https://github.com/martinus/unordered_dense) +* [mcl](https://github.com/azahar-emu/mcl) - subject to removal + +On amd64: +* [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended +* [zycore](https://github.com/zyantific/zycore-c) +* [zydis](https://github.com/zyantific/zydis) 4+ +* Note: zydis and zycore-c MUST match. Using one as a system dependency and the other as a bundled dependency WILL break things + +On aarch64 OR if `DYNARMIC_TESTS` is on: +* [oaknut](https://github.com/merryhime/oaknut) 2.0.1+ + +On riscv64: +* [biscuit](https://github.com/lioncash/biscuit) 0.9.1+ + +## Commands + +These are commands to install all necessary dependencies on various Linux and BSD distributions, as well as macOS. Always review what you're running before you hit Enter! + +Click on the arrows to expand. + +
+Arch Linux + +```sh +sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip zydis zycore vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers +``` + +* Building with QT Web Engine requires `qt6-webengine` as well. +* Proper Wayland support requires `qt6-wayland` +* GCC 11 or later is required. +
+ +
+Ubuntu, Debian, Mint Linux + +```sh +sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +``` + +* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. +
+ +
+Fedora Linux + +```sh +sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel +``` + +* Force system libraries via CMake arguments: + * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` +* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` +* Fedora 32 or later is required. +* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: +
+ +
+macOS +Install dependencies from **[Homebrew](https://brew.sh/)** + +```sh +brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools +``` + +If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. + +To run with MoltenVK, install additional dependencies: +```sh +brew install molten-vk vulkan-loader +``` + +
+ +
+FreeBSD + +``` +devel/cmake +devel/sdl20 +devel/boost-libs +devel/catch2 +devel/libfmt +devel/nlohmann-json +devel/ninja +devel/nasm +devel/autoconf +devel/pkgconf +devel/qt6-base + +net/enet + +multimedia/ffnvcodec-headers +multimedia/ffmpeg + +audio/opus + +archivers/liblz4 + +lang/gcc12 + +graphics/glslang +graphics/vulkan-utility-libraries +``` + +If using FreeBSD 12 or prior, use `devel/pkg-config` instead. +
+ +
+OpenBSD + +```sh +pkg_add -u +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq +``` +
+ +
+Solaris / OpenIndiana + +Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. + +Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. + +- **gcc**: `sudo pkg install developer/gcc-14`. +- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. + +Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. +
+ +
+MSYS2 +* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) +* Download and install all dependencies using: + * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` +* Add MinGW binaries to the PATH: + * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` +* Add VulkanSDK to the PATH: + * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` +
+ +## All Done + +You may now return to the **[root build guide](Build.md)**. \ No newline at end of file diff --git a/docs/Development.md b/docs/Development.md index e4816cd1ec..d170818d10 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -1,23 +1,3 @@ -# Development - -* **Windows**: [Windows Building Guide](./build/Windows.md) -* **Linux**: [Linux Building Guide](./build/Linux.md) -* **Android**: [Android Building Guide](./build/Android.md) -* **Solaris**: [Solaris Building Guide](./build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./build/OpenBSD.md) - -# CPM - -CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden. Documentation on adding dependencies/using CPMUtil is in the works. - -Notes: -- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing -- `CPMUTIL_DEFAULT_SYSTEM` can be set to `OFF` to force the usage of bundled dependencies. This can marginally decrease the final package size. -- When adding new prebuilt dependencies a la OpenSSL, SDL2, or FFmpeg, there *must* be a CMake option made available to forcefully download this bundle. See the OpenSSL implementation in the root CMakeLists for an example. - * This is necessary to allow for creation of fully-qualified source packs that allow for offline builds after download (some package managers and distros enforce this) - # Guidelines ## License Headers @@ -37,6 +17,8 @@ FIX=true .ci/license-header.sh git commit --amend -a --no-edit ``` +If the work is licensed/vendored from other people or projects, you may omit the license headers. Additionally, if you wish to retain authorship over a piece of code, you may attribute it to yourself; however, the code may be changed at any given point and brought under the attribution of Eden. + ## Pull Requests Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed: ``` @@ -49,7 +31,7 @@ Pull requests are only to be merged by core developers when properly tested and - The level of namespacing is generally left to the committer's choice. - However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes. -- Ocassionally, up to two namespaces may be provided for more clarity. +- Ocassionally, up to two additional namespaces may be provided for more clarity. * Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`. - Maintainers are permitted to change namespaces at will. - Commits within PRs are not required to be namespaced, but it is highly recommended. diff --git a/docs/Options.md b/docs/Options.md new file mode 100644 index 0000000000..61f578df8b --- /dev/null +++ b/docs/Options.md @@ -0,0 +1,67 @@ +# CMake Options + +To change these options, add `-DOPTION_NAME=NEWVALUE` to the command line. + +- On Qt Creator, go to Project -> Current Configuration + +Notes: +- Defaults are marked per-platform. +- "Non-UNIX" just means Windows/MSVC and Android (yes, macOS is UNIX +- Android generally doesn't need to change anything; if you do, go to `src/android/app/build.gradle.kts` +- To set a boolean variable to on, use `ON` for the value; to turn it off, use `OFF` +- If a variable is mentioned as being e.g. "ON" for a specific platform(s), that means it is defaulted to OFF on others +- TYPE is always boolean unless otherwise specified +- Format: + * `OPTION_NAME` (TYPE DEFAULT) DESCRIPTION + +## Options + +- `YUZU_USE_CPM` (ON for non-UNIX) Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched. See the [CPM](CPM.md) and [Deps](Deps.md) docs for more info. +- `ENABLE_WEB_SERVICE` (ON) Enable multiplayer service +- `ENABLE_WIFI_SCAN` (OFF) Enable WiFi scanning (requires iw on Linux) - experimental +- `YUZU_USE_BUNDLED_FFMPEG` (ON for non-UNIX) Download (Windows, Android) or build (UNIX) bundled FFmpeg +- `ENABLE_CUBEB` (ON) Enables the cubeb audio backend +- `YUZU_TESTS` (ON) Compile tests - requires Catch2 +- `YUZU_USE_PRECOMPILED_HEADERS` (ON for non-UNIX) Use precompiled headers +- `YUZU_DOWNLOAD_ANDROID_VVL` (ON) Download validation layer binary for Android +- `YUZU_ENABLE_LTO` (OFF) Enable link-time optimization + * Not recommended on Windows + * UNIX may be better off appending `-flto=thin` to compiler args +- `YUZU_DOWNLOAD_TIME_ZONE_DATA` (ON) Always download time zone binaries + * Currently, build fails without this +- `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available + * Only available on UNIX +- `USE_SYSTEM_MOLTENVK` (OFF, macOS only) Use the system MoltenVK lib (instead of the bundled one) +- `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS) +- `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service + * Always enabled if the web service is enabled +- `YUZU_USE_BUNDLED_OPENSSL` (ON for MSVC) Download bundled OpenSSL build + * Always on for Android + * Unavailable on OpenBSD + +The following options are desktop only: +- `ENABLE_SDL2` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) + * Unavailable on Android +- `YUZU_USE_EXTERNAL_SDL2` (ON for non-UNIX) Compiles SDL2 from source +- `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2 + * Unavailable on OpenBSD + * Only enabled if YUZU_USE_CPM and ENABLE_SDL2 are both ON +- `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED) +- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics frontend + * Unavailable on Windows/ARM64 and Android +- `ENABLE_QT` (ON) Enable the Qt frontend (recommended) +- `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend +- `ENABLE_QT_UPDATE_CHECKER` (OFF) Enable update checker for the Qt frontend +- `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries +- `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries +- `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support +- `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended) +- `USE_DISCORD_PRESENCE` (OFF) Enables Discord Rich Presence (Qt frontend only) +- `YUZU_ROOM` (ON) Enable dedicated room functionality +- `YUZU_ROOM_STANDALONE` (ON) Enable standalone room executable (eden-room) + * Requires `YUZU_ROOM` +- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli) - requires SDL2 +- `YUZU_CRASH_DUMPS` Compile crash dump (Minidump) support" + * Currently only available on Windows and Linux + +See `src/dynarmic/CMakeLists.txt` for additional options--usually, these don't need changed \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..ba489b7218 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# Eden Build Documentation + +This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](CPM.md), and more. + +- **[General Build Instructions](CPM.md)** +- **[Development Guidelines](Development.md)** +- **[Dependencies](Deps.md)** +- **[CPM - CMake Package Manager](CPM.md)** +- **[Platform-Specific Caveats](Caveats.md)** +- **[User Directory Handling](User.md)** \ No newline at end of file diff --git a/docs/build/Android.md b/docs/build/Android.md index 0538d351ea..c8ff3a3b1e 100644 --- a/docs/build/Android.md +++ b/docs/build/Android.md @@ -2,7 +2,7 @@ ## Dependencies * [Android Studio](https://developer.android.com/studio) -* [NDK 25.2.9519653 and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) +* [NDK 27+ and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) * [Git](https://git-scm.com/download) ### WINDOWS ONLY - Additional Dependencies @@ -16,8 +16,7 @@ git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git ``` Eden by default will be cloned into - * `C:\Users\\eden` on Windows -* `~/eden` on Linux -* And wherever on macOS +* `~/eden` on Linux and macOS ## Building 1. Start Android Studio, on the startup dialog select `Open`. @@ -32,7 +31,7 @@ Eden by default will be cloned into - `export ANDROID_SDK_ROOT=path/to/sdk` `export ANDROID_NDK_ROOT=path/to/ndk`. 4. Navigate to `eden/src/android`. -5. Then Build with `./gradlew assemblerelWithDebInfo`. +5. Then Build with `./gradlew assembleRelWithDebInfo`. 6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`. ### Script diff --git a/docs/build/FreeBSD.md b/docs/build/FreeBSD.md deleted file mode 100644 index 97eef8f9d8..0000000000 --- a/docs/build/FreeBSD.md +++ /dev/null @@ -1,81 +0,0 @@ -Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. Check back often, as the build process frequently changes. - -## Dependencies. -Eden needs the following dependencies: - -``` -devel/cmake -devel/sdl20 -devel/boost-libs -devel/catch2 -devel/libfmt -devel/nlohmann-json -devel/ninja -devel/nasm -devel/autoconf -devel/pkgconf -devel/qt6-base - -net/enet - -multimedia/ffnvcodec-headers -multimedia/ffmpeg - -audio/opus - -archivers/liblz4 - -lang/gcc12 - -graphics/glslang -graphics/vulkan-utility-libraries -``` - -If using FreeBSD 12 or prior, use `devel/pkg-config` instead. - ---- - -### Build preparations: -Run the following command to clone eden with git: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -``` -You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you. - -Now change into the eden directory and create a build directory there: -```sh -cd eden -mkdir build -``` - -Change into that build directory: -```sh -cd build -``` - -#### 1. Building in Release Mode (usually preferred and the most performant choice): -```sh -cmake .. -GNinja -DYUZU_TESTS=OFF -``` - -#### 2. Building in Release Mode with debugging symbols (useful if you want to debug errors for a eventual fix): -```sh -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=ON -``` - -Build the emulator locally: -```sh -ninja -``` - -Optional: If you wish to install eden globally onto your system issue the following command: -```sh -sudo ninja install -``` -OR -```sh -doas -- ninja install -``` - -## OpenSSL -The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_CPM=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/build/Linux.md b/docs/build/Linux.md deleted file mode 100644 index 5bbd2b1d4b..0000000000 --- a/docs/build/Linux.md +++ /dev/null @@ -1,201 +0,0 @@ -# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. - -## 📋 Index: - -* [Minimal Dependencies](#minimal-dependencies) -* [Cloning Eden with Git](#cloning-eden-with-git) -* [Arch / Manjaro](#arch-manjaro) -* [Ubuntu / Linux Mint / Debian](#ubuntu-linux-mint-debian) -* [Fedora](#fedora) -* [Building with Scripts](#building-with-scripts) -* [Running without Installing](#running-without-installing) - ---- - -## Minimal Dependencies - -You'll need to download and install the following to build Eden: - -* [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc -* If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling -* [CMake](https://www.cmake.org/) 3.22+ -* [Git](https://git-scm.com/) for version control - -The following are handled by Eden's externals: - -* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) -* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON`) -* [opus](https://opus-codec.org/downloads/) 1.3+ - -All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available: - -* [Boost](https://www.boost.org/users/download/) 1.79.0+ -* [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 -* [fmt](https://fmt.dev/) 8.0.1+ -* [lz4](http://www.lz4.org) 1.8+ -* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ -* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ -* [ZLIB](https://www.zlib.net/) 1.2+ -* [zstd](https://facebook.github.io/zstd/) 1.5+ -* [enet](http://enet.bespin.org/) 1.3+ -* [cubeb](https://github.com/mozilla/cubeb) -* [SimpleIni](https://github.com/brofield/simpleini) - -Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended. - -Dependencies are listed here as commands that can be copied/pasted. Inspect them before running. - -## Cloning Eden with Git - -**Master:** - -```bash -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -## Arch / Manjaro - -```sh -sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip -``` -* Building with QT Web Engine requires `qt6-webengine` as well. -* Proper Wayland support requires `qt6-wayland` -* GCC 11 or later is required. - -## Ubuntu / Linux Mint / Debian - -```sh -sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev -``` -* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. -* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - -```sh -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 - -# Build -ninja -``` - -## Fedora - -```sh -sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel -``` -* Force system libraries via CMake arguments: - * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` - * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` -* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` -* Fedora 32 or later is required. -* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: -```sh -# Generate CMake Makefiles (for Clang compiler) -cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -``` - -## Building Eden in Release Mode (Optimised) - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DYUZU_TESTS=OFF - -# Build -ninja - -# Install! -sudo ninja install -``` - -* Enable Discord Rich Presence: -```bash -# ... - -# Generate CMake Makefiles (with Discord Rich Presence) -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON - -# ... -``` - -* If ninja fails with `undefined reference to symbol 'spvOptimizerOptionsCreate'`, add `-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` -* Optionally use `cmake-gui ..` to adjust options (e.g., disable Qt GUI) - -## Building Eden in Debug Mode (Slow) - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF - -# Build -ninja -``` - -## Building with Debug Symbols - -```bash -# Make build dir and enter - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF - -# Build -ninja -``` - -## Building with Scripts - -* Provided script: `.ci/linux/build.sh` -* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` -* Valid targets: - * `native`: Optimize to your native host architecture - * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so - * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so - * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) - * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) - * `aarch64`: For armv8-a CPUs, older than mid-2021 or so - * `armv9`: For armv9-a CPUs, newer than mid-2021 or so -* Extra CMake flags go after the arch target. - -### Environment Variables - -* `NPROC`: Number of compilation threads (default: all cores) -* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` -* `BUILD_TYPE`: Build type (default: `Release`) - -Boolean flags (set `true` to enable, `false` to disable): - -* `DEVEL` (default `FALSE`): Disable Qt update checker - -* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine - -* `USE_MULTIMEDIA` (default `TRUE`): Enable Qt Multimedia - -* AppImage packaging script: `.ci/linux/package.sh` - - * Accepts same arch targets as build script - * Use `DEVEL=true` to rename app to `Eden Nightly` - -## Running without Installing - -After building, binaries `eden` and `eden-cmd` will be in `build/bin/`. - -```bash -# Build Dir -cd build/bin/ - -# SDL2 build -./eden-cmd - -# Qt build -./eden -``` diff --git a/docs/build/OpenBSD.md b/docs/build/OpenBSD.md deleted file mode 100644 index 6a55fd269d..0000000000 --- a/docs/build/OpenBSD.md +++ /dev/null @@ -1,10 +0,0 @@ -# Building for OpenBSD - -```sh -pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq -git --recursive https://git.eden-emu.dev/eden-emu/eden -cmake -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DDYNARMIC_USE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_QT=OFF -DENABLE_OPENSSL=OFF -DENABLE_WEB_SERVICE=OFF -B /usr/obj/eden -``` - -- Modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. diff --git a/docs/build/Solaris.md b/docs/build/Solaris.md deleted file mode 100644 index f7174c2869..0000000000 --- a/docs/build/Solaris.md +++ /dev/null @@ -1,51 +0,0 @@ -# Building for Solaris - -## Dependencies. -Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. - -Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. - -- **gcc**: `sudo pkg install developer/gcc-14`. -- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. - -Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. - -### Building - -Clone eden with git `git clone --recursive https://git.eden-emu.dev/eden-emu/eden` - -```sh -# Needed for some dependencies that call cc directly (tz) -echo '#!/bin/sh' >cc -echo 'gcc $@' >>cc -chmod +x cc -export PATH="$PATH:$PWD" -``` - -Patch for FFmpeg: -```sh -sed -i 's/ make / gmake /' externals/ffmpeg/CMakeFiles/ffmpeg-build.dir/build.make -``` - -- **Configure**: `cmake -B build -DYUZU_USE_CPM=ON -DCMAKE_CXX_FLAGS="-I/usr/include/SDL2" -DCMAKE_C_FLAGS="-I/usr/include/SDL2"`. -- **Build**: `cmake --build build`. -- **Installing**: `sudo cmake --install build`. - -### Running - -Default Mesa is a bit outdated, the following environment variables should be set for a smoother experience: -```sh -export MESA_GL_VERSION_OVERRIDE=4.6 -export MESA_GLSL_VERSION_OVERRIDE=460 -export MESA_EXTENSION_MAX_YEAR=2025 -export MESA_DEBUG=1 -export MESA_VK_VERSION_OVERRIDE=1.3 -# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance -export LIBGL_ALWAYS_SOFTWARE=1 -``` - -### Notes - -- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). -- If using OpenIndiana, due to a bug in SDL2 cmake configuration; Audio driver defaults to SunOS ``, which does not exist on OpenIndiana. -- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_CPM=ON` to use a bundled static OpenSSL, or build a system dependency from source. \ No newline at end of file diff --git a/docs/build/Windows.md b/docs/build/Windows.md deleted file mode 100644 index 93ee9fe551..0000000000 --- a/docs/build/Windows.md +++ /dev/null @@ -1,259 +0,0 @@ -# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. - -## 📋 Current building methods: - -* [ Minimal Dependencies](#minimal-dependencies) -* [⚡ Method I: MSVC Build for Windows](#method-i-msvc-build-for-windows) -* [🐧 Method II: MinGW-w64 Build with MSYS2](#method-ii-mingw-w64-build-with-msys2) -* [🖥️ Method III: CLion Environment Setup](#method-iii-clion-environment-setup) -* [💻 Building from the command line with MSVC](#building-from-the-command-line-with-msvc) -* [📜 Building with Scripts](#building-with-scripts) - ---- - - -## Minimal Dependencies - -On Windows, **all** library dependencies are **automatically included** within the `externals` folder. - -You still need to install: - -* **[CMake](https://cmake.org/download/)** - Used to generate Visual Studio project files. -* **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - Make sure to select **Latest SDK**. - - * *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* -* **[Git for Windows](https://gitforwindows.org)** - We recommend installing Git for command line use and version control integration. - - - - * *While installing Git Bash, select "Git from the command line and also from 3rd-party software". If missed, manually set `git.exe` path in CMake.* - ---- - -## ⚡ Method I: MSVC Build for Windows - -### a. Prerequisites to MSVC Build - -* **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - Make sure to **select C++ support** in the installer, or **update to the latest version** if already installed. - - * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* - ---- - -### b. Clone the eden repository with Git - -Open Terminal on - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -* *By default `eden` downloads to `C:\Users\\eden`* - ---- - -### c. Building - -* Open the CMake GUI application and point it to the `eden` - - - -* For the build directory, use a `build/` subdirectory inside the source directory or some other directory of your choice. (Tell CMake to create it.) - -* Click the "Configure" button and choose `Visual Studio 17 2022`, with `x64` for the optional platform. - - - - * *(You may also want to disable `YUZU_TESTS` in this case since Catch2 is not yet supported with this.)* - - - -* Click "Generate" to create the project files. - - - -* Open the solution file `yuzu.sln` in Visual Studio 2022, which is located in the build folder. - - - -* * Depending on whether you want a graphical user interface or not, select in the Solution Explorer: - * `eden` (GUI) - * `eden-cmd` (command-line only) - * Then **right-click** and choose `Set as StartUp Project`. - - - - -* Select the appropriate build type, `Debug` for debug purposes or `Release` for performance (in case of doubt choose `Release`). - - - -* **Right-click** the project you want to build and press **Build** in the submenu or press `F5`. - - - ---- - -## 🐧 Method II: MinGW-w64 Build with MSYS2 - -### a. Prerequisites to MinGW-w64 - -* **[MSYS2](https://www.msys2.org)** - A versatile and up-to-date development environment for Windows, providing a Unix-like shell, package manager, and toolchain. - ---- - -### b. Install eden dependencies for MinGW-w64 - -* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) -* Download and install all dependencies using: - * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` -* Add MinGW binaries to the PATH: - * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` -* Add VulkanSDK to the PATH: - * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` - ---- - -### c. Clone the eden repository with Git - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - ---- - -### d. Building dynamically-linked eden - -* This process will generate a *dynamically* linked build - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF - -# Build -make -j$(nproc) - -# Run eden! -./bin/eden.exe -``` - -* *Warning: This build is not a **static** build meaning that you **need** to include all of the DLLs with the .exe in order to use it or other systems!* - ---- - -### Additional notes - - -* Eden doesn't require the rather large Qt dependency, but you will lack a GUI frontend - -```bash -# ... - -# Generate CMake Makefiles (withou QT) -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DENABLE_QT=no - -# ... -``` - -* Running programs from inside `MSYS2 MinGW x64` shell has a different `%PATH%` than directly from explorer. - * This different `%PATH%` has the locations of the other DLLs required. - - - ---- - -## 🖥️ Method III: CLion Environment Setup - -### a. Prerequisites to CLion - -* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I - ---- - -### b. Cloning eden with CLion - -* Clone the Repository: - - - - - ---- - -### c. Building & Setup - -* Once Cloned, You will be taken to a prompt like the image below: - - - -* Set the settings to the image below: -* Change `Build type: Release` -* Change `Name: Release` -* Change `Toolchain Visual Studio` -* Change `Generator: Let CMake decide` -* Change `Build directory: build` - - - -* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. -* Once this process has been completed (No loading bar bottom right), you can now build eden -* In the top right, click on the drop-down menu, select all configurations, then select eden - - - -* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. - - - ---- - -## 💻 Building from the command line with MSVC - -```cmd -# Clone eden and enter -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden - -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "Visual Studio 17 2022" -A x64 -DYUZU_TESTS=OFF - -# Build -cmake --build . --config Release -``` - -## 📜 Building with Scripts - -* A convenience script for building is provided in `.ci/windows/build.sh`. -* You must run this with Bash, e.g. Git Bash or MinGW TTY. -* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: - * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. -* You can use `aqtinstall`, more info on and - - -* Extra CMake flags should be placed in the arguments of the script. - -#### Additional environment variables can be used to control building: - -* `BUILD_TYPE` (default `Release`): Sets the build type to use. - -* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: - - * `DEVEL` (default FALSE): Disable Qt update checker - * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine - * `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia - * `BUNDLE_QT` (default FALSE): Use bundled Qt - - * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` - * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` - -* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. - * The resulting zip will be placed into `artifacts` in the source directory. - diff --git a/docs/build/macOS.md b/docs/build/macOS.md deleted file mode 100644 index fd1873b849..0000000000 --- a/docs/build/macOS.md +++ /dev/null @@ -1,78 +0,0 @@ -Please note this article is intended for development, and Eden on macOS is not currently ready for regular use. - -This article was written for developers. Eden support for macOS is not ready for casual use. - -## Dependencies -Install dependencies from Homebrew: -```sh -brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools -``` - -If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. - -Now, clone the repo: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -## Method I: ninja - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -ninja -``` - -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - -## Method II: Xcode - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -# Only if having errors about Xcode 15.0 -sudo /usr/bin/xcode-select --switch /Users/admin/Downloads/Xcode.ap -cmake -B build -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -xcodebuild build -project yuzu.xcodeproj -scheme "yuzu" -configuration "RelWithDebInfo" -``` - -Build with debug symbols: -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - ---- - -To run with MoltenVK, install additional dependencies: -```sh -brew install molten-vk vulkan-loader -``` - -Run with Vulkan loader path: -```sh -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -bin/eden.app/Contents/MacOS/eden -``` diff --git a/docs/img/creator-1.png b/docs/img/creator-1.png new file mode 100644 index 0000000000000000000000000000000000000000..14d679cfbb6dabd5bcf7300395aa4d22ae2b1d62 GIT binary patch literal 64671 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μ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%0Ay*v1tt;;D^9?ybazI(tsNvoIkg)qOU2gHM0m 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 literal 0 HcmV?d00001 diff --git a/docs/scripts/Linux.md b/docs/scripts/Linux.md new file mode 100644 index 0000000000..8b18e41ced --- /dev/null +++ b/docs/scripts/Linux.md @@ -0,0 +1,31 @@ +# Linux Build Scripts + +* Provided script: `.ci/linux/build.sh` +* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` +* Valid targets: + * `native`: Optimize to your native host architecture + * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so + * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so + * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) + * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) + * `aarch64`: For armv8-a CPUs, older than mid-2021 or so + * `armv9`: For armv9-a CPUs, newer than mid-2021 or so +* Extra CMake flags go after the arch target. + +### Environment Variables + +* `NPROC`: Number of compilation threads (default: all cores) +* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` +* `BUILD_TYPE`: Build type (default: `Release`) + +Boolean flags (set `true` to enable, `false` to disable): + +* `DEVEL` (default `FALSE`): Disable Qt update checker +* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine +* `USE_MULTIMEDIA` (default `FALSE`): Enable Qt Multimedia + +* AppImage packaging script: `.ci/linux/package.sh` + + * Accepts same arch targets as build script + * Use `DEVEL=true` to rename app to `Eden Nightly` + * This should generally not be used unless in a tailor-made packaging environment (e.g. Actions/CI) \ No newline at end of file diff --git a/docs/scripts/Windows.md b/docs/scripts/Windows.md new file mode 100644 index 0000000000..c1ebb5a4c2 --- /dev/null +++ b/docs/scripts/Windows.md @@ -0,0 +1,76 @@ +# Windows Build Scripts + +* A convenience script for building is provided in `.ci/windows/build.sh`. +* You must run this with Bash, e.g. Git Bash or the MinGW TTY. +* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: + * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. +* You can use `aqtinstall`, more info on and + + +* Extra CMake flags should be placed in the arguments of the script. + +#### Additional environment variables can be used to control building: + +* `BUILD_TYPE` (default `Release`): Sets the build type to use. + +* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: + + * `DEVEL` (default FALSE): Disable Qt update checker + * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine + * `USE_MULTIMEDIA` (default FALSE): Enable Qt Multimedia + * `BUNDLE_QT` (default FALSE): Use bundled Qt + + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` + * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` + +* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. + * The resulting zip will be placed into `artifacts` in the source directory. + + +## 🖥️ Method III: CLion Environment Setup + +### a. Prerequisites to CLion + +* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I + +--- + +### b. Cloning eden with CLion + +* Clone the Repository: + + + + + +--- + +### c. Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + + + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + + + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + + + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + + + +--- + + + From e30d68e16050c6794c50d861a0473db7bac43d75 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:18:20 -0400 Subject: [PATCH 04/17] Oops Signed-off-by: crueter --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ba489b7218..71e79e15ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](CPM.md), and more. -- **[General Build Instructions](CPM.md)** +- **[General Build Instructions](Build.md)** - **[Development Guidelines](Development.md)** - **[Dependencies](Deps.md)** - **[CPM - CMake Package Manager](CPM.md)** From c1b83a6ee3a4c025440b2d63dd3eb4e935527f31 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:20:18 -0400 Subject: [PATCH 05/17] fix Signed-off-by: crueter --- docs/Build.md | 2 +- docs/Deps.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Build.md b/docs/Build.md index 910f8b43e2..13aa142ac0 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -75,7 +75,7 @@ If you are on Windows and prefer to use Clang: cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl ``` -
+
### CLion diff --git a/docs/Deps.md b/docs/Deps.md index cd875cd292..9cfe36b547 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -125,6 +125,7 @@ sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel
macOS + Install dependencies from **[Homebrew](https://brew.sh/)** ```sh @@ -198,6 +199,7 @@ Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz
MSYS2 + * Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) * Download and install all dependencies using: * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` From 1e69a91193f84f1f5695960ee64b87dd739389e3 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 22:29:41 -0400 Subject: [PATCH 06/17] [docs] clion, openbsd deps, readme Signed-off-by: crueter --- README.md | 8 +------ docs/Build.md | 44 ++++++++++++++++++++++++++++++++++---- docs/Deps.md | 4 ++-- docs/Options.md | 2 ++ docs/scripts/Windows.md | 47 ----------------------------------------- 5 files changed, 45 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index e1f0b50b37..959b903385 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,7 @@ If you would like to contribute, we are open to new developers and pull requests ## Building -* **Windows**: [Windows Building Guide](./docs/build/Windows.md) -* **Linux**: [Linux Building Guide](./docs/build/Linux.md) -* **Android**: [Android Building Guide](./docs/build/Android.md) -* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./docs/build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./docs/build/OpenBSD.md) +See the [General Build Guide](docs/Build.md) ## Download diff --git a/docs/Build.md b/docs/Build.md index 13aa142ac0..52a671ab1e 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -56,6 +56,7 @@ This is recommended for *BSD, Solaris, Linux, and MSYS2. MSVC is possible, but n Note that CMake must be in your PATH, and you must be in the cloned Eden directory. On Windows, you must also set up a Visual C++ development environment. This can be done by running `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat` in the same terminal. Recommended generators: + - MSYS2: `MSYS Makefiles` - MSVC: Install **[ninja](https://ninja-build.org/)** and use `Ninja`, OR use `Visual Studio 17 2022` - macOS: `Ninja` (preferred) or `Xcode` @@ -77,9 +78,44 @@ cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPI
-### CLion +### [CLion](https://www.jetbrains.com/clion/) -TODO +
+Click to Open + +* Clone the Repository: + + + + + +--- + +### Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + + + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + + + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + + + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + + +
## Troubleshooting @@ -103,7 +139,7 @@ Simply hit Ctrl+B, or the "hammer" icon in the bottom left. To run, hit the "pla ### Command Line -If you are not on Windows, and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. +If you are not on Windows and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. ``` cmake --build build @@ -121,4 +157,4 @@ Some platforms have convenience scripts provided for building. - **[Linux](scripts/Linux.md)** - **[Windows](scripts/Windows.md)** -macOS scripts will come soon. Maybe. \ No newline at end of file +macOS scripts will come soon. \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md index 9cfe36b547..f9a083d368 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -180,7 +180,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead. ```sh pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 ```
@@ -194,7 +194,7 @@ Run the usual update + install of essential toolings: `sudo pkg update && sudo p - **gcc**: `sudo pkg install developer/gcc-14`. - **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. -Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. +Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
diff --git a/docs/Options.md b/docs/Options.md index 61f578df8b..d19aab63f6 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -53,6 +53,8 @@ The following options are desktop only: - `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend - `ENABLE_QT_UPDATE_CHECKER` (OFF) Enable update checker for the Qt frontend - `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH`, e.g: + * `-DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` - `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries - `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support - `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended) diff --git a/docs/scripts/Windows.md b/docs/scripts/Windows.md index c1ebb5a4c2..e60c2119a2 100644 --- a/docs/scripts/Windows.md +++ b/docs/scripts/Windows.md @@ -27,50 +27,3 @@ * The resulting zip will be placed into `artifacts` in the source directory. -## 🖥️ Method III: CLion Environment Setup - -### a. Prerequisites to CLion - -* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I - ---- - -### b. Cloning eden with CLion - -* Clone the Repository: - - - - - ---- - -### c. Building & Setup - -* Once Cloned, You will be taken to a prompt like the image below: - - - -* Set the settings to the image below: -* Change `Build type: Release` -* Change `Name: Release` -* Change `Toolchain Visual Studio` -* Change `Generator: Let CMake decide` -* Change `Build directory: build` - - - -* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. -* Once this process has been completed (No loading bar bottom right), you can now build eden -* In the top right, click on the drop-down menu, select all configurations, then select eden - - - -* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. - - - ---- - - - From 8f06e954cd1da3504e987bd7b3d925fc99a272e0 Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 16 Sep 2025 12:55:41 -0400 Subject: [PATCH 07/17] add libusb to openbsd deps Signed-off-by: crueter --- docs/Deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Deps.md b/docs/Deps.md index f9a083d368..cfc6f0365b 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -180,7 +180,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead. ```sh pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1.1.0.27 ```
From cda69581119c967362c0170f094c66358b0b7925 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 17 Sep 2025 02:31:44 +0200 Subject: [PATCH 08/17] [host_memory] decrease latency of mapping on linux (#232) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/232 Reviewed-by: MaranBr Reviewed-by: Shinmegumi Co-authored-by: lizzie Co-committed-by: lizzie --- src/common/host_memory.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 1b7532b6b9..2e36d59569 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -598,12 +598,17 @@ public: bool ClearBackingRegion(size_t physical_offset, size_t length) { #ifdef __linux__ - // Set MADV_REMOVE on backing map to destroy it instantly. - // This also deletes the area from the backing file. - int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); - ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); - - return true; + // Only incur syscall cost IF memset would be slower (theshold = 16MiB) + // TODO(lizzie): Smarter way to dynamically get this threshold (broadwell != raptor lake) for example + if (length >= 2097152UL * 8) { + // Set MADV_REMOVE on backing map to destroy it instantly. + // This also deletes the area from the backing file. + int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); + ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); + return true; + } else { + return false; + } #else return false; #endif From 8ac495aceea5460d7641ffad77c9f6f4a5167b07 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Wed, 17 Sep 2025 17:45:52 +0200 Subject: [PATCH 09/17] [fs] Remove remaining files from NCA bypass and fix some asserts (#2502) Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2502 Reviewed-by: crueter Co-authored-by: MaranBr Co-committed-by: MaranBr --- src/core/CMakeLists.txt | 1 - .../fssystem/fssystem_bucket_tree.cpp | 1 - .../fssystem_nca_file_system_driver.cpp | 2 -- .../file_sys/fssystem/fssystem_nca_header.cpp | 6 ++-- .../fssystem/fssystem_passthrough_storage.h | 32 ------------------- 5 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 src/core/file_sys/fssystem/fssystem_passthrough_storage.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 89c97eb1aa..4d9566a60f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -107,7 +107,6 @@ add_library(core STATIC file_sys/fssystem/fssystem_nca_header.cpp file_sys/fssystem/fssystem_nca_header.h file_sys/fssystem/fssystem_nca_reader.cpp - file_sys/fssystem/fssystem_passthrough_storage.h file_sys/fssystem/fssystem_pooled_buffer.cpp file_sys/fssystem/fssystem_pooled_buffer.h file_sys/fssystem/fssystem_sparse_storage.cpp diff --git a/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp b/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp index 71ba458cef..f58b154968 100644 --- a/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp +++ b/src/core/file_sys/fssystem/fssystem_bucket_tree.cpp @@ -4,7 +4,6 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/settings.h" #include "core/file_sys/errors.h" #include "core/file_sys/fssystem/fssystem_bucket_tree.h" #include "core/file_sys/fssystem/fssystem_bucket_tree_utils.h" diff --git a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp index 37fb71e9e3..25036b02c1 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_file_system_driver.cpp @@ -4,7 +4,6 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/settings.h" #include "core/file_sys/fssystem/fssystem_aes_ctr_counter_extended_storage.h" #include "core/file_sys/fssystem/fssystem_aes_ctr_storage.h" #include "core/file_sys/fssystem/fssystem_aes_xts_storage.h" @@ -14,7 +13,6 @@ #include "core/file_sys/fssystem/fssystem_hierarchical_sha256_storage.h" #include "core/file_sys/fssystem/fssystem_indirect_storage.h" #include "core/file_sys/fssystem/fssystem_integrity_romfs_storage.h" -#include "core/file_sys/fssystem/fssystem_passthrough_storage.h" #include "core/file_sys/fssystem/fssystem_memory_resource_buffer_hold_storage.h" #include "core/file_sys/fssystem/fssystem_nca_file_system_driver.h" #include "core/file_sys/fssystem/fssystem_sparse_storage.h" diff --git a/src/core/file_sys/fssystem/fssystem_nca_header.cpp b/src/core/file_sys/fssystem/fssystem_nca_header.cpp index 2226c087c0..77042dfd43 100644 --- a/src/core/file_sys/fssystem/fssystem_nca_header.cpp +++ b/src/core/file_sys/fssystem/fssystem_nca_header.cpp @@ -13,13 +13,11 @@ u8 NcaHeader::GetProperKeyGeneration() const { } bool NcaPatchInfo::HasIndirectTable() const { - static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'}; - return std::memcmp(indirect_header.data(), BKTR, sizeof(BKTR)) == 0; + return this->indirect_size != 0; } bool NcaPatchInfo::HasAesCtrExTable() const { - static constexpr unsigned char BKTR[4] = {'B', 'K', 'T', 'R'}; - return std::memcmp(aes_ctr_ex_header.data(), BKTR, sizeof(BKTR)) == 0; + return this->aes_ctr_ex_size != 0; } } // namespace FileSys diff --git a/src/core/file_sys/fssystem/fssystem_passthrough_storage.h b/src/core/file_sys/fssystem/fssystem_passthrough_storage.h deleted file mode 100644 index 8fc6f4962a..0000000000 --- a/src/core/file_sys/fssystem/fssystem_passthrough_storage.h +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once -#include "core/file_sys/fssystem/fs_i_storage.h" -#include "core/file_sys/vfs/vfs.h" - -namespace FileSys { - -//TODO: No integrity verification. -class PassthroughStorage final : public IReadOnlyStorage { - YUZU_NON_COPYABLE(PassthroughStorage); - YUZU_NON_MOVEABLE(PassthroughStorage); - -public: - explicit PassthroughStorage(VirtualFile base) : base_(std::move(base)) {} - ~PassthroughStorage() override = default; - - size_t Read(u8* buffer, size_t size, size_t offset) const override { - if (!base_ || size == 0) - return 0; - return base_->Read(buffer, size, offset); - } - size_t GetSize() const override { - return base_ ? base_->GetSize() : 0; - } - -private: - VirtualFile base_{}; -}; - -} // namespace FileSys From 249e006667966b7709b74709a801c46714aecec1 Mon Sep 17 00:00:00 2001 From: wildcard Date: Wed, 17 Sep 2025 21:40:09 +0200 Subject: [PATCH 10/17] [VMA] Use Host cached and Host coherent for Download operations (#482) Increase read speeds by using appropriate usage flags Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/482 Reviewed-by: crueter Reviewed-by: Shinmegumi Co-authored-by: wildcard Co-committed-by: wildcard --- src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 675dede61c..119b4be1c8 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -49,6 +49,9 @@ namespace Vulkan { } [[nodiscard]] VkMemoryPropertyFlags MemoryUsagePreferredVmaFlags(MemoryUsage usage) { + if (usage == MemoryUsage::Download) { + return VK_MEMORY_PROPERTY_HOST_CACHED_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + } return usage != MemoryUsage::DeviceLocal ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VkMemoryPropertyFlagBits{}; } From b8c92f64f843c291a057e184431606a423ca2275 Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Sun, 14 Sep 2025 21:50:06 -0300 Subject: [PATCH 11/17] docs: Update dependencies on Ubuntu Signed-off-by: Caio Oliveira --- docs/build/Linux.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build/Linux.md b/docs/build/Linux.md index a6b7b2dda7..9fc85a27e2 100644 --- a/docs/build/Linux.md +++ b/docs/build/Linux.md @@ -37,7 +37,7 @@ Dependencies are listed here as commands that can be copied/pasted. Of course, t - GCC 11 or later is required. - Ubuntu / Linux Mint / Debian: - - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev` + - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev` - Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. - Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF` From a1ed6a86369ee6e525d5ce91348d714285164d9f Mon Sep 17 00:00:00 2001 From: Caio Oliveira Date: Sun, 14 Sep 2025 22:22:37 -0300 Subject: [PATCH 12/17] [docs] Refactor building with Linux * this a initial PR to improve documentation of building under linux based on updated windows doc Signed-off-by: Caio Oliveira --- docs/build/Linux.md | 227 +++++++++++++++++++++++++++--------------- docs/build/Windows.md | 2 +- 2 files changed, 146 insertions(+), 83 deletions(-) diff --git a/docs/build/Linux.md b/docs/build/Linux.md index 9fc85a27e2..5bbd2b1d4b 100644 --- a/docs/build/Linux.md +++ b/docs/build/Linux.md @@ -1,138 +1,201 @@ -### Dependencies +# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. + +## 📋 Index: + +* [Minimal Dependencies](#minimal-dependencies) +* [Cloning Eden with Git](#cloning-eden-with-git) +* [Arch / Manjaro](#arch-manjaro) +* [Ubuntu / Linux Mint / Debian](#ubuntu-linux-mint-debian) +* [Fedora](#fedora) +* [Building with Scripts](#building-with-scripts) +* [Running without Installing](#running-without-installing) + +--- + +## Minimal Dependencies You'll need to download and install the following to build Eden: - * [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc - * If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling - * [CMake](https://www.cmake.org/) 3.22+ +* [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc +* If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling +* [CMake](https://www.cmake.org/) 3.22+ +* [Git](https://git-scm.com/) for version control The following are handled by Eden's externals: - * [FFmpeg](https://ffmpeg.org/) - * [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ - * [opus](https://opus-codec.org/downloads/) 1.3+ - +* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) +* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON`) +* [opus](https://opus-codec.org/downloads/) 1.3+ + All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available: - * [Boost](https://www.boost.org/users/download/) 1.79.0+ - * [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 - * [fmt](https://fmt.dev/) 8.0.1+ - * [lz4](http://www.lz4.org) 1.8+ - * [nlohmann_json](https://github.com/nlohmann/json) 3.8+ - * [OpenSSL](https://www.openssl.org/source/) 1.1.1+ - * [ZLIB](https://www.zlib.net/) 1.2+ - * [zstd](https://facebook.github.io/zstd/) 1.5+ - * [enet](http://enet.bespin.org/) 1.3+ - * [cubeb](https://github.com/mozilla/cubeb) - * [SimpleIni](https://github.com/brofield/simpleini) +* [Boost](https://www.boost.org/users/download/) 1.79.0+ +* [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 +* [fmt](https://fmt.dev/) 8.0.1+ +* [lz4](http://www.lz4.org) 1.8+ +* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ +* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ +* [ZLIB](https://www.zlib.net/) 1.2+ +* [zstd](https://facebook.github.io/zstd/) 1.5+ +* [enet](http://enet.bespin.org/) 1.3+ +* [cubeb](https://github.com/mozilla/cubeb) +* [SimpleIni](https://github.com/brofield/simpleini) Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended. -Dependencies are listed here as commands that can be copied/pasted. Of course, they should be inspected before being run. +Dependencies are listed here as commands that can be copied/pasted. Inspect them before running. -- Arch / Manjaro: - - `sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip` - - Building with QT Web Engine requires `qt6-webengine` as well. - - Proper wayland support requires `qt6-wayland` - - GCC 11 or later is required. - -- Ubuntu / Linux Mint / Debian: - - `sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev` - - Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. - - Users need to manually specify building with QT Web Engine enabled. This is done using the parameter `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - - Users need to manually disable building SDL2 from externals if they intend to use the version provided by their system by adding the parameters `-DYUZU_USE_EXTERNAL_SDL2=OFF` - -```sh -git submodule update --init --recursive -cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -``` - -- Fedora: - - `sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel` - - Fedora 32 or later is required. - - Due to GCC 12, Fedora 36 or later users need to install `clang`, and configure CMake to use it via `-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang` - - CMake arguments to force system libraries: - - SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` - - FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` - - [RPM Fusion](https://rpmfusion.org/) (free) is required to install `ffmpeg-devel` - -### Cloning Eden with Git +## Cloning Eden with Git **Master:** ```bash -git clone --recursive https://git.eden-emu.dev/eden-emu/eden +git clone https://git.eden-emu.dev/eden-emu/eden cd eden ``` -The `--recursive` option automatically clones the required Git submodules. +## Arch / Manjaro -### Building Eden in Release Mode (Optimised) +```sh +sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip +``` +* Building with QT Web Engine requires `qt6-webengine` as well. +* Proper Wayland support requires `qt6-wayland` +* GCC 11 or later is required. -If you need to run ctests, you can disable `-DYUZU_TESTS=OFF` and install Catch2. +## Ubuntu / Linux Mint / Debian + +```sh +sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +``` +* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. + +```sh +# Make build dir and enter +mkdir build && cd build + +# Generate CMake Makefiles +cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 + +# Build +ninja +``` + +## Fedora + +```sh +sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel +``` +* Force system libraries via CMake arguments: + * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` +* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` +* Fedora 32 or later is required. +* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: +```sh +# Generate CMake Makefiles (for Clang compiler) +cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang +``` + +## Building Eden in Release Mode (Optimised) ```bash +# Make build dir and enter mkdir build && cd build + +# Generate CMake Makefiles cmake .. -GNinja -DYUZU_TESTS=OFF + +# Build ninja -sudo ninja install + +# Install! +sudo ninja install ``` -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` after `cmake ..` -`-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` might be needed if ninja command failed with `undefined reference to symbol 'spvOptimizerOptionsCreate`, reason currently unknown +* Enable Discord Rich Presence: +```bash +# ... -Optionally, you can use `cmake-gui ..` to adjust various options (e.g. disable the Qt GUI). +# Generate CMake Makefiles (with Discord Rich Presence) +cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -### Building Eden in Debug Mode (Slow) +# ... +``` + +* If ninja fails with `undefined reference to symbol 'spvOptimizerOptionsCreate'`, add `-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` +* Optionally use `cmake-gui ..` to adjust options (e.g., disable Qt GUI) + +## Building Eden in Debug Mode (Slow) ```bash +# Make build dir and enter mkdir build && cd build + +# Generate CMake Makefiles cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF + +# Build ninja ``` -### Building with debug symbols +## Building with Debug Symbols ```bash -mkdir build && cd build +# Make build dir and enter + +# Generate CMake Makefiles cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF + +# Build ninja ``` -### Building with Scripts -A convenience script for building is provided in `.ci/linux/build.sh`. You must provide an arch target for optimization, e.g. `.ci/linux/build.sh amd64`. Valid targets: -- `legacy`: x86_64 generic, only needed for CPUs older than 2013 or so -- `amd64`: x86_64-v3, for CPUs newer than 2013 or so -- `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) -- `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) -- `aarch64`: For armv8-a CPUs, older than mid-2021 or so -- `armv9`: For armv9-a CPUs, newer than mid-2021 or so -- `native`: Optimize to your native host architecture +## Building with Scripts -Extra flags to pass to CMake should be passed after the arch target. +* Provided script: `.ci/linux/build.sh` +* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` +* Valid targets: + * `native`: Optimize to your native host architecture + * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so + * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so + * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) + * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) + * `aarch64`: For armv8-a CPUs, older than mid-2021 or so + * `armv9`: For armv9-a CPUs, newer than mid-2021 or so +* Extra CMake flags go after the arch target. -Additional environment variables can be used to control building: -- `NPROC`: Number of threads to use for compilation (defaults to all) -- `TARGET`: Set to `appimage` to disable standalone `eden-cli` and `eden-room` executables -- `BUILD_TYPE`: Sets the build type to use. Defaults to `Release` +### Environment Variables -The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: -- `DEVEL` (default FALSE): Disable Qt update checker -- `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine -- `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia +* `NPROC`: Number of compilation threads (default: all cores) +* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` +* `BUILD_TYPE`: Build type (default: `Release`) -After building, an AppImage can be packaged via `.ci/linux/package.sh`. This script takes the same arch targets as the build script. If the build was created in a different directory, you can specify its path relative to the source directory, e.g. `.ci/linux/package.sh amd64 build-appimage`. Additionally, set the `DEVEL` environment variable to `true` to change the app name to `Eden Nightly`. +Boolean flags (set `true` to enable, `false` to disable): -### Running without installing +* `DEVEL` (default `FALSE`): Disable Qt update checker -After building, the binaries `eden` and `eden-cmd` (depending on your build options) will end up in `build/bin/`. +* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine + +* `USE_MULTIMEDIA` (default `TRUE`): Enable Qt Multimedia + +* AppImage packaging script: `.ci/linux/package.sh` + + * Accepts same arch targets as build script + * Use `DEVEL=true` to rename app to `Eden Nightly` + +## Running without Installing + +After building, binaries `eden` and `eden-cmd` will be in `build/bin/`. ```bash -# SDL +# Build Dir cd build/bin/ + +# SDL2 build ./eden-cmd -# Qt -cd build/bin/ +# Qt build ./eden ``` diff --git a/docs/build/Windows.md b/docs/build/Windows.md index 76602e6d69..93ee9fe551 100644 --- a/docs/build/Windows.md +++ b/docs/build/Windows.md @@ -157,7 +157,7 @@ make -j$(nproc) # Generate CMake Makefiles (withou QT) cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DENABLE_QT=no -$ ... +# ... ``` * Running programs from inside `MSYS2 MinGW x64` shell has a different `%PATH%` than directly from explorer. From b40676f5e3721aa8ca6455594df21a128bb16dbb Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:16:55 -0400 Subject: [PATCH 13/17] [docs] refactor: full rewrite, generalization + dedup Combines most of the stuff that was repeated thrice over verbatim into a single common Build Instructions page, with additional caveats marked elsewhere. Prettifies some stuff too because why not. Signed-off-by: crueter --- docs/Build.md | 124 +++++++++++++++++++ docs/CPM.md | 2 +- docs/Caveats.md | 52 ++++++++ docs/Deps.md | 212 ++++++++++++++++++++++++++++++++ docs/Development.md | 24 +--- docs/Options.md | 67 +++++++++++ docs/README.md | 10 ++ docs/build/Android.md | 7 +- docs/build/FreeBSD.md | 81 ------------- docs/build/Linux.md | 201 ------------------------------- docs/build/OpenBSD.md | 10 -- docs/build/Solaris.md | 51 -------- docs/build/Windows.md | 259 ---------------------------------------- docs/build/macOS.md | 78 ------------ docs/img/creator-1.png | Bin 0 -> 64671 bytes docs/scripts/Linux.md | 31 +++++ docs/scripts/Windows.md | 76 ++++++++++++ 17 files changed, 579 insertions(+), 706 deletions(-) create mode 100644 docs/Build.md create mode 100644 docs/Caveats.md create mode 100644 docs/Deps.md create mode 100644 docs/Options.md create mode 100644 docs/README.md delete mode 100644 docs/build/FreeBSD.md delete mode 100644 docs/build/Linux.md delete mode 100644 docs/build/OpenBSD.md delete mode 100644 docs/build/Solaris.md delete mode 100644 docs/build/Windows.md delete mode 100644 docs/build/macOS.md create mode 100644 docs/img/creator-1.png create mode 100644 docs/scripts/Linux.md create mode 100644 docs/scripts/Windows.md diff --git a/docs/Build.md b/docs/Build.md new file mode 100644 index 0000000000..910f8b43e2 --- /dev/null +++ b/docs/Build.md @@ -0,0 +1,124 @@ +# Building Eden + +> [!WARNING] +> This guide is intended for developers ONLY. If you are not a developer or packager, you are unlikely to receive support. + +This is a full-fledged guide to build Eden on all supported platforms. + +## Dependencies +First, you must [install some dependencies](Deps.md). + +## Clone +Next, you will want to clone Eden via the terminal: + +```sh +git clone https://git.eden-emu.dev/eden-emu/eden.git +cd eden +``` + +Or use Qt Creator (Create Project -> Import Project -> Git Clone). + +## Android + +Android has a completely different build process than other platforms. See its [dedicated page](build/Android.md). + +## Initial Configuration + +If the configure phase fails, see the `Troubleshooting` section below. Usually, as long as you followed the dependencies guide, the defaults *should* successfully configure and build. + +### Qt Creator + +This is the recommended GUI method for Linux, macOS, and Windows. + +
+Click to Open + +> [!WARNING] +> On MSYS2, to use Qt Creator you are recommended to *also* install Qt from the online installer, ensuring to select the "MinGW" version. + +Open the CMakeLists.txt file in your cloned directory via File -> Open File or Project (Ctrl+O), if you didn't clone Eden via the project import tool. + +Select your desired "kit" (usually, the default is okay). RelWithDebInfo or Release is recommended: + +![Qt Creator kits](img/creator-1.png) + +Hit "Configure Project", then wait for CMake to finish configuring (may take a while on Windows). + +
+ +### Command Line + +This is recommended for *BSD, Solaris, Linux, and MSYS2. MSVC is possible, but not recommended. + +
+Click to Open + +Note that CMake must be in your PATH, and you must be in the cloned Eden directory. On Windows, you must also set up a Visual C++ development environment. This can be done by running `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat` in the same terminal. + +Recommended generators: +- MSYS2: `MSYS Makefiles` +- MSVC: Install **[ninja](https://ninja-build.org/)** and use `Ninja`, OR use `Visual Studio 17 2022` +- macOS: `Ninja` (preferred) or `Xcode` +- Others: `Ninja` (preferred) or `UNIX Makefiles` + +BUILD_TYPE should usually be `Release` or `RelWithDebInfo` (debug symbols--compiled executable will be large). If you are using a debugger and annoyed with stuff getting optimized out, try `Debug`. + +Also see the [Options](Options.md) page for additional CMake options. + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_BUILD_TYPE= -DYUZU_TESTS=OFF +``` + +If you are on Windows and prefer to use Clang: + +```sh +cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl +``` + +
+ +### CLion + +TODO + +## Troubleshooting + +If your initial configure failed: +- *Carefully* re-read the [dependencies guide](Deps.md) +- Clear the CPM cache (`.cache/cpm`) and CMake cache (`/CMakeCache.txt`) +- Evaluate the error and find any related settings +- See the [CPM docs](CPM.md) to see if you may need to forcefully bundle any packages + +Otherwise, feel free to ask for help in Revolt or Discord. + +## Caveats + +Many platforms have quirks, bugs, and other fun stuff that may cause issues when building OR running. See the [Caveats page](Caveats.md) before continuing. + +## Building & Running + +### Qt Creator + +Simply hit Ctrl+B, or the "hammer" icon in the bottom left. To run, hit the "play" icon, or Ctrl+R. + +### Command Line + +If you are not on Windows, and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. + +``` +cmake --build build +``` + +Your compiled executable will be in: +- `build/bin/eden.exe` for Windows, +- `build/bin/eden.app/Contents/MacOS/eden` for macOS, +- and `build/bin/eden` for others. + +## Scripts + +Some platforms have convenience scripts provided for building. + +- **[Linux](scripts/Linux.md)** +- **[Windows](scripts/Windows.md)** + +macOS scripts will come soon. Maybe. \ No newline at end of file diff --git a/docs/CPM.md b/docs/CPM.md index bce224da40..03d8a039f9 100644 --- a/docs/CPM.md +++ b/docs/CPM.md @@ -177,7 +177,7 @@ If `ci` is `true`: ### Examples -In order: OpenSSL CI, Boost (tag + artifact), discord-rpc (sha + options + patches), Opus (options + find_args) +In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discord-rpc (sha + options + patches) ```json { diff --git a/docs/Caveats.md b/docs/Caveats.md new file mode 100644 index 0000000000..7bc2428bab --- /dev/null +++ b/docs/Caveats.md @@ -0,0 +1,52 @@ +# Caveats + +## Arch Linux + +- httplib AUR package is broken. Set `httplib_FORCE_BUNDLED=ON` if you have it installed. +- Eden is also available as an [AUR package](https://aur.archlinux.org/packages/eden-git). If you are unable to build, either use that or compare your process to the PKGBUILD. + +## Gentoo Linux + +Do not use the system sirit or xbyak packages. + +## macOS + +macOS is largely untested. Expect crashes, significant Vulkan issues, and other fun stuff. + +## Solaris + +Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configure command. In the meantime, a Qt Quick frontend is in the works--check back later! + +This is needed for some dependencies that call cc directly (tz): + +```sh +echo '#!/bin/sh' >cc +echo 'gcc $@' >>cc +chmod +x cc +export PATH="$PATH:$PWD" +``` + +Default MESA is a bit outdated, the following environment variables should be set for a smoother experience: +```sh +export MESA_GL_VERSION_OVERRIDE=4.6 +export MESA_GLSL_VERSION_OVERRIDE=460 +export MESA_EXTENSION_MAX_YEAR=2025 +export MESA_DEBUG=1 +export MESA_VK_VERSION_OVERRIDE=1.3 +# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance +export LIBGL_ALWAYS_SOFTWARE=1 +``` + +- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). +- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this. +- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source. + +## OpenBSD + +After configuration, you may need to modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. + +## FreeBSD + +Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. + +The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_BUNDLED_OPENSSL=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md new file mode 100644 index 0000000000..cd875cd292 --- /dev/null +++ b/docs/Deps.md @@ -0,0 +1,212 @@ +# Dependencies + +To build Eden, you MUST have a C++ compiler. +* On Linux, this is usually [GCC](https://gcc.gnu.org/) 11+ or [Clang](https://clang.llvm.org/) v14+ + - GCC 12 also requires Clang 14+ +* On Windows, this is either: + - **[MSVC](https://visualstudio.microsoft.com/downloads/)**, + * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* + - clang-cl - can be downloaded from the MSVC installer, + - or **[MSYS2](https://www.msys2.org)** +* On macOS, this is Apple Clang + - This can be installed with `xcode-select --install` + +The following additional tools are also required: + +* **[CMake](https://www.cmake.org/)** 3.22+ - already included with the Android SDK +* **[Git](https://git-scm.com/)** for version control + - **[Windows installer](https://gitforwindows.org)** +* On Windows, you must install the **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** as well + - *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* + +If you are on desktop and plan to use the Qt frontend, you *must* install Qt 6, and optionally Qt Creator (the recommended IDE for building) +* On Linux, *BSD and macOS, this can be done by the package manager + - If you wish to use Qt Creator, append `qtcreator` or `qt-creator` to the commands seen below. +* MSVC/clang-cl users on Windows must install through the [official installer](https://www.qt.io/download-qt-installer-oss) +* Linux and macOS users may choose to use the installer as well. +* MSYS2 can also install Qt 6 via the package manager + +If you are on Windows and NOT building with MSYS2, you may go [back home](Build.md) and continue. + +## Externals +The following are handled by Eden's externals: + +* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) +* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON` OR `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) + +All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available (UNIX-like only): + +* [Boost](https://www.boost.org/users/download/) 1.57.0+ +* [Catch2](https://github.com/catchorg/Catch2) 3.0.1 if `YUZU_TESTS` or `DYNARMIC_TESTS` are on +* [fmt](https://fmt.dev/) 8.0.1+ +* [lz4](http://www.lz4.org) +* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ +* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ +* [ZLIB](https://www.zlib.net/) 1.2+ +* [zstd](https://facebook.github.io/zstd/) 1.5+ +* [enet](http://enet.bespin.org/) 1.3+ +* [Opus](https://opus-codec.org/) 1.3+ +* [MbedTLS](https://github.com/Mbed-TLS/mbedtls) 3+ + +Vulkan 1.3.274+ is also needed: +* [VulkanUtilityLibraries](https://github.com/KhronosGroup/Vulkan-Utility-Libraries) +* [VulkanHeaders](https://github.com/KhronosGroup/Vulkan-Headers) +* [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) +* [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) + +Certain other dependencies will be fetched by CPM regardless. System packages *can* be used for these libraries, but many are either not packaged by most distributions OR have issues when used by the system: + +* [SimpleIni](https://github.com/brofield/simpleini) +* [DiscordRPC](https://github.com/eden-emulator/discord-rpc) +* [cubeb](https://github.com/mozilla/cubeb) +* [libusb](https://github.com/libusb/libusb) +* [VulkanMemoryAllocator](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) +* [sirit](https://github.com/eden-emulator/sirit) +* [httplib](https://github.com/yhirose/cpp-httplib) - if `ENABLE_QT_UPDATE_CHECKER` or `ENABLE_WEB_SERVICE` are on +* [cpp-jwt](https://github.com/arun11299/cpp-jwt) 1.4+ - if `ENABLE_WEB_SERVICE` is on +* [unordered-dense](https://github.com/martinus/unordered_dense) +* [mcl](https://github.com/azahar-emu/mcl) - subject to removal + +On amd64: +* [xbyak](https://github.com/herumi/xbyak) - 7.22 or earlier is recommended +* [zycore](https://github.com/zyantific/zycore-c) +* [zydis](https://github.com/zyantific/zydis) 4+ +* Note: zydis and zycore-c MUST match. Using one as a system dependency and the other as a bundled dependency WILL break things + +On aarch64 OR if `DYNARMIC_TESTS` is on: +* [oaknut](https://github.com/merryhime/oaknut) 2.0.1+ + +On riscv64: +* [biscuit](https://github.com/lioncash/biscuit) 0.9.1+ + +## Commands + +These are commands to install all necessary dependencies on various Linux and BSD distributions, as well as macOS. Always review what you're running before you hit Enter! + +Click on the arrows to expand. + +
+Arch Linux + +```sh +sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip zydis zycore vulkan-headers vulkan-utility-libraries libusb spirv-tools spirv-headers +``` + +* Building with QT Web Engine requires `qt6-webengine` as well. +* Proper Wayland support requires `qt6-wayland` +* GCC 11 or later is required. +
+ +
+Ubuntu, Debian, Mint Linux + +```sh +sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev +``` + +* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. +* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. +
+ +
+Fedora Linux + +```sh +sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel +``` + +* Force system libraries via CMake arguments: + * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` +* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` +* Fedora 32 or later is required. +* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: +
+ +
+macOS +Install dependencies from **[Homebrew](https://brew.sh/)** + +```sh +brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools +``` + +If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. + +To run with MoltenVK, install additional dependencies: +```sh +brew install molten-vk vulkan-loader +``` + +
+ +
+FreeBSD + +``` +devel/cmake +devel/sdl20 +devel/boost-libs +devel/catch2 +devel/libfmt +devel/nlohmann-json +devel/ninja +devel/nasm +devel/autoconf +devel/pkgconf +devel/qt6-base + +net/enet + +multimedia/ffnvcodec-headers +multimedia/ffmpeg + +audio/opus + +archivers/liblz4 + +lang/gcc12 + +graphics/glslang +graphics/vulkan-utility-libraries +``` + +If using FreeBSD 12 or prior, use `devel/pkg-config` instead. +
+ +
+OpenBSD + +```sh +pkg_add -u +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq +``` +
+ +
+Solaris / OpenIndiana + +Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. + +Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. + +- **gcc**: `sudo pkg install developer/gcc-14`. +- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. + +Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. +
+ +
+MSYS2 +* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) +* Download and install all dependencies using: + * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` +* Add MinGW binaries to the PATH: + * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` +* Add VulkanSDK to the PATH: + * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` +
+ +## All Done + +You may now return to the **[root build guide](Build.md)**. \ No newline at end of file diff --git a/docs/Development.md b/docs/Development.md index e4816cd1ec..d170818d10 100644 --- a/docs/Development.md +++ b/docs/Development.md @@ -1,23 +1,3 @@ -# Development - -* **Windows**: [Windows Building Guide](./build/Windows.md) -* **Linux**: [Linux Building Guide](./build/Linux.md) -* **Android**: [Android Building Guide](./build/Android.md) -* **Solaris**: [Solaris Building Guide](./build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./build/OpenBSD.md) - -# CPM - -CPM (CMake Package Manager) is the preferred method of managing dependencies within Eden. Documentation on adding dependencies/using CPMUtil is in the works. - -Notes: -- `YUZU_USE_CPM` is set by default on MSVC and Android. Other platforms should use this if certain "required" system dependencies (e.g. OpenSSL) are broken or missing -- `CPMUTIL_DEFAULT_SYSTEM` can be set to `OFF` to force the usage of bundled dependencies. This can marginally decrease the final package size. -- When adding new prebuilt dependencies a la OpenSSL, SDL2, or FFmpeg, there *must* be a CMake option made available to forcefully download this bundle. See the OpenSSL implementation in the root CMakeLists for an example. - * This is necessary to allow for creation of fully-qualified source packs that allow for offline builds after download (some package managers and distros enforce this) - # Guidelines ## License Headers @@ -37,6 +17,8 @@ FIX=true .ci/license-header.sh git commit --amend -a --no-edit ``` +If the work is licensed/vendored from other people or projects, you may omit the license headers. Additionally, if you wish to retain authorship over a piece of code, you may attribute it to yourself; however, the code may be changed at any given point and brought under the attribution of Eden. + ## Pull Requests Pull requests are only to be merged by core developers when properly tested and discussions conclude on Discord or other communication channels. Labels are recommended but not required. However, all PRs MUST be namespaced and optionally typed: ``` @@ -49,7 +31,7 @@ Pull requests are only to be merged by core developers when properly tested and - The level of namespacing is generally left to the committer's choice. - However, we never recommend going more than two levels *except* in `hle`, in which case you may go as many as four levels depending on the specificity of your changes. -- Ocassionally, up to two namespaces may be provided for more clarity. +- Ocassionally, up to two additional namespaces may be provided for more clarity. * Changes that affect the entire project (sans CMake changes) should be namespaced as `meta`. - Maintainers are permitted to change namespaces at will. - Commits within PRs are not required to be namespaced, but it is highly recommended. diff --git a/docs/Options.md b/docs/Options.md new file mode 100644 index 0000000000..61f578df8b --- /dev/null +++ b/docs/Options.md @@ -0,0 +1,67 @@ +# CMake Options + +To change these options, add `-DOPTION_NAME=NEWVALUE` to the command line. + +- On Qt Creator, go to Project -> Current Configuration + +Notes: +- Defaults are marked per-platform. +- "Non-UNIX" just means Windows/MSVC and Android (yes, macOS is UNIX +- Android generally doesn't need to change anything; if you do, go to `src/android/app/build.gradle.kts` +- To set a boolean variable to on, use `ON` for the value; to turn it off, use `OFF` +- If a variable is mentioned as being e.g. "ON" for a specific platform(s), that means it is defaulted to OFF on others +- TYPE is always boolean unless otherwise specified +- Format: + * `OPTION_NAME` (TYPE DEFAULT) DESCRIPTION + +## Options + +- `YUZU_USE_CPM` (ON for non-UNIX) Use CPM to fetch system dependencies (fmt, boost, etc) if needed. Externals will still be fetched. See the [CPM](CPM.md) and [Deps](Deps.md) docs for more info. +- `ENABLE_WEB_SERVICE` (ON) Enable multiplayer service +- `ENABLE_WIFI_SCAN` (OFF) Enable WiFi scanning (requires iw on Linux) - experimental +- `YUZU_USE_BUNDLED_FFMPEG` (ON for non-UNIX) Download (Windows, Android) or build (UNIX) bundled FFmpeg +- `ENABLE_CUBEB` (ON) Enables the cubeb audio backend +- `YUZU_TESTS` (ON) Compile tests - requires Catch2 +- `YUZU_USE_PRECOMPILED_HEADERS` (ON for non-UNIX) Use precompiled headers +- `YUZU_DOWNLOAD_ANDROID_VVL` (ON) Download validation layer binary for Android +- `YUZU_ENABLE_LTO` (OFF) Enable link-time optimization + * Not recommended on Windows + * UNIX may be better off appending `-flto=thin` to compiler args +- `YUZU_DOWNLOAD_TIME_ZONE_DATA` (ON) Always download time zone binaries + * Currently, build fails without this +- `YUZU_USE_FASTER_LD` (ON) Check if a faster linker is available + * Only available on UNIX +- `USE_SYSTEM_MOLTENVK` (OFF, macOS only) Use the system MoltenVK lib (instead of the bundled one) +- `YUZU_TZDB_PATH` (string) Path to a pre-downloaded timezone database (useful for nixOS) +- `ENABLE_OPENSSL` (ON for Linux and *BSD) Enable OpenSSL backend for the ssl service + * Always enabled if the web service is enabled +- `YUZU_USE_BUNDLED_OPENSSL` (ON for MSVC) Download bundled OpenSSL build + * Always on for Android + * Unavailable on OpenBSD + +The following options are desktop only: +- `ENABLE_SDL2` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) + * Unavailable on Android +- `YUZU_USE_EXTERNAL_SDL2` (ON for non-UNIX) Compiles SDL2 from source +- `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2 + * Unavailable on OpenBSD + * Only enabled if YUZU_USE_CPM and ENABLE_SDL2 are both ON +- `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED) +- `ENABLE_OPENGL` (ON) Enable the OpenGL graphics frontend + * Unavailable on Windows/ARM64 and Android +- `ENABLE_QT` (ON) Enable the Qt frontend (recommended) +- `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend +- `ENABLE_QT_UPDATE_CHECKER` (OFF) Enable update checker for the Qt frontend +- `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries +- `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries +- `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support +- `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended) +- `USE_DISCORD_PRESENCE` (OFF) Enables Discord Rich Presence (Qt frontend only) +- `YUZU_ROOM` (ON) Enable dedicated room functionality +- `YUZU_ROOM_STANDALONE` (ON) Enable standalone room executable (eden-room) + * Requires `YUZU_ROOM` +- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli) - requires SDL2 +- `YUZU_CRASH_DUMPS` Compile crash dump (Minidump) support" + * Currently only available on Windows and Linux + +See `src/dynarmic/CMakeLists.txt` for additional options--usually, these don't need changed \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000000..ba489b7218 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,10 @@ +# Eden Build Documentation + +This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](CPM.md), and more. + +- **[General Build Instructions](CPM.md)** +- **[Development Guidelines](Development.md)** +- **[Dependencies](Deps.md)** +- **[CPM - CMake Package Manager](CPM.md)** +- **[Platform-Specific Caveats](Caveats.md)** +- **[User Directory Handling](User.md)** \ No newline at end of file diff --git a/docs/build/Android.md b/docs/build/Android.md index 0538d351ea..c8ff3a3b1e 100644 --- a/docs/build/Android.md +++ b/docs/build/Android.md @@ -2,7 +2,7 @@ ## Dependencies * [Android Studio](https://developer.android.com/studio) -* [NDK 25.2.9519653 and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) +* [NDK 27+ and CMake 3.22.1](https://developer.android.com/studio/projects/install-ndk#default-version) * [Git](https://git-scm.com/download) ### WINDOWS ONLY - Additional Dependencies @@ -16,8 +16,7 @@ git clone --recursive https://git.eden-emu.dev/eden-emu/eden.git ``` Eden by default will be cloned into - * `C:\Users\\eden` on Windows -* `~/eden` on Linux -* And wherever on macOS +* `~/eden` on Linux and macOS ## Building 1. Start Android Studio, on the startup dialog select `Open`. @@ -32,7 +31,7 @@ Eden by default will be cloned into - `export ANDROID_SDK_ROOT=path/to/sdk` `export ANDROID_NDK_ROOT=path/to/ndk`. 4. Navigate to `eden/src/android`. -5. Then Build with `./gradlew assemblerelWithDebInfo`. +5. Then Build with `./gradlew assembleRelWithDebInfo`. 6. To build the optimised build use `./gradlew assembleGenshinSpoofRelWithDebInfo`. ### Script diff --git a/docs/build/FreeBSD.md b/docs/build/FreeBSD.md deleted file mode 100644 index 97eef8f9d8..0000000000 --- a/docs/build/FreeBSD.md +++ /dev/null @@ -1,81 +0,0 @@ -Eden is not currently available as a port on FreeBSD, though it is in the works. For now, the recommended method of usage is to compile it yourself. Check back often, as the build process frequently changes. - -## Dependencies. -Eden needs the following dependencies: - -``` -devel/cmake -devel/sdl20 -devel/boost-libs -devel/catch2 -devel/libfmt -devel/nlohmann-json -devel/ninja -devel/nasm -devel/autoconf -devel/pkgconf -devel/qt6-base - -net/enet - -multimedia/ffnvcodec-headers -multimedia/ffmpeg - -audio/opus - -archivers/liblz4 - -lang/gcc12 - -graphics/glslang -graphics/vulkan-utility-libraries -``` - -If using FreeBSD 12 or prior, use `devel/pkg-config` instead. - ---- - -### Build preparations: -Run the following command to clone eden with git: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -``` -You usually want to add the `--recursive` parameter as it also takes care of the external dependencies for you. - -Now change into the eden directory and create a build directory there: -```sh -cd eden -mkdir build -``` - -Change into that build directory: -```sh -cd build -``` - -#### 1. Building in Release Mode (usually preferred and the most performant choice): -```sh -cmake .. -GNinja -DYUZU_TESTS=OFF -``` - -#### 2. Building in Release Mode with debugging symbols (useful if you want to debug errors for a eventual fix): -```sh -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=ON -``` - -Build the emulator locally: -```sh -ninja -``` - -Optional: If you wish to install eden globally onto your system issue the following command: -```sh -sudo ninja install -``` -OR -```sh -doas -- ninja install -``` - -## OpenSSL -The available OpenSSL port (3.0.17) is out-of-date, and using a bundled static library instead is recommended; to do so, add `-DYUZU_USE_CPM=ON` to your CMake configure command. \ No newline at end of file diff --git a/docs/build/Linux.md b/docs/build/Linux.md deleted file mode 100644 index 5bbd2b1d4b..0000000000 --- a/docs/build/Linux.md +++ /dev/null @@ -1,201 +0,0 @@ -# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. - -## 📋 Index: - -* [Minimal Dependencies](#minimal-dependencies) -* [Cloning Eden with Git](#cloning-eden-with-git) -* [Arch / Manjaro](#arch-manjaro) -* [Ubuntu / Linux Mint / Debian](#ubuntu-linux-mint-debian) -* [Fedora](#fedora) -* [Building with Scripts](#building-with-scripts) -* [Running without Installing](#running-without-installing) - ---- - -## Minimal Dependencies - -You'll need to download and install the following to build Eden: - -* [GCC](https://gcc.gnu.org/) v11+ (for C++20 support) & misc -* If GCC 12 is installed, [Clang](https://clang.llvm.org/) v14+ is required for compiling -* [CMake](https://www.cmake.org/) 3.22+ -* [Git](https://git-scm.com/) for version control - -The following are handled by Eden's externals: - -* [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) -* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON`) -* [opus](https://opus-codec.org/downloads/) 1.3+ - -All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available: - -* [Boost](https://www.boost.org/users/download/) 1.79.0+ -* [Catch2](https://github.com/catchorg/Catch2) 2.13.7 - 2.13.9 -* [fmt](https://fmt.dev/) 8.0.1+ -* [lz4](http://www.lz4.org) 1.8+ -* [nlohmann\_json](https://github.com/nlohmann/json) 3.8+ -* [OpenSSL](https://www.openssl.org/source/) 1.1.1+ -* [ZLIB](https://www.zlib.net/) 1.2+ -* [zstd](https://facebook.github.io/zstd/) 1.5+ -* [enet](http://enet.bespin.org/) 1.3+ -* [cubeb](https://github.com/mozilla/cubeb) -* [SimpleIni](https://github.com/brofield/simpleini) - -Certain other dependencies (httplib, jwt, sirit, etc.) will be fetched by CPM regardless. System packages *can* be used for these libraries but this is generally not recommended. - -Dependencies are listed here as commands that can be copied/pasted. Inspect them before running. - -## Cloning Eden with Git - -**Master:** - -```bash -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -## Arch / Manjaro - -```sh -sudo pacman -Syu --needed base-devel boost catch2 cmake enet ffmpeg fmt git glslang libzip lz4 mbedtls ninja nlohmann-json openssl opus qt6-base qt6-multimedia sdl2 zlib zstd zip unzip -``` -* Building with QT Web Engine requires `qt6-webengine` as well. -* Proper Wayland support requires `qt6-wayland` -* GCC 11 or later is required. - -## Ubuntu / Linux Mint / Debian - -```sh -sudo apt-get install autoconf cmake g++ gcc git glslang-tools libasound2 libboost-context-dev libglu1-mesa-dev libhidapi-dev libpulse-dev libtool libudev-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xkb1 libxext-dev libxkbcommon-x11-0 mesa-common-dev nasm ninja-build qt6-base-private-dev libmbedtls-dev catch2 libfmt-dev liblz4-dev nlohmann-json3-dev libzstd-dev libssl-dev libavfilter-dev libavcodec-dev libswscale-dev pkg-config zlib1g-dev libva-dev libvdpau-dev qt6-tools-dev libzydis-dev zydis-tools libzycore-dev -``` -* Ubuntu 22.04, Linux Mint 20, or Debian 12 or later is required. -* To enable QT Web Engine, add `-DYUZU_USE_QT_WEB_ENGINE=ON` when running CMake. - -```sh -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 - -# Build -ninja -``` - -## Fedora - -```sh -sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel json-devel libtool libusb1-devel libzstd-devel lz4-devel nasm ninja-build openssl-devel pulseaudio-libs-devel qt6-linguist qt6-qtbase{-private,}-devel qt6-qtwebengine-devel qt6-qtmultimedia-devel speexdsp-devel wayland-devel zlib-devel ffmpeg-devel libXext-devel -``` -* Force system libraries via CMake arguments: - * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` - * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` -* [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` -* Fedora 32 or later is required. -* Fedora 36+ users with GCC 12 need Clang and should configure CMake with: -```sh -# Generate CMake Makefiles (for Clang compiler) -cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -``` - -## Building Eden in Release Mode (Optimised) - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DYUZU_TESTS=OFF - -# Build -ninja - -# Install! -sudo ninja install -``` - -* Enable Discord Rich Presence: -```bash -# ... - -# Generate CMake Makefiles (with Discord Rich Presence) -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON - -# ... -``` - -* If ninja fails with `undefined reference to symbol 'spvOptimizerOptionsCreate'`, add `-DYUZU_USE_EXTERNAL_VULKAN_SPIRV_TOOLS=OFF` -* Optionally use `cmake-gui ..` to adjust options (e.g., disable Qt GUI) - -## Building Eden in Debug Mode (Slow) - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DYUZU_TESTS=OFF - -# Build -ninja -``` - -## Building with Debug Symbols - -```bash -# Make build dir and enter - -# Generate CMake Makefiles -cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU -DYUZU_TESTS=OFF - -# Build -ninja -``` - -## Building with Scripts - -* Provided script: `.ci/linux/build.sh` -* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` -* Valid targets: - * `native`: Optimize to your native host architecture - * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so - * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so - * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) - * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) - * `aarch64`: For armv8-a CPUs, older than mid-2021 or so - * `armv9`: For armv9-a CPUs, newer than mid-2021 or so -* Extra CMake flags go after the arch target. - -### Environment Variables - -* `NPROC`: Number of compilation threads (default: all cores) -* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` -* `BUILD_TYPE`: Build type (default: `Release`) - -Boolean flags (set `true` to enable, `false` to disable): - -* `DEVEL` (default `FALSE`): Disable Qt update checker - -* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine - -* `USE_MULTIMEDIA` (default `TRUE`): Enable Qt Multimedia - -* AppImage packaging script: `.ci/linux/package.sh` - - * Accepts same arch targets as build script - * Use `DEVEL=true` to rename app to `Eden Nightly` - -## Running without Installing - -After building, binaries `eden` and `eden-cmd` will be in `build/bin/`. - -```bash -# Build Dir -cd build/bin/ - -# SDL2 build -./eden-cmd - -# Qt build -./eden -``` diff --git a/docs/build/OpenBSD.md b/docs/build/OpenBSD.md deleted file mode 100644 index 6a55fd269d..0000000000 --- a/docs/build/OpenBSD.md +++ /dev/null @@ -1,10 +0,0 @@ -# Building for OpenBSD - -```sh -pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq -git --recursive https://git.eden-emu.dev/eden-emu/eden -cmake -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DDYNARMIC_USE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=Debug -DENABLE_QT=OFF -DENABLE_OPENSSL=OFF -DENABLE_WEB_SERVICE=OFF -B /usr/obj/eden -``` - -- Modify `externals/ffmpeg/CMakeFiles/ffmpeg-build/build.make` to use `-j$(nproc)` instead of just `-j`. diff --git a/docs/build/Solaris.md b/docs/build/Solaris.md deleted file mode 100644 index f7174c2869..0000000000 --- a/docs/build/Solaris.md +++ /dev/null @@ -1,51 +0,0 @@ -# Building for Solaris - -## Dependencies. -Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability. - -Run the usual update + install of essential toolings: `sudo pkg update && sudo pkg install git cmake`. - -- **gcc**: `sudo pkg install developer/gcc-14`. -- **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. - -Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. - -### Building - -Clone eden with git `git clone --recursive https://git.eden-emu.dev/eden-emu/eden` - -```sh -# Needed for some dependencies that call cc directly (tz) -echo '#!/bin/sh' >cc -echo 'gcc $@' >>cc -chmod +x cc -export PATH="$PATH:$PWD" -``` - -Patch for FFmpeg: -```sh -sed -i 's/ make / gmake /' externals/ffmpeg/CMakeFiles/ffmpeg-build.dir/build.make -``` - -- **Configure**: `cmake -B build -DYUZU_USE_CPM=ON -DCMAKE_CXX_FLAGS="-I/usr/include/SDL2" -DCMAKE_C_FLAGS="-I/usr/include/SDL2"`. -- **Build**: `cmake --build build`. -- **Installing**: `sudo cmake --install build`. - -### Running - -Default Mesa is a bit outdated, the following environment variables should be set for a smoother experience: -```sh -export MESA_GL_VERSION_OVERRIDE=4.6 -export MESA_GLSL_VERSION_OVERRIDE=460 -export MESA_EXTENSION_MAX_YEAR=2025 -export MESA_DEBUG=1 -export MESA_VK_VERSION_OVERRIDE=1.3 -# Only if nvidia/intel drm drivers cause crashes, will severely hinder performance -export LIBGL_ALWAYS_SOFTWARE=1 -``` - -### Notes - -- Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). -- If using OpenIndiana, due to a bug in SDL2 cmake configuration; Audio driver defaults to SunOS ``, which does not exist on OpenIndiana. -- System OpenSSL generally does not work. Instead, use `-DYUZU_USE_CPM=ON` to use a bundled static OpenSSL, or build a system dependency from source. \ No newline at end of file diff --git a/docs/build/Windows.md b/docs/build/Windows.md deleted file mode 100644 index 93ee9fe551..0000000000 --- a/docs/build/Windows.md +++ /dev/null @@ -1,259 +0,0 @@ -# ⚠️ This guide is for developers ONLY! Support will be provided to developers ONLY. - -## 📋 Current building methods: - -* [ Minimal Dependencies](#minimal-dependencies) -* [⚡ Method I: MSVC Build for Windows](#method-i-msvc-build-for-windows) -* [🐧 Method II: MinGW-w64 Build with MSYS2](#method-ii-mingw-w64-build-with-msys2) -* [🖥️ Method III: CLion Environment Setup](#method-iii-clion-environment-setup) -* [💻 Building from the command line with MSVC](#building-from-the-command-line-with-msvc) -* [📜 Building with Scripts](#building-with-scripts) - ---- - - -## Minimal Dependencies - -On Windows, **all** library dependencies are **automatically included** within the `externals` folder. - -You still need to install: - -* **[CMake](https://cmake.org/download/)** - Used to generate Visual Studio project files. -* **[Vulkan SDK](https://vulkan.lunarg.com/sdk/home#windows)** - Make sure to select **Latest SDK**. - - * *A convenience script to install the latest SDK is provided in `.ci/windows/install-vulkan-sdk.ps1`* -* **[Git for Windows](https://gitforwindows.org)** - We recommend installing Git for command line use and version control integration. - - - - * *While installing Git Bash, select "Git from the command line and also from 3rd-party software". If missed, manually set `git.exe` path in CMake.* - ---- - -## ⚡ Method I: MSVC Build for Windows - -### a. Prerequisites to MSVC Build - -* **[Visual Studio 2022 Community](https://visualstudio.microsoft.com/downloads/)** - Make sure to **select C++ support** in the installer, or **update to the latest version** if already installed. - - * *A convenience script to install the **minimal** version (Visual Build Tools) is provided in `.ci/windows/install-msvc.ps1`* - ---- - -### b. Clone the eden repository with Git - -Open Terminal on - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -* *By default `eden` downloads to `C:\Users\\eden`* - ---- - -### c. Building - -* Open the CMake GUI application and point it to the `eden` - - - -* For the build directory, use a `build/` subdirectory inside the source directory or some other directory of your choice. (Tell CMake to create it.) - -* Click the "Configure" button and choose `Visual Studio 17 2022`, with `x64` for the optional platform. - - - - * *(You may also want to disable `YUZU_TESTS` in this case since Catch2 is not yet supported with this.)* - - - -* Click "Generate" to create the project files. - - - -* Open the solution file `yuzu.sln` in Visual Studio 2022, which is located in the build folder. - - - -* * Depending on whether you want a graphical user interface or not, select in the Solution Explorer: - * `eden` (GUI) - * `eden-cmd` (command-line only) - * Then **right-click** and choose `Set as StartUp Project`. - - - - -* Select the appropriate build type, `Debug` for debug purposes or `Release` for performance (in case of doubt choose `Release`). - - - -* **Right-click** the project you want to build and press **Build** in the submenu or press `F5`. - - - ---- - -## 🐧 Method II: MinGW-w64 Build with MSYS2 - -### a. Prerequisites to MinGW-w64 - -* **[MSYS2](https://www.msys2.org)** - A versatile and up-to-date development environment for Windows, providing a Unix-like shell, package manager, and toolchain. - ---- - -### b. Install eden dependencies for MinGW-w64 - -* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) -* Download and install all dependencies using: - * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` -* Add MinGW binaries to the PATH: - * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` -* Add VulkanSDK to the PATH: - * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` - ---- - -### c. Clone the eden repository with Git - -```cmd -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - ---- - -### d. Building dynamically-linked eden - -* This process will generate a *dynamically* linked build - -```bash -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF - -# Build -make -j$(nproc) - -# Run eden! -./bin/eden.exe -``` - -* *Warning: This build is not a **static** build meaning that you **need** to include all of the DLLs with the .exe in order to use it or other systems!* - ---- - -### Additional notes - - -* Eden doesn't require the rather large Qt dependency, but you will lack a GUI frontend - -```bash -# ... - -# Generate CMake Makefiles (withou QT) -cmake .. -G "MSYS Makefiles" -DYUZU_TESTS=OFF -DENABLE_QT=no - -# ... -``` - -* Running programs from inside `MSYS2 MinGW x64` shell has a different `%PATH%` than directly from explorer. - * This different `%PATH%` has the locations of the other DLLs required. - - - ---- - -## 🖥️ Method III: CLion Environment Setup - -### a. Prerequisites to CLion - -* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I - ---- - -### b. Cloning eden with CLion - -* Clone the Repository: - - - - - ---- - -### c. Building & Setup - -* Once Cloned, You will be taken to a prompt like the image below: - - - -* Set the settings to the image below: -* Change `Build type: Release` -* Change `Name: Release` -* Change `Toolchain Visual Studio` -* Change `Generator: Let CMake decide` -* Change `Build directory: build` - - - -* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. -* Once this process has been completed (No loading bar bottom right), you can now build eden -* In the top right, click on the drop-down menu, select all configurations, then select eden - - - -* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. - - - ---- - -## 💻 Building from the command line with MSVC - -```cmd -# Clone eden and enter -git clone https://git.eden-emu.dev/eden-emu/eden -cd eden - -# Make build dir and enter -mkdir build && cd build - -# Generate CMake Makefiles -cmake .. -G "Visual Studio 17 2022" -A x64 -DYUZU_TESTS=OFF - -# Build -cmake --build . --config Release -``` - -## 📜 Building with Scripts - -* A convenience script for building is provided in `.ci/windows/build.sh`. -* You must run this with Bash, e.g. Git Bash or MinGW TTY. -* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: - * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. -* You can use `aqtinstall`, more info on and - - -* Extra CMake flags should be placed in the arguments of the script. - -#### Additional environment variables can be used to control building: - -* `BUILD_TYPE` (default `Release`): Sets the build type to use. - -* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: - - * `DEVEL` (default FALSE): Disable Qt update checker - * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine - * `USE_MULTIMEDIA` (default TRUE): Enable Qt Multimedia - * `BUNDLE_QT` (default FALSE): Use bundled Qt - - * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` - * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` - -* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. - * The resulting zip will be placed into `artifacts` in the source directory. - diff --git a/docs/build/macOS.md b/docs/build/macOS.md deleted file mode 100644 index fd1873b849..0000000000 --- a/docs/build/macOS.md +++ /dev/null @@ -1,78 +0,0 @@ -Please note this article is intended for development, and Eden on macOS is not currently ready for regular use. - -This article was written for developers. Eden support for macOS is not ready for casual use. - -## Dependencies -Install dependencies from Homebrew: -```sh -brew install autoconf automake boost ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@6 sdl2 speexdsp zlib zstd cmake Catch2 molten-vk vulkan-loader spirv-tools -``` - -If you are compiling on Intel Mac, or are using a Rosetta Homebrew installation, you must replace all references of `/opt/homebrew` with `/usr/local`. - -Now, clone the repo: -```sh -git clone --recursive https://git.eden-emu.dev/eden-emu/eden -cd eden -``` - -## Method I: ninja - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -ninja -``` - -You may also want to include support for Discord Rich Presence by adding `-DUSE_DISCORD_PRESENCE=ON` -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - -## Method II: Xcode - ---- -Build for release -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -# Only if having errors about Xcode 15.0 -sudo /usr/bin/xcode-select --switch /Users/admin/Downloads/Xcode.ap -cmake -B build -GXcode -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=ON -DENABLE_LIBUSB=OFF -DCLANG_FORMAT=ON -DSDL2_DISABLE_INSTALL=ON -DSDL_ALTIVEC=ON -xcodebuild build -project yuzu.xcodeproj -scheme "yuzu" -configuration "RelWithDebInfo" -``` - -Build with debug symbols: -```sh -export Qt6_DIR="/opt/homebrew/opt/qt@6/lib/cmake" -cmake -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DYUZU_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF -ninja -``` - -Run the output: -``` -bin/eden.app/Contents/MacOS/eden -``` - ---- - -To run with MoltenVK, install additional dependencies: -```sh -brew install molten-vk vulkan-loader -``` - -Run with Vulkan loader path: -```sh -export LIBVULKAN_PATH=/opt/homebrew/lib/libvulkan.dylib -bin/eden.app/Contents/MacOS/eden -``` diff --git a/docs/img/creator-1.png b/docs/img/creator-1.png new file mode 100644 index 0000000000000000000000000000000000000000..14d679cfbb6dabd5bcf7300395aa4d22ae2b1d62 GIT binary patch literal 64671 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μ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%0Ay*v1tt;;D^9?ybazI(tsNvoIkg)qOU2gHM0m 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 literal 0 HcmV?d00001 diff --git a/docs/scripts/Linux.md b/docs/scripts/Linux.md new file mode 100644 index 0000000000..8b18e41ced --- /dev/null +++ b/docs/scripts/Linux.md @@ -0,0 +1,31 @@ +# Linux Build Scripts + +* Provided script: `.ci/linux/build.sh` +* Must specify arch target, e.g.: `.ci/linux/build.sh amd64` +* Valid targets: + * `native`: Optimize to your native host architecture + * `legacy`: x86\_64 generic, only needed for CPUs older than 2013 or so + * `amd64`: x86\_64-v3, for CPUs newer than 2013 or so + * `steamdeck` / `zen2`: For Steam Deck or Zen >= 2 AMD CPUs (untested on Intel) + * `rog-ally` / `allyx` / `zen4`: For ROG Ally X or Zen >= 4 AMD CPUs (untested on Intel) + * `aarch64`: For armv8-a CPUs, older than mid-2021 or so + * `armv9`: For armv9-a CPUs, newer than mid-2021 or so +* Extra CMake flags go after the arch target. + +### Environment Variables + +* `NPROC`: Number of compilation threads (default: all cores) +* `TARGET`: Set `appimage` to disable standalone `eden-cli` and `eden-room` +* `BUILD_TYPE`: Build type (default: `Release`) + +Boolean flags (set `true` to enable, `false` to disable): + +* `DEVEL` (default `FALSE`): Disable Qt update checker +* `USE_WEBENGINE` (default `FALSE`): Enable Qt WebEngine +* `USE_MULTIMEDIA` (default `FALSE`): Enable Qt Multimedia + +* AppImage packaging script: `.ci/linux/package.sh` + + * Accepts same arch targets as build script + * Use `DEVEL=true` to rename app to `Eden Nightly` + * This should generally not be used unless in a tailor-made packaging environment (e.g. Actions/CI) \ No newline at end of file diff --git a/docs/scripts/Windows.md b/docs/scripts/Windows.md new file mode 100644 index 0000000000..c1ebb5a4c2 --- /dev/null +++ b/docs/scripts/Windows.md @@ -0,0 +1,76 @@ +# Windows Build Scripts + +* A convenience script for building is provided in `.ci/windows/build.sh`. +* You must run this with Bash, e.g. Git Bash or the MinGW TTY. +* To use this script, you must have `windeployqt` installed (usually bundled with Qt) and set the `WINDEPLOYQT` environment variable to its canonical Bash location: + * `WINDEPLOYQT="/c/Qt/6.9.1/msvc2022_64/bin/windeployqt6.exe" .ci/windows/build.sh`. +* You can use `aqtinstall`, more info on and + + +* Extra CMake flags should be placed in the arguments of the script. + +#### Additional environment variables can be used to control building: + +* `BUILD_TYPE` (default `Release`): Sets the build type to use. + +* The following environment variables are boolean flags. Set to `true` to enable or `false` to disable: + + * `DEVEL` (default FALSE): Disable Qt update checker + * `USE_WEBENGINE` (default FALSE): Enable Qt WebEngine + * `USE_MULTIMEDIA` (default FALSE): Enable Qt Multimedia + * `BUNDLE_QT` (default FALSE): Use bundled Qt + + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH` + * `.ci/windows/build.sh -DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` + +* After building, a zip can be packaged via `.ci/windows/package.sh`. You must have 7-zip installed and in your PATH. + * The resulting zip will be placed into `artifacts` in the source directory. + + +## 🖥️ Method III: CLion Environment Setup + +### a. Prerequisites to CLion + +* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I + +--- + +### b. Cloning eden with CLion + +* Clone the Repository: + + + + + +--- + +### c. Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + + + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + + + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + + + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + + + +--- + + + From eddfa300a4c47b568b6c6370a3b2b81dd0e75ac8 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:18:20 -0400 Subject: [PATCH 14/17] Oops Signed-off-by: crueter --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ba489b7218..71e79e15ea 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ This contains documentation created by developers. This contains build instructions, guidelines, instructions/layouts for [cool stuff we made](CPM.md), and more. -- **[General Build Instructions](CPM.md)** +- **[General Build Instructions](Build.md)** - **[Development Guidelines](Development.md)** - **[Dependencies](Deps.md)** - **[CPM - CMake Package Manager](CPM.md)** From 0625b2b5298608bcae6856781548d6e755c47ceb Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 00:20:18 -0400 Subject: [PATCH 15/17] fix Signed-off-by: crueter --- docs/Build.md | 2 +- docs/Deps.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Build.md b/docs/Build.md index 910f8b43e2..13aa142ac0 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -75,7 +75,7 @@ If you are on Windows and prefer to use Clang: cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl ``` -
+
### CLion diff --git a/docs/Deps.md b/docs/Deps.md index cd875cd292..9cfe36b547 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -125,6 +125,7 @@ sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel
macOS + Install dependencies from **[Homebrew](https://brew.sh/)** ```sh @@ -198,6 +199,7 @@ Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz
MSYS2 + * Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) * Download and install all dependencies using: * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` From e99b7bd60a820c9d72dd9840c351932f69f4b8b4 Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 15 Sep 2025 22:29:41 -0400 Subject: [PATCH 16/17] [docs] clion, openbsd deps, readme Signed-off-by: crueter --- README.md | 8 +------ docs/Build.md | 44 ++++++++++++++++++++++++++++++++++---- docs/Deps.md | 4 ++-- docs/Options.md | 2 ++ docs/scripts/Windows.md | 47 ----------------------------------------- 5 files changed, 45 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index e1f0b50b37..959b903385 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,7 @@ If you would like to contribute, we are open to new developers and pull requests ## Building -* **Windows**: [Windows Building Guide](./docs/build/Windows.md) -* **Linux**: [Linux Building Guide](./docs/build/Linux.md) -* **Android**: [Android Building Guide](./docs/build/Android.md) -* **Solaris**: [Solaris Building Guide](./docs/build/Solaris.md) -* **FreeBSD**: [FreeBSD Building Guide](./docs/build/FreeBSD.md) -* **macOS**: [macOS Building Guide](./docs/build/macOS.md) -* **OpenBSD**: [OpenBSD Building Guide](./docs/build/OpenBSD.md) +See the [General Build Guide](docs/Build.md) ## Download diff --git a/docs/Build.md b/docs/Build.md index 13aa142ac0..52a671ab1e 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -56,6 +56,7 @@ This is recommended for *BSD, Solaris, Linux, and MSYS2. MSVC is possible, but n Note that CMake must be in your PATH, and you must be in the cloned Eden directory. On Windows, you must also set up a Visual C++ development environment. This can be done by running `C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat` in the same terminal. Recommended generators: + - MSYS2: `MSYS Makefiles` - MSVC: Install **[ninja](https://ninja-build.org/)** and use `Ninja`, OR use `Visual Studio 17 2022` - macOS: `Ninja` (preferred) or `Xcode` @@ -77,9 +78,44 @@ cmake -S . -B build -G "GENERATOR" -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPI
-### CLion +### [CLion](https://www.jetbrains.com/clion/) -TODO +
+Click to Open + +* Clone the Repository: + + + + + +--- + +### Building & Setup + +* Once Cloned, You will be taken to a prompt like the image below: + + + +* Set the settings to the image below: +* Change `Build type: Release` +* Change `Name: Release` +* Change `Toolchain Visual Studio` +* Change `Generator: Let CMake decide` +* Change `Build directory: build` + + + +* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. +* Once this process has been completed (No loading bar bottom right), you can now build eden +* In the top right, click on the drop-down menu, select all configurations, then select eden + + + +* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. + + +
## Troubleshooting @@ -103,7 +139,7 @@ Simply hit Ctrl+B, or the "hammer" icon in the bottom left. To run, hit the "pla ### Command Line -If you are not on Windows, and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. +If you are not on Windows and are using the `UNIX Makefiles` generator, you must also add `-j$(nproc)` to this command. ``` cmake --build build @@ -121,4 +157,4 @@ Some platforms have convenience scripts provided for building. - **[Linux](scripts/Linux.md)** - **[Windows](scripts/Windows.md)** -macOS scripts will come soon. Maybe. \ No newline at end of file +macOS scripts will come soon. \ No newline at end of file diff --git a/docs/Deps.md b/docs/Deps.md index 9cfe36b547..f9a083d368 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -180,7 +180,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead. ```sh pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 ```
@@ -194,7 +194,7 @@ Run the usual update + install of essential toolings: `sudo pkg update && sudo p - **gcc**: `sudo pkg install developer/gcc-14`. - **clang**: Version 20 is broken, use `sudo pkg install developer/clang-19`. -Then install the libraies: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`. +Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/lz4 nlohmann-json openssl opus sdl2 zlib compress/zstd unzip pkg-config nasm autoconf mesa library/libdrm header-drm developer/fmt`.
diff --git a/docs/Options.md b/docs/Options.md index 61f578df8b..d19aab63f6 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -53,6 +53,8 @@ The following options are desktop only: - `ENABLE_QT_TRANSLATION` (OFF) Enable translations for the Qt frontend - `ENABLE_QT_UPDATE_CHECKER` (OFF) Enable update checker for the Qt frontend - `YUZU_USE_BUNDLED_QT` (ON for MSVC) Download bundled Qt binaries + * Note that using **system Qt** requires you to include the Qt CMake directory in `CMAKE_PREFIX_PATH`, e.g: + * `-DCMAKE_PREFIX_PATH=C:/Qt/6.9.0/msvc2022_64/lib/cmake/Qt6` - `YUZU_QT_MIRROR` (string) What mirror to use for downloading the bundled Qt libraries - `YUZU_USE_QT_MULTIMEDIA` (OFF) Use QtMultimedia for camera support - `YUZU_USE_QT_WEB_ENGINE` (OFF) Use QtWebEngine for web applet implementation (requires the huge QtWebEngine dependency; not recommended) diff --git a/docs/scripts/Windows.md b/docs/scripts/Windows.md index c1ebb5a4c2..e60c2119a2 100644 --- a/docs/scripts/Windows.md +++ b/docs/scripts/Windows.md @@ -27,50 +27,3 @@ * The resulting zip will be placed into `artifacts` in the source directory. -## 🖥️ Method III: CLion Environment Setup - -### a. Prerequisites to CLion - -* [CLion](https://www.jetbrains.com/clion/) - This IDE is not free; for a free alternative, check Method I - ---- - -### b. Cloning eden with CLion - -* Clone the Repository: - - - - - ---- - -### c. Building & Setup - -* Once Cloned, You will be taken to a prompt like the image below: - - - -* Set the settings to the image below: -* Change `Build type: Release` -* Change `Name: Release` -* Change `Toolchain Visual Studio` -* Change `Generator: Let CMake decide` -* Change `Build directory: build` - - - -* Click OK; now Clion will build a directory and index your code to allow for IntelliSense. Please be patient. -* Once this process has been completed (No loading bar bottom right), you can now build eden -* In the top right, click on the drop-down menu, select all configurations, then select eden - - - -* Now run by clicking the play button or pressing Shift+F10, and eden will auto-launch once built. - - - ---- - - - From 94932270a5d4bbe406cbdff1f3d7429a4388fb0b Mon Sep 17 00:00:00 2001 From: crueter Date: Tue, 16 Sep 2025 12:55:41 -0400 Subject: [PATCH 17/17] add libusb to openbsd deps Signed-off-by: crueter --- docs/Deps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Deps.md b/docs/Deps.md index f9a083d368..cfc6f0365b 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -180,7 +180,7 @@ If using FreeBSD 12 or prior, use `devel/pkg-config` instead. ```sh pkg_add -u -pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 +pkg_add cmake nasm git boost unzip--iconv autoconf-2.72p0 bash ffmpeg glslang gmake llvm-19.1.7p3 qt6 jq fmt nlohmann-json enet boost vulkan-utility-libraries vulkan-headers spirv-headers spirv-tools catch2 sdl2 libusb1.1.0.27 ```