| include(CMakeCheckCompilerFlagCommonPatterns) | |
| # This function takes an OS and a list of architectures and identifies the | |
| # subset of the architectures list that the installed toolchain can target. | |
| function(try_compile_only output) | |
| cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN}) | |
| if(NOT ARG_SOURCE) | |
| set(ARG_SOURCE "int foo(int x, int y) { return x + y; }\n") | |
| endif() | |
| set(SIMPLE_C ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/src.c) | |
| file(WRITE ${SIMPLE_C} "${ARG_SOURCE}\n") | |
| string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions | |
| ${CMAKE_C_COMPILE_OBJECT}) | |
| set(TRY_COMPILE_FLAGS "${ARG_FLAGS}") | |
| if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) | |
| list(APPEND TRY_COMPILE_FLAGS "-target ${CMAKE_C_COMPILER_TARGET}") | |
| endif() | |
| string(REPLACE ";" " " extra_flags "${TRY_COMPILE_FLAGS}") | |
| set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}") | |
| foreach(substitution ${substitutions}) | |
| if(substitution STREQUAL "<CMAKE_C_COMPILER>") | |
| string(REPLACE "<CMAKE_C_COMPILER>" | |
| "${CMAKE_C_COMPILER}" test_compile_command ${test_compile_command}) | |
| elseif(substitution STREQUAL "<OBJECT>") | |
| string(REPLACE "<OBJECT>" | |
| "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/test.o" | |
| test_compile_command ${test_compile_command}) | |
| elseif(substitution STREQUAL "<SOURCE>") | |
| string(REPLACE "<SOURCE>" "${SIMPLE_C}" test_compile_command | |
| ${test_compile_command}) | |
| elseif(substitution STREQUAL "<FLAGS>") | |
| string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}" | |
| test_compile_command ${test_compile_command}) | |
| else() | |
| string(REPLACE "${substitution}" "" test_compile_command | |
| ${test_compile_command}) | |
| endif() | |
| endforeach() | |
| string(REPLACE " " ";" test_compile_command "${test_compile_command}") | |
| execute_process( | |
| COMMAND ${test_compile_command} | |
| RESULT_VARIABLE result | |
| OUTPUT_VARIABLE TEST_OUTPUT | |
| ERROR_VARIABLE TEST_ERROR | |
| ) | |
| CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS) | |
| set(ERRORS_FOUND OFF) | |
| foreach(var ${_CheckCCompilerFlag_COMMON_PATTERNS}) | |
| if("${var}" STREQUAL "FAIL_REGEX") | |
| continue() | |
| endif() | |
| if("${TEST_ERROR}" MATCHES "${var}" OR "${TEST_OUTPUT}" MATCHES "${var}") | |
| set(ERRORS_FOUND ON) | |
| endif() | |
| endforeach() | |
| if(result EQUAL 0 AND NOT ERRORS_FOUND) | |
| set(${output} True PARENT_SCOPE) | |
| else() | |
| file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log | |
| "Testing compiler for supporting " ${ARGN} ":\n" | |
| "Command: ${test_compile_command}\n" | |
| "${TEST_OUTPUT}\n${TEST_ERROR}\n${result}\n") | |
| set(${output} False PARENT_SCOPE) | |
| endif() | |
| endfunction() | |
| function(builtin_check_c_compiler_flag flag output) | |
| if(NOT DEFINED ${output}) | |
| message(STATUS "Performing Test ${output}") | |
| try_compile_only(result FLAGS ${flag}) | |
| set(${output} ${result} CACHE INTERNAL "Compiler supports ${flag}") | |
| if(${result}) | |
| message(STATUS "Performing Test ${output} - Success") | |
| else() | |
| message(STATUS "Performing Test ${output} - Failed") | |
| endif() | |
| endif() | |
| endfunction() | |
| function(builtin_check_c_compiler_source output source) | |
| if(NOT DEFINED ${output}) | |
| message(STATUS "Performing Test ${output}") | |
| try_compile_only(result SOURCE ${source}) | |
| set(${output} ${result} CACHE INTERNAL "Compiler supports ${flag}") | |
| if(${result}) | |
| message(STATUS "Performing Test ${output} - Success") | |
| else() | |
| message(STATUS "Performing Test ${output} - Failed") | |
| endif() | |
| endif() | |
| endfunction() |