Files
Xenia-Canary/CMakeLists.txt
2026-03-05 16:18:23 +09:00

245 lines
8.4 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(xenia LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
# Options
option(XENIA_BUILD_TESTS "Build test suites" OFF)
option(XENIA_BUILD_MISC "Build misc subprojects (trace viewers, shader compiler, vfs-dump, demos)" OFF)
if(XENIA_BUILD_TESTS)
enable_testing()
include(${PROJECT_SOURCE_DIR}/third_party/catch/contrib/Catch.cmake)
endif()
# Multi-config generators (VS, Ninja Multi-Config)
get_property(_is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_is_multi_config)
set(CMAKE_CONFIGURATION_TYPES "Checked;Debug;Release" CACHE STRING "" FORCE)
endif()
# Custom Checked configuration (ASan + debug runtime)
set(CMAKE_C_FLAGS_CHECKED "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_CHECKED "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_CHECKED "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING "" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING "" FORCE)
set(CMAKE_STATIC_LINKER_FLAGS_CHECKED "${CMAKE_STATIC_LINKER_FLAGS_DEBUG}" CACHE STRING "" FORCE)
# Platform name for output paths
if(WIN32)
set(XE_PLATFORM_NAME "Windows")
else()
set(XE_PLATFORM_NAME "Linux")
endif()
# Output directories (use PROJECT_SOURCE_DIR so VS and Ninja share the same paths)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build/bin/${XE_PLATFORM_NAME}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build/bin/${XE_PLATFORM_NAME}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build/obj/${XE_PLATFORM_NAME}")
# Create scratch/ if needed
file(MAKE_DIRECTORY "${PROJECT_SOURCE_DIR}/scratch")
# Python for shader compilation scripts
find_package(Python3 REQUIRED COMPONENTS Interpreter)
# Include helpers
include(cmake/XeniaHelpers.cmake)
# Global include directories (these apply to all targets via directory scope)
include_directories(
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/third_party
)
# Global defines
add_compile_definitions(
VULKAN_HPP_NO_TO_STRING
IMGUI_DISABLE_DEFAULT_FONT
IMGUI_USE_STB_SPRINTF
USE_CPP17 # Tabulate
)
# Static library define
add_compile_definitions(_LIB)
# ==============================================================================
# Platform-specific global settings
# ==============================================================================
if(MSVC)
# Global MSVC settings
add_compile_options(
/utf-8 # Build correctly on systems with non-Latin codepages
/wd4201 # Nameless struct/unions are ok
/arch:AVX # AVX vector extensions
/MP # Multi-processor compilation
)
add_compile_definitions(
_CRT_NONSTDC_NO_DEPRECATE
_CRT_SECURE_NO_WARNINGS
WIN32
_WIN64=1
_AMD64=1
UNICODE
_UNICODE
IMGUI_DISABLE_OBSOLETE_FUNCTIONS
)
add_link_options(
/ignore:4006 # Ignores complaints about empty obj files
/ignore:4221
)
# Global Windows system libraries
link_libraries(
ntdll wsock32 ws2_32 xinput comctl32 shcore shlwapi dxguid bcrypt
)
# Windows manifest for executables is handled per-target
# --- Per-configuration MSVC flags ---
# Checked
string(APPEND CMAKE_C_FLAGS_CHECKED " /RTCsu /fsanitize=address")
string(APPEND CMAKE_CXX_FLAGS_CHECKED " /RTCsu /fsanitize=address")
string(APPEND CMAKE_EXE_LINKER_FLAGS_CHECKED " /INCREMENTAL:NO")
add_compile_definitions($<$<CONFIG:Checked>:DEBUG>)
# Debug: use release runtime (/MD) for heap performance, matching premake
string(REPLACE "/MDd" "/MD" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
string(REPLACE "/MDd" "/MD" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
add_compile_definitions($<$<CONFIG:Debug>:DEBUG>)
add_compile_definitions($<$<CONFIG:Debug>:_NO_DEBUG_HEAP=1>)
# Checked or Debug: full symbols
string(APPEND CMAKE_C_FLAGS_CHECKED " /Zi")
string(APPEND CMAKE_CXX_FLAGS_CHECKED " /Zi")
# Debug already has /Zi by default
# Release
add_compile_definitions($<$<CONFIG:Release>:NDEBUG>)
add_compile_definitions($<$<CONFIG:Release>:_NO_DEBUG_HEAP=1>)
add_compile_options($<$<CONFIG:Release>:/Gw>)
add_compile_options($<$<CONFIG:Release>:/GS->) # NoBufferSecurityCheck
# Replace /Ob2 with /Ob3 in CMake's default Release flags
string(REPLACE "/Ob2" "/Ob3" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "/Ob2" "/Ob3" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
# Link-time optimization (whole program optimization)
add_compile_options($<$<CONFIG:Release>:/GL>)
add_link_options($<$<CONFIG:Release>:/LTCG>)
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
else()
# GCC/Clang (Linux)
add_compile_options(-mavx)
# Disable specific warnings for C++
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-Wno-switch>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-attributes>
)
# Clang-specific C++ warnings
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-register>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-volatile>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
)
# Check Clang version for newer warnings
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 20)
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-literal-operator>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-nontrivial-memcall>
)
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 21)
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-Wno-character-conversion>
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# GCC-specific
add_compile_options(
$<$<COMPILE_LANGUAGE:CXX>:-Wno-unused-result>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-volatile>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-template-id-cdtor>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-return-type>
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated>
-fpermissive # HACK
)
add_link_options(-fpermissive)
# GCC: do not use -Werror
endif()
# C-specific warnings
add_compile_options(
$<$<COMPILE_LANGUAGE:C>:-Wno-implicit-function-declaration>
)
# GTK3 via pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK3 REQUIRED gtk+-x11-3.0)
include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
add_compile_options(${GTK3_CFLAGS_OTHER})
# Global Linux libraries
link_libraries(stdc++fs dl lz4 pthread rt)
# Link groups for executables (resolves circular deps)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--start-group")
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} -Wl,--end-group")
# --- Per-configuration Linux flags ---
# Checked
string(APPEND CMAKE_C_FLAGS_CHECKED " -fsanitize=address")
string(APPEND CMAKE_CXX_FLAGS_CHECKED " -fsanitize=address")
string(APPEND CMAKE_EXE_LINKER_FLAGS_CHECKED " -fsanitize=address")
add_compile_definitions(
$<$<CONFIG:Checked>:DEBUG>
$<$<CONFIG:Checked>:_GLIBCXX_DEBUG>
)
# Debug
add_compile_definitions(
$<$<CONFIG:Debug>:DEBUG>
$<$<CONFIG:Debug>:_NO_DEBUG_HEAP=1>
$<$<CONFIG:Debug>:_GLIBCXX_DEBUG>
)
# Release
add_compile_definitions(
$<$<CONFIG:Release>:NDEBUG>
$<$<CONFIG:Release>:_NO_DEBUG_HEAP=1>
)
add_compile_options($<$<CONFIG:Release>:-O3>)
# Link-time optimization (use lld to avoid system linker LTO plugin version mismatch)
add_compile_options($<$<CONFIG:Release>:-flto=thin>)
add_link_options($<$<CONFIG:Release>:-flto=thin>)
add_link_options($<$<CONFIG:Release>:-fuse-ld=lld>)
# No symbols in release on non-Windows
string(REPLACE "-g" "" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
string(REPLACE "-g" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
endif()
# ==============================================================================
# Subdirectories
# ==============================================================================
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Third-party libraries first (no -Werror applied to these)
set(CMAKE_FOLDER "third_party")
add_subdirectory(third_party)
# Xenia source modules (xe_target_defaults applies -Werror)
set(CMAKE_FOLDER "src")
add_subdirectory(src/xenia)
set(CMAKE_FOLDER "")
# Set default startup project for Visual Studio
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT xenia-app)