From c817eadcc43bff91b56f8e032f1dcaeb76974788 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 2 Jan 2023 15:26:46 +0000 Subject: [PATCH] Add Android support. Convert line endings --- cmake/Modules/DetectArchitecture.cmake | 441 +++++++++++++------------ 1 file changed, 221 insertions(+), 220 deletions(-) diff --git a/cmake/Modules/DetectArchitecture.cmake b/cmake/Modules/DetectArchitecture.cmake index 73eecef96..024b3a53f 100644 --- a/cmake/Modules/DetectArchitecture.cmake +++ b/cmake/Modules/DetectArchitecture.cmake @@ -1,220 +1,221 @@ -include_guard(GLOBAL) - -include(CheckCXXCompilerFlag) -include(CheckSymbolExists) -include(CMakePushCheckState) - -# Detect current compilation architecture and create standard definitions -macro(detect_architecture symbol arch) - if (NOT DEFINED ARCHITECTURE) - check_symbol_exists("${symbol}" "" ARCHITECTURE_${arch}) - - if (ARCHITECTURE_${arch}) - set(ARCHITECTURE ${arch}) - set(ARCHITECTURE_${arch} TRUE) - add_compile_definitions(ARCHITECTURE_${arch}) - endif() - endif() -endmacro() - -macro(force_ext_available extension) - message(STATUS "Looking for __${extension}__ - forced found") - set(HAS_${extension} 1 CACHE INTERNAL "") -endmacro() - -function(detect_extensions extension) - unset(HAS_${extension}) - if (ARGC EQUAL 2 AND (${ARGV1})) # force available - force_ext_available(${extension}) - endif() - check_symbol_exists("__${extension}__" "" HAS_${extension}) - if (HAS_${extension}) - add_compile_definitions(USE_${extension}) - endif() -endfunction() - -function(detect_msvc_native_opt) - set(TEST_DIR ${PROJECT_SOURCE_DIR}/cmake/test) - - try_run(RUN_AVX512 COMPILE_AVX512 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx512.cxx" COMPILE_DEFINITIONS /arch:AVX512) - if (COMPILE_AVX512 AND RUN_AVX512 EQUAL 0) - set(ARCH_OPT "AVX512" PARENT_SCOPE) - return() - endif() - try_run(RUN_AVX2 COMPILE_AVX2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx2.cxx" COMPILE_DEFINITIONS /arch:AVX2) - if (COMPILE_AVX2 AND RUN_AVX2 EQUAL 0) - set(ARCH_OPT "AVX2" PARENT_SCOPE) - return() - endif() - try_run(RUN_AVX COMPILE_AVX "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx.cxx" COMPILE_DEFINITIONS /arch:AVX) - if (COMPILE_AVX AND RUN_AVX EQUAL 0) - set(ARCH_OPT "AVX" PARENT_SCOPE) - return() - endif() - - # Supporting 32-bit x86, what year is it? - set(COMPILE_DEF "") - set(ARCH_OPT "" PARENT_SCOPE) - if (ARCHITECTURE_x86) - set(COMPILE_DEF "/arch:SSE2") - set(ARCH_OPT "SSE2" PARENT_SCOPE) - endif() - - try_run(RUN_SSE42 COMPILE_SSE42 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse42.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) - if (COMPILE_SSE42 AND RUN_SSE42 EQUAL 0) - force_ext_available(SSE4_2) - return() - endif() - try_run(RUN_SSE41 COMPILE_SSE41 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse41.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) - if (COMPILE_SSE41 AND RUN_SSE41 EQUAL 0) - force_ext_available(SSE4_1) - return() - endif() - try_run(RUN_SSSE3 COMPILE_SSSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_ssse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) - if (COMPILE_SSSE3 AND RUN_SSSE3 EQUAL 0) - force_ext_available(SSSE3) - return() - endif() - try_run(RUN_SSE3 COMPILE_SSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) - if (COMPILE_SSE3 AND RUN_SSE3 EQUAL 0) - force_ext_available(SSE3) - return() - endif() - try_run(RUN_SSE2 COMPILE_SSE2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse2.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) - if (COMPILE_SSE2 AND RUN_SSE2 EQUAL 0) - force_ext_available(SSE2) - return() - endif() - - if (ARCHITECTURE_x86) - # At this point we might as well... - set(ARCH_OPT "IA32" PARENT_SCOPE) - return() - endif() -endfunction() - -if (MSVC) - detect_architecture("_M_AMD64" x86_64) - detect_architecture("_M_IX86" x86) - detect_architecture("_M_ARM" ARM) - detect_architecture("_M_ARM64" ARM64) -else() - detect_architecture("__x86_64__" x86_64) - detect_architecture("__i386__" x86) - detect_architecture("__arm__" ARM) - detect_architecture("__aarch64__" ARM64) - detect_architecture("__PPC64__" PPC64) -endif() -if (NOT DEFINED ARCHITECTURE) - message(FATAL_ERROR "Not supported. Please add needed architecture detection.") -endif() - -# Note: On x86 MSVC's /arch:SSE2 enables all SSE intrinsics support and is default option. -# On x86_64 MSVC's SSE is supported and enabled, so only AVX selection is needed. - -if (FORCE_SSSE3) - message(WARNING "FORCE_SSSE3 flag is deprecated, please use ARCH_OPT option.") - set(ARCH_OPT "") - if (MSVC) - if (ARCHITECTURE_x86) - set(ARCH_OPT "SSE2") - endif() - force_ext_available(SSSE3) - else() - set(FORCE_OPT "-mssse3") - endif() -endif() - -if (FORCE_SSE41) - message(WARNING "FORCE_SSE41 flag is deprecated, please use ARCH_OPT option.") - set(ARCH_OPT "") - if (MSVC) - if (ARCHITECTURE_x86) - set(ARCH_OPT "SSE2") - else() - force_ext_available(SSE4_1) - endif() - else() - set(FORCE_OPT "-msse4.1") - endif() -endif() - -if (MSVC) - # Glue to make ARCH_OPT more flexible for MSVC - if (ARCH_OPT STREQUAL "native") - # Some compilers simulating MSVC supports the march flag, so use it if we can - check_cxx_compiler_flag("-march=native" MARCH_NATIVE_SUPPORTED) - if (NOT MARCH_NATIVE_SUPPORTED) - detect_msvc_native_opt() - FILE(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/tmp) - endif() - elseif(ARCH_OPT STREQUAL "SSE4_2") - force_ext_available(SSE4_2) - set(ARCH_OPT "") - elseif(ARCH_OPT STREQUAL "SSE4_1") - force_ext_available(SSE4_1) - set(ARCH_OPT "") - elseif(ARCH_OPT STREQUAL "SSSE3") - force_ext_available(SSSE3) - set(ARCH_OPT "") - elseif(ARCH_OPT STREQUAL "SSE3") - force_ext_available(SSE3) - set(ARCH_OPT "") - elseif(ARCH_OPT STREQUAL "SSE2") - force_ext_available(SSE2) - set(ARCH_OPT "") - endif() -endif() - -message(STATUS "Target architecture: ${ARCHITECTURE}-${ARCH_OPT}") - -cmake_push_check_state(RESET) -if (ARCH_OPT) - if(MSVC AND NOT MARCH_NATIVE_SUPPORTED) - set(CMAKE_REQUIRED_FLAGS "/arch:${ARCH_OPT}") - add_compile_options(${CMAKE_REQUIRED_FLAGS}) - elseif (ARCHITECTURE_PPC64) - set(CMAKE_REQUIRED_FLAGS "-mcpu=${ARCH_OPT}") - add_compile_options(-mcpu=${ARCH_OPT}) - else() - set(CMAKE_REQUIRED_FLAGS "-march=${ARCH_OPT}") - add_compile_options(-march=${ARCH_OPT}) - endif() -elseif(FORCE_SSSE3 OR FORCE_SSE41) - if (NOT MSVC) - set(CMAKE_REQUIRED_FLAGS ${FORCE_OPT}) - add_compile_options(${FORCE_OPT}) - endif() -endif() - -check_cxx_compiler_flag("${CMAKE_REQUIRED_FLAGS}" FLAG_SUPPORTED) -if (NOT FLAG_SUPPORTED) - message(FATAL_ERROR "Flag '${CMAKE_REQUIRED_FLAGS}' rejected by compiler. Please adjust ARCH_OPT option.") -endif() - -if (ARCHITECTURE_ARM) - if (MSVC) - force_ext_available(ARM_NEON) - else() - list(APPEND CMAKE_REQUIRED_FLAGS -mfpu=neon) - endif() -endif() - -# Extensions detection for ARM -check_symbol_exists("__ARM_NEON" "" HAS_NEON) -if (HAS_NEON) - message(STATUS "ARM Neon extensions enabled") - add_compile_definitions(USE_NEON) -endif() - -# This is quite basic detection, can be extended if needed -detect_extensions(AVX512F) -detect_extensions(AVX2 HAS_AVX512F) -detect_extensions(AVX HAS_AVX2) -detect_extensions(SSE4_2 HAS_AVX) -detect_extensions(SSE4_1 HAS_SSE4_2) -detect_extensions(SSSE3 HAS_SSE4_1) -detect_extensions(SSE3 HAS_SSSE3) -detect_extensions(SSE2 HAS_SSE3) - -cmake_pop_check_state() +include_guard(GLOBAL) + +include(CheckCXXCompilerFlag) +include(CheckSymbolExists) +include(CMakePushCheckState) + +# Detect current compilation architecture and create standard definitions +macro(detect_architecture symbol arch) + if (NOT DEFINED ARCHITECTURE) + check_symbol_exists("${symbol}" "" ARCHITECTURE_${arch}) + + if (ARCHITECTURE_${arch}) + set(ARCHITECTURE ${arch}) + set(ARCHITECTURE_${arch} TRUE) + add_compile_definitions(ARCHITECTURE_${arch}) + endif() + endif() +endmacro() + +macro(force_ext_available extension) + message(STATUS "Looking for __${extension}__ - forced found") + set(HAS_${extension} 1 CACHE INTERNAL "") +endmacro() + +function(detect_extensions extension) + unset(HAS_${extension}) + if (ARGC EQUAL 2 AND (${ARGV1})) # force available + force_ext_available(${extension}) + endif() + check_symbol_exists("__${extension}__" "" HAS_${extension}) + if (HAS_${extension}) + add_compile_definitions(USE_${extension}) + endif() +endfunction() + +function(detect_msvc_native_opt) + set(TEST_DIR ${PROJECT_SOURCE_DIR}/cmake/test) + + try_run(RUN_AVX512 COMPILE_AVX512 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx512.cxx" COMPILE_DEFINITIONS /arch:AVX512) + if (COMPILE_AVX512 AND RUN_AVX512 EQUAL 0) + set(ARCH_OPT "AVX512" PARENT_SCOPE) + return() + endif() + try_run(RUN_AVX2 COMPILE_AVX2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx2.cxx" COMPILE_DEFINITIONS /arch:AVX2) + if (COMPILE_AVX2 AND RUN_AVX2 EQUAL 0) + set(ARCH_OPT "AVX2" PARENT_SCOPE) + return() + endif() + try_run(RUN_AVX COMPILE_AVX "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_avx.cxx" COMPILE_DEFINITIONS /arch:AVX) + if (COMPILE_AVX AND RUN_AVX EQUAL 0) + set(ARCH_OPT "AVX" PARENT_SCOPE) + return() + endif() + + # Supporting 32-bit x86, what year is it? + set(COMPILE_DEF "") + set(ARCH_OPT "" PARENT_SCOPE) + if (ARCHITECTURE_x86) + set(COMPILE_DEF "/arch:SSE2") + set(ARCH_OPT "SSE2" PARENT_SCOPE) + endif() + + try_run(RUN_SSE42 COMPILE_SSE42 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse42.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE42 AND RUN_SSE42 EQUAL 0) + force_ext_available(SSE4_2) + return() + endif() + try_run(RUN_SSE41 COMPILE_SSE41 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse41.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE41 AND RUN_SSE41 EQUAL 0) + force_ext_available(SSE4_1) + return() + endif() + try_run(RUN_SSSE3 COMPILE_SSSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_ssse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSSE3 AND RUN_SSSE3 EQUAL 0) + force_ext_available(SSSE3) + return() + endif() + try_run(RUN_SSE3 COMPILE_SSE3 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse3.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE3 AND RUN_SSE3 EQUAL 0) + force_ext_available(SSE3) + return() + endif() + try_run(RUN_SSE2 COMPILE_SSE2 "${CMAKE_BINARY_DIR}/tmp" "${TEST_DIR}/test_x86_sse2.cxx" COMPILE_DEFINITIONS ${COMPILE_DEF}) + if (COMPILE_SSE2 AND RUN_SSE2 EQUAL 0) + force_ext_available(SSE2) + return() + endif() + + if (ARCHITECTURE_x86) + # At this point we might as well... + set(ARCH_OPT "IA32" PARENT_SCOPE) + return() + endif() +endfunction() + +if (MSVC) + detect_architecture("_M_AMD64" x86_64) + detect_architecture("_M_IX86" x86) + detect_architecture("_M_ARM" ARM) + detect_architecture("_M_ARM64" ARM64) +else() + detect_architecture("__x86_64__" x86_64) + detect_architecture("__i386__" x86) + detect_architecture("__arm__" ARM) + detect_architecture("__aarch64__" ARM64) + detect_architecture("__PPC64__" PPC64) +endif() +if (NOT DEFINED ARCHITECTURE) + message(FATAL_ERROR "Not supported. Please add needed architecture detection.") +endif() + +# Note: On x86 MSVC's /arch:SSE2 enables all SSE intrinsics support and is default option. +# On x86_64 MSVC's SSE is supported and enabled, so only AVX selection is needed. + +if (FORCE_SSSE3) + message(WARNING "FORCE_SSSE3 flag is deprecated, please use ARCH_OPT option.") + set(ARCH_OPT "") + if (MSVC) + if (ARCHITECTURE_x86) + set(ARCH_OPT "SSE2") + endif() + force_ext_available(SSSE3) + else() + set(FORCE_OPT "-mssse3") + endif() +endif() + +if (FORCE_SSE41) + message(WARNING "FORCE_SSE41 flag is deprecated, please use ARCH_OPT option.") + set(ARCH_OPT "") + if (MSVC) + if (ARCHITECTURE_x86) + set(ARCH_OPT "SSE2") + else() + force_ext_available(SSE4_1) + endif() + else() + set(FORCE_OPT "-msse4.1") + endif() +endif() + +if (MSVC) + # Glue to make ARCH_OPT more flexible for MSVC + if (ARCH_OPT STREQUAL "native") + # Some compilers simulating MSVC supports the march flag, so use it if we can + check_cxx_compiler_flag("-march=native" MARCH_NATIVE_SUPPORTED) + if (NOT MARCH_NATIVE_SUPPORTED) + detect_msvc_native_opt() + FILE(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/tmp) + endif() + elseif(ARCH_OPT STREQUAL "SSE4_2") + force_ext_available(SSE4_2) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE4_1") + force_ext_available(SSE4_1) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSSE3") + force_ext_available(SSSE3) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE3") + force_ext_available(SSE3) + set(ARCH_OPT "") + elseif(ARCH_OPT STREQUAL "SSE2") + force_ext_available(SSE2) + set(ARCH_OPT "") + endif() +endif() + +message(STATUS "Target architecture: ${ARCHITECTURE}-${ARCH_OPT}") + +cmake_push_check_state(RESET) +if (ARCH_OPT) + if(MSVC AND NOT MARCH_NATIVE_SUPPORTED) + set(CMAKE_REQUIRED_FLAGS "/arch:${ARCH_OPT}") + add_compile_options(${CMAKE_REQUIRED_FLAGS}) + elseif (ARCHITECTURE_PPC64) + set(CMAKE_REQUIRED_FLAGS "-mcpu=${ARCH_OPT}") + add_compile_options(-mcpu=${ARCH_OPT}) + elseif(ANDROID) + else() + set(CMAKE_REQUIRED_FLAGS "-march=${ARCH_OPT}") + add_compile_options(-march=${ARCH_OPT}) + endif() +elseif(FORCE_SSSE3 OR FORCE_SSE41) + if (NOT MSVC) + set(CMAKE_REQUIRED_FLAGS ${FORCE_OPT}) + add_compile_options(${FORCE_OPT}) + endif() +endif() + +check_cxx_compiler_flag("${CMAKE_REQUIRED_FLAGS}" FLAG_SUPPORTED) +if (NOT FLAG_SUPPORTED) + message(FATAL_ERROR "Flag '${CMAKE_REQUIRED_FLAGS}' rejected by compiler. Please adjust ARCH_OPT option.") +endif() + +if (ARCHITECTURE_ARM) + if (MSVC) + force_ext_available(ARM_NEON) + else() + list(APPEND CMAKE_REQUIRED_FLAGS -mfpu=neon) + endif() +endif() + +# Extensions detection for ARM +check_symbol_exists("__ARM_NEON" "" HAS_NEON) +if (HAS_NEON) + message(STATUS "ARM Neon extensions enabled") + add_compile_definitions(USE_NEON) +endif() + +# This is quite basic detection, can be extended if needed +detect_extensions(AVX512F) +detect_extensions(AVX2 HAS_AVX512F) +detect_extensions(AVX HAS_AVX2) +detect_extensions(SSE4_2 HAS_AVX) +detect_extensions(SSE4_1 HAS_SSE4_2) +detect_extensions(SSSE3 HAS_SSE4_1) +detect_extensions(SSE3 HAS_SSSE3) +detect_extensions(SSE2 HAS_SSE3) + +cmake_pop_check_state()