mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-08 11:03:25 -08:00
* [CI] Build the Windows and macOS legs without debug information Debug information is most of what a compiler cache stores: one Linux configuration measures 1.2 GB with full DWARF and 660 MB at -g1. The Windows leg cannot be lowered that way, because MSVC has no -g level and /Z7 is the only cacheable form, so it sits at full debug info and fills a 1.2 GB cache. Teach COCKATRICE_DEBUG_INFO_LEVEL=0 to mean something on MSVC by leaving /Z7 out, and build the vcpkg legs (Windows and macOS) at level 0 for every non-tag ref. A tag is the build that ships and is symbolicated, so it keeps the full set. The Linux legs keep -g1: a sanitizer report without file and line is not worth the quota it would save. Report the ccache directory and the object total at the end of each leg, so the working set a bound has to fit is a number in the log rather than an estimate. * [CI] Size the Windows cache for the no-debug footprint Measured on run 42377451921, one Windows configuration without /Z7 writes a 890 MB ccache directory, against 1.2 GB with it. A 950M bound holds that with 5.4% headroom, which is the same rule the Linux bounds follow. The comment block that splits the quota follows: 4.25 GB of bounds, 3.9 GB of stored compiler cache, 8.1 GB of 10 in total.
578 lines
24 KiB
CMake
578 lines
24 KiB
CMake
# Cockatrice's main CMakeLists.txt
|
|
#
|
|
# This is basically a wrapper to enable/disable the compilation of the different projects:
|
|
# Cockatrice, Oracle, Servatrice, Test
|
|
# This file sets all the variables shared between the projects
|
|
# like the installation path, compilation flags etc..
|
|
|
|
# CMake 3.16 is required for Qt6 and target_precompile_headers()
|
|
cmake_minimum_required(VERSION 3.16)
|
|
|
|
# Use compiler cache (ccache)
|
|
option(USE_CCACHE "Cache the build results with ccache" ON)
|
|
# Treat warnings as errors (Debug builds only)
|
|
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
|
# Check for translation updates
|
|
option(UPDATE_TRANSLATIONS "Update translations on compile" OFF)
|
|
# Compile Cockatrice
|
|
option(WITH_CLIENT "Build Cockatrice client" ON)
|
|
# Compile Oracle
|
|
option(WITH_ORACLE "Build Cockatrice card database tool (Oracle)" ON)
|
|
# Compile Servatrice
|
|
option(WITH_SERVER "Build Cockatrice server (Servatrice)" OFF)
|
|
# Compile GUI tests (QtTesting widget-level playback)
|
|
option(WITH_GUI_TEST "Build the QtTesting-based GUI test harness" OFF)
|
|
# Compile tests
|
|
option(TEST "Build tests" OFF)
|
|
# Build with AddressSanitizer and UndefinedBehaviorSanitizer
|
|
option(ENABLE_SANITIZERS "Build with AddressSanitizer and UndefinedBehaviorSanitizer" OFF)
|
|
# Build instrumented for GCC line coverage, reported with gcovr
|
|
option(ENABLE_COVERAGE "Build instrumented for GCC line coverage" OFF)
|
|
# Use vcpkg regardless of OS
|
|
option(USE_VCPKG "Use vcpkg regardless of OS" OFF)
|
|
|
|
# The GUI test harness lives in a submodule; a checkout without it must still configure.
|
|
if(WITH_GUI_TEST AND NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/external/qttesting/CMakeLists.txt")
|
|
message(WARNING "WITH_GUI_TEST is ON but external/qttesting is missing, so GUI tests are disabled.\n"
|
|
"Run 'git submodule update --init external/qttesting' to enable them."
|
|
)
|
|
set(WITH_GUI_TEST OFF)
|
|
endif()
|
|
|
|
# Default to "Release" build type
|
|
# A user-provided CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE
|
|
Release
|
|
CACHE STRING "Build type"
|
|
)
|
|
endif()
|
|
|
|
# ccache drives MSVC too (since 4.7), but only when the compiler writes debug
|
|
# information into the object file: /Zi and /ZI keep it in a shared PDB, and ccache
|
|
# reports them as unsupported rather than risk a stale one. The MSVC flags below
|
|
# therefore use /Z7. MSVC precompiled headers are cached as well, with the same
|
|
# sloppiness the other toolchains need.
|
|
if(USE_CCACHE)
|
|
find_program(CCACHE_PROGRAM ccache)
|
|
if(CCACHE_PROGRAM)
|
|
# Support Unix Makefiles and Ninja
|
|
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
|
# PCH-aware caching, matching .ci/compile.sh: without this ccache refuses
|
|
# to cache any TU that consumes a precompiled header, so every PCH-backed
|
|
# target recompiles from scratch on each build.
|
|
# The include_file_mtime/include_file_ctime entries that CI also sets are
|
|
# deliberately not set here: --set-config writes the user's global
|
|
# ccache.conf, and those two would turn off the modified-during-compile
|
|
# check for every project on the machine, not just this one.
|
|
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config sloppiness=pch_defines,time_macros)
|
|
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
|
else()
|
|
# An explicit opt-in must not disappear silently.
|
|
message(STATUS "ccache requested but not found; building without a compiler cache")
|
|
endif()
|
|
endif()
|
|
|
|
if(WIN32 OR USE_VCPKG)
|
|
# Use vcpkg toolchain on Windows (and on macOS in CI)
|
|
set(CMAKE_TOOLCHAIN_FILE
|
|
${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
|
CACHE STRING "Vcpkg toolchain file"
|
|
)
|
|
# Qt path set by user or env var
|
|
if(QTDIR
|
|
OR QTDIR32
|
|
OR QTDIR64
|
|
OR DEFINED ENV{QTDIR}
|
|
OR DEFINED ENV{QTDIR32}
|
|
OR DEFINED ENV{QTDIR64}
|
|
)
|
|
|
|
else()
|
|
set(QTDIR
|
|
""
|
|
CACHE PATH "Path to Qt (e.g. C:/Qt/6.4.2/msvc2019_64)"
|
|
)
|
|
message(
|
|
WARNING
|
|
"QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/6.4.2/msvc2019_64)"
|
|
)
|
|
endif()
|
|
endif()
|
|
|
|
# A project name is needed for CPack
|
|
# Version can be overriden by git tags, see cmake/getversion.cmake
|
|
project("Cockatrice" VERSION 3.2.0)
|
|
|
|
# Set release name if not provided via ENV/CMake var
|
|
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
|
set(GIT_TAG_RELEASENAME "Reality Check")
|
|
endif()
|
|
|
|
# Use C++20 for all targets
|
|
set(CMAKE_CXX_STANDARD
|
|
20
|
|
CACHE STRING "C++ ISO Standard"
|
|
)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
|
|
|
# Set conventional loops
|
|
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
|
|
|
|
# Search path for cmake modules
|
|
set(COCKATRICE_CMAKE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
|
list(INSERT CMAKE_MODULE_PATH 0 "${COCKATRICE_CMAKE_PATH}")
|
|
|
|
include(getversion)
|
|
|
|
# Create a header and a cpp file containing the version hash
|
|
include(createversionfile)
|
|
|
|
# Define a proper install path
|
|
if(UNIX)
|
|
if(APPLE) # macOS
|
|
# Due to the special bundle structure ignore the prefix eventually set by the user
|
|
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
|
|
|
# Force ccache usage if requested and available
|
|
if(USE_CCACHE)
|
|
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
|
if(RULE_LAUNCH_COMPILE)
|
|
message(STATUS "Force enabling ccache usage under macOS")
|
|
|
|
# Set up wrapper scripts
|
|
configure_file("${COCKATRICE_CMAKE_PATH}/launch-c.in" launch-c)
|
|
configure_file("${COCKATRICE_CMAKE_PATH}/launch-cxx.in" launch-cxx)
|
|
execute_process(COMMAND chmod a+rx "${CMAKE_BINARY_DIR}/launch-c" "${CMAKE_BINARY_DIR}/launch-cxx")
|
|
|
|
# Set Xcode project attributes to route compilation through our scripts
|
|
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
|
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
|
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
|
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
|
endif()
|
|
endif()
|
|
else() # Linux / BSD
|
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
# Fix package build
|
|
if(PREFIX)
|
|
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
|
else()
|
|
set(CMAKE_INSTALL_PREFIX /usr/local)
|
|
endif()
|
|
endif()
|
|
endif()
|
|
elseif(WIN32) # Windows (including 64-bit)
|
|
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/rundir/${CMAKE_BUILD_TYPE})
|
|
endif()
|
|
|
|
# Define compiler flags
|
|
if(MSVC) # Microsoft Visual C++ compiler
|
|
# /EHsc Enable standard C++ exception handling
|
|
# /MP Enable parallel compilation
|
|
# /permissive- Enable more standards-conforming behavior
|
|
# /utf-8 Set source file encoding and execution character set to UTF-8
|
|
# /W4 Enable warning level 4
|
|
# /Zc:__cplusplus Enable correct __cplusplus reporting
|
|
# /Z7 Generate debugging information in each object file (ccache-cacheable)
|
|
# instead of a compiler-shared PDB, which ccache rejects
|
|
set(CMAKE_CXX_FLAGS "/EHsc /MP /permissive- /utf-8 /W4 /Zc:__cplusplus /Z7")
|
|
# /O2 Balanced optimization
|
|
# /MD Link against the multi-threaded DLL runtime library (Release CRT)
|
|
set(CMAKE_CXX_FLAGS_RELEASE "/O2 /MD")
|
|
# /Od Disable optimization
|
|
# /MDd Link against the multi-threaded Debug DLL runtime library (Debug CRT)
|
|
set(CMAKE_CXX_FLAGS_DEBUG "/Od /MDd")
|
|
|
|
# Generate PDBs, even in release builds, so developers can better analyze crash logs
|
|
# /DEBUG Enable debug symbols and PDB generation
|
|
# /OPT:REF Remove unreferenced functions/data
|
|
# /OPT:ICF Fold identical COMDAT functions/data
|
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
|
|
|
|
add_compile_definitions(_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING)
|
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # GCC compiler
|
|
include(CheckCXXCompilerFlag)
|
|
|
|
# -O2 Balanced optimization
|
|
# -s Remove symbols from the executable
|
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s")
|
|
|
|
# -ggdb Produce GDB debugging symbols
|
|
# -O0 Disable optimization
|
|
# -Wall Enable a broad set of useful warnings
|
|
# -Wextra Enable a set of extra warnings
|
|
# -Werror Treat warnings as compilation errors
|
|
if(WARNING_AS_ERROR)
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
|
else()
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
|
endif()
|
|
|
|
# -Wcast-align Catch unsafe pointer casts
|
|
# -Wmissing-declarations Catch defined functions without a prior declaration
|
|
# -Wno-error=extra Downgrade some -Wextra warnings from errors to warnings
|
|
# -Wno-error=delete-non-virtual-dtor Downgrade delete-non-virtual-dtor from error to warning
|
|
# -Wno-error=sign-compare Downgrade signed/unsigned comparison from error to warning
|
|
# -Wno-error=missing-declarations Downgrade -Wmissing-declarations from error to warning
|
|
# -Wno-error=sfinae-incomplete GCC 16+: Qt MOC + protobuf forward decls trigger this
|
|
set(ADDITIONAL_DEBUG_FLAGS
|
|
-Wcast-align
|
|
-Wmissing-declarations
|
|
-Wno-error=extra
|
|
-Wno-error=delete-non-virtual-dtor
|
|
-Wno-error=sign-compare
|
|
-Wno-error=missing-declarations
|
|
-Wno-error=sfinae-incomplete
|
|
)
|
|
|
|
foreach(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
|
check_cxx_compiler_flag("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
|
if(CXX_HAS_WARNING_${FLAG})
|
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
|
endif()
|
|
endforeach()
|
|
|
|
# Reduce compiler I/O by using pipes between stages instead of temp files
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe")
|
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Clang and AppleClang compilers
|
|
# -O2 Balanced optimization
|
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
|
|
|
# -g Include debug information
|
|
# -O0 Disable optimization
|
|
# -Wall Enable a broad set of useful warnings
|
|
# -Wextra Enable a set of extra warnings
|
|
# -Werror Treat warnings as compilation errors
|
|
# -Wno-unused-parameter Suppress warnings about unused function parameters (common in Qt callbacks)
|
|
if(WARNING_AS_ERROR)
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror -Wno-unused-parameter")
|
|
else()
|
|
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
|
endif()
|
|
|
|
# Reduce compiler I/O by using pipes between stages instead of temp files
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe")
|
|
else() # Unknown compiler
|
|
message(WARNING "Unknown C++ compiler: ${CMAKE_CXX_COMPILER_ID}")
|
|
endif()
|
|
|
|
# Always included, because they define cockatrice_disable_sanitizers_for() and
|
|
# cockatrice_disable_coverage_for() for the vendored trees. They only touch the global flags
|
|
# when ENABLE_SANITIZERS or ENABLE_COVERAGE is on.
|
|
include(Sanitizers)
|
|
include(Coverage)
|
|
include(CrashReporting)
|
|
|
|
# Debug information is what makes a cached object large, and a build configuration needs more
|
|
# room than a per-leg cache bound can spare when it carries full DWARF: ccache then fills to
|
|
# its limit and evicts the entries the next build is about to ask for, so it serves a few
|
|
# percent of calls while holding most of a build. CI sets a lower level so one whole
|
|
# configuration fits; level 1 keeps file and line, which is what a failing test or a sanitizer
|
|
# backtrace reports. Empty (the default) leaves local, distro and release builds exactly as
|
|
# they were. This comes after CrashReporting, so the -g it adds for Sentry symbols cannot
|
|
# raise the level again.
|
|
set(COCKATRICE_DEBUG_INFO_LEVEL
|
|
""
|
|
CACHE STRING "DWARF level for Debug and Release objects (empty keeps the built-in flags)"
|
|
)
|
|
if(NOT COCKATRICE_DEBUG_INFO_LEVEL STREQUAL "")
|
|
if(MSVC)
|
|
# MSVC has no -g level, so /Z7 is either there or it is not. Level 0 is the only value
|
|
# that means something here: without /Z7 the objects carry no debug information, which is
|
|
# what a cache that has to fit a bound holds. Anything else is the full debug info.
|
|
if(COCKATRICE_DEBUG_INFO_LEVEL STREQUAL "0")
|
|
string(REPLACE " /Z7" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
|
else()
|
|
message(WARNING "COCKATRICE_DEBUG_INFO_LEVEL is ignored on MSVC except 0")
|
|
endif()
|
|
else()
|
|
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -g${COCKATRICE_DEBUG_INFO_LEVEL}")
|
|
string(APPEND CMAKE_CXX_FLAGS_RELEASE " -g${COCKATRICE_DEBUG_INFO_LEVEL}")
|
|
endif()
|
|
endif()
|
|
|
|
# GNU systems need to define the Mersenne exponent for SFMT, so the RNG compiles without warnings
|
|
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
|
add_compile_definitions(SFMT_MEXP=19937)
|
|
endif()
|
|
|
|
find_package(Threads REQUIRED)
|
|
|
|
# Determine 32 or 64 bit build
|
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
set(_lib_suffix 64)
|
|
else()
|
|
set(_lib_suffix 32)
|
|
endif()
|
|
|
|
if(NOT "${QTDIR${_lib_suffix}}" STREQUAL "")
|
|
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
|
elseif(NOT "${QTDIR}" STREQUAL "")
|
|
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
|
elseif(NOT "$ENV{QTDIR${_lib_suffix}}" STREQUAL "")
|
|
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}")
|
|
elseif(NOT "$ENV{QTDIR}" STREQUAL "")
|
|
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
|
endif()
|
|
|
|
message(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}")
|
|
|
|
include(FindQtRuntime)
|
|
|
|
# Reject APIs that were deprecated before the oldest Qt release we support
|
|
# (6.4). Qt 6.5 renamed the switch, so use whichever spelling the found
|
|
# version understands while still compiling everywhere.
|
|
if(Qt6_VERSION VERSION_GREATER_EQUAL 6.5)
|
|
add_compile_definitions(QT_DISABLE_DEPRECATED_UP_TO=0x060400)
|
|
else()
|
|
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x060400)
|
|
endif()
|
|
|
|
# Set once here for every target: these variables are inherited by the
|
|
# subdirectories, so the per-directory copies were redundant. Only the
|
|
# variables are set; qt_standard_project_setup would also change the runtime
|
|
# output directories and the install RPATH.
|
|
set(CMAKE_AUTOMOC TRUE)
|
|
set(CMAKE_AUTOUIC TRUE)
|
|
set(CMAKE_AUTORCC TRUE)
|
|
|
|
# Find other needed libraries
|
|
find_package(Protobuf CONFIG)
|
|
if(NOT Protobuf_FOUND)
|
|
find_package(Protobuf REQUIRED)
|
|
endif()
|
|
|
|
if(${Protobuf_VERSION} VERSION_LESS "3.21.0.0" AND NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
|
message(FATAL_ERROR "No protoc command found!")
|
|
endif()
|
|
|
|
# Find OpenSSL
|
|
if(WIN32) # Windows (including 64-bit)
|
|
find_package(OpenSSL REQUIRED)
|
|
if(OPENSSL_FOUND)
|
|
include_directories(${OPENSSL_INCLUDE_DIRS})
|
|
endif()
|
|
endif()
|
|
|
|
# Find Visual C++ Redistributable
|
|
if(MSVC)
|
|
find_package(VCredistRuntime)
|
|
endif()
|
|
|
|
# Package builder
|
|
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zach@cockatrice.us>")
|
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
|
|
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
|
set(CPACK_PACKAGE_DESCRIPTION
|
|
"Cockatrice is an open-source, multiplatform application for playing tabletop card games over a network. The program's server design prevents users from manipulating the game for unfair advantage. The client also provides a single-player mode, which allows users to brew while offline."
|
|
)
|
|
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
|
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
|
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
|
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
|
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}")
|
|
|
|
if(UNIX)
|
|
if(APPLE)
|
|
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
|
set(CPACK_GENERATOR "DragNDrop")
|
|
set(CPACK_DMG_FORMAT "UDBZ")
|
|
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
|
set(CPACK_SYSTEM_NAME "OSX")
|
|
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
|
set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeDMGSetup.script")
|
|
set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/dmgBackground.tif")
|
|
set(CPACK_PRE_BUILD_SCRIPTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SignMacApplications.cmake")
|
|
else()
|
|
# linux
|
|
if(CPACK_GENERATOR STREQUAL "RPM")
|
|
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
|
set(CPACK_RPM_MAIN_COMPONENT "cockatrice")
|
|
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt6-qtimageformats, qt6-qtmultimedia, qt6-qtsvg, qt6-qttools")
|
|
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
|
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
|
# stop directories from making package conflicts
|
|
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
|
/usr/share/applications
|
|
/usr/share/icons
|
|
/usr/share/icons/hicolor
|
|
/usr/share/icons/hicolor/48x48
|
|
/usr/share/icons/hicolor/48x48/apps
|
|
/usr/share/icons/hicolor/scalable
|
|
/usr/share/icons/hicolor/scalable/apps
|
|
)
|
|
else()
|
|
set(CPACK_GENERATOR DEB)
|
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
|
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
|
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice")
|
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6multimedia6, libqt6svg6, qt6-image-formats-plugins, qt6-qpa-plugins")
|
|
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "libqt6sql6-mysql") # for connecting servatrice to a mysql db
|
|
endif()
|
|
endif()
|
|
elseif(WIN32)
|
|
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
set(TRICE_IS_64_BIT 1)
|
|
else()
|
|
set(TRICE_IS_64_BIT 0)
|
|
endif()
|
|
|
|
# Configure file with custom definitions for NSIS.
|
|
configure_file("${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in" "${PROJECT_BINARY_DIR}/NSIS.definitions.nsh")
|
|
|
|
# Installer-log sender for the AbortInstall Sentry hook (values parsed out of COCKATRICE_SENTRY_DSN in
|
|
# cmake/CrashReporting.cmake). Generated only when a DSN was parsed: cmake/NSIS.template.in embeds it under
|
|
# the same CPACK_SENTRY_ENABLED check, so a build without reporting never references or carries the helper.
|
|
if(CPACK_SENTRY_ENABLED)
|
|
configure_file(
|
|
"${COCKATRICE_CMAKE_PATH}/SendInstallerLog.ps1.in" "${PROJECT_BINARY_DIR}/SendInstallerLog.ps1" @ONLY
|
|
)
|
|
endif()
|
|
|
|
# Every runtime DLL a Windows install has to contain, as paths relative to the
|
|
# install root. .ci/compile.sh reads this and fails the build when the packaged
|
|
# installer is missing one of them, or carries a runtime it does not know about.
|
|
#
|
|
# All three applications are packaged into the same directory on Windows, so
|
|
# this is the union of their Qt module lists, not just the client's: Servatrice
|
|
# contributes Qt6Sql.dll and Oracle contributes nothing the client lacks, and a
|
|
# client-only manifest leaves Qt6Sql.dll unasserted even though servatrice.exe
|
|
# is installed next to cockatrice.exe and cannot start without it.
|
|
#
|
|
# A statically linked Qt module ships no runtime DLL, so requiring one would
|
|
# fail the package check on a static build for no reason. cockatrice/CMakeLists.txt
|
|
# installs the runtime of every module listed here, and skips static ones the
|
|
# same way, so the two can never disagree.
|
|
#
|
|
# Only the Qt modules, and that is deliberate. protobuf, Abseil, liblzma, zlib
|
|
# and OpenSSL also ride in on the "*.dll" glob, and a client whose runtime is
|
|
# absent, stale or of the wrong architecture fails to start with "abseil_dll.dll
|
|
# is either not designed to run on Windows or it contains an error", so they
|
|
# are exactly the files worth asserting.
|
|
#
|
|
# Their names cannot be derived from the vcpkg bin directory, which is what a
|
|
# first attempt did and what a Windows build immediately refuted: bin holds
|
|
# everything vcpkg installed, not everything the applications import. It also
|
|
# contains gmock.dll, libprotobuf-lite.dll, libprotoc.dll, legacy.dll and three
|
|
# pthreadVC*.dll FindThreads probes, none of which any shipped executable
|
|
# links, so requiring them failed a build over a package that was correct.
|
|
#
|
|
# Deriving them from the executables' own import tables is the real answer,
|
|
# and fixup_bundle already walks it to decide what to copy. Until that result
|
|
# is available to CMake, requiring the vcpkg half would mean guessing names
|
|
# again, which is what produced this bug report in the first place. So assert
|
|
# what is derived from the build's own link lists and leave the rest to the
|
|
# purge in cmake/NSIS.template.in, which removes every DLL regardless of name.
|
|
set(_required_runtime "")
|
|
foreach(_qt_module IN LISTS COCKATRICE_QT_MODULES SERVATRICE_QT_MODULES ORACLE_QT_MODULES)
|
|
get_target_property(_qt_module_type ${_qt_module} TYPE)
|
|
if(_qt_module_type STREQUAL "SHARED_LIBRARY")
|
|
string(REGEX REPLACE "^Qt6::" "" _qt_component "${_qt_module}")
|
|
list(APPEND _required_runtime "Qt6${_qt_component}.dll")
|
|
endif()
|
|
endforeach()
|
|
list(APPEND _required_runtime "Plugins/platforms/qwindows.dll")
|
|
|
|
list(REMOVE_DUPLICATES _required_runtime)
|
|
list(SORT _required_runtime)
|
|
string(REPLACE ";" "\n" _required_runtime "${_required_runtime}")
|
|
file(WRITE "${PROJECT_BINARY_DIR}/required-runtime.txt" "${_required_runtime}\n")
|
|
|
|
# include vcredist into the package; NSIS will take care of running it
|
|
if(VCREDISTRUNTIME_FOUND)
|
|
install(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
|
endif()
|
|
endif()
|
|
|
|
include(CPack)
|
|
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_interfaces ${CMAKE_BINARY_DIR}/libcockatrice_interfaces)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_protocol ${CMAKE_BINARY_DIR}/libcockatrice_protocol)
|
|
if(WITH_CLIENT
|
|
OR WITH_SERVER
|
|
OR WITH_ORACLE
|
|
)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_network ${CMAKE_BINARY_DIR}/libcockatrice_network)
|
|
endif()
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_deck_list ${CMAKE_BINARY_DIR}/libcockatrice_deck_list)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_rng ${CMAKE_BINARY_DIR}/libcockatrice_rng)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_card ${CMAKE_BINARY_DIR}/libcockatrice_card)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_utility ${CMAKE_BINARY_DIR}/libcockatrice_utility)
|
|
if(WITH_ORACLE OR WITH_CLIENT)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_settings ${CMAKE_BINARY_DIR}/libcockatrice_settings)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_models ${CMAKE_BINARY_DIR}/libcockatrice_models)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_filters ${CMAKE_BINARY_DIR}/libcockatrice_filters)
|
|
endif()
|
|
if(WITH_CLIENT)
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/libcockatrice_game ${CMAKE_BINARY_DIR}/libcockatrice_game)
|
|
endif()
|
|
|
|
if(WITH_SERVER)
|
|
add_subdirectory(servatrice)
|
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
|
endif()
|
|
|
|
if(WITH_CLIENT)
|
|
add_subdirectory(cockatrice)
|
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
|
endif()
|
|
|
|
if(WIN32 AND WITH_CLIENT)
|
|
# Runs from the installer's $PLUGINSDIR when a purge fails, and is never installed
|
|
# (see LogProcessesUsingInstallDir in cmake/NSIS.template.in), so it has no install
|
|
# rules and is not part of the client's staged tree.
|
|
add_subdirectory(${CMAKE_SOURCE_DIR}/tools/installer-holder-probe ${CMAKE_BINARY_DIR}/tools/installer-holder-probe)
|
|
endif()
|
|
|
|
if(WITH_ORACLE)
|
|
add_subdirectory(oracle)
|
|
set(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
|
endif()
|
|
|
|
if(WITH_GUI_TEST)
|
|
set(QtTesting_QT_VERSION "6")
|
|
# QtTesting registers its own unit tests when BUILD_TESTING is on. They target the
|
|
# Qt version the harness was written for and fail on Qt 6.11 (toolbutton
|
|
# long-press recording), and they are not Cockatrice's tests, so suppress them
|
|
# for the duration of the subdirectory instead of painting ctest red.
|
|
if(DEFINED BUILD_TESTING)
|
|
set(_cockatrice_saved_build_testing ${BUILD_TESTING})
|
|
endif()
|
|
set(BUILD_TESTING
|
|
OFF
|
|
CACHE BOOL "Build the testing tree." FORCE
|
|
)
|
|
add_subdirectory(external/qttesting)
|
|
if(DEFINED _cockatrice_saved_build_testing)
|
|
set(BUILD_TESTING
|
|
${_cockatrice_saved_build_testing}
|
|
CACHE BOOL "Build the testing tree." FORCE
|
|
)
|
|
else()
|
|
unset(BUILD_TESTING CACHE)
|
|
endif()
|
|
# cl.exe has no warnings-as-errors here, and it rejects -Wno-error with D8021.
|
|
if(NOT MSVC)
|
|
target_compile_options(qttesting PRIVATE -Wno-error)
|
|
endif()
|
|
endif()
|
|
|
|
if(TEST)
|
|
include(CTest)
|
|
add_subdirectory(tests)
|
|
endif()
|
|
|
|
if(Qt6_FOUND AND Qt6_VERSION_MINOR GREATER_EQUAL 3)
|
|
# Qt6.3+ requires project finalization to support translations
|
|
qt_finalize_project()
|
|
endif()
|
|
|
|
# Print compiler identification at configuration time
|
|
message(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER_ID}")
|
|
message(STATUS "C++ compiler version: ${CMAKE_CXX_COMPILER_VERSION}")
|
|
message(STATUS "C++ compiler path: ${CMAKE_CXX_COMPILER}")
|
|
message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}")
|
|
message(STATUS "C++ extensions: ${CMAKE_CXX_EXTENSIONS}")
|