Files
parallel-gx2/CMakeLists.txt
T
WizzardSK ef29126250 Drop the standalone's backends and keep them from coming back with upstream
None of these were built into the core any more; now they are gone from the
tree as well. Input comes from the frontend and audio goes to it, so SDL, the
DSU client, the keyboard provider, real Wiimotes over hidapi/BlueZ, the
GameCube adapter, XInput and DirectInput go, and so do cubeb (the submodule
with it), XAudio2, XAudio 2.7, DirectSound and the DirectX 2010 headers, the
Discord Rich Presence client, Feral GameMode and the ScreenSaver helper that
only SDL filled in. The code that stays loses the #if branches that named
them; the API enums keep their values, since config files store them. The
README's build steps lose the packages and flags only these needed, and
upstream's BUILD.md, CONTRIBUTING.md, CODING_STYLE.md and boost.natvis go
with the standalone they describe. libusb stays: nsyshid passes real USB toy
portals through to the game.

.upstream-excluded lists every path removed for being standalone-only, the
wx GUI included, and AGENTS.md says to run git rm --pathspec-from-file on it
right after merging upstream Cemu. That settles modify/delete conflicts in
favour of the deletion and also removes files upstream newly adds under those
paths, which git would otherwise bring in without any conflict.

Built on all seven targets plus iOS and tvOS.
2026-09-26 11:17:20 +02:00

325 lines
13 KiB
CMake

