build: Add Nix and Docker build environments

This commit is contained in:
fooly
2026-07-14 18:55:16 +09:00
parent acb105bd58
commit 878f0c4b39
6 changed files with 382 additions and 2 deletions

8
.dockerignore Normal file
View File

@@ -0,0 +1,8 @@
build/
cmake-build-*/
out/
.cache/
result
bin/Cemu_*
bin/*.pdb
bin/*.ilk

View File

@@ -15,6 +15,8 @@
- [Troubleshooting Steps](#troubleshooting-steps)
- [Compiling Errors](#compiling-errors)
- [Building Errors](#building-errors)
- [Nix](#nix)
- [Docker](#docker)
- [macOS](#macos)
- [Installing brew](#installing-brew)
- [Installing Tool Dependencies](#installing-tool-dependencies)
@@ -131,6 +133,32 @@ This section refers to running `cmake -S...` (truncated).
If you are getting a different error than any of the errors listed above, you may either open an issue in this repo or try using [GCC](#gcc). Make sure your standard library and compilers are updated since Cemu uses a lot of modern features!
## Nix
The repository includes a flake that provides a reproducible Linux build and development shell. It uses Nixpkgs for the native dependencies and does not invoke vcpkg.
From the CemuExtend directory:
```
nix develop
cmake -S . -B build/nix -G Ninja -DCMAKE_BUILD_TYPE=Debug -DENABLE_VCPKG=OFF -DALLOW_PORTABLE=OFF
cmake --build build/nix --parallel
```
The development build is written to `bin/Cemu_debug`. To build the packaged Nix output instead, run `nix build .#cemu-extend`; the executable is available as `result/bin/cemu`.
## Docker
The Dockerfile uses CemuExtend's vcpkg manifest and initializes all git submodules inside the image. Build from the CemuExtend directory:
```
git submodule update --init --recursive
docker build -t cemu-extend:build .
docker run --rm -it cemu-extend:build
```
The default image performs a Release build. Use `--build-arg BUILD_TYPE=Debug` for a Debug build. The compiled executable is at `/workspace/CemuExtend/bin/Cemu_release` (or `Cemu_debug`) inside the container. To create only the dependency-enabled development image without compiling, use `docker build --target dev -t cemu-extend:dev .`.
##### Building Errors

97
Dockerfile Normal file
View File

@@ -0,0 +1,97 @@
# syntax=docker/dockerfile:1
FROM ubuntu:24.04 AS cemu-extend-base
ARG DEBIAN_FRONTEND=noninteractive
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
VCPKG_FORCE_SYSTEM_BINARIES=1 \
VCPKG_DEFAULT_BINARY_CACHE=/root/.cache/vcpkg/archives
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
build-essential \
ca-certificates \
clang \
cmake \
curl \
file \
freeglut3-dev \
git \
libasound2-dev \
libbluetooth-dev \
libdbus-1-dev \
libdrm-dev \
libegl1-mesa-dev \
libgcrypt20-dev \
libgbm-dev \
libgl1-mesa-dev \
libglu1-mesa-dev \
libgtk-3-dev \
libpulse-dev \
libsecret-1-dev \
libssl-dev \
libsystemd-dev \
libtool \
libudev-dev \
libusb-1.0-0-dev \
libwayland-dev \
libx11-dev \
libx11-xcb-dev \
libxcursor-dev \
libxext-dev \
libxfixes-dev \
libxi-dev \
libxinerama-dev \
libxkbcommon-dev \
libxrandr-dev \
libxrender-dev \
libxtst-dev \
nasm \
ninja-build \
pkg-config \
python3 \
unzip \
wayland-protocols \
zip \
&& rm -rf /var/lib/apt/lists/*
RUN mkdir -p "$VCPKG_DEFAULT_BINARY_CACHE"
RUN apt-get update \
&& apt-get install --no-install-recommends -y \
autoconf \
autoconf-archive \
automake \
libglm-dev \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /workspace/CemuExtend
COPY . .
# CemuExtend keeps most third-party sources in git submodules. Initializing
# them here also makes a checkout with empty submodule directories usable as a
# Docker build context.
RUN test -e .git \
&& git submodule update --init --recursive \
&& bash ./dependencies/vcpkg/bootstrap-vcpkg.sh -disableMetrics
FROM cemu-extend-base AS dev
CMD ["bash"]
FROM dev AS build
ARG BUILD_TYPE=Release
RUN --mount=type=cache,target=/root/.cache/vcpkg/archives \
cmake -S . -B build/docker \
-G Ninja \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DENABLE_VCPKG=ON \
-DALLOW_PORTABLE=OFF \
-DVCPKG_INSTALL_OPTIONS=--clean-after-build \
&& cmake --build build/docker --parallel
CMD ["bash"]

45
flake.lock generated Normal file
View File

@@ -0,0 +1,45 @@
{
"nodes": {
"imgui-src": {
"flake": false,
"locked": {
"lastModified": 1728049365,
"narHash": "sha256-J4gz4rnydu8JlzqNC/OIoVoRcgeFd6B1Qboxu5drOKY=",
"owner": "ocornut",
"repo": "imgui",
"rev": "cb16568fca5297512ff6a8f3b877f461c4323fbe",
"type": "github"
},
"original": {
"owner": "ocornut",
"ref": "v1.91.3",
"repo": "imgui",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1783856661,
"narHash": "sha256-ZGP04e+Q6WyQJGA9ZvI5CL6+heGQldbAG9U1T9NGvmU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "569d578509928497eddc3fdbf94a799027050be4",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"imgui-src": "imgui-src",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

204
flake.nix Normal file
View File

@@ -0,0 +1,204 @@
{
description = "CemuExtend Nix build environment";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
# Cemu expects the complete Dear ImGui source tree, not only installed
# headers. Keep it as an explicit input so the flake also works when the
# git submodules in a checkout have not been initialized yet.
imgui-src = {
url = "github:ocornut/imgui/v1.91.3";
flake = false;
};
};
outputs =
inputs@{
self,
nixpkgs,
imgui-src,
...
}:
let
system = "x86_64-linux";
pkgs = import nixpkgs { inherit system; };
lib = pkgs.lib;
# Keep the Nix source small and reproducible. Dependencies that are
# supplied by Nixpkgs are deliberately omitted and linked in
# preConfigure below where Cemu expects a vendored source tree.
source = lib.fileset.toSource {
root = ./.;
fileset = lib.fileset.unions [
./CMakeLists.txt
./bin/gameProfiles/default
./bin/resources
./cmake
./dependencies/DirectX_2010
./dependencies/gamemode
./dependencies/ih264d
./dist
./src
];
};
# glslang's CMake package refers to SPIRV-Tools-opt before it is
# otherwise loaded. This is the same initialization used by the
# cemu_pinkd reference flake.
devCmakeInit = pkgs.writeText "cemu-extend-nix-init.cmake" ''
if(NOT TARGET SPIRV-Tools-opt)
find_package(SPIRV-Tools-opt REQUIRED)
endif()
'';
cemu = pkgs.stdenv.mkDerivation {
pname = "cemu-extend";
version = "2.0-${self.shortRev or "dirty"}";
src = source;
nativeBuildInputs = with pkgs; [
addDriverRunpath
cmake
nasm
ninja
pkg-config
wayland-scanner
wrapGAppsHook3
wxwidgets_3_3
];
buildInputs = with pkgs; [
bluez
boost
cubeb
curl
fmt_12
glm
glslang
gtk3
hidapi
libGL
libGLU
libpng
libusb1
libxrender
libzip
openssl
pugixml
rapidjson
sdl3
spirv-tools
vulkan-headers
vulkan-loader
wayland
wayland-protocols
wxwidgets_3_3
libx11
libxrender
zarchive
zlib
zstd
];
cmakeFlags = [
(lib.cmakeBool "ALLOW_PORTABLE" false)
(lib.cmakeBool "ENABLE_FERAL_GAMEMODE" true)
(lib.cmakeBool "ENABLE_VCPKG" false)
(lib.cmakeFeature "CMAKE_PROJECT_INCLUDE" (toString devCmakeInit))
(lib.cmakeFeature "EMULATOR_VERSION_MAJOR" "2")
(lib.cmakeFeature "EMULATOR_VERSION_MINOR" "0")
];
postPatch = ''
# The Nixpkgs wxWidgets package exposes wx-config rather than the
# vcpkg wxWidgets::wxWidgets target. The module already creates a
# complete wx::base interface target in this case, so provide the
# compatibility alias expected by CemuExtend.
substituteInPlace cmake/FindwxWidgets.cmake \
--replace-fail \
' find_package_handle_standard_args(wxWidgets' \
' if (NOT TARGET wxWidgets::wxWidgets AND TARGET wx::base)
add_library(wxWidgets::wxWidgets ALIAS wx::base)
endif()
find_package_handle_standard_args(wxWidgets'
'';
preConfigure = ''
rm -rf dependencies/imgui dependencies/Vulkan-Headers
ln -s ${imgui-src} dependencies/imgui
ln -s ${pkgs.vulkan-headers} dependencies/Vulkan-Headers
substituteInPlace dependencies/gamemode/lib/gamemode_client.h \
--replace-fail "libgamemode.so.0" \
"${pkgs.gamemode.lib}/lib/libgamemode.so.0"
'';
installPhase = ''
runHook preInstall
install -Dm755 ../bin/Cemu_release $out/bin/Cemu
ln -s Cemu $out/bin/cemu
install -d $out/share/Cemu
cp -r ../bin/resources ../bin/gameProfiles $out/share/Cemu/
install -d $out/share/applications
substitute ../dist/linux/info.cemu.Cemu.desktop \
$out/share/applications/info.cemu.Cemu.desktop \
--replace-fail "Exec=Cemu" "Exec=$out/bin/cemu"
install -Dm644 ../dist/linux/info.cemu.Cemu.metainfo.xml \
$out/share/metainfo/info.cemu.Cemu.metainfo.xml
install -Dm644 ../src/resource/logo_icon.png \
$out/share/icons/hicolor/128x128/apps/info.cemu.Cemu.png
runHook postInstall
'';
preFixup = ''
gappsWrapperArgs+=(
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ pkgs.vulkan-loader ]}"
)
'';
strictDeps = true;
enableParallelBuilding = true;
meta = {
description = "CemuExtend Wii U emulator build for NixOS";
homepage = "https://github.com/fooly9858/CemuExtend";
license = lib.licenses.mpl20;
mainProgram = "cemu";
platforms = [ system ];
};
};
in
{
packages.${system} = {
default = cemu;
cemu-extend = cemu;
};
apps.${system}.default = {
type = "app";
program = lib.getExe cemu;
meta.description = "Run CemuExtend";
};
devShells.${system}.default = pkgs.mkShell {
inputsFrom = [ cemu ];
packages = [ pkgs.git ];
CMAKE_PROJECT_INCLUDE = devCmakeInit;
shellHook = ''
echo "CemuExtend Nix development shell"
echo "Configure with: cmake -S . -B build/nix -G Ninja -DCMAKE_BUILD_TYPE=Debug -DENABLE_VCPKG=OFF -DALLOW_PORTABLE=OFF"
'';
};
checks.${system}.default = cemu;
formatter.${system} = pkgs.nixfmt;
};
}

View File

@@ -133,8 +133,6 @@ void ImGui_UpdateWindowInformation(bool mainWindow)
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
#if BOOST_OS_WINDOWS
io.ImeWindowHandle = mainWindow ? windowInfo.window_main.surface : windowInfo.window_pad.surface;
#else
io.ImeWindowHandle = nullptr;
#endif
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);