CheckLinkerFlag: Add module to check validity of linker flags
Fixes: #15934
This commit is contained in:
parent
3c4cc77d55
commit
af96c0f4fa
@ -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
|
||||
|
1
Help/module/CheckLinkerFlag.rst
Normal file
1
Help/module/CheckLinkerFlag.rst
Normal file
@ -0,0 +1 @@
|
||||
.. cmake-module:: ../../Modules/CheckLinkerFlag.cmake
|
5
Help/release/dev/CheckLinkerFlag.rst
Normal file
5
Help/release/dev/CheckLinkerFlag.rst
Normal file
@ -0,0 +1,5 @@
|
||||
CheckLinkerFlag
|
||||
---------------
|
||||
|
||||
* New :module:`CheckLinkerFlag` module has been added to provide a facility to
|
||||
check validity of link flags.
|
81
Modules/CheckLinkerFlag.cmake
Normal file
81
Modules/CheckLinkerFlag.cmake
Normal file
@ -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()
|
@ -487,6 +487,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)
|
||||
|
||||
|
5
Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt
Normal file
5
Tests/RunCMake/CheckLinkerFlag/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
project(${RunCMake_TEST} LANGUAGES NONE)
|
||||
|
||||
include(${RunCMake_TEST}.cmake)
|
3
Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake
Normal file
3
Tests/RunCMake/CheckLinkerFlag/CheckCLinkerFlag.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_LANGUAGE C)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
|
3
Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake
Normal file
3
Tests/RunCMake/CheckLinkerFlag/CheckCXXLinkerFlag.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_LANGUAGE CXX)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
|
@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_LANGUAGE Fortran)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
|
14
Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake
Normal file
14
Tests/RunCMake/CheckLinkerFlag/CheckLinkerFlag.cmake
Normal file
@ -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()
|
3
Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake
Normal file
3
Tests/RunCMake/CheckLinkerFlag/CheckOBJCLinkerFlag.cmake
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_LANGUAGE OBJC)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
|
@ -0,0 +1,3 @@
|
||||
|
||||
set (CHECK_LANGUAGE OBJCXX)
|
||||
include ("${CMAKE_CURRENT_SOURCE_DIR}/CheckLinkerFlag.cmake")
|
14
Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake
Normal file
14
Tests/RunCMake/CheckLinkerFlag/RunCMakeTest.cmake
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user