From b59bbb1c83f6a1def9ef856002cf1b581936ddbd Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 28 Mar 2025 01:03:52 +0300 Subject: [PATCH] CMake improvements, add 64-bit support for use in Xash3D FWGS (#1053) * cmake: do not strip debuginfo during link if DEBUG was enabled * cmake: use compiler id instead of env checks to determine Intel compiler or Clang * cmake: introduce XASH_COMPAT option, which will let regamedll to be built for 64-bit and non-x86 targets * cmake: add LibraryNaming module from hlsdk-portable repository and platform detection header * cmake: now, integrate LibraryNaming into regamedll CMakeLists file. Disable x86 options on non-x86 platforms * server: add support for 64-bit ABI used in Xash3D FWGS --- regamedll/CMakeLists.txt | 94 +++++++--- regamedll/cmake/LibraryNaming.cmake | 198 ++++++++++++++++++++ regamedll/dlls/qstring.h | 35 +++- regamedll/public/build.h | 269 ++++++++++++++++++++++++++++ 4 files changed, 565 insertions(+), 31 deletions(-) create mode 100644 regamedll/cmake/LibraryNaming.cmake create mode 100644 regamedll/public/build.h diff --git a/regamedll/CMakeLists.txt b/regamedll/CMakeLists.txt index bc0a990e..c1a13f9b 100644 --- a/regamedll/CMakeLists.txt +++ b/regamedll/CMakeLists.txt @@ -20,20 +20,47 @@ cmake_minimum_required(VERSION 3.1) project(regamedll CXX) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + option(DEBUG "Build with debug information." OFF) option(USE_STATIC_LIBSTDC "Enables static linking libstdc++." OFF) option(USE_LEGACY_LIBC "Enables linking against legacy libc (<= 2.15) for compat with older distros (Debian 8/Ubuntu 16.04/Centos 7)." OFF) +option(XASH_COMPAT "Enable Xash3D FWGS compatiblity (support for it's 64-bit ABI support and crossplatform library suffix)") set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Avoid -rdynamic -fPIC options -set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "") -set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") +if (NOT XASH_COMPAT) + set(CMAKE_SHARED_LIBRARY_CXX_FLAGS "") + set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") +endif() -set(COMPILE_FLAGS "-m32 -U_FORTIFY_SOURCE") -set(LINK_FLAGS "-m32 -s") -set(LINK_LIBS dl aelf32) +set(COMPILE_FLAGS "-U_FORTIFY_SOURCE") +set(LINK_LIBS dl) + +# do not strip debuginfo during link +if (NOT DEBUG) + set(LINK_FLAGS "-s") +endif() + +# add -m32 flag only on 64-bit systems, if building for 64-bit wasn't enabled with XASH_COMPAT +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + if (XASH_COMPAT) + set(COMPILE_FLAGS "${COMPILE_FLAGS} -DXASH_64BIT") + else() + set(COMPILE_FLAGS "${COMPILE_FLAGS} -m32") + set(LINK_FLAGS "${LINK_FLAGS} -m32") + list(APPEND LINK_LIBS aelf32) + set(CMAKE_SIZEOF_VOID_P 4) + endif() +endif() + +if(XASH_COMPAT) + # Xash3D FWGS Library Naming Scheme compliance + # see documentation: https://github.com/FWGS/xash3d-fwgs/blob/master/Documentation/extensions/library-naming.md + include(LibraryNaming) +endif() set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wall -fno-exceptions -fno-builtin -Wno-unknown-pragmas") @@ -47,7 +74,7 @@ else() endif() # Check Intel C++ compiler -if ("$ENV{CXX}" MATCHES "icpc") +if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") # # -fp-model=precise # ICC uses -fp-model fast=1 by default for more aggressive optimizations on floating-point calculations @@ -75,11 +102,15 @@ if ("$ENV{CXX}" MATCHES "icpc") set(COMPILE_FLAGS "${COMPILE_FLAGS} -ipo") set(LINK_FLAGS "${LINK_FLAGS} -ipo") endif() -else() - # Produce code optimized for the most common IA32/AMD64/EM64T processors. - # As new processors are deployed in the marketplace, the behavior of this option will change. +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + if (NOT XASH_COMPAT OR XASH_AMD64 OR XASH_X86) + # Produce code optimized for the most common IA32/AMD64/EM64T processors. + # As new processors are deployed in the marketplace, the behavior of this option will change. + set(COMPILE_FLAGS "${COMPILE_FLAGS} \ + -mtune=generic -msse3") + endif() + set(COMPILE_FLAGS "${COMPILE_FLAGS} \ - -mtune=generic -msse3\ -fpermissive -fno-sized-deallocation\ -Wno-delete-non-virtual-dtor -Wno-invalid-offsetof\ -Wno-unused-variable -Wno-unused-value -Wno-unused-result -Wno-unused-function\ @@ -87,7 +118,7 @@ else() -Wno-sign-compare -Wno-format -Wno-ignored-attributes -Wno-strict-aliasing") # Check Clang compiler - if ("$ENV{CXX}" MATCHES "clang") + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(COMPILE_FLAGS "${COMPILE_FLAGS} \ -Wno-unused-local-typedef\ -Wno-unused-private-field\ @@ -102,16 +133,11 @@ else() # GCC >= 8.3 if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess") + set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-stringop-truncation -Wno-format-truncation -Wno-class-memaccess -fcf-protection=none") endif() endif() endif() -# GCC >= 8.3 -if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 8.0) - set(COMPILE_FLAGS "${COMPILE_FLAGS} -fcf-protection=none") -endif() - if (NOT DEBUG) set(LINK_FLAGS "${LINK_FLAGS} \ -Wl,-gc-sections -Wl,--version-script=\"${PROJECT_SOURCE_DIR}/../version_script.lds\"") @@ -378,14 +404,36 @@ if (USE_STATIC_LIBSTDC) set(LINK_FLAGS "${LINK_FLAGS} -static-libgcc -static-libstdc++") endif() -set(LINK_FLAGS "${LINK_FLAGS} \ - -Wl,-rpath,'$ORIGIN/.' \ - -L${PROJECT_SOURCE_DIR}/lib/linux32") +set(LINK_FLAGS "${LINK_FLAGS} -Wl,-rpath,'$ORIGIN/.'") + +if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(LINK_FLAGS "${LINK_FLAGS} -L${PROJECT_SOURCE_DIR}/lib/linux32") +endif() set_target_properties(regamedll PROPERTIES - OUTPUT_NAME cs - PREFIX "" COMPILE_FLAGS ${COMPILE_FLAGS} LINK_FLAGS ${LINK_FLAGS} - POSITION_INDEPENDENT_CODE OFF ) + +if (XASH_COMPAT) + if (CMAKE_SYSTEM_NAME STREQUAL "Android") + set_target_properties(regamedll PROPERTIES + OUTPUT_NAME server) + else() + set_target_properties(regamedll PROPERTIES + PREFIX "" + OUTPUT_NAME cs${POSTFIX}) + endif() +else() + set_target_properties(regamedll PROPERTIES + OUTPUT_NAME cs + PREFIX "" + POSITION_INDEPENDENT_CODE OFF) +endif() + +install(TARGETS regamedll + RUNTIME DESTINATION "cstrike/dlls/" + LIBRARY DESTINATION "cstrike/dlls/" + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE) diff --git a/regamedll/cmake/LibraryNaming.cmake b/regamedll/cmake/LibraryNaming.cmake new file mode 100644 index 00000000..a20529ae --- /dev/null +++ b/regamedll/cmake/LibraryNaming.cmake @@ -0,0 +1,198 @@ +include(CheckSymbolExists) + +macro(check_build_target symbol) + check_symbol_exists(${symbol} "build.h" ${symbol}) +endmacro() + +macro(check_group_build_target symbol group) + if(NOT ${group}) + check_build_target(${symbol}) + if(${symbol}) + set(${group} TRUE) + endif() + else() + set(${symbol} FALSE) + endif() +endmacro() + +# So there is a problem: +# 1. Number of these symbols only grows, as we support more and more ports +# 2. CMake was written by morons and can't check these symbols in parallel +# 3. MSVC is very slow at everything (startup, parsing, generating error) + +# Solution: group these symbols and set variable if one of them was found +# this way we can reorder to reorder them by most common configurations +# but we can't generate this list anymore! ... OR IS IT ??? + +# Well, after reordering positions in engine's buildenums.h, we can partially autogenerate this list! +# echo "check_build_target(XASH_64BIT)" +# grep "#define PLATFORM" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_PLATFORM)" }' +# grep "#define ARCHITECTURE" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 " XASH_ARCHITECTURE)" +# grep "#define ENDIAN" buildenums.h | cut -d' ' -f 2 | cut -d_ -f 2- | awk '{ print "check_group_build_target(XASH_" $1 "_ENDIAN XASH_ENDIANNESS)"}' +# echo "if(XASH_ARM)" +# grep '^#undef XASH' build.h | grep "XASH_ARM[v_]" | awk '{ print "check_build_target(" $2 ")"}' +# echo "endif()" +# echo "if(XASH_RISCV)" +# grep '^#undef XASH' build.h | grep "XASH_RISCV_" | awk '{ print "check_build_target(" $2 ")"}' +# echo "endif()" + +# NOTE: Android must have priority over Linux to work correctly! + +set(CMAKE_REQUIRED_INCLUDES "${PROJECT_SOURCE_DIR}/public/") +check_build_target(XASH_64BIT) +check_group_build_target(XASH_WIN32 XASH_PLATFORM) +check_group_build_target(XASH_ANDROID XASH_PLATFORM) +check_group_build_target(XASH_LINUX XASH_PLATFORM) +check_group_build_target(XASH_FREEBSD XASH_PLATFORM) +check_group_build_target(XASH_APPLE XASH_PLATFORM) +check_group_build_target(XASH_NETBSD XASH_PLATFORM) +check_group_build_target(XASH_OPENBSD XASH_PLATFORM) +check_group_build_target(XASH_EMSCRIPTEN XASH_PLATFORM) +check_group_build_target(XASH_DOS4GW XASH_PLATFORM) +check_group_build_target(XASH_HAIKU XASH_PLATFORM) +check_group_build_target(XASH_SERENITY XASH_PLATFORM) +check_group_build_target(XASH_IRIX XASH_PLATFORM) +check_group_build_target(XASH_NSWITCH XASH_PLATFORM) +check_group_build_target(XASH_PSVITA XASH_PLATFORM) +check_group_build_target(XASH_WASI XASH_PLATFORM) +check_group_build_target(XASH_SUNOS XASH_PLATFORM) +check_group_build_target(XASH_X86 XASH_ARCHITECTURE) +check_group_build_target(XASH_AMD64 XASH_ARCHITECTURE) +check_group_build_target(XASH_ARM XASH_ARCHITECTURE) +check_group_build_target(XASH_MIPS XASH_ARCHITECTURE) +check_group_build_target(XASH_PPC XASH_ARCHITECTURE) +check_group_build_target(XASH_JS XASH_ARCHITECTURE) +check_group_build_target(XASH_E2K XASH_ARCHITECTURE) +check_group_build_target(XASH_RISCV XASH_ARCHITECTURE) +check_group_build_target(XASH_LITTLE_ENDIAN XASH_ENDIANNESS) +check_group_build_target(XASH_BIG_ENDIAN XASH_ENDIANNESS) +if(XASH_ARM) +check_build_target(XASH_ARM_HARDFP) +check_build_target(XASH_ARM_SOFTFP) +check_build_target(XASH_ARMv4) +check_build_target(XASH_ARMv5) +check_build_target(XASH_ARMv6) +check_build_target(XASH_ARMv7) +check_build_target(XASH_ARMv8) +endif() +if(XASH_RISCV) +check_build_target(XASH_RISCV_DOUBLEFP) +check_build_target(XASH_RISCV_SINGLEFP) +check_build_target(XASH_RISCV_SOFTFP) +endif() +unset(CMAKE_REQUIRED_INCLUDES) + +# engine/common/build.c +if(XASH_ANDROID) + set(BUILDOS "android") +elseif(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE) + set(BUILDOS "") # no prefix for default OS +elseif(XASH_FREEBSD) + set(BUILDOS "freebsd") +elseif(XASH_NETBSD) + set(BUILDOS "netbsd") +elseif(XASH_OPENBSD) + set(BUILDOS "openbsd") +elseif(XASH_EMSCRIPTEN) + set(BUILDOS "emscripten") +elseif(XASH_DOS4GW) + set(BUILDOS "DOS4GW") +elseif(XASH_HAIKU) + set(BUILDOS "haiku") +elseif(XASH_SERENITY) + set(BUILDOS "serenityos") +elseif(XASH_NSWITCH) + set(BUILDOS "nswitch") +elseif(XASH_PSVITA) + set(BUILDOS "psvita") +elseif(XASH_IRIX) + set(BUILDOS "irix") +elseif(XASH_WASI) + set(BUILDOS "wasi") +elseif(XASH_SUNOS) + set(BUILDOS "sunos") +else() + message(SEND_ERROR "Place your operating system name here! If this is a mistake, try to fix conditions above and report a bug") +endif() + +if(XASH_AMD64) + set(BUILDARCH "amd64") +elseif(XASH_X86) + if(XASH_WIN32 OR XASH_LINUX OR XASH_APPLE) + set(BUILDARCH "") # no prefix for default OS + else() + set(BUILDARCH "i386") + endif() +elseif(XASH_ARM AND XASH_64BIT) + set(BUILDARCH "arm64") +elseif(XASH_ARM) + set(BUILDARCH "armv") + if(XASH_ARMv8) + set(BUILDARCH "${BUILDARCH}8_32") + elseif(XASH_ARMv7) + set(BUILDARCH "${BUILDARCH}7") + elseif(XASH_ARMv6) + set(BUILDARCH "${BUILDARCH}6") + elseif(XASH_ARMv5) + set(BUILDARCH "${BUILDARCH}5") + elseif(XASH_ARMv4) + set(BUILDARCH "${BUILDARCH}4") + else() + message(SEND_ERROR "Unknown ARM") + endif() + + if(XASH_ARM_HARDFP) + set(BUILDARCH "${BUILDARCH}hf") + else() + set(BUILDARCH "${BUILDARCH}l") + endif() +elseif(XASH_MIPS) + set(BUILDARCH "mips") + if(XASH_64BIT) + set(BUILDARCH "${BUILDARCH}64") + endif() + + if(XASH_LITTLE_ENDIAN) + set(BUILDARCH "${BUILDARCH}el") + endif() +elseif(XASH_RISCV) + set(BUILDARCH "riscv") + if(XASH_64BIT) + set(BUILDARCH "${BUILDARCH}64") + else() + set(BUILDARCH "${BUILDARCH}32") + endif() + + if(XASH_RISCV_DOUBLEFP) + set(BUILDARCH "${BUILDARCH}d") + elseif(XASH_RISCV_SINGLEFP) + set(BUILDARCH "${BUILDARCH}f") + endif() +elseif(XASH_JS) + set(BUILDARCH "javascript") +elseif(XASH_E2K) + set(BUILDARCH "e2k") +elseif(XASH_PPC) + set(BUILDARCH "ppc") + if(XASH_64BIT) + set(BUILDARCH "${BUILDARCH}64") + endif() + + if(XASH_LITTLE_ENDIAN) + set(BUILDARCH "${BUILDARCH}el") + endif() +else() + message(SEND_ERROR "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug") +endif() + +if(BUILDOS STREQUAL "android") + set(POSTFIX "") # force disable for Android, as Android ports aren't distributed in normal way and doesn't follow library naming +elseif(BUILDOS AND BUILDARCH) + set(POSTFIX "_${BUILDOS}_${BUILDARCH}") +elseif(BUILDARCH) + set(POSTFIX "_${BUILDARCH}") +else() + set(POSTFIX "") +endif() + +message(STATUS "Library postfix: " ${POSTFIX}) diff --git a/regamedll/dlls/qstring.h b/regamedll/dlls/qstring.h index 0b158292..1f5d679d 100644 --- a/regamedll/dlls/qstring.h +++ b/regamedll/dlls/qstring.h @@ -30,16 +30,18 @@ #define QSTRING_DEFINE -constexpr unsigned int iStringNull = {0}; - // Quake string (helper class) class QString final { public: +#if XASH_64BIT + using qstring_t = int; +#else using qstring_t = unsigned int; +#endif - QString(): m_string(iStringNull) {}; - QString(qstring_t string): m_string(string) {}; + QString(); + QString(qstring_t string); bool IsNull() const; bool IsNullOrEmpty() const; @@ -52,13 +54,15 @@ public: bool operator==(const char *pszString) const; operator const char *() const; - operator unsigned int() const; + operator qstring_t() const; const char *str() const; private: qstring_t m_string; }; +constexpr QString::qstring_t iStringNull = {0}; + #ifdef USE_QSTRING #define string_t QString #endif @@ -70,10 +74,25 @@ private: extern globalvars_t *gpGlobals; -#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (unsigned int)(offset))) -#define MAKE_STRING(str) ((unsigned int)(str) - (unsigned int)(STRING(0))) +#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (QString::qstring_t)(offset))) +#if XASH_64BIT +// Xash3D FWGS in 64-bit mode has internal string pool which allows mods to continue use 32-bit string_t +inline int MAKE_STRING(const char *str) +{ + ptrdiff_t diff = str - STRING(0); + if (diff >= INT_MIN && diff <= INT_MAX) + return (int)diff; + + return ALLOC_STRING(str); +} +#else +#define MAKE_STRING(str) ((QString::qstring_t)(str) - (QString::qstring_t)(STRING(0))) +#endif // Inlines +inline QString::QString(): m_string(iStringNull) {} +inline QString::QString(qstring_t string): m_string(string) {} + inline bool QString::IsNull() const { return m_string == iStringNull; @@ -115,7 +134,7 @@ inline QString::operator const char *() const return str(); } -inline QString::operator unsigned int() const +inline QString::operator qstring_t() const { return m_string; } diff --git a/regamedll/public/build.h b/regamedll/public/build.h new file mode 100644 index 00000000..24fd9d5b --- /dev/null +++ b/regamedll/public/build.h @@ -0,0 +1,269 @@ +/* +build.h - compile-time build information + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +*/ +#pragma once +#ifndef BUILD_H +#define BUILD_H + +/* +All XASH_* macros set by this header are guaranteed to have positive value +otherwise not defined. + +Every macro is intended to be the unified interface for buildsystems that lack +platform & CPU detection, and a neat quick way for checks in platform code +For Q_build* macros, refer to buildenums.h + +Any new define must be undefined at first +You can generate #undef list below with this oneliner: + $ sed 's/\t//g' build.h | grep '^#define XASH' | awk '{ print $2 }' | \ + sort | uniq | awk '{ print "#undef " $1 }' + +Then you can use another oneliner to query all variables: + $ grep '^#undef XASH' build.h | awk '{ print $2 }' +*/ + +#undef XASH_64BIT +#undef XASH_AMD64 +#undef XASH_ANDROID +#undef XASH_APPLE +#undef XASH_ARM +#undef XASH_ARM_HARDFP +#undef XASH_ARM_SOFTFP +#undef XASH_ARMv4 +#undef XASH_ARMv5 +#undef XASH_ARMv6 +#undef XASH_ARMv7 +#undef XASH_ARMv8 +#undef XASH_BIG_ENDIAN +#undef XASH_DOS4GW +#undef XASH_E2K +#undef XASH_EMSCRIPTEN +#undef XASH_FREEBSD +#undef XASH_HAIKU +#undef XASH_IOS +#undef XASH_IRIX +#undef XASH_JS +#undef XASH_LINUX +#undef XASH_LITTLE_ENDIAN +#undef XASH_MIPS +#undef XASH_MOBILE_PLATFORM +#undef XASH_NETBSD +#undef XASH_OPENBSD +#undef XASH_POSIX +#undef XASH_PPC +#undef XASH_RISCV +#undef XASH_RISCV_DOUBLEFP +#undef XASH_RISCV_SINGLEFP +#undef XASH_RISCV_SOFTFP +#undef XASH_SERENITY +#undef XASH_SUNOS +#undef XASH_WIN32 +#undef XASH_X86 +#undef XASH_NSWITCH +#undef XASH_PSVITA +#undef XASH_WASI +#undef XASH_WASM + +//================================================================ +// +// PLATFORM DETECTION CODE +// +//================================================================ +#if defined _WIN32 + #define XASH_WIN32 1 +#elif defined __EMSCRIPTEN__ + #define XASH_EMSCRIPTEN 1 +#elif defined __WATCOMC__ && defined __DOS__ + #define XASH_DOS4GW 1 +#else // POSIX compatible + #define XASH_POSIX 1 + #if defined __linux__ + #if defined __ANDROID__ + #define XASH_ANDROID 1 + #endif + #define XASH_LINUX 1 + #elif defined __FreeBSD__ + #define XASH_FREEBSD 1 + #elif defined __NetBSD__ + #define XASH_NETBSD 1 + #elif defined __OpenBSD__ + #define XASH_OPENBSD 1 + #elif defined __HAIKU__ + #define XASH_HAIKU 1 + #elif defined __serenity__ + #define XASH_SERENITY 1 + #elif defined __sgi + #define XASH_IRIX 1 + #elif defined __APPLE__ + #include + #define XASH_APPLE 1 + #if TARGET_OS_IOS + #define XASH_IOS 1 + #endif // TARGET_OS_IOS + #elif defined __SWITCH__ + #define XASH_NSWITCH 1 + #elif defined __vita__ + #define XASH_PSVITA 1 + #elif defined __wasi__ + #define XASH_WASI 1 + #elif defined __sun__ + #define XASH_SUNOS 1 + #else + #error + #endif +#endif + +// XASH_SAILFISH is special: SailfishOS by itself is a normal GNU/Linux platform +// It doesn't make sense to split it to separate platform +// but we still need XASH_MOBILE_PLATFORM for the engine. +// So this macro is defined entirely in build-system: see main wscript +// HLSDK/PrimeXT/other SDKs users note: you may ignore this macro +#if XASH_ANDROID || XASH_IOS || XASH_NSWITCH || XASH_PSVITA || XASH_SAILFISH + #define XASH_MOBILE_PLATFORM 1 +#endif + +//================================================================ +// +// ENDIANNESS DEFINES +// +//================================================================ + +#if !defined XASH_ENDIANNESS + #if defined XASH_WIN32 || __LITTLE_ENDIAN__ + //!!! Probably all WinNT installations runs in little endian + #define XASH_LITTLE_ENDIAN 1 + #elif __BIG_ENDIAN__ + #define XASH_BIG_ENDIAN 1 + #elif defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ && defined __ORDER_LITTLE_ENDIAN__ // some compilers define this + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define XASH_BIG_ENDIAN 1 + #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #define XASH_LITTLE_ENDIAN 1 + #endif + #else + #include + #if __BYTE_ORDER == __BIG_ENDIAN + #define XASH_BIG_ENDIAN 1 + #elif __BYTE_ORDER == __LITTLE_ENDIAN + #define XASH_LITTLE_ENDIAN 1 + #endif + #endif // !XASH_WIN32 +#endif + +//================================================================ +// +// CPU ARCHITECTURE DEFINES +// +//================================================================ +#if defined __x86_64__ || defined _M_X64 + #define XASH_64BIT 1 + #define XASH_AMD64 1 +#elif defined __i386__ || defined _X86_ || defined _M_IX86 + #define XASH_X86 1 +#elif defined __aarch64__ || defined _M_ARM64 + #define XASH_64BIT 1 + #define XASH_ARM 8 +#elif defined __mips__ + #define XASH_MIPS 1 +#elif defined __EMSCRIPTEN__ + #define XASH_JS 1 +#elif defined __e2k__ + #define XASH_64BIT 1 + #define XASH_E2K 1 +#elif defined __PPC__ || defined __powerpc__ + #define XASH_PPC 1 + #if defined __PPC64__ || defined __powerpc64__ + #define XASH_64BIT 1 + #endif +#elif defined _M_ARM // msvc + #define XASH_ARM 7 + #define XASH_ARM_HARDFP 1 +#elif defined __arm__ + #if __ARM_ARCH == 8 || __ARM_ARCH_8__ + #define XASH_ARM 8 + #elif __ARM_ARCH == 7 || __ARM_ARCH_7__ + #define XASH_ARM 7 + #elif __ARM_ARCH == 6 || __ARM_ARCH_6__ || __ARM_ARCH_6J__ + #define XASH_ARM 6 + #elif __ARM_ARCH == 5 || __ARM_ARCH_5__ + #define XASH_ARM 5 + #elif __ARM_ARCH == 4 || __ARM_ARCH_4__ + #define XASH_ARM 4 + #else + #error "Unknown ARM" + #endif + + #if defined __SOFTFP__ || __ARM_PCS_VFP == 0 + #define XASH_ARM_SOFTFP 1 + #else // __SOFTFP__ + #define XASH_ARM_HARDFP 1 + #endif // __SOFTFP__ +#elif defined __riscv + #define XASH_RISCV 1 + + #if __riscv_xlen == 64 + #define XASH_64BIT 1 + #elif __riscv_xlen != 32 + #error "Unknown RISC-V ABI" + #endif + + #if defined __riscv_float_abi_soft + #define XASH_RISCV_SOFTFP 1 + #elif defined __riscv_float_abi_single + #define XASH_RISCV_SINGLEFP 1 + #elif defined __riscv_float_abi_double + #define XASH_RISCV_DOUBLEFP 1 + #else + #error "Unknown RISC-V float ABI" + #endif +#elif defined __wasm__ + #if defined __wasm64__ + #define XASH_64BIT 1 + #endif + #define XASH_WASM 1 +#else + #error "Place your architecture name here! If this is a mistake, try to fix conditions above and report a bug" +#endif + +#if !XASH_64BIT && ( defined( __LP64__ ) || defined( _LP64 )) +#define XASH_64BIT 1 +#endif + +#if XASH_ARM == 8 + #define XASH_ARMv8 1 +#elif XASH_ARM == 7 + #define XASH_ARMv7 1 +#elif XASH_ARM == 6 + #define XASH_ARMv6 1 +#elif XASH_ARM == 5 + #define XASH_ARMv5 1 +#elif XASH_ARM == 4 + #define XASH_ARMv4 1 +#endif + +#endif // BUILD_H