diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2020-10-25 16:26:42 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-10-26 14:57:55 (GMT) |
commit | d192918586364b98e916887b190da825c1373f7f (patch) | |
tree | 5c753be8114cfd322a88a117c922b4cd20081907 /Modules/Internal | |
parent | 9fa7afe7d332ced27264f1ef7c921aa1d95bc476 (diff) | |
download | CMake-d192918586364b98e916887b190da825c1373f7f.zip CMake-d192918586364b98e916887b190da825c1373f7f.tar.gz CMake-d192918586364b98e916887b190da825c1373f7f.tar.bz2 |
Modules: Do not implicitly add new functions via old Check Modules
The conversion of Check<Lang>CompilerFlag, SourceCompiles, and
SourceRuns over to the new functions has the possibility of breaking
projects that had functions with those existing names.
To reduce the possibility of collisions we now have all the
legacy code call functions that start with `cmake_`, and users
will need to explicitly include the new modules to get the
non-prefixed versions
Fixes: #21359
Diffstat (limited to 'Modules/Internal')
-rw-r--r-- | Modules/Internal/CheckCompilerFlag.cmake | 79 | ||||
-rw-r--r-- | Modules/Internal/CheckSourceCompiles.cmake | 127 | ||||
-rw-r--r-- | Modules/Internal/CheckSourceRuns.cmake | 137 |
3 files changed, 343 insertions, 0 deletions
diff --git a/Modules/Internal/CheckCompilerFlag.cmake b/Modules/Internal/CheckCompilerFlag.cmake new file mode 100644 index 0000000..f790d87 --- /dev/null +++ b/Modules/Internal/CheckCompilerFlag.cmake @@ -0,0 +1,79 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +include_guard(GLOBAL) +include(Internal/CheckSourceCompiles) +include(CMakeCheckCompilerFlagCommonPatterns) + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced +cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST + +function(CMAKE_CHECK_COMPILER_FLAG _lang _flag _var) + + if(_lang STREQUAL C) + set(_lang_src "int main(void) { return 0; }") + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C") + elseif(_lang STREQUAL CXX) + set(_lang_src "int main() { return 0; }") + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+") + elseif(_lang STREQUAL CUDA) + set(_lang_src "__host__ int main() { return 0; }") + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for C\\+\\+" # Host GNU + FAIL_REGEX "argument unused during compilation: .*") # Clang + elseif(_lang STREQUAL Fortran) + set(_lang_src " program test\n stop\n end program") + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Fortran") + elseif(_lang STREQUAL OBJC) + set(_lang_src [=[ +#ifndef __OBJC__ +# error "Not an Objective-C compiler" +#endif +int main(void) { return 0; }]=]) + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C" # GNU + FAIL_REGEX "argument unused during compilation: .*") # Clang + elseif(_lang STREQUAL OBJCXX) + set(_lang_src [=[ +#ifndef __OBJC__ +# error "Not an Objective-C++ compiler" +#endif +int main(void) { return 0; }]=]) + set(_lang_fail_regex FAIL_REGEX "command[ -]line option .* is valid for .* but not for Objective-C\\+\\+" # GNU + FAIL_REGEX "argument unused during compilation: .*") # Clang + elseif(_lang STREQUAL ISPC) + set(_lang_src "float func(uniform int32, float a) { return a / 2.25; }") + else() + message (SEND_ERROR "check_compiler_flag: ${_lang}: unknown language.") + return() + endif() + + get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT _lang IN_LIST _supported_languages) + message (SEND_ERROR "check_compiler_flag: ${_lang}: needs to be enabled before use.") + return() + endif() + + set(CMAKE_REQUIRED_DEFINITIONS ${_flag}) + + # Normalize locale during test compilation. + set(_locale_vars LC_ALL LC_MESSAGES LANG) + foreach(v IN LISTS _locale_vars) + set(_locale_vars_saved_${v} "$ENV{${v}}") + set(ENV{${v}} C) + endforeach() + + check_compiler_flag_common_patterns(_common_patterns) + cmake_check_source_compiles(${_lang} + "${_lang_src}" + ${_var} + ${_lang_fail_regex} + ${_common_patterns} + ) + + foreach(v IN LISTS _locale_vars) + set(ENV{${v}} ${_locale_vars_saved_${v}}) + endforeach() + set(${_var} "${${_var}}" PARENT_SCOPE) +endfunction () + +cmake_policy(POP) diff --git a/Modules/Internal/CheckSourceCompiles.cmake b/Modules/Internal/CheckSourceCompiles.cmake new file mode 100644 index 0000000..91c8964 --- /dev/null +++ b/Modules/Internal/CheckSourceCompiles.cmake @@ -0,0 +1,127 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +include_guard(GLOBAL) + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced +cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST + +function(CMAKE_CHECK_SOURCE_COMPILES _lang _source _var) + if(NOT DEFINED "${_var}") + + if(_lang STREQUAL C) + set(_lang_textual "C") + set(_lang_ext "c") + elseif(_lang STREQUAL CXX) + set(_lang_textual "C++") + set(_lang_ext "cxx") + elseif(_lang STREQUAL CUDA) + set(_lang_textual "CUDA") + set(_lang_ext "cu") + elseif(_lang STREQUAL Fortran) + set(_lang_textual "Fortran") + set(_lang_ext "F90") + elseif(_lang STREQUAL ISPC) + set(_lang_textual "ISPC") + set(_lang_ext "ispc") + elseif(_lang STREQUAL OBJC) + set(_lang_textual "Objective-C") + set(_lang_ext "m") + elseif(_lang STREQUAL OBJCXX) + set(_lang_textual "Objective-C++") + set(_lang_ext "mm") + else() + message (SEND_ERROR "check_source_compiles: ${_lang}: unknown language.") + return() + endif() + + get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT _lang IN_LIST _supported_languages) + message (SEND_ERROR "check_source_compiles: ${_lang}: needs to be enabled before use.") + return() + endif() + + set(_FAIL_REGEX) + set(_SRC_EXT) + set(_key) + foreach(arg ${ARGN}) + if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$") + set(_key "${arg}") + elseif(_key STREQUAL "FAIL_REGEX") + list(APPEND _FAIL_REGEX "${arg}") + elseif(_key STREQUAL "SRC_EXT") + set(_SRC_EXT "${arg}") + set(_key "") + else() + message(FATAL_ERROR "Unknown argument:\n ${arg}\n") + endif() + endforeach() + + if(NOT _SRC_EXT) + set(_SRC_EXT ${_lang_ext}) + endif() + + if(CMAKE_REQUIRED_LINK_OPTIONS) + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS + LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) + else() + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS) + endif() + if(CMAKE_REQUIRED_LIBRARIES) + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES + LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + else() + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES) + endif() + if(CMAKE_REQUIRED_INCLUDES) + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + else() + set(CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES) + endif() + file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}" + "${_source}\n") + + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_START "Performing Test ${_var}") + endif() + try_compile(${_var} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} + COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS} + ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LINK_OPTIONS} + ${CHECK_${LANG}_SOURCE_COMPILES_ADD_LIBRARIES} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS} + "${CHECK_${LANG}_SOURCE_COMPILES_ADD_INCLUDES}" + OUTPUT_VARIABLE OUTPUT) + + foreach(_regex ${_FAIL_REGEX}) + if("${OUTPUT}" MATCHES "${_regex}") + set(${_var} 0) + endif() + endforeach() + + if(${_var}) + set(${_var} 1 CACHE INTERNAL "Test ${_var}") + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_PASS "Success") + endif() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following output:\n" + "${OUTPUT}\n" + "Source file was:\n${_source}\n") + else() + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_FAIL "Failed") + endif() + set(${_var} "" CACHE INTERNAL "Test ${_var}") + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following output:\n" + "${OUTPUT}\n" + "Source file was:\n${_source}\n") + endif() + endif() +endfunction() + +cmake_policy(POP) diff --git a/Modules/Internal/CheckSourceRuns.cmake b/Modules/Internal/CheckSourceRuns.cmake new file mode 100644 index 0000000..c667245 --- /dev/null +++ b/Modules/Internal/CheckSourceRuns.cmake @@ -0,0 +1,137 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +include_guard(GLOBAL) + +cmake_policy(PUSH) +cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced +cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST + +function(CMAKE_CHECK_SOURCE_RUNS _lang _source _var) + if(NOT DEFINED "${_var}") + + if(_lang STREQUAL C) + set(_lang_textual "C") + set(_lang_ext "c") + elseif(_lang STREQUAL CXX) + set(_lang_textual "C++") + set(_lang_ext "cxx") + elseif(_lang STREQUAL CUDA) + set(_lang_textual "CUDA") + set(_lang_ext "cu") + elseif(_lang STREQUAL Fortran) + set(_lang_textual "Fortran") + set(_lang_ext "F90") + elseif(_lang STREQUAL OBJC) + set(_lang_textual "Objective-C") + set(_lang_ext "m") + elseif(_lang STREQUAL OBJCXX) + set(_lang_textual "Objective-C++") + set(_lang_ext "mm") + else() + message (SEND_ERROR "check_source_runs: ${_lang}: unknown language.") + return() + endif() + + get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT _lang IN_LIST _supported_languages) + message (SEND_ERROR "check_source_runs: ${_lang}: needs to be enabled before use.") + return() + endif() + + set(_FAIL_REGEX) + set(_SRC_EXT) + set(_key) + foreach(arg ${ARGN}) + if("${arg}" MATCHES "^(FAIL_REGEX|SRC_EXT)$") + set(_key "${arg}") + elseif(_key STREQUAL "FAIL_REGEX") + list(APPEND _FAIL_REGEX "${arg}") + elseif(_key STREQUAL "SRC_EXT") + set(_SRC_EXT "${arg}") + set(_key "") + else() + message(FATAL_ERROR "Unknown argument:\n ${arg}\n") + endif() + endforeach() + + if(NOT _SRC_EXT) + set(_SRC_EXT ${_lang_ext}) + endif() + + if(CMAKE_REQUIRED_LINK_OPTIONS) + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS + LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS}) + else() + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS) + endif() + if(CMAKE_REQUIRED_LIBRARIES) + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES + LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) + else() + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES) + endif() + if(CMAKE_REQUIRED_INCLUDES) + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}") + else() + set(CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES) + endif() + file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}" + "${_source}\n") + + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_START "Performing Test ${_var}") + endif() + try_run(${_var}_EXITCODE ${_var}_COMPILED + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT} + COMPILE_DEFINITIONS -D${_var} ${CMAKE_REQUIRED_DEFINITIONS} + ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LINK_OPTIONS} + ${CHECK_${_lang}_SOURCE_COMPILES_ADD_LIBRARIES} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS} + -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH} + "${CHECK_${_lang}_SOURCE_COMPILES_ADD_INCLUDES}" + COMPILE_OUTPUT_VARIABLE OUTPUT + RUN_OUTPUT_VARIABLE RUN_OUTPUT) + # if it did not compile make the return value fail code of 1 + if(NOT ${_var}_COMPILED) + set(${_var}_EXITCODE 1) + set(${_var}_EXITCODE 1 PARENT_SCOPE) + endif() + # if the return value was 0 then it worked + if("${${_var}_EXITCODE}" EQUAL 0) + set(${_var} 1 CACHE INTERNAL "Test ${_var}") + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_PASS "Success") + endif() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Performing ${_lang_textual} SOURCE FILE Test ${_var} succeeded with the following compile output:\n" + "${OUTPUT}\n" + "...and run output:\n" + "${RUN_OUTPUT}\n" + "Return value: ${${_var}}\n" + "Source file was:\n${_source}\n") + else() + if(CMAKE_CROSSCOMPILING AND "${${_var}_EXITCODE}" MATCHES "FAILED_TO_RUN") + set(${_var} "${${_var}_EXITCODE}" PARENT_SCOPE) + else() + set(${_var} "" CACHE INTERNAL "Test ${_var}") + endif() + + if(NOT CMAKE_REQUIRED_QUIET) + message(CHECK_FAIL "Failed") + endif() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log + "Performing ${_lang_textual} SOURCE FILE Test ${_var} failed with the following compile output:\n" + "${OUTPUT}\n" + "...and run output:\n" + "${RUN_OUTPUT}\n" + "Return value: ${${_var}_EXITCODE}\n" + "Source file was:\n${_source}\n") + + endif() + endif() +endfunction() + +cmake_policy(POP) |