diff options
author | Robert Maynard <robert.maynard@kitware.com> | 2020-09-25 18:58:18 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-09-28 13:07:54 (GMT) |
commit | 90dead024c5adee57e5ea3f3c90aed297d41ce3a (patch) | |
tree | 421c29f6c1d89bd68f23b5ce8f7c7330396d2149 /Modules | |
parent | 0cd1ef0932dfb4c0c2c7d0eaa5d91a8593b3a3d7 (diff) | |
download | CMake-90dead024c5adee57e5ea3f3c90aed297d41ce3a.zip CMake-90dead024c5adee57e5ea3f3c90aed297d41ce3a.tar.gz CMake-90dead024c5adee57e5ea3f3c90aed297d41ce3a.tar.bz2 |
CheckCompilerFlag: unified way to check compiler flags per language
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/CheckCCompilerFlag.cmake | 26 | ||||
-rw-r--r-- | Modules/CheckCXXCompilerFlag.cmake | 26 | ||||
-rw-r--r-- | Modules/CheckCompilerFlag.cmake | 105 | ||||
-rw-r--r-- | Modules/CheckFortranCompilerFlag.cmake | 28 | ||||
-rw-r--r-- | Modules/CheckOBJCCompilerFlag.cmake | 27 | ||||
-rw-r--r-- | Modules/CheckOBJCXXCompilerFlag.cmake | 27 |
6 files changed, 122 insertions, 117 deletions
diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake index 1452b51..f835f29 100644 --- a/Modules/CheckCCompilerFlag.cmake +++ b/Modules/CheckCCompilerFlag.cmake @@ -34,24 +34,8 @@ effect or even a specific one is beyond the scope of this module. include_guard(GLOBAL) include(CheckCSourceCompiles) -include(CMakeCheckCompilerFlagCommonPatterns) - -function(check_c_compiler_flag _flag _var) - 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) - check_c_source_compiles("int main(void) { return 0; }" ${_var} - # Some compilers do not fail with a bad flag - FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU - ${_common_patterns} - ) - foreach(v IN LISTS _locale_vars) - set(ENV{${v}} ${_locale_vars_saved_${v}}) - endforeach() -endfunction() +include(CheckCompilerFlag) + +macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT) + check_compiler_flag(C "${_FLAG}" ${_RESULT}) +endmacro () diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake index 544e9ac..ce49ae3 100644 --- a/Modules/CheckCXXCompilerFlag.cmake +++ b/Modules/CheckCXXCompilerFlag.cmake @@ -34,24 +34,8 @@ effect or even a specific one is beyond the scope of this module. include_guard(GLOBAL) include(CheckCXXSourceCompiles) -include(CMakeCheckCompilerFlagCommonPatterns) - -function(check_cxx_compiler_flag _flag _var) - 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) - check_cxx_source_compiles("int main() { return 0; }" ${_var} - # Some compilers do not fail with a bad flag - FAIL_REGEX "command line option .* is valid for .* but not for C\\\\+\\\\+" # GNU - ${_common_patterns} - ) - foreach(v IN LISTS _locale_vars) - set(ENV{${v}} ${_locale_vars_saved_${v}}) - endforeach() -endfunction() +include(CheckCompilerFlag) + +macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT) + check_compiler_flag(CXX "${_FLAG}" ${_RESULT}) +endmacro () diff --git a/Modules/CheckCompilerFlag.cmake b/Modules/CheckCompilerFlag.cmake new file mode 100644 index 0000000..9223009 --- /dev/null +++ b/Modules/CheckCompilerFlag.cmake @@ -0,0 +1,105 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckCompilerFlag +--------------------- + +.. versionadded:: 3.19 + +Check whether the compiler supports a given flag. + +.. command:: check_compiler_flag + + .. code-block:: cmake + + check_compiler_flag(<lang> <flag> <var>) + +Check that the ``<flag>`` is accepted by the compiler without a diagnostic. +Stores the result in an internal cache entry named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable +and calls the ``check_source_compiles(<LANG>`` function from the +:module:`CheckSourceCompiles` module. See documentation of that +module for a listing of variables that can otherwise modify the build. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the flag. Whether the flag has any +effect or even a specific one is beyond the scope of this module. + +.. note:: + Since the :command:`try_compile` command forwards flags from variables + like :variable:`CMAKE_<LANG>_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags + in such variables may cause a false negative for this check. +#]=======================================================================] + +include_guard(GLOBAL) +include(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(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 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 + 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) + 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/CheckFortranCompilerFlag.cmake b/Modules/CheckFortranCompilerFlag.cmake index b8fac97..0f5cf9a 100644 --- a/Modules/CheckFortranCompilerFlag.cmake +++ b/Modules/CheckFortranCompilerFlag.cmake @@ -36,30 +36,8 @@ effect or even a specific one is beyond the scope of this module. include_guard(GLOBAL) include(CheckFortranSourceCompiles) -include(CMakeCheckCompilerFlagCommonPatterns) +include(CheckCompilerFlag) -macro (CHECK_Fortran_COMPILER_FLAG _FLAG _RESULT) - set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") - - # Normalize locale during test compilation. - set(_CheckFortranCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) - foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS}) - set(_CheckFortranCompilerFlag_SAVED_${v} "$ENV{${v}}") - set(ENV{${v}} C) - endforeach() - CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckFortranCompilerFlag_COMMON_PATTERNS) - CHECK_Fortran_SOURCE_COMPILES(" program test\n stop\n end program" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "command line option .* is valid for .* but not for Fortran" # GNU - ${_CheckFortranCompilerFlag_COMMON_PATTERNS} - ) - foreach(v ${_CheckFortranCompilerFlag_LOCALE_VARS}) - set(ENV{${v}} ${_CheckFortranCompilerFlag_SAVED_${v}}) - unset(_CheckFortranCompilerFlag_SAVED_${v}) - endforeach() - unset(_CheckFortranCompilerFlag_LOCALE_VARS) - unset(_CheckFortranCompilerFlag_COMMON_PATTERNS) - - set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") +macro (CHECK_FORTRAN_COMPILER_FLAG _FLAG _RESULT) + check_compiler_flag(Fortran "${_FLAG}" ${_RESULT}) endmacro () diff --git a/Modules/CheckOBJCCompilerFlag.cmake b/Modules/CheckOBJCCompilerFlag.cmake index a98f429..df9d724 100644 --- a/Modules/CheckOBJCCompilerFlag.cmake +++ b/Modules/CheckOBJCCompilerFlag.cmake @@ -36,31 +36,8 @@ effect or even a specific one is beyond the scope of this module. include_guard(GLOBAL) include(CheckOBJCSourceCompiles) -include(CMakeCheckCompilerFlagCommonPatterns) +include(CheckCompilerFlag) macro (CHECK_OBJC_COMPILER_FLAG _FLAG _RESULT) - set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") - - # Normalize locale during test compilation. - set(_CheckOBJCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) - foreach(v ${_CheckOBJCCompilerFlag_LOCALE_VARS}) - set(_CheckOBJCCompilerFlag_SAVED_${v} "$ENV{${v}}") - set(ENV{${v}} OBJC) - endforeach() - CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckOBJCCompilerFlag_COMMON_PATTERNS) - CHECK_OBJC_SOURCE_COMPILES("#ifndef __OBJC__\n# error \"Not an Objective-C compiler\"\n#endif\nint main(void) { return 0; }" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "command line option .* is valid for .* but not for Objective-C" # GNU - FAIL_REGEX "argument unused during compilation: .*" # Clang - ${_CheckOBJCCompilerFlag_COMMON_PATTERNS} - ) - foreach(v ${_CheckOBJCCompilerFlag_LOCALE_VARS}) - set(ENV{${v}} ${_CheckOBJCCompilerFlag_SAVED_${v}}) - unset(_CheckOBJCCompilerFlag_SAVED_${v}) - endforeach() - unset(_CheckOBJCCompilerFlag_LOCALE_VARS) - unset(_CheckOBJCCompilerFlag_COMMON_PATTERNS) - - set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") + check_compiler_flag(OBJC "${_FLAG}" ${_RESULT}) endmacro () diff --git a/Modules/CheckOBJCXXCompilerFlag.cmake b/Modules/CheckOBJCXXCompilerFlag.cmake index 7944ab0..6e01bcc 100644 --- a/Modules/CheckOBJCXXCompilerFlag.cmake +++ b/Modules/CheckOBJCXXCompilerFlag.cmake @@ -36,31 +36,8 @@ effect or even a specific one is beyond the scope of this module. include_guard(GLOBAL) include(CheckOBJCXXSourceCompiles) -include(CMakeCheckCompilerFlagCommonPatterns) +include(CheckCompilerFlag) macro (CHECK_OBJCXX_COMPILER_FLAG _FLAG _RESULT) - set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}") - set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}") - - # Normalize locale during test compilation. - set(_CheckOBJCXXCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG) - foreach(v ${_CheckOBJCXXCompilerFlag_LOCALE_VARS}) - set(_CheckOBJCXXCompilerFlag_SAVED_${v} "$ENV{${v}}") - set(ENV{${v}} OBJCXX) - endforeach() - CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckOBJCXXCompilerFlag_COMMON_PATTERNS) - CHECK_OBJCXX_SOURCE_COMPILES("#ifndef __OBJC__\n# error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }" ${_RESULT} - # Some compilers do not fail with a bad flag - FAIL_REGEX "command line option .* is valid for .* but not for Objective-C\\\\+\\\\+" # GNU - FAIL_REGEX "argument unused during compilation: .*" # Clang - ${_CheckOBJCXXCompilerFlag_COMMON_PATTERNS} - ) - foreach(v ${_CheckOBJCXXCompilerFlag_LOCALE_VARS}) - set(ENV{${v}} ${_CheckOBJCXXCompilerFlag_SAVED_${v}}) - unset(_CheckOBJCXXCompilerFlag_SAVED_${v}) - endforeach() - unset(_CheckOBJCXXCompilerFlag_LOCALE_VARS) - unset(_CheckOBJCXXCompilerFlag_COMMON_PATTERNS) - - set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}") + check_compiler_flag(OBJCXX "${_FLAG}" ${_RESULT}) endmacro () |