diff options
author | Brad King <brad.king@kitware.com> | 2020-05-25 14:58:54 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-05-25 14:59:01 (GMT) |
commit | a354b7f21e858728606ddc7c275bad35914d8eaa (patch) | |
tree | 3766fcf93b02ebbe0ecc48bbce0f7e99258850d5 | |
parent | b82bdbf44aeef29ba7b266989f1557a0ffcaa969 (diff) | |
parent | af96c0f4faf5bf9f4a4dbc958b09a1dfc58dab38 (diff) | |
download | CMake-a354b7f21e858728606ddc7c275bad35914d8eaa.zip CMake-a354b7f21e858728606ddc7c275bad35914d8eaa.tar.gz CMake-a354b7f21e858728606ddc7c275bad35914d8eaa.tar.bz2 |
Merge topic 'CheckLinkerFlag-module'
af96c0f4fa CheckLinkerFlag: Add module to check validity of linker flags
3c4cc77d55 Tests: Extend Fortran compiler information
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4777
-rw-r--r-- | Help/manual/cmake-modules.7.rst | 1 | ||||
-rw-r--r-- | Help/module/CheckLinkerFlag.rst | 1 | ||||
-rw-r--r-- | Help/release/dev/CheckLinkerFlag.rst | 5 | ||||
-rw-r--r-- | Modules/CheckLinkerFlag.cmake | 81 | ||||
-rw-r--r-- | Tests/CheckFortran.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 6 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake | 14 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake | 14 |
14 files changed, 145 insertions, 0 deletions
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index be64112..50131e8 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -36,6 +36,7 @@ These modules are loaded using the :command:`include` command. /module/CheckIncludeFiles /module/CheckLanguage /module/CheckLibraryExists + /module/CheckLinkerFlag /module/CheckOBJCCompilerFlag /module/CheckOBJCSourceCompiles /module/CheckOBJCSourceRuns diff --git a/Help/module/CheckLinkerFlag.rst b/Help/module/CheckLinkerFlag.rst new file mode 100644 index 0000000..4005725 --- /dev/null +++ b/Help/module/CheckLinkerFlag.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CheckLinkerFlag.cmake diff --git a/Help/release/dev/CheckLinkerFlag.rst b/Help/release/dev/CheckLinkerFlag.rst new file mode 100644 index 0000000..fd48d99 --- /dev/null +++ b/Help/release/dev/CheckLinkerFlag.rst @@ -0,0 +1,5 @@ +CheckLinkerFlag +--------------- + +* New :module:`CheckLinkerFlag` module has been added to provide a facility to + check validity of link flags. diff --git a/Modules/CheckLinkerFlag.cmake b/Modules/CheckLinkerFlag.cmake new file mode 100644 index 0000000..beda5fe --- /dev/null +++ b/Modules/CheckLinkerFlag.cmake @@ -0,0 +1,81 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +CheckLinkerFlag +--------------- + +Check whether the compiler supports a given link flag. + +.. command:: check_linker_flag + + .. code-block:: cmake + + check_linker_flag(<lang> <flag> <var>) + +Check that the link ``<flag>`` is accepted by the ``<lang>`` compiler without +a diagnostic. Stores the result in an internal cache entry named ``<var>``. + +This command temporarily sets the ``CMAKE_REQUIRED_LINK_OPTIONS`` variable +and calls the ``check_<lang>_source_compiles`` macro from the +``Check<lang>SourceCompiles`` module (:module:`CheckCSourceCompiles`, +:module:`CheckCSourceCompiles`, :module:`CheckCXXSourceCompiles`, +:module:`CheckOBJCSourceCompiles`, :module:`CheckOBJCXXSourceCompiles` or +:module:`CheckFortranSourceCompiles`). See documentation of these +modules for a listing of variables that can otherwise modify the build. + +The underlying implementation rely on :prop_tgt:`LINK_OPTIONS` property to +check the specified flag. The ``LINKER:`` prefix, as described in +:command:`target_link_options` command, can be used as well. + +A positive result from this check indicates only that the compiler did not +issue a diagnostic message when given the link 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`, unknown flags in such variables may + cause a false negative for this check. +#]=======================================================================] + +include_guard(GLOBAL) + +include(CMakeCheckCompilerFlagCommonPatterns) + +function(CHECK_LINKER_FLAG _lang _flag _var) + get_property (_supported_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (NOT _lang IN_LIST _supported_languages) + message (SEND_ERROR "check_linker_flag: ${_lang}: unknown language.") + return() + endif() + + include (Check${_lang}SourceCompiles) + + set(CMAKE_REQUIRED_LINK_OPTIONS "${_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() + + if (_lang MATCHES "^(C|CXX)$") + set (_source "int main() { return 0; }") + elseif (_lang STREQUAL "Fortran") + set (_source " program test\n stop\n end program") + elseif (_lang MATCHES "^(OBJC|OBJCXX)$") + set (_source "#ifndef __OBJC__\n# error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }") + else() + message (SEND_ERROR "check_linker_flag: ${_lang}: unsupported language.") + return() + endif() + check_compiler_flag_common_patterns(_common_patterns) + + cmake_language (CALL check_${_lang}_source_compiles "${_source}" ${_var} ${_common_patterns}) + + foreach(v IN LISTS _locale_vars) + set(ENV{${v}} ${_locale_vars_saved_${v}}) + endforeach() + set(${_var} "${${_var}}" PARENT_SCOPE) +endfunction() diff --git a/Tests/CheckFortran.cmake b/Tests/CheckFortran.cmake index 16a8ed2..33e1bfb 100644 --- a/Tests/CheckFortran.cmake +++ b/Tests/CheckFortran.cmake @@ -11,6 +11,7 @@ if(NOT DEFINED CMAKE_Fortran_COMPILER) project(CheckFortran Fortran) file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" \"set(CMAKE_Fortran_COMPILER \\\"\${CMAKE_Fortran_COMPILER}\\\")\\n\" + \"set(CMAKE_Fortran_COMPILER_ID \\\"\${CMAKE_Fortran_COMPILER_ID}\\\")\\n\" \"set(CMAKE_Fortran_FLAGS \\\"\${CMAKE_Fortran_FLAGS}\\\")\\n\" \"set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 \\\"\${CMAKE_Fortran_COMPILER_SUPPORTS_F90}\\\")\\n\" ) @@ -45,6 +46,8 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\" message(STATUS "${_desc} - ${CMAKE_Fortran_COMPILER}") set(CMAKE_Fortran_COMPILER "${CMAKE_Fortran_COMPILER}" CACHE FILEPATH "Fortran compiler") mark_as_advanced(CMAKE_Fortran_COMPILER) + set(CMAKE_Fortran_COMPILER_ID "${CMAKE_Fortran_COMPILER_ID}" CACHE STRING "Fortran compiler Id") + mark_as_advanced(CMAKE_Fortran_COMPILER_ID) set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING "Fortran flags") mark_as_advanced(CMAKE_Fortran_FLAGS) set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 "${CMAKE_Fortran_COMPILER_SUPPORTS_F90}" CACHE BOOL "Fortran compiler supports F90") diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 5f3f38b..983f7e4 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -488,6 +488,12 @@ add_RunCMake_test(target_include_directories) add_RunCMake_test(target_sources) add_RunCMake_test(CheckModules) add_RunCMake_test(CheckIPOSupported) +if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin)" + AND (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU" OR CMAKE_Fortran_COMPILER_ID MATCHES "GNU")) + add_RunCMake_test(CheckLinkerFlag -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} + -DCMAKE_Fortran_COMPILER_ID=${CMAKE_Fortran_COMPILER_ID}) +endif() + add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}) add_RunCMake_test(CommandLineTar) diff --git a/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt new file mode 100644 index 0000000..0421e28 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.13) + +project(${RunCMake_TEST} LANGUAGES NONE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake new file mode 100644 index 0000000..c8e87a4 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE C) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake new file mode 100644 index 0000000..4e299b9 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE CXX) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake new file mode 100644 index 0000000..bca288e --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckFortranLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE Fortran) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake new file mode 100644 index 0000000..c3bd465 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake @@ -0,0 +1,14 @@ + +enable_language (${CHECK_LANGUAGE}) + +include(CheckLinkerFlag) + +check_linker_flag(${CHECK_LANGUAGE} "LINKER:-L,/dir" VALID_LINKER_FLAG) +if(NOT VALID_LINKER_FLAG) + message(SEND_ERROR "Test fail for valid linker flag.") +endif() + +check_linker_flag(${CHECK_LANGUAGE} "LINKER:-D" INVALID_LINKER_FLAG) +if(INVALID_LINKER_FLAG) + message(SEND_ERROR "Test fail for invalid linker flag.") +endif() diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake new file mode 100644 index 0000000..fa1d18e --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE OBJC) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake new file mode 100644 index 0000000..414efb8 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/CheckOBJCXXLinkerFlag.cmake @@ -0,0 +1,3 @@ + +set (CHECK_LANGUAGE OBJCXX) +include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake") diff --git a/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake new file mode 100644 index 0000000..224a2a3 --- /dev/null +++ b/Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake @@ -0,0 +1,14 @@ +include(RunCMake) + +if (CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + run_cmake(CheckCLinkerFlag) + run_cmake(CheckCXXLinkerFlag) + if (APPLE) + run_cmake(CheckOBJCLinkerFlag) + run_cmake(CheckOBJCXXLinkerFlag) + endif() +endif() + +if (CMAKE_Fortran_COMPILER_ID MATCHES "GNU") + run_cmake(CheckFortranLinkerFlag) +endif() |