cmake_minimum_required(VERSION 3.21.1)
option(ENABLE_VCPKG "Enable the vcpkg package manager" ON)
# This repository builds the libretro core and nothing else - the standalone
# wx application is gone. ENABLE_LIBRETRO stays as a variable because the rest
# of the build, much of it shared with upstream Cemu, still asks for it.
set(ENABLE_LIBRETRO ON)
option(ALLOW_PORTABLE "Allow Cemu to be run in portable mode" ON)
# used by CI script to set version:
set(EMULATOR_VERSION_MAJOR "0" CACHE STRING "")
set(EMULATOR_VERSION_MINOR "0" CACHE STRING "")
set(EMULATOR_VERSION_PATCH "0" CACHE STRING "")
set(THREADS_PREFER_PTHREAD_FLAG true) # needs to be set before vcpkg
execute_process(
COMMAND git log --format=%h -1
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
# webOS is a Linux by CMAKE_SYSTEM_NAME with a buildroot as bare as Android's:
# EGL and GLES and nothing else - no X11, no Wayland, no desktop GL, no session
# bus. It has to be settled here, before the vcpkg block below picks the overlay
# ports and before the option defaults further down are chosen - which is ahead
# of project(), so the compiler is not known yet and the SDK's toolchain file is
# what gives it away (/developer/aarch64-webos-linux-gnu_sdk-buildroot/...), the
# same tell CEMU_TARGET_ANDROID uses below. -DWEBOS=ON says it outright.
if(NOT WEBOS AND CMAKE_TOOLCHAIN_FILE MATCHES "webos")
set(WEBOS TRUE)
endif()
if (ENABLE_VCPKG)
# check if vcpkg is shallow and unshallow it if necessary
execute_process(
COMMAND git rev-parse --is-shallow-repository
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/dependencies/vcpkg
OUTPUT_VARIABLE is_vcpkg_shallow
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(is_vcpkg_shallow STREQUAL "true")
message(STATUS "vcpkg is shallow. Unshallowing it now...")
execute_process(
COMMAND git fetch --unshallow
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/dependencies/vcpkg"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
)
endif()
# Cross builds hand cmake a toolchain file of their own - the NDK's on
# Android, MXE's for the MinGW Windows build - which would bypass vcpkg
# entirely and leave every find_package() below unsatisfied. Hand it to
# vcpkg as a chainload toolchain instead and let vcpkg's own toolchain take
# the primary slot. (A cache entry set from the command line wins over the
# plain set() below, so this has to be done here rather than there.)
if(CMAKE_TOOLCHAIN_FILE AND NOT VCPKG_CHAINLOAD_TOOLCHAIN_FILE
AND NOT CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake$")
if(CMAKE_TOOLCHAIN_FILE MATCHES "android.toolchain.cmake$")
set(CEMU_TARGET_ANDROID ON)
endif()
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" CACHE STRING "" FORCE)
unset(CMAKE_TOOLCHAIN_FILE CACHE)
endif()
if(WEBOS)
# The Linux overlays take libpng, cairo and gtk3 from the system, which
# for a cross build would mean the host's x86_64 copies. Only the dbus
# one is worth carrying over - nothing links D-Bus, SDL dlopen()s it -
# and its port exists because upstream's tarball host answers 504 often
# enough to fail whole pipelines.
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_webos;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
# vcpkg builds its ports with the triplet's own toolchain, not with the
# one this file chainloads for the core (that reaches try_compile and
# nothing else), so the cross compiler has to be named in a triplet of
# its own. arm64-linux would build them for the host.
set(VCPKG_OVERLAY_TRIPLETS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_triplets")
elseif(CEMU_TARGET_ANDROID)
# no android-specific overlay ports at the moment - vcpkg refuses to start
# if an overlay path does not exist, so do not name one that is not there
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
elseif(VCPKG_TARGET_TRIPLET MATCHES "mingw")
# Cross-compiling to Windows from a Unix host: WIN32 is not set yet (no
# project() call so far, and the host is what counts before it), so the
# triplet is what tells the Windows overlay apart from the Linux one.
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_win;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
elseif(UNIX AND NOT APPLE)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
elseif(APPLE)
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_mac;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
else()
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_win;${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports")
endif()
# libusb is a feature rather than a plain dependency because iOS and tvOS
# have no USB API to build it against: its Darwin backend is IOKit's USB
# family, and the SDK there does not even carry IOKit/IOCFBundle.h, so the
# port stops on a missing header before anything of ours is compiled.
# Nothing is lost - a phone or a TV box has no Wii U GamePad adapter to
# plug in - and ENABLE_LIBUSB below follows the same condition.
#
# This runs before project(), so APPLE is not set yet and the system name
# is what tells the platforms apart.
# webOS is left out for a different reason than the Apple ones: the port
# builds there, but its Linux backend wants libudev, which the buildroot
# does not carry - and a webOS app has no raw USB access to use it with.
if (NOT CMAKE_SYSTEM_NAME STREQUAL "iOS" AND NOT CMAKE_SYSTEM_NAME STREQUAL "tvOS" AND NOT WEBOS)
list(APPEND VCPKG_MANIFEST_FEATURES "usb")
endif()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/vcpkg/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "Vcpkg toolchain file")
# Set this so that all the various find_package() calls don't need an explicit
# CONFIG option
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
if (WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
endif()
endif()
project(Cemu VERSION 2.0.0)
# vcpkg hangs an applocal.ps1 post-build step on every Windows target, to copy
# the DLLs it built next to the binary. That is a PowerShell script, and the
# MinGW job cross-compiles on Linux, where linking cemu_libretro.dll then ends
# in "/bin/sh: 1: powershell.exe: not found" with everything else already done.
# A static triplet has no DLLs to copy anyway.
if(WIN32 AND NOT MSVC)
set(VCPKG_APPLOCAL_DEPS OFF)
endif()
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_definitions($<$<CONFIG:Debug>:CEMU_DEBUG_ASSERT>) # if build type is debug, set CEMU_DEBUG_ASSERT
add_definitions(-DEMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR})
add_definitions(-DEMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR})
add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# enable link time optimization for release builds
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO ON)
if (MSVC)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT CemuBin)
# floating point model: precise, fiber safe optimizations
add_compile_options(/EHsc /fp:precise)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Speeds up static linking (especially helpful in incremental compilation)
if((CMAKE_LINKER MATCHES ".*lld-link.*") AND (CMAKE_AR MATCHES ".*llvm-lib.*"))
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY STATIC_LIBRARY_OPTIONS /llvmlibthin)
endif()
else()
add_compile_options(/GT)
endif()
# enable additional optimization flags for release builds
add_compile_options($<$<CONFIG:Release,RelWithDebInfo>:/Oi>) # enable intrinsic functions
add_compile_options($<$<CONFIG:Release,RelWithDebInfo>:/Ot>) # favor speed
endif()
if(CMAKE_GENERATOR STREQUAL "Xcode")
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY XCODE_STARTUP_PROJECT CemuBin)
endif()
if (APPLE)
enable_language(OBJC OBJCXX)
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.4")
endif()
if (UNIX AND NOT APPLE)
# webOS: the buildroot carries no Wayland.
if (WEBOS)
set(CEMU_DESKTOP_SESSION_DEFAULT OFF)
else()
set(CEMU_DESKTOP_SESSION_DEFAULT ON)
endif()
option(ENABLE_WAYLAND "Build with Wayland support" ${CEMU_DESKTOP_SESSION_DEFAULT})
endif()
if (APPLE)
set(ENABLE_METAL_DEFAULT ON)
set(ENABLE_OPENGL_DEFAULT OFF)
else()
set(ENABLE_METAL_DEFAULT OFF)
# The GL backend here is desktop GL 4.5 with direct state access; webOS
# offers GLES through EGL and nothing more, so Vulkan is the backend that
# fits there - the same split as Android.
if (WEBOS)
set(ENABLE_OPENGL_DEFAULT OFF)
else()
set(ENABLE_OPENGL_DEFAULT ON)
endif()
endif()
option(ENABLE_OPENGL "Enables the OpenGL backend" ${ENABLE_OPENGL_DEFAULT})
option(ENABLE_VULKAN "Enables the Vulkan backend" ON)
option(ENABLE_METAL "Enables the Metal backend" ${ENABLE_METAL_DEFAULT})
if (ENABLE_METAL AND NOT APPLE)
message(FATAL_ERROR "Metal backend is only supported on Apple platforms")
endif()
# Input comes from the frontend (LibretroControllerProvider) and audio goes to
# it (LibretroAudioAPI); the standalone's own backends - SDL, the DSU client,
# the keyboard, real Wiimotes over hidapi/BlueZ, XInput, DirectInput, cubeb,
# XAudio2, DirectSound - are gone. libusb stays: nsyshid passes real USB toy
# portals through to the game with it, which the frontend cannot do.
#
# Off on the Apple embedded platforms, where there is no USB API to talk to and
# the dependency is not built either (see the manifest features above).
if (CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "tvOS" OR WEBOS)
set(ENABLE_LIBUSB_DEFAULT OFF)
else()
set(ENABLE_LIBUSB_DEFAULT ON)
endif()
option(ENABLE_LIBUSB "Build with libusb support" ${ENABLE_LIBUSB_DEFAULT})
if (ENABLE_LIBUSB)
add_compile_definitions(HAS_LIBUSB)
endif()
if (ENABLE_LIBRETRO)
add_compile_definitions(ENABLE_LIBRETRO)
# All static libs must be compiled with -fPIC for shared library linking
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
if(ENABLE_LIBRETRO)
add_compile_definitions(RETRO_CORE)
endif()
find_package(Threads REQUIRED)
find_package(CURL REQUIRED)
find_package(pugixml REQUIRED)
find_package(RapidJSON REQUIRED)
set(CEMU_BOOST_COMPONENTS program_options filesystem nowide)
if (ANDROID)
# Fiber/FiberAndroid.cpp needs fcontext
list(APPEND CEMU_BOOST_COMPONENTS context)
endif()
find_package(Boost COMPONENTS ${CEMU_BOOST_COMPONENTS} REQUIRED)
find_package(libzip REQUIRED)
find_package(glslang REQUIRED)
find_package(ZLIB REQUIRED)
find_package(zstd MODULE REQUIRED) # MODULE so that zstd::zstd is available
find_package(OpenSSL COMPONENTS Crypto SSL REQUIRED)
find_package(glm REQUIRED)
find_package(fmt 12.1 REQUIRED)
find_package(PNG REQUIRED)
# glslang versions older than 11.11.0 define targets without a namespace
if (NOT TARGET glslang::SPIRV AND TARGET SPIRV)
add_library(glslang::SPIRV ALIAS SPIRV)
endif()
# Android and webOS are UNIX as far as CMake is concerned, but have none of
# this: no X11 and no Wayland.
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBOS)
find_package(X11 REQUIRED)
if (ENABLE_WAYLAND)
find_package(Wayland REQUIRED Client)
find_package(WaylandScanner REQUIRED)
find_package(WaylandProtocols 1.15 REQUIRED)
ecm_add_wayland_client_protocol(WAYLAND_PROTOCOL_SRCS
PROTOCOL "${WaylandProtocols_DATADIR}/stable/viewporter/viewporter.xml"
BASENAME viewporter)
add_library(CemuWaylandProtocols STATIC ${WAYLAND_PROTOCOL_SRCS})
target_include_directories(CemuWaylandProtocols PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")
target_include_directories(CemuWaylandProtocols PRIVATE ${Wayland_INCLUDE_DIRS})
add_compile_definitions(HAS_WAYLAND)
endif()
endif()
if (WEBOS)
add_compile_definitions(WEBOS)
endif()
if (ENABLE_VULKAN)
include_directories("dependencies/Vulkan-Headers/include")
add_compile_definitions(ENABLE_VULKAN)
add_compile_definitions(VK_NO_PROTOTYPES)
endif()
if (ENABLE_OPENGL AND NOT ANDROID AND NOT WEBOS)
# Android and webOS have no desktop OpenGL, only GLES/EGL - the core uses
# Vulkan on both.
find_package(OpenGL REQUIRED)
add_compile_definitions(ENABLE_OPENGL)
endif()
if (ENABLE_METAL)
include_directories(${CMAKE_SOURCE_DIR}/dependencies/metal-cpp)
add_compile_definitions(ENABLE_METAL)
endif()
add_subdirectory("dependencies/ih264d" EXCLUDE_FROM_ALL)
if (CMAKE_OSX_ARCHITECTURES)
set(CEMU_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
else()
set(CEMU_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(CEMU_ARCHITECTURE MATCHES "(aarch64)|(AARCH64)|(arm64)|(ARM64)")
add_subdirectory("dependencies/xbyak_aarch64" EXCLUDE_FROM_ALL)
endif()
find_package(ZArchive QUIET)
if (NOT ZArchive_FOUND)
add_subdirectory("dependencies/ZArchive" EXCLUDE_FROM_ALL)
endif()
add_subdirectory(src)