Browse Source

Optionally exclude implicit link directories via environment

A misconfigured compiler may pass extraneous implicit link directories
to its linker.  If they are in `CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES`,
CMake may generate extra `-L` flags on mixed-language link lines that
break linking.  Add an environment variable that users can set to work
around such misconfiguration of their compilers.
pull/365/head
Brad King 2 years ago
parent
commit
023de565d3
  1. 13
      Help/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE.rst
  2. 1
      Help/manual/cmake-env-variables.7.rst
  3. 7
      Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
  4. 4
      Modules/CMakeDetermineCompilerABI.cmake
  5. 10
      Tests/RunCMake/ParseImplicitLinkInfo/ExcludeDirs.cmake
  6. 12
      Tests/RunCMake/ParseImplicitLinkInfo/Inspect.cmake
  7. 8
      Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake

13
Help/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE.rst

@ -0,0 +1,13 @@
CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES_EXCLUDE
----------------------------------------------
.. versionadded:: 3.27
.. include:: ENV_VAR.txt
A :ref:`semicolon-separated list <CMake Language Lists>` of directories
to exclude from the :variable:`CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES`
variable when it is automatically detected from the ``<LANG>`` compiler.
This may be used to work around misconfigured compiler drivers that pass
extraneous implicit link directories to their linker.

1
Help/manual/cmake-env-variables.7.rst

@ -50,6 +50,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_GENERATOR_TOOLSET
/envvar/CMAKE_INSTALL_MODE
/envvar/CMAKE_LANG_COMPILER_LAUNCHER
/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE
/envvar/CMAKE_LANG_LINKER_LAUNCHER
/envvar/CMAKE_MSVCIDE_RUN_PATH
/envvar/CMAKE_NO_VERBOSE

7
Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst

@ -6,9 +6,14 @@ Implicit linker search path detected for language ``<LANG>``.
Compilers typically pass directories containing language runtime
libraries and default library search paths when they invoke a linker.
These paths are implicit linker search directories for the compiler's
language. For each language enabled by the :command:`project` or
language.
For each language enabled by the :command:`project` or
:command:`enable_language` command, CMake automatically detects these
directories and reports the results in this variable.
The :envvar:`CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES_EXCLUDE` environment
variable may be set to exclude specific directories from the automatically
detected results.
When linking to a static library, CMake adds the implicit link directories
from this variable for each language used in the static library (except

4
Modules/CMakeDetermineCompilerABI.cmake

@ -181,6 +181,10 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
endif()
endif()
if(DEFINED ENV{CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES_EXCLUDE})
list(REMOVE_ITEM implicit_dirs $ENV{CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES_EXCLUDE})
endif()
set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)

10
Tests/RunCMake/ParseImplicitLinkInfo/ExcludeDirs.cmake

@ -0,0 +1,10 @@
include("${info}")
list(GET INFO_CMAKE_C_IMPLICIT_LINK_DIRECTORIES -1 last_dir)
set(ENV{CMAKE_C_IMPLICIT_LINK_DIRECTORIES_EXCLUDE} "${last_dir}")
enable_language(C)
message(STATUS "INFO_CMAKE_C_IMPLICIT_LINK_DIRECTORIES=[${INFO_CMAKE_C_IMPLICIT_LINK_DIRECTORIES}]")
message(STATUS "ENV{CMAKE_C_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}=[$ENV{CMAKE_C_IMPLICIT_LINK_DIRECTORIES_EXCLUDE}]")
message(STATUS "CMAKE_C_IMPLICIT_LINK_DIRECTORIES=[${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}]")
if("${last_dir}" IN_LIST CMAKE_C_IMPLICIT_LINK_DIRECTORIES)
message(FATAL_ERROR "${last_dir} was not excluded!")
endif()

12
Tests/RunCMake/ParseImplicitLinkInfo/Inspect.cmake

@ -0,0 +1,12 @@
enable_language(C)
set(info "")
foreach(var
CMAKE_C_IMPLICIT_LINK_DIRECTORIES
)
if(DEFINED ${var})
string(APPEND info "set(INFO_${var} \"${${var}}\")\n")
endif()
endforeach()
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")

8
Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake

@ -1,3 +1,11 @@
include(RunCMake)
run_cmake(ParseImplicitLinkInfo)
run_cmake(Inspect)
set(info "${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
include("${info}")
if(INFO_CMAKE_C_IMPLICIT_LINK_DIRECTORIES MATCHES ";")
run_cmake_with_options(ExcludeDirs "-Dinfo=${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
endif()
Loading…
Cancel
Save