From 72f6b4bfbe84a369fbdf4c9671470ba8c3ce14cc Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 25 Nov 2020 10:45:12 -0500 Subject: 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 --- Modules/CheckPIESupported.cmake | 8 +- Modules/Compiler/GNU.cmake | 1 - Modules/Internal/CMakeCheckCompilerFlag.cmake | 158 --------------------- .../Internal/CMakeTryCompilerOrLinkerFlag.cmake | 158 +++++++++++++++++++++ 4 files changed, 163 insertions(+), 162 deletions(-) delete mode 100644 Modules/Internal/CMakeCheckCompilerFlag.cmake create mode 100644 Modules/Internal/CMakeTryCompilerOrLinkerFlag.cmake diff --git a/Modules/CheckPIESupported.cmake b/Modules/CheckPIESupported.cmake index a99d8c4..fb87822 100644 --- a/Modules/CheckPIESupported.cmake +++ b/Modules/CheckPIESupported.cmake @@ -62,7 +62,7 @@ Examples #]=======================================================================] -include (Internal/CMakeCheckCompilerFlag) +include (Internal/CMakeTryCompilerOrLinkerFlag) function (check_pie_supported) cmake_policy(GET CMP0083 cmp0083) @@ -109,14 +109,16 @@ function (check_pie_supported) foreach(lang IN LISTS CHECK_PIE_LANGUAGES) if(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER) - cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_PIE}" + cmake_try_compiler_or_linker_flag(${lang} + "${CMAKE_${lang}_LINK_OPTIONS_PIE}" CMAKE_${lang}_LINK_PIE_SUPPORTED OUTPUT_VARIABLE output) if (NOT CMAKE_${lang}_LINK_PIE_SUPPORTED) string (APPEND outputs "PIE (${lang}): ${output}\n") endif() - cmake_check_compiler_flag(${lang} "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}" + cmake_try_compiler_or_linker_flag(${lang} + "${CMAKE_${lang}_LINK_OPTIONS_NO_PIE}" CMAKE_${lang}_LINK_NO_PIE_SUPPORTED OUTPUT_VARIABLE output) if (NOT CMAKE_${lang}_LINK_NO_PIE_SUPPORTED) diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake index 668a6a9..81ab3a2 100644 --- a/Modules/Compiler/GNU.cmake +++ b/Modules/Compiler/GNU.cmake @@ -9,7 +9,6 @@ endif() set(__COMPILER_GNU 1) include(Compiler/CMakeCommonCompilerMacros) -include(Internal/CMakeCheckCompilerFlag) set(__pch_header_C "c-header") set(__pch_header_CXX "c++-header") diff --git a/Modules/Internal/CMakeCheckCompilerFlag.cmake b/Modules/Internal/CMakeCheckCompilerFlag.cmake deleted file mode 100644 index 9c8dfb6..0000000 --- a/Modules/Internal/CMakeCheckCompilerFlag.cmake +++ /dev/null @@ -1,158 +0,0 @@ -# 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_check_compiler_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_check_compiler_flag( - [SRC_EXT ] [COMMAND_PATTERN ] - [FAIL_REGEX ...] - [OUTPUT_VARIABLE ]) - -Parameters: - - Language to check. - - The flag to add to the compile/link command line. - - 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 - ' -o ' - 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 variable with details about any error. -#]=] - -include_guard(GLOBAL) -include(CMakeCheckCompilerFlagCommonPatterns) - -function(CMAKE_CHECK_COMPILER_FLAG lang flag result) - # Cache results between runs similar to check__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 " -o ") - 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 "" "${COMPILER_FLAG_SRC}") - list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${COMPILER_FLAG_EXE}") - list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${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() 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( + [SRC_EXT ] [COMMAND_PATTERN ] + [FAIL_REGEX ...] + [OUTPUT_VARIABLE ]) + +Parameters: + - Language to check. + - The flag to add to the compile/link command line. + - 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 + ' -o ' + 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 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__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 " -o ") + 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 "" "${COMPILER_FLAG_SRC}") + list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${COMPILER_FLAG_EXE}") + list(TRANSFORM CCCF_COMMAND_PATTERN REPLACE "" "${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() -- cgit v0.12