diff --git a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake --- a/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake +++ b/libc/cmake/modules/LLVMLibCCheckCpuFeatures.cmake @@ -44,44 +44,44 @@ set(${output_var} ${tmp} PARENT_SCOPE) endfunction() -# Generates a cpp file to introspect the compiler defined flags. -function(_generate_check_code) +# Generates cpp files to introspect the compiler defined flags. +set(AVAILABLE_CPU_FEATURES "") +if(LIBC_CROSSBUILD) + # If we are doing a cross build, we will just assume that all CPU features + # are available. + set(AVAILABLE_CPU_FEATURES ${ALL_CPU_FEATURES}) +else() + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) foreach(feature IN LISTS ALL_CPU_FEATURES) - set(DEFINITIONS - "${DEFINITIONS} -#ifdef __${feature}__ - \"${feature}\", -#endif") - endforeach() - configure_file( - "${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_cpu_features.cpp.in" - "cpu_features/check_cpu_features.cpp" @ONLY) -endfunction() -_generate_check_code() + set(CPU_FEATURE_CHECK_SOURCE " + int main() { + #ifdef __${feature}__ + return 0; + #else + __## syntax error ##__ + #endif + }") + configure_file( + "${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_cpu_features.cpp.in" + "check_cpu_features/check_cpu_feature_${feature}.cpp" @ONLY + ) + try_compile( + has_feature ${CMAKE_CURRENT_BINARY_DIR}/cpu_features + ${CMAKE_CURRENT_BINARY_DIR}/check_cpu_features/check_cpu_feature_${feature}.cpp + COMPILE_DEFINITIONS ${LIBC_COMPILE_OPTIONS_NATIVE} + ) + if(has_feature) + list(APPEND AVAILABLE_CPU_FEATURES ${feature}) + endif() +endforeach() +endif() -set(LIBC_CPU_FEATURES "" CACHE PATH "Host supported CPU features") +set(LIBC_CPU_FEATURES ${AVAILABLE_CPU_FEATURES} CACHE STRING "Host supported CPU features") -if(LIBC_CROSSBUILD) - _intersection(cpu_features "${ALL_CPU_FEATURES}" "${LIBC_CPU_FEATURES}") - if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}") - message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}") - endif() +_intersection(cpu_features "${AVAILABLE_CPU_FEATURES}" "${LIBC_CPU_FEATURES}") +if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}") + message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}") +else() message(STATUS "Set CPU features: ${cpu_features}") set(LIBC_CPU_FEATURES "${cpu_features}") -else() - # Populates the LIBC_CPU_FEATURES list from host. - try_run( - run_result compile_result "${CMAKE_CURRENT_BINARY_DIR}/check_${feature}" - "${CMAKE_CURRENT_BINARY_DIR}/cpu_features/check_cpu_features.cpp" - COMPILE_DEFINITIONS ${LIBC_COMPILE_OPTIONS_NATIVE} - COMPILE_OUTPUT_VARIABLE compile_output - RUN_OUTPUT_VARIABLE run_output) - if("${run_result}" EQUAL 0) - message(STATUS "Set CPU features: ${run_output}") - set(LIBC_CPU_FEATURES "${run_output}") - elseif(NOT ${compile_result}) - message(FATAL_ERROR "Failed to compile: ${compile_output}") - else() - message(FATAL_ERROR "Failed to run: ${run_output}") - endif() endif() diff --git a/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in b/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in --- a/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in +++ b/libc/cmake/modules/cpu_features/check_cpu_features.cpp.in @@ -1,32 +1 @@ -#include -#include - -// This file is instantiated by CMake. -// DEFINITIONS below is replaced with a set of lines like so: -// #ifdef __SSE2__ -// "SSE2", -// #endif -// -// This allows for introspection of compiler definitions. -// The output of the program is a single line of semi colon separated feature -// names. - -// MSVC is using a different set of preprocessor definitions for -// SSE and SSE2, see _M_IX86_FP in -// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros - -int main(int, char **) { - const char *strings[] = { - @DEFINITIONS@ - // If DEFINITIONS turns out to be empty, we don't want to list - // an empty array. So, we add an end of list marker. - "" - }; - const size_t size = sizeof(strings) / sizeof(strings[0]); - for (size_t i = 0; i < size; ++i) { - if (i) - putchar(';'); - fputs(strings[i], stdout); - } - return EXIT_SUCCESS; -} +@CPU_FEATURE_CHECK_SOURCE@