summaryrefslogtreecommitdiffstats
path: root/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2020-11-25 15:45:12 (GMT)
committerBrad King <brad.king@kitware.com>2020-11-25 16:06:15 (GMT)
commit72f6b4bfbe84a369fbdf4c9671470ba8c3ce14cc (patch)
tree692c9030a9a5503281310aa960b9fd8020aec5ac /Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake
parent9e83e77129880885d0490d6519e30c1559c5a47c (diff)
downloadCMake-72f6b4bfbe84a369fbdf4c9671470ba8c3ce14cc.zip
CMake-72f6b4bfbe84a369fbdf4c9671470ba8c3ce14cc.tar.gz
CMake-72f6b4bfbe84a369fbdf4c9671470ba8c3ce14cc.tar.bz2
Modules: Rename Internal/CMake{CheckCompiler => TryCompilerOrLinker}Flag
Rename the `CheckPIESupported` helper functions so that they don't clobber other internal functions. Also rename them to document they can't be unified with `CheckCompilerFlag`. Fixes: #21497
Diffstat (limited to 'Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake')
-rw-r--r--Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake158
1 files changed, 158 insertions, 0 deletions
diff --git a/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake b/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake
new file mode 100644
index 0000000..d6fa5f0
--- /dev/null
+++ b/Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake
@@ -0,0 +1,158 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=[
+
+NOTE: This function is used internally by CMake. Projects should not include
+ this file directly.
+
+The cmake_try_compiler_or_linker_flag() function can be used to compile and link a
+source file to check whether a specific compiler or linker flag is supported.
+The function does not use the try_compile() command so as to avoid infinite
+recursion. It may not work for all platforms or toolchains, the caller is
+responsible for ensuring it is only called in valid situations.
+
+ cmake_try_compiler_or_linker_flag(<lang> <flag> <result>
+ [SRC_EXT <ext>] [COMMAND_PATTERN <pattern>]
+ [FAIL_REGEX <regex> ...]
+ [OUTPUT_VARIABLE <output>])
+
+Parameters:
+ <lang> - Language to check.
+ <flag> - The flag to add to the compile/link command line.
+ <result> - Boolean output variable. It will be stored in the cache as an
+ internal variable and if true, will cause future tests that assign
+ to that variable to be bypassed.
+
+Optional parameters:
+ SRC_EXT - Overrides the extension of the source file used for the
+ check. Defaults are 'c' (C), 'cxx' (CXX), 'F' (Fortran).
+ COMMAND_PATTERN - Pattern to be used for the command line. The default is
+ '<FLAG> -o <OUTPUT> <SOURCE>'
+ FAIL_REGEX - List of additional regular expressions that, if matched by
+ the output, give a failed result for the check. A common
+ set of regular expressions will be included in addition to
+ those given by FAIL_REGEX.
+ OUTPUT_VARIABLE - Set <output> variable with details about any error.
+#]=]
+
+include_guard(GLOBAL)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+function(CMAKE_TRY_COMPILER_OR_LINKER_FLAG lang flag result)
+ # Cache results between runs similar to check_<lang>_source_compiles()
+ if(DEFINED ${result})
+ return()
+ endif()
+
+ set(comment "Is the '${flag}' option(s) supported")
+ string(REPLACE ";" " " comment "${comment}")
+
+ if (NOT lang MATCHES "^(C|CXX|Fortran|ASM)$")
+ # other possible languages are not supported
+ # log message to keep trace of this problem...
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Function 'CMAKE_CHECK_COMPILER_FLAG' called with unsupported language: ${lang}\n")
+ set(${result} FALSE CACHE INTERNAL ${comment})
+ return()
+ endif()
+ if (lang STREQUAL "ASM")
+ # assume ASM compiler is a multi-language compiler, so supports C language as well
+ set(check_lang C)
+ else()
+ set(check_lang ${lang})
+ endif()
+
+ cmake_parse_arguments(CCCF "" "SRC_EXT;COMMAND_PATTERN;OUTPUT_VARIABLE" "FAIL_REGEX" ${ARGN})
+
+ if (NOT CCCF_COMMAND_PATTERN)
+ set (CCCF_COMMAND_PATTERN "<FLAG> -o <OUTPUT> <SOURCE>")
+ endif()
+
+ list (APPEND CCCF_FAIL_REGEX "argument unused during compilation") # clang
+ if (check_lang STREQUAL "C")
+ list(APPEND CCCF_FAIL_REGEX
+ "command line option .* is valid for .* but not for C") # GNU
+ elseif(check_lang STREQUAL "CXX")
+ list(APPEND CCCF_FAIL_REGEX
+ "command line option .* is valid for .* but not for C\\+\\+") # GNU
+ elseif(check_lang STREQUAL "Fortran")
+ list(APPEND CCCF_FAIL_REGEX
+ "command line option .* is valid for .* but not for Fortran") # GNU
+ endif()
+
+ # Add patterns for common errors
+ check_compiler_flag_common_patterns(COMPILER_FLAG_COMMON_PATTERNS)
+ foreach(arg IN LISTS COMPILER_FLAG_COMMON_PATTERNS)
+ if(arg MATCHES "^FAIL_REGEX$")
+ continue()
+ endif()
+ list(APPEND CCCF_FAIL_REGEX "${arg}")
+ endforeach()
+
+ if(NOT CCCF_SRC_EXT)
+ if (check_lang STREQUAL "C")
+ set(CCCF_SRC_EXT c)
+ elseif(check_lang STREQUAL "CXX")
+ set(CCCF_SRC_EXT cxx)
+ elseif(check_lang STREQUAL "Fortran")
+ set(CCCF_SRC_EXT F)
+ endif()
+ endif()
+
+ if (CCCF_OUTPUT_VARIABLE)
+ unset(${CCCF_OUTPUT_VARIABLE} PARENT_SCOPE)
+ endif()
+
+ # Compute the directory in which to run the test.
+ set(COMPILER_FLAG_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp")
+ # Compute source and output files.
+ set(COMPILER_FLAG_SRC
+ "${COMPILER_FLAG_DIR}/CompilerFlag${lang}.${CCCF_SRC_EXT}")
+ if(check_lang STREQUAL "Fortran")
+ file(WRITE "${COMPILER_FLAG_SRC}"
+ " program simple\n end program simple\n")
+ else()
+ file(WRITE "${COMPILER_FLAG_SRC}" "int main (void)\n{ return 0; }\n")
+ endif()
+ get_filename_component(COMPILER_FLAG_EXE "${COMPILER_FLAG_SRC}" NAME_WE)
+ string(APPEND COMPILER_FLAG_EXE "${CMAKE_EXECUTABLE_SUFFIX}")
+
+ # Build command line
+ separate_arguments(CCCF_COMMAND_PATTERN UNIX_COMMAND
+ "${CCCF_COMMAND_PATTERN}")
+ list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<SOURCE>" "${COMPILER_FLAG_SRC}")
+ list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<OUTPUT>" "${COMPILER_FLAG_EXE}")
+ list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "<FLAG>" "${flag}")
+
+ execute_process(
+ COMMAND "${CMAKE_COMMAND}" -E env LC_ALL=C LC_MESSAGES=C LANG=C
+ "${CMAKE_${lang}_COMPILER}" ${CCCF_COMMAND_PATTERN}
+ WORKING_DIRECTORY "${COMPILER_FLAG_DIR}"
+ OUTPUT_VARIABLE COMPILER_FLAG_OUTPUT
+ ERROR_VARIABLE COMPILER_FLAG_OUTPUT
+ RESULT_VARIABLE COMPILER_FLAG_RESULT)
+
+ # Record result in the cache so we can avoid re-testing every CMake run
+ if (COMPILER_FLAG_RESULT)
+ set(${result} FALSE CACHE INTERNAL ${comment})
+ else()
+ foreach(regex IN LISTS CCCF_FAIL_REGEX)
+ if(COMPILER_FLAG_OUTPUT MATCHES "${regex}")
+ set(${result} FALSE CACHE INTERNAL ${comment})
+ endif()
+ endforeach()
+ endif()
+ if (DEFINED ${result})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "Determining if the ${flag} option "
+ "is supported for ${lang} language failed with the following output:\n"
+ "${COMPILER_FLAG_OUTPUT}\n")
+ if (CCCF_OUTPUT_VARIABLE)
+ set(${CCCF_OUTPUT_VARIABLE} "${COMPILER_FLAG_OUTPUT}" PARENT_SCOPE)
+ endif()
+ return()
+ endif()
+
+ set(${result} TRUE CACHE INTERNAL ${comment})
+endfunction()