1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-17 15:32:10 +08:00

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.
This commit is contained in:
Brad King
2023-05-25 11:59:26 -04:00
parent cf7b7600c6
commit 023de565d3
7 changed files with 54 additions and 1 deletions

View File

@@ -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.

View File

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

View File

@@ -6,9 +6,14 @@ Implicit linker search path detected for language ``<LANG>``.
Compilers typically pass directories containing language runtime Compilers typically pass directories containing language runtime
libraries and default library search paths when they invoke a linker. libraries and default library search paths when they invoke a linker.
These paths are implicit linker search directories for the compiler's 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 :command:`enable_language` command, CMake automatically detects these
directories and reports the results in this variable. 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 When linking to a static library, CMake adds the implicit link directories
from this variable for each language used in the static library (except from this variable for each language used in the static library (except

View File

@@ -181,6 +181,10 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
endif() endif()
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_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE) set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE) set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)

View File

@@ -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()

View File

@@ -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}")

View File

@@ -1,3 +1,11 @@
include(RunCMake) include(RunCMake)
run_cmake(ParseImplicitLinkInfo) 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()