cmake: detect CPU architecture in 1 compilation

This commit is contained in:
Anonymous Maarten
2024-05-26 22:40:47 +02:00
parent 3af4f120d0
commit bba76859f5
8 changed files with 209 additions and 154 deletions

View File

@@ -1,48 +0,0 @@
include(CheckCSourceCompiles)
include(CMakePushCheckState)
function(_internal_check_cpu_architecture macro_check NAME VARIABLE)
cmake_push_check_state()
string(TOUPPER "${NAME}" UPPER_NAME)
set(CACHE_VARIABLE "CHECK_CPU_ARCHITECTURE_${UPPER_NAME}")
set(test_src "
int main(int argc, char *argv[]) {
#if ${macro_check}
return 0;
#else
choke
#endif
}
")
check_c_source_compiles("${test_src}" "${CACHE_VARIABLE}")
cmake_pop_check_state()
if(${CACHE_VARIABLE})
set(${VARIABLE} "TRUE" PARENT_SCOPE)
else()
set(${VARIABLE} "FALSE" PARENT_SCOPE)
endif()
endfunction()
function(check_cpu_architecture ARCH VARIABLE)
if(ARCH STREQUAL "x86")
_internal_check_cpu_architecture("defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)" x86 ${VARIABLE})
elseif(ARCH STREQUAL "x64")
_internal_check_cpu_architecture("defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)" x64 ${VARIABLE})
elseif(ARCH STREQUAL "arm32")
_internal_check_cpu_architecture("defined(__arm__) || defined(_M_ARM)" arm32 ${VARIABLE})
elseif(ARCH STREQUAL "arm64")
_internal_check_cpu_architecture("defined(__aarch64__) || defined(_M_ARM64)" arm64 ${VARIABLE})
elseif(ARCH STREQUAL "loongarch64")
_internal_check_cpu_architecture("defined(__loongarch64)" loongarch64 ${VARIABLE})
elseif(ARCH STREQUAL "emscripten")
_internal_check_cpu_architecture("defined(__EMSCRIPTEN__)" emscripten ${VARIABLE})
elseif(ARCH STREQUAL "powerpc64")
_internal_check_cpu_architecture("defined(__PPC64__) || defined(__powerpc64__)" powerpc64 ${VARIABLE})
elseif(ARCH STREQUAL "powerpc32")
_internal_check_cpu_architecture("(defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)" powerpc32 ${VARIABLE})
else()
message(WARNING "Unknown CPU architectures (${ARCH}).")
set("${VARIABLE}" FALSE)
endif()
set("${VARIABLE}" "${${VARIABLE}}" PARENT_SCOPE)
endfunction()

149
cmake/sdlcpu.cmake Normal file
View File

@@ -0,0 +1,149 @@
function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS)
set(DETECTABLE_ARCHS ARM32 ARM64 EMSCRIPTEN LOONGARCH64 POWERPC32 POWERPC64 X86 X64)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(arch IN LISTS DETECTABLE_ARCHS)
set(SDL_CPU_${arch} "0")
endforeach()
set(detected_archs)
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
if(osx_arch STREQUAL "x86_64")
set(SDL_CPU_X64 "1")
list(APPEND detected_archs "X64")
elseif(osx_arch STREQUAL "arm64")
set(SDL_CPU_ARM64 "1")
list(APPEND detected_archs "ARM64")
endif()
endforeach()
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
return()
endif()
set(detected_archs)
foreach(arch IN LISTS DETECTABLE_ARCHS)
if(SDL_CPU_${arch})
list(APPEND detected_archs "${arch}")
endif()
endforeach()
if(detected_archs)
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
return()
endif()
set(src_arch_detect [=====[
#if defined(__arm__) || defined(_M_ARM)
#define ARCH_ARM32 "1"
#else
#define ARCH_ARM32 "0"
#endif
const char *arch_arm32 = "INFO<ARM32=" ARCH_ARM32 ">";
#if defined(__aarch64__) || defined(_M_ARM64)
#define ARCH_ARM64 "1"
#else
#define ARCH_ARM64 "0"
#endif
const char *arch_arm64 = "INFO<ARM64=" ARCH_ARM64 ">";
#if defined(__EMSCRIPTEN__)
#define ARCH_EMSCRIPTEN "1"
#else
#define ARCH_EMSCRIPTEN "0"
#endif
const char *arch_emscripten = "INFO<EMSCRIPTEN=" ARCH_EMSCRIPTEN ">";
#if defined(__loongarch64)
#define ARCH_LOONGARCH64 "1"
#else
#define ARCH_LOONGARCH64 "0"
#endif
const char *arch_loongarch64 = "INFO<LOONGARCH64=" ARCH_LOONGARCH64 ">";
#if (defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)
#define ARCH_POWERPC32 "1"
#else
#define ARCH_POWERPC32 "0"
#endif
const char *arch_powerpc32 = "INFO<ARCH_POWERPC32=" ARCH_POWERPC32 ">";
#if defined(__PPC64__) || defined(__powerpc64__)
#define ARCH_POWERPC64 "1"
#else
#define ARCH_POWERPC64 "0"
#endif
const char *arch_powerpc64 = "INFO<POWERPC64=" ARCH_POWERPC64 ">";
#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)
#define ARCH_X86 "1"
#else
#define ARCH_X86 "0"
#endif
const char *arch_x86 = "INFO<X86=" ARCH_X86 ">";
#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
#define ARCH_X64 "1"
#else
#define ARCH_X64 "0"
#endif
const char *arch_x64 = "INFO<X64=" ARCH_X64 ">";
int main(int argc, char *argv[]) {
(void) argv;
int result = argc;
result += arch_arm32[argc];
result += arch_arm64[argc];
result += arch_emscripten[argc];
result += arch_loongarch64[argc];
result += arch_powerpc32[argc];
result += arch_powerpc64[argc];
result += arch_x86[argc];
result += arch_x64[argc];
return result;
}
]=====])
set(path_src_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch.c")
file(WRITE "${path_src_arch_detect}" "${src_arch_detect}")
set(path_dir_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch")
set(path_bin_arch_detect "${path_dir_arch_detect}/bin")
set(msg "Detecting Target CPU Architecture")
message(STATUS "${msg}")
try_compile(COMPILED_RES
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch"
SOURCES "${path_src_arch_detect}"
COPY_FILE "${path_bin_arch_detect}"
)
if(NOT COMPILED_RES)
message(STATUS "${msg} - <ERROR>")
message(WARNING "Failed to compile source detecting the target CPU architecture")
endif()
set(re "INFO<([A-Z0-9]+)=([01])>")
file(STRINGS "${path_bin_arch_detect}" infos REGEX "${re}")
set(detected_archs)
foreach(info_arch_01 IN LISTS infos)
string(REGEX MATCH "${re}" A "${info_arch_01}")
if(NOT "${CMAKE_MATCH_1}" IN_LIST DETECTABLE_ARCHS)
message(WARNING "Unknown architecture: \"${CMAKE_MATCH_1}\"")
continue()
endif()
set(arch "${CMAKE_MATCH_1}")
set(arch_01 "${CMAKE_MATCH_2}")
if(arch_01)
list(APPEND detected_archs "${arch}")
endif()
set("SDL_CPU_${arch}" "${arch_01}" CACHE BOOL "Detected architecture ${arch}")
endforeach()
message(STATUS "${msg} - ${detected_archs}")
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
endfunction()

View File

@@ -1,110 +1,70 @@
macro(SDL_DetectCMakePlatform)
set(SDL_CMAKE_PLATFORM )
# Get the platform
function(SDL_DetectCMakePlatform)
set(sdl_cmake_platform )
if(WIN32)
set(SDL_CMAKE_PLATFORM Windows)
set(sdl_cmake_platform Windows)
elseif(PSP)
set(SDL_CMAKE_PLATFORM psp)
set(sdl_cmake_platform psp)
elseif(APPLE)
if(CMAKE_SYSTEM_NAME MATCHES ".*(Darwin|MacOS).*")
set(SDL_CMAKE_PLATFORM macOS)
set(sdl_cmake_platform macOS)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*tvOS.*")
set(SDL_CMAKE_PLATFORM tvOS)
set(sdl_cmake_platform tvOS)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*iOS.*")
set(SDL_CMAKE_PLATFORM iOS)
set(sdl_cmake_platform iOS)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*watchOS.*")
set(SDL_CMAKE_PLATFORM watchOS)
set(sdl_cmake_platform watchOS)
elseif (CMAKE_SYSTEM_NAME MATCHES "visionOS")
set(SDL_CMAKE_PLATFORM visionOS)
set(sdl_cmake_platform visionOS)
else()
message(WARNING "Unknown Apple platform: \"${CMAKE_SYSTEM_NAME}\"")
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Haiku.*")
set(SDL_CMAKE_PLATFORM Haiku)
set(sdl_cmake_platform Haiku)
elseif(NINTENDO_3DS)
set(SDL_CMAKE_PLATFORM n3ds)
set(sdl_cmake_platform n3ds)
elseif(PS2)
set(SDL_CMAKE_PLATFORM ps2)
set(sdl_cmake_platform ps2)
elseif(VITA)
set(SDL_CMAKE_PLATFORM Vita)
set(sdl_cmake_platform Vita)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*Linux")
set(SDL_CMAKE_PLATFORM Linux)
set(sdl_cmake_platform Linux)
elseif(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD.*")
set(SDL_CMAKE_PLATFORM FreeBSD)
set(sdl_cmake_platform FreeBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES "kNetBSD.*|NetBSD.*")
set(SDL_CMAKE_PLATFORM NetBSD)
set(sdl_cmake_platform NetBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*")
set(SDL_CMAKE_PLATFORM OpenBSD)
set(sdl_cmake_platform OpenBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*GNU.*")
set(SDL_CMAKE_PLATFORM GNU)
set(sdl_cmake_platform GNU)
elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
set(SDL_CMAKE_PLATFORM BSDi)
set(sdl_cmake_platform BSDi)
elseif(CMAKE_SYSTEM_NAME MATCHES "DragonFly.*|FreeBSD")
set(SDL_CMAKE_PLATFORM FreeBSD)
set(sdl_cmake_platform FreeBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES "SYSV5.*")
set(SDL_CMAKE_PLATFORM SYSV5)
set(sdl_cmake_platform SYSV5)
elseif(CMAKE_SYSTEM_NAME MATCHES "Solaris.*|SunOS.*")
set(SDL_CMAKE_PLATFORM Solaris)
set(sdl_cmake_platform Solaris)
elseif(CMAKE_SYSTEM_NAME MATCHES "HP-UX.*")
set(SDL_CMAKE_PLATFORM HPUX)
set(sdl_cmake_platform HPUX)
elseif(CMAKE_SYSTEM_NAME MATCHES "AIX.*")
set(SDL_CMAKE_PLATFORM AIX)
set(sdl_cmake_platform AIX)
elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
set(SDL_CMAKE_PLATFORM Minix)
set(sdl_cmake_platform Minix)
elseif(CMAKE_SYSTEM_NAME MATCHES "Android.*")
set(SDL_CMAKE_PLATFORM Android)
set(sdl_cmake_platform Android)
elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten.*")
set(SDL_CMAKE_PLATFORM Emscripten)
set(sdl_cmake_platform Emscripten)
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX.*")
set(SDL_CMAKE_PLATFORM QNX)
set(sdl_cmake_platform QNX)
elseif(CMAKE_SYSTEM_NAME MATCHES "BeOS.*")
message(FATAL_ERROR "BeOS support has been removed as of SDL 2.0.2.")
endif()
if(SDL_CMAKE_PLATFORM)
string(TOUPPER "${SDL_CMAKE_PLATFORM}" _upper_platform)
set(${_upper_platform} TRUE)
if(sdl_cmake_platform)
string(TOUPPER "${sdl_cmake_platform}" _upper_platform)
set("${_upper_platform}" TRUE PARENT_SCOPE)
else()
set(SDL_CMAKE_PLATFORM "unknown")
set(sdl_cmake_platform "unknown")
endif()
endmacro()
function(SDL_DetectCPUArchitecture)
set(sdl_cpu_names)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if(osx_arch STREQUAL "x86_64")
list(APPEND sdl_cpu_names "x64")
elseif(osx_arch STREQUAL "arm64")
list(APPEND sdl_cpu_names "arm64")
endif()
endforeach()
endif()
set(sdl_known_archs x64 x86 arm64 arm32 emscripten powerpc64 powerpc32 loongarch64)
if(NOT sdl_cpu_names)
set(found FALSE)
foreach(sdl_known_arch ${sdl_known_archs})
if(NOT found)
string(TOUPPER "${sdl_known_arch}" sdl_known_arch_upper)
set(var_name "SDL_CPU_${sdl_known_arch_upper}")
check_cpu_architecture(${sdl_known_arch} ${var_name})
if(${var_name})
list(APPEND sdl_cpu_names ${sdl_known_arch})
set(found TRUE)
endif()
endif()
endforeach()
endif()
foreach(sdl_known_arch ${sdl_known_archs})
string(TOUPPER "${sdl_known_arch}" sdl_known_arch_upper)
set(var_name "SDL_CPU_${sdl_known_arch_upper}")
if(sdl_cpu_names MATCHES "(^|;)${sdl_known_arch}($|;)") # FIXME: use if(IN_LIST)
set(${var_name} 1 PARENT_SCOPE)
else()
set(${var_name} 0 PARENT_SCOPE)
endif()
endforeach()
set(SDL_CPU_NAMES ${sdl_cpu_names} PARENT_SCOPE)
set(SDL_CMAKE_PLATFORM "${sdl_cmake_platform}" PARENT_SCOPE)
endfunction()