diff --git a/CMakeLists.txt b/CMakeLists.txt index e339747def..8f1b7667b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,8 +75,7 @@ if (Daemon_OUT) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Daemon_OUT}) endif() -include(DaemonSourceGenerator) -include(DaemonPlatform) +include(DaemonPlatform/Platform) ################################################################################ # Configuration options @@ -91,11 +90,11 @@ if(NOT DAEMON_EXTERNAL_APP) set(NACL_RUNTIME_PATH "" CACHE STRING "Directory containing the NaCl binaries") - if (WIN32) + if (DAEMON_SYSTEM_Windows) # The alternative code is based on non-curses unix terminal functions. set(USE_CURSES ON) else() - if (NOT APPLE) + if (NOT DAEMON_SYSTEM_macOS) # Not supported on macOS because the included version is too old. option(USE_CURSES_NCURSES "Use ncurses instead of PDCursesMod" ON) endif() @@ -200,29 +199,29 @@ endmacro() set(DEFAULT_USE_EXTERNAL_DEPS_LIBS ON) -if (USE_EXTERNAL_DEPS AND NOT NACL) +if (USE_EXTERNAL_DEPS AND NOT DAEMON_SYSTEM_NaCl) set(EXTERNAL_DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external_deps" CACHE STRING "Directory in which to store the downloaded dependencies.") set(DEPS_EXT ".tar.xz") - set(DEPS_ARCH "${ARCH}") + set(DEPS_ARCH "${DAEMON_ARCH_NAME}") - if (MSVC) + if (DAEMON_CXX_COMPILER_MSVC) set(DEPS_COMPILER msvc) - elseif (WIN32) + elseif (DAEMON_CXX_COMPILER_MinGW) set(DEPS_COMPILER mingw) else() set(DEPS_COMPILER default) endif() - if (WIN32) + if (DAEMON_SYSTEM_Windows) set(DEPS_SYSTEM windows) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 i686) - elseif (APPLE) + elseif (DAEMON_SYSTEM_macOS) set(DEPS_SYSTEM macos) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64) - if (ARCH STREQUAL arm64) + if (DAEMON_ARCH_arm64) set(DEPS_ARCH amd64) set_deps_dir() @@ -231,10 +230,10 @@ if (USE_EXTERNAL_DEPS AND NOT NACL) set(DEFAULT_USE_EXTERNAL_DEPS_LIBS OFF) endif() endif() - elseif (LINUX) + elseif (DAEMON_SYSTEM_Linux) set(DEPS_SYSTEM linux) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 i686 arm64 armhf) - elseif (FREEBSD) + elseif (DAEMON_SYSTEM_FreeBSD) set(DEPS_SYSTEM freebsd) set(SUPPORTED_${DEPS_SYSTEM}_ARCH amd64 i686) @@ -265,7 +264,7 @@ endif() option(USE_EXTERNAL_DEPS_LIBS "Build and link against libraries from the EXTERNAL_DEPS_DIR" ${DEFAULT_USE_EXTERNAL_DEPS_LIBS}) -if (USE_EXTERNAL_DEPS AND NOT NACL) +if (USE_EXTERNAL_DEPS AND NOT DAEMON_SYSTEM_NaCl) if (DEPS_DIR) message(STATUS "Using external deps dir: ${DEPS_DIR}") @@ -463,14 +462,13 @@ endif() # Native client include(DaemonNacl) -if (NACL) +if (DAEMON_SYSTEM_NaCl) add_library(srclibs-nacl-module EXCLUDE_FROM_ALL ${NACLLIST_MODULE}) - set_target_properties(srclibs-nacl-module PROPERTIES POSITION_INDEPENDENT_CODE ${GAME_PIE} FOLDER "libs") set(LIBS_BASE ${LIBS_BASE} srclibs-nacl-module) else() add_library(srclibs-nacl-native EXCLUDE_FROM_ALL ${NACLLIST_NATIVE}) set_target_properties(srclibs-nacl-native PROPERTIES POSITION_INDEPENDENT_CODE 1 FOLDER "libs") - if (APPLE) + if (DAEMON_SYSTEM_macOS) # Do not error for OSAtomic* deprecation notices target_compile_options(srclibs-nacl-native PRIVATE "-Wno-error=deprecated-declarations") endif() @@ -478,9 +476,9 @@ else() endif() # Base OS libs -if (WIN32) +if (DAEMON_SYSTEM_Windows) set(LIBS_BASE ${LIBS_BASE} winmm ws2_32) -elseif (NACL) +elseif (DAEMON_SYSTEM_NaCl) find_library(NACL_EXCEPTION nacl_exception) find_library(NACL_MINIDUMP minidump_generator) @@ -512,7 +510,7 @@ else() set(LIBS_BASE ${LIBS_BASE} ${CMAKE_DL_LIBS}) find_package(Threads REQUIRED) set(LIBS_BASE ${LIBS_BASE} ${CMAKE_THREAD_LIBS_INIT}) - if (APPLE) + if (DAEMON_SYSTEM_macOS) set(LIBS_CLIENT ${LIBS_CLIENT} "-framework Carbon" "-framework IOKit" "-framework Cocoa") endif() endif() @@ -535,7 +533,7 @@ else() # Look for OpenGL here before we potentially switch to looking for static libs. if (BUILD_CLIENT) - if (LINUX OR FREEBSD) + if (DAEMON_SYSTEM_Unix_COMPATIBILITY) # Set LEGACY OpenGL ABI if the variable is not explictly set. # The backward-incompatible GLVND OpenGL ABI should only be used # by developers who have a good reason to require it. @@ -551,7 +549,7 @@ else() # This code is unreachable since it already errored out at find_package time. # This code only executes if OpenGL is supported, either because the GLVND ABI # is available, either because the LEGACY ABI is available. - if (LINUX OR FREEBSD) + if (DAEMON_SYSTEM_Unix_COMPATIBILITY) if (NOT OPENGL_gl_LIBRARY) # When OpenGL_GL_PREFERENCE is supported and GLVND is available # OPENGL_gl_LIBRARY is expected to be empty. So we can use the @@ -598,7 +596,7 @@ endif() # Prefer static libs if ( USE_STATIC_LIBS ) - if (LINUX OR FREEBSD) + if (DAEMON_SYSTEM_Unix_COMPATIBILITY) set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) endif() endif() @@ -626,7 +624,7 @@ if (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER OR BUILD_DUMMY_APP) set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} ${CURSESW_LIBRARIES}) include_directories(${CURSESW_INCLUDE_DIR}) else () - if (WIN32) + if (DAEMON_SYSTEM_Windows) set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} gdi32 comdlg32) endif() @@ -676,22 +674,22 @@ if (BUILD_CLIENT OR BUILD_TTY_CLIENT) endif() # SDL, required for all targets on win32 because of iconv and SDL_SetHint(SDL_TIMER_RESOLUTION, 0) -if (BUILD_CLIENT OR WIN32) +if (BUILD_CLIENT OR DAEMON_SYSTEM_Windows) # Use our detected architecture instead of letting SDL do it again # Note that sdlcpu.cmake is only included on a random subset of platforms set(sdlvar_i686 SDL_CPU_X86) set(sdlvar_amd64 SDL_CPU_X64) set(sdlvar_armhf SDL_CPU_ARM32) set(sdlvar_arm64 SDL_CPU_ARM64) - if (sdlvar_${ARCH}) - set(${sdlvar_${ARCH}} 1) + if (sdlvar_${DAEMON_ARCH_NAME}) + set(${sdlvar_${DAEMON_ARCH_NAME}} 1) else() - message("Developer TODO: translate architecture ${ARCH} for SDL") + message("Developer TODO: translate architecture ${DAEMON_ARCH_NAME} for SDL") endif() find_package(SDL3 REQUIRED CONFIG) - if (WIN32) + if (DAEMON_SYSTEM_Windows) set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} SDL3::SDL3) else() set(LIBS_CLIENT ${LIBS_CLIENT} SDL3::SDL3) @@ -703,7 +701,7 @@ if (USE_BREAKPAD) add_definitions(-DUSE_BREAKPAD) include_directories(${LIB_DIR}/breakpad/src) - if (WIN32) + if (DAEMON_SYSTEM_Windows) add_library(srclibs-breakpad-common EXCLUDE_FROM_ALL ${BREAKPAD_COMMON_LIST}) add_library(srclibs-breakpad-crash_generation_server EXCLUDE_FROM_ALL ${BREAKPAD_CRASHGENERATIONSERVER_LIST}) add_library(srclibs-breakpad-exception_handler EXCLUDE_FROM_ALL ${BREAKPAD_EXCEPTIONHANDLER_LIST}) @@ -733,7 +731,7 @@ if (USE_BREAKPAD) set(LIBS_ENGINE_BASE ${LIBS_ENGINE_BASE} srclibs-breakpad-exception_handler srclibs-breakpad-crash_generation_client srclibs-breakpad-common) - elseif (LINUX) + elseif (DAEMON_SYSTEM_Linux_COMPATIBILITY) add_library(srclibs-breakpad EXCLUDE_FROM_ALL ${BREAKPAD_LIST}) set_target_properties(srclibs-breakpad PROPERTIES POSITION_INDEPENDENT_CODE 1 FOLDER "libs") target_compile_definitions(srclibs-breakpad PUBLIC HAVE_GETCONTEXT=1) @@ -748,7 +746,7 @@ option(PREFER_EXTERNAL_LIBS "Tries to use system libs where possible." ON) macro(prefer_package LIB_NAME LIB_CMAKE) if (NOT ${LIB_NAME}_FOUND) - if (PREFER_EXTERNAL_LIBS AND NOT NACL) + if (PREFER_EXTERNAL_LIBS AND NOT DAEMON_SYSTEM_NaCl) find_package(${LIB_NAME}) if (NOT ${LIB_NAME}_FOUND) @@ -836,9 +834,9 @@ macro(AddApplicationInternal Target Executable) # Append Windows specific manifests. # Adding the .manifest as a source works better for MSVC, but it has no # effect for MinGW (https://gitlab.kitware.com/cmake/cmake/-/issues/23244). - if (MINGW) + if (DAEMON_CXX_COMPILER_MinGW) target_sources(${Target} PRIVATE ${ENGINE_DIR}/sys/windows-resource/manifest.rc) - elseif (WIN32) + elseif (DAEMON_CXX_COMPILER_MSVC) target_sources(${Target} PRIVATE ${ENGINE_DIR}/sys/windows-resource/supported-os.manifest) endif() @@ -878,7 +876,7 @@ endfunction() daemon_write_buildinfo("Engine") -if (NOT NACL) +if (NOT DAEMON_SYSTEM_NaCl) add_library(engine-lib EXCLUDE_FROM_ALL ${PCH_FILE} ${BUILDINFOLIST} ${COMMONLIST} ${ENGINELIST}) target_link_libraries(engine-lib ${LIBS_BASE} ${LIBS_ENGINE_BASE} ${CPP23SupportLibrary}) set_property(TARGET engine-lib APPEND PROPERTY COMPILE_DEFINITIONS BUILD_ENGINE) @@ -976,13 +974,13 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DEPS_DIR}/irt_core-${NACL_ARCH}.nexe - ${FULL_OUTPUT_DIR}/irt_core-${NACL_ARCH}.nexe + ${DEPS_DIR}/irt_core-${DAEMON_NACL_ARCH_NAME}.nexe + ${FULL_OUTPUT_DIR}/irt_core-${DAEMON_NACL_ARCH_NAME}.nexe ) # Linux uses a bootstrap program to reserve address space - if (LINUX OR FREEBSD) - if (ARCH STREQUAL "arm64") + if (DAEMON_SYSTEM_Unix_COMPATIBILITY) + if (DAEMON_ARCH_arm64) add_executable(nacl_helper_bootstrap-armhf tools/nacl_helper_bootstrap-armhf/nacl_helper_bootstrap-armhf.cpp) add_dependencies(runtime_deps nacl_helper_bootstrap-armhf) @@ -1006,7 +1004,7 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER endif() # Win32 requires nacl_loader_amd64.exe in order to run on Win64 - if (WIN32 AND ARCH STREQUAL i686) + if (DAEMON_SYSTEM_Windows AND DAEMON_ARCH_i686) add_custom_command(TARGET runtime_deps PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DEPS_DIR}/nacl_loader-amd64${CMAKE_EXECUTABLE_SUFFIX} @@ -1020,7 +1018,7 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER endif() # Mac requires some libraries from external_deps - if (APPLE) + if (DAEMON_SYSTEM_macOS) file(GLOB RUNTIME_FRAMEWORKS ${DEPS_DIR}/lib/*.framework) foreach(RUNTIME_FRAMEWORK ${RUNTIME_FRAMEWORKS}) get_filename_component(RUNTIME_FRAMEWORK_NAME ${RUNTIME_FRAMEWORK} NAME) @@ -1042,7 +1040,7 @@ if (DEPS_DIR AND HAS_NACL AND (BUILD_CLIENT OR BUILD_TTY_CLIENT OR BUILD_SERVER endif() # Windows requires some libraries from external_deps - if (WIN32) + if (DAEMON_SYSTEM_Windows) file(GLOB RUNTIME_LIBS ${DEPS_DIR}/bin/*.dll ${DEPS_DIR}/SDL3/lib/*/SDL3.dll) foreach(RUNTIME_LIB ${RUNTIME_LIBS}) add_custom_command(TARGET runtime_deps PRE_BUILD diff --git a/cmake/DaemonArchitecture.cmake b/cmake/DaemonArchitecture.cmake deleted file mode 100644 index cbf0033b0b..0000000000 --- a/cmake/DaemonArchitecture.cmake +++ /dev/null @@ -1,117 +0,0 @@ -# Daemon BSD Source Code -# Copyright (c) 2022, Daemon Developers -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -################################################################################ -# Determine architecture -################################################################################ - -# When adding a new architecture, look at all the places ARCH is used - -try_compile(BUILD_RESULT - "${CMAKE_BINARY_DIR}" - "${DAEMON_DIR}/cmake/DaemonArchitecture/DaemonArchitecture.cpp" - CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} - OUTPUT_VARIABLE BUILD_LOG -) - -# Setting -Werror in CXXFLAGS would produce errors instead of warning -# but that should not break the architecture detection, -# so we only print a CMake warning there and use BUILD_LOG content to -# detect unsupported platforms. -# Catching compilation error is still useful, for example to detect -# undefined types, missing header or things like that. -# Setting USE_WERROR to ON doesn't print this warning. -if (NOT BUILD_RESULT) - message(WARNING - "Failed to build DaemonArchitecture.cpp\n" - "Setting -Werror in CXXFLAGS can produce false positive errors\n" - "${BUILD_LOG}" - ) -endif() - -string(REGEX MATCH "DAEMON_ARCH_([a-zA-Z0-9_]+)" ARCH_DEFINE "${BUILD_LOG}") -string(REPLACE "DAEMON_ARCH_" "" ARCH "${ARCH_DEFINE}") - -if (NOT ARCH) - message(FATAL_ERROR - "Missing DAEMON_ARCH, there is a mistake in DaemonArchitecture.cpp\n" - "${BUILD_LOG}" - ) -elseif(ARCH STREQUAL "unsupported") - message(FATAL_ERROR "Architecture not supported") -endif() - -message(STATUS "Detected architecture: ${ARCH}") - -add_definitions(-D${ARCH_DEFINE}) - -# This string can be modified without breaking compatibility. -daemon_add_buildinfo("char*" "DAEMON_ARCH_STRING" "\"${ARCH}\"") - -# Modifying NACL_ARCH breaks engine compatibility with nexe game binaries -# since NACL_ARCH contributes to the nexe file name. -set(NACL_ARCH "${ARCH}") -if (LINUX OR FREEBSD) - set(ARMHF_USAGE arm64 armel) - if (ARCH IN_LIST ARMHF_USAGE) - # Load 32-bit armhf nexe on 64-bit arm64 engine on Linux with multiarch. - # The nexe is system agnostic so there should be no difference with armel. - set(NACL_ARCH "armhf") - endif() -elseif(APPLE) - if ("${ARCH}" STREQUAL arm64) - # You can get emulated NaCl going like this: - # cp external_deps/macos-amd64-default_10/{nacl_loader,irt_core-amd64.nexe} build/ - set(NACL_ARCH "amd64") - endif() -endif() - -daemon_add_buildinfo("char*" "DAEMON_NACL_ARCH_STRING" "\"${NACL_ARCH}\"") - -option(USE_ARCH_INTRINSICS "Enable custom code using intrinsics functions or asm declarations" ON) -mark_as_advanced(USE_ARCH_INTRINSICS) - -macro(set_arch_intrinsics name) - if (USE_ARCH_INTRINSICS) - message(STATUS "Enabling ${name} architecture intrinsics") - add_definitions(-DDAEMON_USE_ARCH_INTRINSICS_${name}=1) - else() - message(STATUS "Disabling ${name} architecture intrinsics") - endif() -endmacro() - -if (USE_ARCH_INTRINSICS) - add_definitions(-DDAEMON_USE_ARCH_INTRINSICS=1) -endif() - -set_arch_intrinsics(${ARCH}) - -set(amd64_PARENT "i686") -set(arm64_PARENT "armhf") - -if (${ARCH}_PARENT) - set_arch_intrinsics(${${ARCH}_PARENT}) -endif() diff --git a/cmake/DaemonCompiler/DaemonCompiler.cpp b/cmake/DaemonCompiler/DaemonCompiler.cpp deleted file mode 100644 index 4b3d5f846a..0000000000 --- a/cmake/DaemonCompiler/DaemonCompiler.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "DaemonCompiler.c" diff --git a/cmake/DaemonFlags.cmake b/cmake/DaemonFlags.cmake index 868be61185..eec22d60e7 100644 --- a/cmake/DaemonFlags.cmake +++ b/cmake/DaemonFlags.cmake @@ -55,7 +55,7 @@ mark_as_advanced(USE_RECOMMENDED_CXX_STANDARD) option(USE_CPP23 "Use C++23 standard where possible" OFF) -if (MSVC) +if (DAEMON_CXX_COMPILER_MSVC) set(DEFAULT_STRIP_SOURCE_PATHS ON) else() set(DEFAULT_STRIP_SOURCE_PATHS OFF) @@ -153,7 +153,7 @@ function(try_flag LIST FLAG) # Other compilers might interpret it as a filename so reject without testing. string(SUBSTRING "${FLAG}" 0 1 FLAG_FIRST_CHAR) if ("${FLAG_FIRST_CHAR}" STREQUAL "/") - if (MSVC) + if (DAEMON_CXX_COMPILER_MSVC) set(${TEST} 1) else() set(${TEST} 0) @@ -233,7 +233,7 @@ if (STRIP_SOURCE_PATHS) set(FILENAME_STRIP_DIRS ${FILENAME_STRIP_DIRS} "${DAEMON_DIR}/src" "${DAEMON_DIR}") endif() foreach(strip_dir ${FILENAME_STRIP_DIRS}) - if (MSVC) + if (DAEMON_CXX_COMPILER_MSVC) string(REPLACE "/" "\\" backslashed_dir ${strip_dir}) # set_c_cxx_flag can't be used because macros barf if the input contains backslashes # https://gitlab.kitware.com/cmake/cmake/-/issues/19281 @@ -259,7 +259,7 @@ if (USE_FLOAT_EXCEPTIONS) add_definitions(-DDAEMON_USE_FLOAT_EXCEPTIONS) endif() -if (MSVC) +if (DAEMON_CXX_COMPILER_MSVC) set_c_cxx_flag("/MP") # There is no flag for standards before C++17 @@ -362,7 +362,7 @@ else() endif() endif() - if (NACL AND USE_NACL_SAIGO AND SAIGO_ARCH STREQUAL "arm") + if (DAEMON_SYSTEM_NaCl AND USE_NACL_SAIGO AND SAIGO_DAEMON_ARCH_arm) # This should be set for every build type because build type flags # are set after the other custom flags and then have the last word. # DEBUG should already use -O0 anyway. @@ -413,7 +413,7 @@ else() try_flag(WARNINGS "-Werror") endif() - if (NACL AND NOT USE_NACL_SAIGO) + if (DAEMON_SYSTEM_NaCl AND NOT USE_NACL_SAIGO) # PNaCl only supports libc++ as standard library. set_c_cxx_flag("-stdlib=libc++") set_c_cxx_flag("--pnacl-allow-exceptions") @@ -425,12 +425,12 @@ else() try_cxx_flag(FNO_GNU_UNIQUE "-fno-gnu-unique") # Use MSVC-compatible bitfield layout - if (WIN32) + if (DAEMON_SYSTEM_Windows) set_c_cxx_flag("-mms-bitfields") endif() # Linker flags - if (NOT APPLE) + if (NOT DAEMON_SYSTEM_macOS) try_linker_flag(LINKER_O1 "-Wl,-O1") try_linker_flag(LINKER_SORT_COMMON "-Wl,--sort-common") try_linker_flag(LINKER_AS_NEEDED "-Wl,--as-needed") @@ -443,7 +443,7 @@ else() try_linker_flag(LINKER_Z_NOW "-Wl,-z,now") endif() - if (WIN32) + if (DAEMON_SYSTEM_Windows) try_linker_flag(LINKER_DYNAMICBASE "-Wl,--dynamicbase") try_linker_flag(LINKER_NXCOMPAT "-Wl,--nxcompat") try_linker_flag(LINKER_LARGE_ADDRESS_AWARE "-Wl,--large-address-aware") @@ -456,7 +456,7 @@ else() # The -pthread flag sets some preprocessor defines, # it is also used to link with libpthread on Linux. - if (NOT APPLE) + if (NOT DAEMON_SYSTEM_macOS) try_c_cxx_flag(PTHREAD "-pthread") endif() @@ -480,7 +480,7 @@ else() if (USE_HARDENING) # PNaCl accepts the flags but does not define __stack_chk_guard and __stack_chk_fail. - if (NOT NACL) + if (NOT DAEMON_SYSTEM_NaCl) try_c_cxx_flag(FSTACK_PROTECTOR_STRONG "-fstack-protector-strong") if (NOT FLAG_FSTACK_PROTECTOR_STRONG) @@ -491,24 +491,24 @@ else() try_c_cxx_flag(FNO_STRICT_OVERFLOW "-fno-strict-overflow") try_c_cxx_flag(WSTACK_PROTECTOR "-Wstack-protector") - if (NOT NACL OR (NACL AND GAME_PIE)) + if (NOT DAEMON_SYSTEM_NaCl) # The -pie flag requires -fPIC: # > ld: error: relocation R_X86_64_64 cannot be used against local symbol; recompile with -fPIC # This flag isn't used on macOS: # > clang: warning: argument unused during compilation: '-pie' [-Wunused-command-line-argument] - if (FLAG_FPIC AND NOT APPLE) + if (FLAG_FPIC AND NOT DAEMON_SYSTEM_macOS) try_exe_linker_flag(LINKER_PIE "-pie") endif() endif() if ("${FLAG_LINKER_PIE}" AND MINGW) # https://github.com/msys2/MINGW-packages/issues/4100 - if (ARCH STREQUAL "i686") + if (DAEMON_ARCH_i686) set_linker_flag("-Wl,-e,_mainCRTStartup") - elseif(ARCH STREQUAL "amd64") + elseif(DAEMON_ARCH_amd64) set_linker_flag("-Wl,-e,mainCRTStartup") else() - message(FATAL_ERROR "Unsupported architecture ${ARCH}") + message(FATAL_ERROR "Unsupported architecture ${DAEMON_ARCH_NAME}") endif() endif() endif() @@ -519,7 +519,7 @@ else() # PNaCl accepts the flag but does nothing with it, underlying clang doesn't support it. # Saigo NaCl compiler doesn't support LTO, the flag is accepted but linking fails # with “unable to pass LLVM bit-code files to linker” error. - if (USE_LTO AND NOT NACL) + if (USE_LTO AND NOT DAEMON_SYSTEM_NaCl) try_c_cxx_flag(LTO_AUTO "-flto=auto") if (NOT FLAG_LTO_AUTO) @@ -577,15 +577,15 @@ endif() option(USE_CPU_RECOMMENDED_FEATURES "Use some common hardware features like SSE2, NEON, VFP, MCX16, etc." ON) # Target options. -if (MSVC) - if (ARCH STREQUAL "i686") +if (DAEMON_CXX_COMPILER_MSVC) + if (DAEMON_ARCH_i686) if (USE_CPU_RECOMMENDED_FEATURES) set_c_cxx_flag("/arch:SSE2") # This is the default else() set_c_cxx_flag("/arch:IA32") # minimum endif() endif() -elseif (NOT NACL) +elseif (NOT DAEMON_SYSTEM_NaCl) # Among the required hardware features, the NX bit (No eXecute bit) # feature may be required for NativeClient to work. Some early # Intel EM64T processors are known to not implement the NX bit. @@ -598,7 +598,7 @@ elseif (NOT NACL) # Running a server with a native executable game is also a valid usage # not requiring the NX bit. - if (ARCH STREQUAL "amd64") + if (DAEMON_ARCH_amd64) # K8 or EM64T minimum: AMD Athlon 64 ClawHammer, Intel Xeon Nocona, Intel Pentium 4 model F (Prescott revision EO), VIA Nano. if (DAEMON_CXX_COMPILER_ICC) set(GCC_GENERIC_ARCH "pentium4") @@ -608,15 +608,15 @@ elseif (NOT NACL) set(GCC_GENERIC_ARCH "x86-64") endif() set(GCC_GENERIC_TUNE "generic") - elseif (ARCH STREQUAL "i686") + elseif (DAEMON_ARCH_i686) # P6 or K6 minimum: Intel Pentium Pro, AMD K6, Via Cyrix III, Via C3. set(GCC_GENERIC_ARCH "i686") set(GCC_GENERIC_TUNE "generic") - elseif (ARCH STREQUAL "arm64") + elseif (DAEMON_ARCH_arm64) # Armv8-A minimum: Cortex-A50. set(GCC_GENERIC_ARCH "armv8-a") set(GCC_GENERIC_TUNE "generic") - elseif (ARCH STREQUAL "armhf") + elseif (DAEMON_ARCH_armhf) # Armv7-A minimum with VFPv3 and optional NEONv1: Cortex-A5. # Hard float ABI (mainstream 32-bit ARM Linux distributions). # An FPU should be explicitly set on recent compilers or this @@ -625,7 +625,7 @@ elseif (NOT NACL) # lacks an FPU set(GCC_GENERIC_ARCH "armv7-a+fp") set(GCC_GENERIC_TUNE "generic-armv7-a") - elseif (ARCH STREQUAL "armel") + elseif (DAEMON_ARCH_armel) # Armv6 minimum with optional VFP: ARM11. # Soft float ABI (previous mainstream 32-bit ARM Linux # distributions, mainstream 32-bit ARM Android distributions). @@ -633,7 +633,7 @@ elseif (NOT NACL) # There is no generic tuning option for armv6. unset(GCC_GENERIC_TUNE) else() - message(WARNING "Unknown architecture ${ARCH}") + message(WARNING "Unknown architecture ${DAEMON_ARCH_NAME}") endif() if ("${DAEMON_CXX_COMPILER_NAME}" STREQUAL "Zig") @@ -652,18 +652,18 @@ elseif (NOT NACL) endif() if (USE_CPU_RECOMMENDED_FEATURES) - if (ARCH STREQUAL "amd64") + if (DAEMON_ARCH_amd64) # CMPXCHG16B minimum (x86-64-v2): AMD64 revision F. try_c_cxx_flag_werror(MCX16 "-mcx16") - elseif (ARCH STREQUAL "i686") + elseif (DAEMON_ARCH_i686) # SSE2 minimum: Intel Pentium 4 (Prescott), # Intel Pentium M (Banias), AMD K8, Via C7. try_c_cxx_flag_werror(MSSE2 "-msse2") try_c_cxx_flag_werror(MFPMATH_SSE "-mfpmath=sse") - elseif (ARCH STREQUAL "armhf") + elseif (DAEMON_ARCH_armhf) # NEONv1 minimum. try_c_cxx_flag_werror(MFPU_NEON "-mfpu=neon") - elseif (ARCH STREQUAL "armel") + elseif (DAEMON_ARCH_armel) # VFP minimum, hard float with soft float ABI. try_c_cxx_flag_werror(MFPU_VFP "-mfpu=vfp") try_c_cxx_flag_werror(MFLOAT_ABI_SOFTFP "-mfloat-abi=softfp") @@ -672,7 +672,7 @@ elseif (NOT NACL) endif() # Windows-specific definitions -if (WIN32) +if (DAEMON_SYSTEM_Windows) add_definitions( -DWINVER=0x501 # Minimum Windows version: XP -DWIN32 # Define WIN32 for compatibility (compiler defines _WIN32) @@ -682,12 +682,12 @@ if (WIN32) set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "" "lib") endif() -if (MSVC) +if (DAEMON_CXX_COMPILER_MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) endif() # Mac-specific definitions -if (APPLE) +if (DAEMON_SYSTEM_macOS) add_definitions(-DMACOS_X) set(CMAKE_INSTALL_RPATH "@executable_path") set(CMAKE_BUILD_WITH_INSTALL_RPATH ON) diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 9cf9ee95cc..93581f0437 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -39,8 +39,7 @@ option(BUILD_GAME_NATIVE_DLL "Build the shared library files, mostly useful for option(BUILD_GAME_NATIVE_EXE "Build native executable, which might be used for better performances by server owners" OFF) include(ExternalProject) -include(DaemonSourceGenerator) -include(DaemonPlatform) +include(DaemonPlatform/Platform) # Do not report unused native compiler if native vms are not built. # If only NACL vms are built, this will be reported in chainloaded build. @@ -71,7 +70,7 @@ include(CMakeParseArguments) # The NaCl SDK only runs on amd64 or i686. if (NOT FORK EQUAL 2) if (CMAKE_SYSTEM_NAME STREQUAL CMAKE_HOST_SYSTEM_NAME - AND (ARCH STREQUAL "amd64" OR ARCH STREQUAL "i686")) + AND (DAEMON_ARCH_amd64 OR DAEMON_ARCH_i686)) # can be loaded by daemon with vm.[sc]game.type 0 or 1 option(BUILD_GAME_NACL "Build the NaCl \"pexe\" and \"nexe\" gamelogic modules for enabled architecture targets, required to host mods." OFF) @@ -82,7 +81,7 @@ if (NOT FORK EQUAL 2) if (BUILD_GAME_NACL_TARGETS STREQUAL "all") set(NACL_TARGETS "${NACL_ALL_TARGETS}") elseif (BUILD_GAME_NACL_TARGETS STREQUAL "native") - set(NACL_TARGETS "${ARCH}") + set(NACL_TARGETS "${DAEMON_ARCH_NAME}") elseif (BUILD_GAME_NACL_TARGETS STREQUAL "none") set(NACL_TARGETS "") else() diff --git a/cmake/DaemonNacl.cmake b/cmake/DaemonNacl.cmake index f3310514ee..e1dc818593 100644 --- a/cmake/DaemonNacl.cmake +++ b/cmake/DaemonNacl.cmake @@ -28,10 +28,10 @@ option(USE_NACL_SAIGO "Use Saigo toolchain to build NaCl executables" OFF) -if( NACL ) +if (DAEMON_SYSTEM_NaCl) # Build nexe binary. if(USE_NACL_SAIGO) - # NACL_ARCH is "pnacl" here, NACL_TARGET carries the architecture. + # DAEMON_NACL_ARCH is "pnacl" here, NACL_TARGET carries the architecture. if (NACL_TARGET STREQUAL "amd64") add_definitions(-DNACL_BUILD_ARCH=x86) add_definitions(-DNACL_BUILD_SUBARCH=64) @@ -47,32 +47,32 @@ if( NACL ) # Those defines looks to be meaningless to produce arch-independent pexe # with PNaCl but they must be set to anything supported by native builds. # This requirement looks to be a PNaCl bug. - # NACL_ARCH is "pnacl" here, NACL_TARGET is not set. + # DAEMON_NACL_ARCH is "pnacl" here, NACL_TARGET is not set. add_definitions( -DNACL_BUILD_ARCH=x86 ) add_definitions( -DNACL_BUILD_SUBARCH=64 ) endif() else() # Build native dll or native exe. - if( APPLE ) + if (DAEMON_SYSTEM_macOS) add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=1 ) - elseif( LINUX ) + elseif (DAEMON_SYSTEM_Linux) add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=1 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0 ) - elseif( FREEBSD ) + elseif (DAEMON_SYSTEM_FreeBSD) add_definitions( -DNACL_WINDOWS=0 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=1 -DNACL_OSX=0 ) - elseif( WIN32 ) + elseif (DAEMON_SYSTEM_Windows) add_definitions( -DNACL_WINDOWS=1 -DNACL_LINUX=0 -DNACL_ANDROID=0 -DNACL_FREEBSD=0 -DNACL_OSX=0 ) endif() - if( NACL_ARCH STREQUAL "amd64" ) + if (DAEMON_NACL_ARCH_amd64) add_definitions( -DNACL_BUILD_ARCH=x86 ) add_definitions( -DNACL_BUILD_SUBARCH=64 ) - elseif( NACL_ARCH STREQUAL "i686" ) + elseif (DAEMON_NACL_ARCH_i686) add_definitions( -DNACL_BUILD_ARCH=x86 ) add_definitions( -DNACL_BUILD_SUBARCH=32 ) - elseif( NACL_ARCH STREQUAL "armhf" ) + elseif (DAEMON_NACL_ARCH_armhf) add_definitions( -DNACL_BUILD_ARCH=arm ) else() - message(WARNING "Unknown architecture ${NACL_ARCH}") + message(WARNING "Unknown NaCl architecture ${DAEMON_NACL_ARCH_NAME}") endif() endif() diff --git a/cmake/DaemonPlatform/Architecture.cmake b/cmake/DaemonPlatform/Architecture.cmake new file mode 100644 index 0000000000..97d4691c65 --- /dev/null +++ b/cmake/DaemonPlatform/Architecture.cmake @@ -0,0 +1,105 @@ +# Daemon BSD Source Code +# Copyright (c) 2022-2025, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# Architecture detection. +################################################################################ + +# When adding a new architecture, look at all the places DAEMON_ARCH is used. + +option(USE_ARCH_INTRINSICS "Enable custom code using intrinsics functions or asm declarations" ON) +mark_as_advanced(USE_ARCH_INTRINSICS) + +function(daemon_detect_arch) + daemon_run_detection("" "ARCH" "Architecture.c" "") + + set(DAEMON_ARCH_NAME "${arch_name}" PARENT_SCOPE) + + message(STATUS "Detected target architecture: ${arch_name}") + + add_definitions(-DDAEMON_ARCH_${arch_name}) + + set(nacl_arch "${arch_name}") + if (DAEMON_SYSTEM_Unix_COMPATIBILITY) + set(armhf_usage "arm64;armel") + if ("${arch_name}" IN_LIST armhf_usage) + # Load 32-bit armhf nexe on 64-bit arm64 engine on Linux with multiarch. + # The nexe is system agnostic so there should be no difference with armel. + set(nacl_arch "armhf") + endif() + elseif(DAEMON_SYSTEM_macOS) + if ("${arch_name}" STREQUAL "arm64") + # You can get emulated NaCl going like this: + # cp external_deps/macos-amd64-default_10/{nacl_loader,irt_core-amd64.nexe} build/ + set(nacl_arch "amd64") + endif() + endif() + + # The DAEMON_NACL_ARCH variable contributes to the nexe file name. + set(DAEMON_NACL_ARCH_NAME "${nacl_arch}" PARENT_SCOPE) +endfunction() + +function(daemon_set_arch_intrinsics name) + message(STATUS "Enabling ${name} architecture intrinsics") + add_definitions(-DDAEMON_USE_ARCH_INTRINSICS_${name}) +endfunction() + +function(daemon_set_intrinsics) + if (USE_ARCH_INTRINSICS) + # Makes possible to do that in C++ code: + # > if defined(DAEMON_USE_ARCH_INTRINSICS) + add_definitions(-DDAEMON_USE_ARCH_INTRINSICS) + + # Makes possible to do that in C++ code: + # > if defined(DAEMON_USE_ARCH_INTRINSICS_amd64) + # > if defined(DAEMON_USE_ARCH_INTRINSICS_i686) + daemon_set_arch_intrinsics("${DAEMON_ARCH_NAME}") + + set(amd64_PARENT "i686") + set(arm64_PARENT "armhf") + + if ("${DAEMON_ARCH_NAME}_PARENT") + daemon_set_arch_intrinsics("${${DAEMON_ARCH_NAME}_PARENT}") + endif() + else() + message(STATUS "Disabling ${DAEMON_ARCH_NAME} architecture intrinsics") + endif() +endfunction() + +daemon_detect_arch() +daemon_set_intrinsics() + +# Makes possible to do that in CMake code: +# > if (DAEMON_ARCH_arm64) +# > if (DAEMON_NACL_ARCH_armhf) +set("DAEMON_ARCH_${DAEMON_ARCH_NAME}" ON) +set("DAEMON_NACL_ARCH_${DAEMON_NACL_ARCH_NAME}" ON) + +if (DAEMON_SOURCE_GENERATOR) + # Add printable strings to the executable. + daemon_add_buildinfo("char*" "DAEMON_ARCH_STRING" "\"${DAEMON_ARCH_NAME}\"") + daemon_add_buildinfo("char*" "DAEMON_NACL_ARCH_STRING" "\"${DAEMON_NACL_ARCH_NAME}\"") +endif() diff --git a/cmake/DaemonCompiler.cmake b/cmake/DaemonPlatform/Compiler.cmake similarity index 76% rename from cmake/DaemonCompiler.cmake rename to cmake/DaemonPlatform/Compiler.cmake index e00480cd24..a838415b35 100644 --- a/cmake/DaemonCompiler.cmake +++ b/cmake/DaemonPlatform/Compiler.cmake @@ -1,5 +1,5 @@ # Daemon BSD Source Code -# Copyright (c) 2024, Daemon Developers +# Copyright (c) 2024-2025, Daemon Developers # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,66 +25,21 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ################################################################################ -# Determine compiler +# Compiler detection. ################################################################################ -# FIXME: Force -W#pragma-messages and -Wno-error -# In case there is -Wno-#pragma-messages or -Werror in CFLAGS/CXXFLAGS +# When adding a new compiler, look at all the places DAEMON_C_COMPILER +# and DAEMON_CXX_COMPILER are used. -function(detect_daemon_compiler lang) +function(daemon_detect_compiler lang) set(C_NAME "C") set(CXX_NAME "C++") set(C_EXT ".c") set(CXX_EXT ".cpp") - try_compile(BUILD_RESULT - "${CMAKE_BINARY_DIR}" - "${DAEMON_DIR}/cmake/DaemonCompiler/DaemonCompiler${${lang}_EXT}" - CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} - OUTPUT_VARIABLE BUILD_LOG - ) - get_filename_component(compiler_basename "${CMAKE_${lang}_COMPILER}" NAME) - if (NOT BUILD_RESULT) - message(WARNING "Failed to build DaemonCompiler${${lang}_EXT}, relying on CMake builtin detection.") - set(compiler_name "Unknown") - else() - set(BUILD_LOG "\n${BUILD_LOG}\n") - string(REGEX REPLACE "\n[^\n]*REPORT>[^\n]*\n" "\n" BUILD_LOG "${BUILD_LOG}") - - string(REGEX REPLACE ".*\nDAEMON_COMPILER_NAME=([^\n]*)\n.*" "\\1" - compiler_name "${BUILD_LOG}") - - foreach(name GCC;Clang;generic;${compiler_name}) - set(compatibility_regex ".*\nDAEMON_COMPILER_${name}_COMPATIBILITY=([^\n]*)\n.*") - if ("${BUILD_LOG}" MATCHES ${compatibility_regex}) - string(REGEX REPLACE ${compatibility_regex} "\\1" - compiler_${name}_compatibility "${BUILD_LOG}") - endif() - - set(version_regex ".*\nDAEMON_COMPILER_${name}_VERSION=([^\n]*)\n.*") - if ("${BUILD_LOG}" MATCHES ${version_regex}) - string(REGEX REPLACE ${version_regex} "\\1" - compiler_${name}_version "${BUILD_LOG}") - endif() - - set(version_string_regex ".*\nDAEMON_COMPILER_${name}_VERSION_STRING=([^\n]*)\n.*") - if ("${BUILD_LOG}" MATCHES ${version_string_regex}) - string(REGEX REPLACE ${version_string_regex} "\\1" - compiler_${name}_version_string "${BUILD_LOG}") - endif() - - set(DAEMON_${lang}_COMPILER_${name}_VERSION - "${compiler_${name}_version}" - PARENT_SCOPE) - - set(DAEMON_${lang}_COMPILER_${name}_COMPATIBILITY - "${compiler_${name}_compatibility}" - PARENT_SCOPE) - endforeach() - endif() + daemon_run_detection("${lang}_" "COMPILER" "Compiler${${lang}_EXT}" "GCC;Clang;generic") if (compiler_name STREQUAL "Unknown") if (CMAKE_${lang}_COMPILER_ID) @@ -126,7 +81,7 @@ function(detect_daemon_compiler lang) endif() endif() - # Compilers that use underlying Clang version as their own version. + # Compilers that use the underlying Clang version as their own version. foreach(name in AppleClang) if (compiler_name STREQUAL "${name}") set(compiler_${name}_version "${compiler_Clang_version}") @@ -189,7 +144,7 @@ foreach(lang C;CXX) set(DAEMON_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}") get_filename_component(DAEMON_${lang}_COMPILER_BASENAME "${CMAKE_${lang}_COMPILER}" NAME) else() - detect_daemon_compiler(${lang}) + daemon_detect_compiler(${lang}) if (DAEMON_${lang}_COMPILER_Clang_COMPATIBILITY) if (NOT DAEMON_${lang}_COMPILER_NAME STREQUAL "Clang") @@ -233,9 +188,17 @@ foreach(lang C;CXX) message(STATUS "Detected ${${lang}_NAME} compiler: ${DAEMON_${lang}_COMPILER_STRING}") + # Makes possible to do that in C++ code: + # > if defined(DAEMON_CXX_COMPILER_Clang) set(compiler_var_name "DAEMON_${lang}_COMPILER_${DAEMON_${lang}_COMPILER_NAME}") - set(${compiler_var_name} ON) - add_definitions(-D${compiler_var_name}=1) + add_definitions(-D${compiler_var_name}) + + # Makes possible to do that in CMake code: + # > if (DAEMON_CXX_COMPILER_Clang) + set("${compiler_var_name}" ON) - daemon_add_buildinfo("char*" "DAEMON_${lang}_COMPILER_STRING" "\"${DAEMON_${lang}_COMPILER_STRING}\"") + if (DAEMON_SOURCE_GENERATOR) + # Add printable string to the executable. + daemon_add_buildinfo("char*" "DAEMON_${lang}_COMPILER_STRING" "\"${DAEMON_${lang}_COMPILER_STRING}\"") + endif() endforeach() diff --git a/cmake/DaemonPlatform/Detection.cmake b/cmake/DaemonPlatform/Detection.cmake new file mode 100644 index 0000000000..8418e37fea --- /dev/null +++ b/cmake/DaemonPlatform/Detection.cmake @@ -0,0 +1,102 @@ +# Daemon BSD Source Code +# Copyright (c) 2025, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# Make sure to always call this macro from within a function, not in the global scope. +# As a macro it produces a lot of variables in the parent scope but it is meant to +# only be called by functions so they should never pollute the globale scope. +# It's a macro because we need to write a lot of variables in the calling function scope +# and we need to write some variables to the parent scope of the calling function. +macro(daemon_run_detection slug_prefix report_slug file_name compat_list) + string(TOLOWER "${report_slug}" local_slug) + + # Setting -Werror in CXXFLAGS would produce errors instead of warning + # but that should not break the detection, + # so we only print a CMake warning there and use build_log content to + # detect unknown platforms. + # Catching compilation error is still useful, for example to detect + # undefined types, missing header or things like that. + # Setting USE_WERROR to ON doesn't print this warning as the flag + # is set after the detection. + try_compile(build_result + "${CMAKE_BINARY_DIR}" + "${CMAKE_CURRENT_LIST_DIR}/Detection/${file_name}" + # TODO: Force -W#pragma-messages and -Wno-error + # In case there is -Wno-#pragma-messages or -Werror in CFLAGS/CXXFLAGS + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + OUTPUT_VARIABLE build_log + ) + + if (NOT build_result) + message(WARNING "Failed to build ${file_name}.\n" + "Setting -Werror in CFLAGS can produce false positive errors\n" + "${build_log}" + ) + set(${local_slug}_name "Unknown" PARENT_SCOPE) + else() + set(build_log "\n${build_log}\n") + + string(REGEX REPLACE "\n[^\n]*REPORT>[^\n]*\n" "\n" build_log "${build_log}") + + string(REGEX REPLACE ".*\nDAEMON_${report_slug}_NAME=([^\n]*)\n.*" "\\1" + ${local_slug}_name "${build_log}") + + foreach(name ${compat_list};${${local_slug}_name}) + set(COMPATIBILITY_REGEX ".*\nDAEMON_${report_slug}_${name}_COMPATIBILITY=([^\n]*)\n.*") + if ("${build_log}" MATCHES ${COMPATIBILITY_REGEX}) + string(REGEX REPLACE ${COMPATIBILITY_REGEX} "\\1" + ${local_slug}_${name}_compatibility "${build_log}") + + set("DAEMON_${slug_prefix}${report_slug}_${name}_COMPATIBILITY" + "${${local_slug}_${name}_compatibility}" + PARENT_SCOPE) + endif() + + set(VERSION_REGEX ".*\nDAEMON_${report_slug}_${name}_VERSION=([^\n]*)\n.*") + if ("${build_log}" MATCHES ${VERSION_REGEX}) + string(REGEX REPLACE ${VERSION_REGEX} "\\1" + ${local_slug}_${name}_version "${build_log}") + + set("DAEMON_${slug_prefix}${report_slug}_${name}_VERSION" + "${${local_slug}_${name}_version}" + PARENT_SCOPE) + endif() + + set(VERSION_STRING_REGEX ".*\nDAEMON_${report_slug}_${name}_VERSION_STRING=([^\n]*)\n.*") + if ("${build_log}" MATCHES ${VERSION_STRING_REGEX}) + string(REGEX REPLACE ${VERSION_STRING_REGEX} "\\1" + ${local_slug}_${name}_version_string "${build_log}") + endif() + endforeach() + endif() +endmacro() + +# Target detection. +include("${CMAKE_CURRENT_LIST_DIR}/System.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/Architecture.cmake") + +# Compiler detection. +include("${CMAKE_CURRENT_LIST_DIR}/Compiler.cmake") diff --git a/cmake/DaemonArchitecture/DaemonArchitecture.cpp b/cmake/DaemonPlatform/Detection/Architecture.c similarity index 81% rename from cmake/DaemonArchitecture/DaemonArchitecture.cpp rename to cmake/DaemonPlatform/Detection/Architecture.c index b201f4a6be..ae973a210a 100644 --- a/cmake/DaemonArchitecture/DaemonArchitecture.cpp +++ b/cmake/DaemonPlatform/Detection/Architecture.c @@ -1,7 +1,7 @@ /* =========================================================================== Daemon BSD Source Code -Copyright (c) 2022, Daemon Developers +Copyright (c) 2022-2025, Daemon Developers All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,21 +28,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================== */ +#define REPORT_SLUG "ARCH" +#include "report.h" + /* The qprocessordetection.h file doesn't detect endianness for some platforms including ppc64, but we know how to do it for them. */ #include -#include "../../src/common/Endian.h" - -/* qprocessordetection.h will print an error if it fails to detect -endianness and while it is not already set, so the else clause is -outsourced to that qprocessordetection.h file instead. */ - -#if defined(Q3_BIG_ENDIAN) - #define Q_BYTE_ORDER Q_BIG_ENDIAN -#elif defined(Q3_LITTLE_ENDIAN) - #define Q_BYTE_ORDER Q_LITTLE_ENDIAN -#endif /* This source file includes qprocessordetection.h from Qt: @@ -65,12 +57,12 @@ care of platform name variants that are meant to distinguish platform variants we cannot support anyway. */ /* PNaCl virtual machines. */ -#if defined(__native_client__) - #pragma message("DAEMON_ARCH_nacl") +#if defined(__pnacl__) + #pragma message(REPORT_NAME("pnacl")) /* Wasm virtual machines, work in progress. */ #elif defined(Q_PROCESSOR_WASM) - #pragma message("DAEMON_ARCH_wasm") + #pragma message(REPORT_NAME("wasm")) /* Devices like: - IBM PC compatibles and derivatives, @@ -78,13 +70,13 @@ platform variants we cannot support anyway. */ - Steam Deck, Atari VCS consoles… */ #elif defined(Q_PROCESSOR_X86_64) - #pragma message("DAEMON_ARCH_amd64") + #pragma message(REPORT_NAME("amd64")) #elif defined(Q_PROCESSOR_X86_32) // Assume at least i686. Detecting older revisions would be unlikely to work here // because the revisions are likely configured by flags, but this file is "compiled" // without most command-line flags. - #pragma message("DAEMON_ARCH_i686") + #pragma message(REPORT_NAME("i686")) /* Devices like: - Raspberry Pi, @@ -92,31 +84,36 @@ platform variants we cannot support anyway. */ - Android phones and tablets… */ #elif defined(Q_PROCESSOR_ARM_64) - #pragma message("DAEMON_ARCH_arm64") + #pragma message(REPORT_NAME("arm64")) #elif defined(Q_PROCESSOR_ARM_32) && defined(__ARM_PCS_VFP) - #pragma message("DAEMON_ARCH_armhf") + #pragma message(REPORT_NAME("armhf")) #elif defined(Q_PROCESSOR_ARM_32) && !defined(__ARM_PCS_VFP) - #pragma message("DAEMON_ARCH_armel") + #pragma message(REPORT_NAME("armel")) /* Devices like: - Raptor Computing Systems Talos, Blackbird… */ #elif defined(Q_PROCESSOR_POWER_64) && Q_BYTE_ORDER == Q_BIG_ENDIAN - #pragma message("DAEMON_ARCH_ppc64") + #pragma message(REPORT_NAME("ppc64")) #elif defined(Q_PROCESSOR_POWER_64) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN - #pragma message("DAEMON_ARCH_ppc64el") + #pragma message(REPORT_NAME("ppc64el")) /* Devices like: - SiFive HiFive Unmatched, Horse Creek… */ #elif defined(Q_PROCESSOR_RISCV_64) - #pragma message("DAEMON_ARCH_riscv64") + #pragma message(REPORT_NAME("riscv64")) + +/* Remaining native NaCl architecture. */ + +#elif defined(Q_PROCESSOR_MIPS_32) && Q_BYTE_ORDER == Q_LITTLE_ENDIAN + #pragma message(REPORT_NAME("mipsel")) #else - #pragma message("DAEMON_ARCH_unknown") + #pragma message(REPORT_NAME("unknown")) #endif // Make the compilation succeeds if architecture is supported. diff --git a/cmake/DaemonCompiler/DaemonCompiler.c b/cmake/DaemonPlatform/Detection/Compiler.c similarity index 90% rename from cmake/DaemonCompiler/DaemonCompiler.c rename to cmake/DaemonPlatform/Detection/Compiler.c index f05c0954bf..a6c80ab201 100644 --- a/cmake/DaemonCompiler/DaemonCompiler.c +++ b/cmake/DaemonPlatform/Detection/Compiler.c @@ -1,7 +1,7 @@ /* =========================================================================== Daemon BSD Source Code -Copyright (c) 2024, Daemon Developers +Copyright (c) 2024-2025, Daemon Developers All rights reserved. Redistribution and use in source and binary forms, with or without @@ -28,23 +28,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =========================================================================== */ -#define STRING(s) #s -#define XSTRING(s) STRING(s) - -#define REPORT(key, value) \ - "REPORT>" -#define REPORT_VERSION_3(name, major, minor, patch) \ - REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor) "." XSTRING(patch)) -#define REPORT_VERSION_2(name, major, minor) \ - REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor)) -#define REPORT_VERSION_1(name, major) \ - REPORT(name "_VERSION", XSTRING(major)) -#define REPORT_VERSION_STRING(name, value) \ - REPORT(name "_VERSION_STRING", value) -#define REPORT_COMPATIBILITY(name) \ - REPORT(name "_COMPATIBILITY", "ON") -#define REPORT_NAME(name) \ - REPORT("NAME", name) +#define REPORT_SLUG "COMPILER" +#include "report.h" // GCC diff --git a/cmake/DaemonPlatform/Detection/Compiler.cpp b/cmake/DaemonPlatform/Detection/Compiler.cpp new file mode 100644 index 0000000000..41c3f576b6 --- /dev/null +++ b/cmake/DaemonPlatform/Detection/Compiler.cpp @@ -0,0 +1 @@ +#include "Compiler.c" diff --git a/cmake/DaemonPlatform/Detection/System.c b/cmake/DaemonPlatform/Detection/System.c new file mode 100644 index 0000000000..130136e45a --- /dev/null +++ b/cmake/DaemonPlatform/Detection/System.c @@ -0,0 +1,72 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2025, Daemon Developers +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +#define REPORT_SLUG "SYSTEM" +#include "report.h" + +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) + #pragma message(REPORT_COMPATIBILITY("Linux")) +#endif + +#if defined(__unix__) || defined(__unix) || defined(unix) + #pragma message(REPORT_COMPATIBILITY("Unix")) +#endif + +#if defined(__wasm__) || defined(__wasm) || defined(__wasm32) || defined(__wasi__) + #pragma message(REPORT_NAME("Wasm")) +#elif defined(__pnacl__) || defined(__saigo__) || defined(NACLENTRYALIGN) + #pragma message(REPORT_NAME("NaCl")) +#elif defined(__WINNT__) || defined(__WINNT) || defined(WINNT) \ +|| defined(__WIN64__) || defined(__WIN64) || defined(_WIN64) || defined(WIN64) \ +|| defined(__WIN32__) || defined(__WIN32) || defined(_WIN32) || defined(WIN32) \ +|| defined(__MINGW64__) || defined(__MINGW32__) + #pragma message(REPORT_NAME("Windows")) +#elif defined(__APPLE__) && defined(__MACH__) && (TARGET_OS_MAC && !TARGET_OS_IPHONE) + #pragma message(REPORT_NAME("macOS")) +#elif defined(__FreeBSD__) + #pragma message(REPORT_NAME("FreeBSD")) +#elif defined(__ANDROID__) + #pragma message(REPORT_NAME("Android")) +#elif defined(__gnu_linux__) + #pragma message(REPORT_NAME("Linux")) +#elif defined(__linux__) || defined(__linux) || defined(linux) + #pragma message(REPORT_NAME("Linux") +#else + #pragma message(REPORT_NAME("Unknown")) +#endif + +// Make the compilation succeeds if system is supported. +int main(int argc, char** argv) { + return 0; +} diff --git a/cmake/DaemonCompiler/DaemonCompiler.sh b/cmake/DaemonPlatform/Detection/detect similarity index 69% rename from cmake/DaemonCompiler/DaemonCompiler.sh rename to cmake/DaemonPlatform/Detection/detect index d93cae3c44..8bf3503be6 100755 --- a/cmake/DaemonCompiler/DaemonCompiler.sh +++ b/cmake/DaemonPlatform/Detection/detect @@ -27,23 +27,33 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Test script not used by the CMake build system. Usage example: -# ./DaemonCompiler.sh gcc +# ./detect gcc set -ueo pipefail script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -file_path="${script_dir}/DaemonCompiler.c" -# PNaCl doesn't work with “-o /dev/null” as it uses the output path as a -# pattern for temporary files and then the parent folder should be writable. -# Zig caches the build if both the source and the output don't change. Since -# the /dev/null file never changes, Zig skips the compilation once done once. -# So we need to use a randomly named path in a writable directory. -temp_file="$(mktemp)" +if [ -z "${1:-}" ] +then + echo "ERROR: missing compiler" >&2 + false +fi -"${@}" "${file_path}" -o "${temp_file}" 2>&1 \ - | grep 'REPORT>.*//' \ -|| "${@}" "${file_path}" -o "${temp_file}" +for base_name in Compiler System Architecture +do + file_path="${script_dir}/${base_name}.c" -rm "${temp_file}" + # PNaCl doesn't work with “-o /dev/null” as it uses the output path as a + # pattern for temporary files and then the parent folder should be writable. + # Zig caches the build if both the source and the output don't change. Since + # the /dev/null file never changes, Zig skips the compilation once done once. + # So we need to use a randomly named path in a writable directory. + temp_file="$(mktemp)" + + "${@}" "${file_path}" -o "${temp_file}" 2>&1 \ + | grep 'REPORT>.*//' \ + || "${@}" "${file_path}" -o "${temp_file}" + + rm "${temp_file}" +done diff --git a/cmake/DaemonArchitecture/qprocessordetection.h b/cmake/DaemonPlatform/Detection/qprocessordetection.h similarity index 100% rename from cmake/DaemonArchitecture/qprocessordetection.h rename to cmake/DaemonPlatform/Detection/qprocessordetection.h diff --git a/cmake/DaemonPlatform/Detection/report.h b/cmake/DaemonPlatform/Detection/report.h new file mode 100644 index 0000000000..f819d290ee --- /dev/null +++ b/cmake/DaemonPlatform/Detection/report.h @@ -0,0 +1,47 @@ +/* +=========================================================================== +Daemon BSD Source Code +Copyright (c) 2024-2025, Daemon Developers +All rights reserveid. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================== +*/ + +#define STRING(s) #s +#define XSTRING(s) STRING(s) + +#define REPORT(key, value) \ + "REPORT>" +#define REPORT_VERSION_3(name, major, minor, patch) \ + REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor) "." XSTRING(patch)) +#define REPORT_VERSION_2(name, major, minor) \ + REPORT(name "_VERSION", XSTRING(major) "." XSTRING(minor)) +#define REPORT_VERSION_1(name, major) \ + REPORT(name "_VERSION", XSTRING(major)) +#define REPORT_VERSION_STRING(name, value) \ + REPORT(name "_VERSION_STRING", value) +#define REPORT_COMPATIBILITY(name) \ + REPORT(name "_COMPATIBILITY", "ON") +#define REPORT_NAME(name) \ + REPORT("NAME", name) diff --git a/cmake/DaemonFileEmbedder.cmake b/cmake/DaemonPlatform/FileEmbedder.cmake similarity index 100% rename from cmake/DaemonFileEmbedder.cmake rename to cmake/DaemonPlatform/FileEmbedder.cmake diff --git a/cmake/DaemonPlatform.cmake b/cmake/DaemonPlatform/Platform.cmake similarity index 70% rename from cmake/DaemonPlatform.cmake rename to cmake/DaemonPlatform/Platform.cmake index be8f5f1c81..0e79eec906 100644 --- a/cmake/DaemonPlatform.cmake +++ b/cmake/DaemonPlatform/Platform.cmake @@ -1,5 +1,5 @@ # Daemon BSD Source Code -# Copyright (c) 2013-2016, Daemon Developers +# Copyright (c) 2025, Daemon Developers # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,29 +25,12 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ################################################################################ -# Determine platform +# Collection of reusable CMake helpers written for the Dæmon engine and related +# projects. ################################################################################ -# When adding a new platform, look at all the places WIN32, APPLE and LINUX are used -if( CMAKE_SYSTEM_NAME MATCHES "Linux" ) - set( LINUX ON ) -elseif( CMAKE_SYSTEM_NAME MATCHES "FreeBSD" ) - set( FREEBSD ON ) -elseif( WIN32 ) -elseif( APPLE ) -elseif( NACL ) -else() - message( FATAL_ERROR "Platform not supported" ) -endif() +# Source generation. +include("${CMAKE_CURRENT_LIST_DIR}/SourceGenerator.cmake") -if (NACL AND USE_NACL_SAIGO) - # Saigo clang reports weird errors when building some cgame and sgame arm nexe with PIE. - # Saigo clang crashes when building amd64 cgame with PIE, sgame builds properly though. - set(GAME_PIE 0) -else() - set(GAME_PIE 1) -endif() - - -include(DaemonArchitecture) -include(DaemonCompiler) +# System, architecture and compiler detection. +include("${CMAKE_CURRENT_LIST_DIR}/Detection.cmake") diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonPlatform/SourceGenerator.cmake similarity index 95% rename from cmake/DaemonSourceGenerator.cmake rename to cmake/DaemonPlatform/SourceGenerator.cmake index 3086830d22..7fc6d71090 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonPlatform/SourceGenerator.cmake @@ -24,9 +24,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +################################################################################ +# Source generation and file embedding. +################################################################################ + set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -set(DAEMON_FILE_EMBEDDER "${current_list_dir}/DaemonFileEmbedder.cmake") +set(DAEMON_FILE_EMBEDDER "${current_list_dir}/FileEmbedder.cmake") set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") diff --git a/cmake/DaemonPlatform/System.cmake b/cmake/DaemonPlatform/System.cmake new file mode 100644 index 0000000000..5da47ea8ed --- /dev/null +++ b/cmake/DaemonPlatform/System.cmake @@ -0,0 +1,116 @@ +# Daemon BSD Source Code +# Copyright (c) 2025, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################################################################################ +# System detection. +################################################################################ + +# When adding a new system, look at all the places DAEMON_HOST_SYSTEM +# and DAEMON_SYSTEM are used. + +function(daemon_detect_host_system) + set(system_name "Unknown") + + foreach(name Linux;FreeBSD;Android;Windows) + if (CMAKE_HOST_SYSTEM_NAME MATCHES "${name}") + set(system_name "${CMAKE_SYSTEM_NAME}") + endif() + endforeach() + + if (system_name STREQUAL "Unknown") + message(WARNING "Host system detection failed, may misdetect the target as the host.") + + if (WIN32) + set(system_name "Windows") + elseif (APPLE) + set(system_name "macOS") + endif() + endif() + + if (system_name STREQUAL "Unknown") + set(SYSTEM_Darwin "macOS") + set(SYSTEM_MSYS "Windows") + + foreach(name Darwin;MSYS) + if ("${CMAKE_HOST_SYSTEM_NAME}" MATCHES "${name}") + set(system_name "${SYSTEM_${name}}") + endif() + endforeach() + + detect_cmake_host_system("system_name") + endif() + + set(DAEMON_HOST_SYSTEM_NAME "${system_name}" PARENT_SCOPE) +endfunction() + +function(daemon_detect_system) + daemon_run_detection("" "SYSTEM" "System.c" "Linux;Unix") + + if (system_name STREQUAL "Unknown") + detect_cmake_host_system("system_name") + endif() + + set(DAEMON_SYSTEM_NAME "${system_name}" PARENT_SCOPE) +endfunction() + +daemon_detect_host_system() +daemon_detect_system() + +if ("${DAEMON_HOST_SYSTEM_NAME}" STREQUAL "Unknown") + message(WARNING "Unknown host system") +endif() + +if ("${DAEMON_SYSTEM_NAME}" STREQUAL "Unknown") + message(WARNING "Unknown target system") +endif() + +if ("${DAEMON_HOST_SYSTEM_NAME}" STREQUAL "Unknown" AND NOT "${DAEMON_SYSTEM_NAME}" STREQUAL "Unknown") + message(WARNING "Assuming the host system is the same as the target: ${DAEMON_SYSTEM_NAME}") + set(DAEMON_HOST_SYSTEM_NAME "${DAEMON_SYSTEM_NAME}") +endif() + +if ("${DAEMON_SYSTEM_NAME}" STREQUAL "Unknown" AND NOT "${DAEMON_HOST_SYSTEM_NAME}" STREQUAL "Unknown") + message(WARNING "Assuming the target system is the same as the host: ${DAEMON_SYSTEM_NAME}") + set(DAEMON_SYSTEM_NAME "${DAEMON_HOST_SYSTEM_NAME}") +endif() + +message(STATUS "Detected host system: ${DAEMON_HOST_SYSTEM_NAME}") +message(STATUS "Detected target system: ${DAEMON_SYSTEM_NAME}") + +if (NOT "${DAEMON_HOST_SYSTEM_NAME}" STREQUAL "${DAEMON_SYSTEM_NAME}") + message(STATUS "Detected cross-compilation") +endif() + +# Makes possible to do that in CMake code: +# > if (DAEMON_HOST_SYSTEM_Linux) +# > if (DAEMON_SYSTEM_Windows) +set("DAEMON_HOST_SYSTEM_${DAEMON_HOST_SYSTEM_NAME}" ON) +set("DAEMON_SYSTEM_${DAEMON_SYSTEM_NAME}" ON) + +if (DAEMON_SOURCE_GENERATOR) + # Add printable string to the executable. + daemon_add_buildinfo("char*" "DAEMON_SYSTEM_STRING" "\"${DAEMON_SYSTEM_NAME}\"") +endif() diff --git a/freetype.cmake b/freetype.cmake index f6556dbaca..6dff87a83e 100644 --- a/freetype.cmake +++ b/freetype.cmake @@ -2,7 +2,7 @@ set(FREETYPE_DIR ${DAEMON_DIR}/libs/freetype) set(FREETYPE_INCLUDE_DIRS ${FREETYPE_DIR}/include) set(FREETYPE_LIBRARIES freetype) -if (NACL) +if (DAEMON_SYSTEM_NaCl) # Using Freetype's own zlib prevents the need for a zlib submodule when building the nexe cgame. set(FREETYPE_INTERNAL_ZLIB ON) else() diff --git a/src.cmake b/src.cmake index 7430a577b9..2cd0bd732d 100644 --- a/src.cmake +++ b/src.cmake @@ -207,7 +207,7 @@ set(ENGINELIST ${ENGINE_DIR}/RefAPI.h ) -if (WIN32) +if (DAEMON_SYSTEM_Windows) set(ENGINELIST ${ENGINELIST} ${ENGINE_DIR}/sys/con_passive.cpp ) @@ -296,7 +296,7 @@ set(CLIENTLIST ${RENDERERLIST} ) -if (APPLE) +if (DAEMON_SYSTEM_macOS) set(CLIENTLIST ${CLIENTLIST} ${ENGINE_DIR}/sys/DisableAccentMenu.m) endif() diff --git a/src/common/Platform.h b/src/common/Platform.h index 1dba232341..15e686a898 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -33,19 +33,17 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Platform-specific configuration #if defined(_WIN32) -#define PLATFORM_STRING "Windows" #elif defined(__APPLE__) -#define PLATFORM_STRING "macOS" #elif defined(__linux__) -#define PLATFORM_STRING "Linux" #elif defined(__FreeBSD__) -#define PLATFORM_STRING "FreeBSD" #elif defined(__native_client__) -#define PLATFORM_STRING "NaCl" #else #error "Platform not supported" #endif +// TODO: Remove once the game code is ported to DAEMON_SYSTEM_STRING. +#define PLATFORM_STRING DAEMON_SYSTEM_STRING + #if defined(__native_client__) #elif defined(_WIN32) #define DLL_EXT ".dll" diff --git a/src/engine/framework/System.cpp b/src/engine/framework/System.cpp index 2d66f2a791..bb999b61ff 100644 --- a/src/engine/framework/System.cpp +++ b/src/engine/framework/System.cpp @@ -844,7 +844,7 @@ static void Init(int argc, char** argv) #endif // Print a banner and a copy of the command-line arguments - Log::Notice("%s %s %s (%s) %s", Q3_VERSION, PLATFORM_STRING, DAEMON_ARCH_STRING, DAEMON_CXX_COMPILER_STRING, __DATE__); + Log::Notice("%s %s %s (%s) %s", Q3_VERSION, DAEMON_SYSTEM_STRING, DAEMON_ARCH_STRING, DAEMON_CXX_COMPILER_STRING, __DATE__); std::string argsString = "cmdline:"; for (int i = 1; i < argc; i++) { diff --git a/srclibs.cmake b/srclibs.cmake index 08b1a31b7a..d6765e25d2 100644 --- a/srclibs.cmake +++ b/srclibs.cmake @@ -33,19 +33,19 @@ set(NACLLIST_MODULE ${LIB_DIR}/nacl/native_client/src/untrusted/nacl/imc_socketpair.c ) -if (APPLE) +if (DAEMON_SYSTEM_macOS) set(NACLLIST_NATIVE ${LIB_DIR}/nacl/native_client/src/shared/imc/nacl_imc_common.cc ${LIB_DIR}/nacl/native_client/src/shared/imc/posix/nacl_imc_posix.cc ${LIB_DIR}/nacl/native_client/src/shared/imc/osx/nacl_imc.cc ) -elseif (LINUX OR FREEBSD) +elseif (DAEMON_SYSTEM_Unix_COMPATIBILITY) set(NACLLIST_NATIVE ${LIB_DIR}/nacl/native_client/src/shared/imc/nacl_imc_common.cc ${LIB_DIR}/nacl/native_client/src/shared/imc/posix/nacl_imc_posix.cc ${LIB_DIR}/nacl/native_client/src/shared/imc/linux/nacl_imc.cc ) -elseif (WIN32) +elseif (DAEMON_SYSTEM_Windows) set(NACLLIST_NATIVE ${LIB_DIR}/nacl/native_client/src/shared/imc/nacl_imc_common.cc ${LIB_DIR}/nacl/native_client/src/shared/imc/win/nacl_imc.cc @@ -101,7 +101,7 @@ set(PDCURSESLIST ${LIB_DIR}/pdcursesmod/pdcurses/window.c ) -if (WIN32) +if (DAEMON_SYSTEM_Windows) set(PDCURSESLIST ${PDCURSESLIST} ${LIB_DIR}/pdcursesmod/wingui/pdcclip.c @@ -153,7 +153,7 @@ set(TINYGETTEXTLIST ${LIB_DIR}/tinygettext/tinygettext.hpp ) -if (WIN32) +if (DAEMON_SYSTEM_Windows) set(BREAKPAD_COMMON_LIST ${LIB_DIR}/breakpad/src/common/windows/guid_string.cc ${LIB_DIR}/breakpad/src/common/windows/guid_string.h @@ -179,7 +179,7 @@ if (WIN32) ${LIB_DIR}/breakpad/src/client/windows/handler/exception_handler.cc ${LIB_DIR}/breakpad/src/client/windows/handler/exception_handler.h ) -elseif (LINUX) +elseif (DAEMON_SYSTEM_Linux_COMPATIBILITY) set(BREAKPAD_LIST ${LIB_DIR}/breakpad/src/client/linux/crash_generation/crash_generation_client.cc ${LIB_DIR}/breakpad/src/client/linux/crash_generation/crash_generation_server.cc