From 4b0f52b04e0038e72026d842bd2310f278cc2499 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 30 May 2024 20:45:14 +0200 Subject: [PATCH] cmake: fall back to per-cpu test when all-in-one test fails The 'all-in-one' test fails for Emscripten because try_compile does not copy back the actual binary: the wasm file contains the machine parseable strings, not the html or js file(s). --- cmake/sdlcpu.cmake | 196 ++++++++++++++++++++++----------------------- 1 file changed, 96 insertions(+), 100 deletions(-) diff --git a/cmake/sdlcpu.cmake b/cmake/sdlcpu.cmake index fbaa0f389d..3c22b2782c 100644 --- a/cmake/sdlcpu.cmake +++ b/cmake/sdlcpu.cmake @@ -1,10 +1,10 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS) - set(DETECTABLE_ARCHS ARM32 ARM64 EMSCRIPTEN LOONGARCH64 POWERPC32 POWERPC64 X86 X64) + set(known_archs EMSCRIPTEN ARM32 ARM64 LOONGARCH64 POWERPC32 POWERPC64 X86 X64) if(APPLE AND CMAKE_OSX_ARCHITECTURES) - foreach(arch IN LISTS DETECTABLE_ARCHS) - set(SDL_CPU_${arch} "0") + foreach(known_arch IN LISTS known_archs) + set(SDL_CPU_${known_arch} "0") endforeach() set(detected_archs) foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES) @@ -21,9 +21,9 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS) endif() set(detected_archs) - foreach(arch IN LISTS DETECTABLE_ARCHS) - if(SDL_CPU_${arch}) - list(APPEND detected_archs "${arch}") + foreach(known_arch IN LISTS known_archs) + if(SDL_CPU_${known_arch}) + list(APPEND detected_archs "${known_arch}") endif() endforeach() @@ -32,118 +32,114 @@ function(SDL_DetectTargetCPUArchitectures DETECTED_ARCHS) return() endif() - set(src_arch_detect [=====[ + set(arch_check_ARM32 "defined(__arm__) || defined(_M_ARM)") + set(arch_check_ARM64 "defined(__aarch64__) || defined(_M_ARM64)") + set(arch_check_EMSCRIPTEN "defined(__EMSCRIPTEN__)") + set(arch_check_LOONGARCH64 "defined(__loongarch64)") + set(arch_check_POWERPC32 "(defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)") + set(arch_check_POWERPC64 "defined(__PPC64__) || defined(__powerpc64__)") + set(arch_check_X86 "defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)") + set(arch_check_X64 "defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)") -#if defined(__arm__) || defined(_M_ARM) -#define ARCH_ARM32 "1" + set(src_vars "") + set(src_main "") + foreach(known_arch IN LISTS known_archs) + set(detected_${known_arch} "0") + + string(APPEND src_vars " +#if ${arch_check_${known_arch}} +#define ARCH_${known_arch} \"1\" #else -#define ARCH_ARM32 "0" +#define ARCH_${known_arch} \"0\" #endif -const char *arch_arm32 = "INFO"; - -#if defined(__aarch64__) || defined(_M_ARM64) -#define ARCH_ARM64 "1" -#else -#define ARCH_ARM64 "0" -#endif -const char *arch_arm64 = "INFO"; - -#if defined(__EMSCRIPTEN__) -#define ARCH_EMSCRIPTEN "1" -#else -#define ARCH_EMSCRIPTEN "0" -#endif -const char *arch_emscripten = "INFO"; - -#if defined(__loongarch64) -#define ARCH_LOONGARCH64 "1" -#else -#define ARCH_LOONGARCH64 "0" -#endif -const char *arch_loongarch64 = "INFO"; - -#if (defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__) -#define ARCH_POWERPC32 "1" -#else -#define ARCH_POWERPC32 "0" -#endif -const char *arch_powerpc32 = "INFO"; - -#if defined(__PPC64__) || defined(__powerpc64__) -#define ARCH_POWERPC64 "1" -#else -#define ARCH_POWERPC64 "0" -#endif -const char *arch_powerpc64 = "INFO"; - -#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"; - -#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"; +const char *arch_${known_arch} = \"INFO<${known_arch}=\" ARCH_${known_arch} \">\"; +") + string(APPEND src_main " + result += arch_${known_arch}[argc];") + endforeach() + set(src_arch_detect "${src_vars} 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]; + (void)argv; + int result = 0; +${src_main} 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(detected_archs) + 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) + include(CMakePushCheckState) + + cmake_push_check_state(RESET) + try_compile(SDL_CPU_CHECK_ALL + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/SDL_detect_arch" + SOURCES "${path_src_arch_detect}" + COPY_FILE "${path_bin_arch_detect}" + ) + cmake_pop_check_state() + if(NOT SDL_CPU_CHECK_ALL) message(STATUS "${msg} - ") message(WARNING "Failed to compile source detecting the target CPU architecture") + else() + set(re "INFO<([A-Z0-9]+)=([01])>") + file(STRINGS "${path_bin_arch_detect}" infos REGEX "${re}") + + foreach(info_arch_01 IN LISTS infos) + string(REGEX MATCH "${re}" A "${info_arch_01}") + if(NOT "${CMAKE_MATCH_1}" IN_LIST known_archs) + message(WARNING "Unknown architecture: \"${CMAKE_MATCH_1}\"") + continue() + endif() + set(arch "${CMAKE_MATCH_1}") + set(arch_01 "${CMAKE_MATCH_2}") + set(detected_${arch} "${arch_01}") + endforeach() + + foreach(known_arch IN LISTS known_archs) + if(detected_${known_arch}) + list(APPEND detected_archs ${known_arch}) + endif() + endforeach() 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}") - + if(detected_archs) + foreach(known_arch IN LISTS known_archs) + set("SDL_CPU_${known_arch}" "${detected_${known_arch}}" CACHE BOOL "Detected architecture ${known_arch}") + endforeach() + message(STATUS "${msg} - ${detected_archs}") + else() + include(CheckCSourceCompiles) + cmake_push_check_state(RESET) + foreach(known_arch IN LISTS known_archs) + if(NOT detected_archs) + set(cache_variable "SDL_CPU_${known_arch}") + set(test_src " + int main(int argc, char *argv[]) { + #if ${arch_check_${known_arch}} + return 0; + #else + choke + #endif + } + ") + check_c_source_compiles("${test_src}" "${cache_variable}") + if(${cache_variable}) + set(SDL_CPU_${known_arch} "1" CACHE BOOL "Detected architecture ${known_arch}") + set(detected_archs ${known_arch}) + else() + set(SDL_CPU_${known_arch} "0" CACHE BOOL "Detected architecture ${known_arch}") + endif() + endif() + endforeach() + cmake_pop_check_state() + endif() set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE) - endfunction()