summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-05-25 15:59:26 (GMT)
committerBrad King <brad.king@kitware.com>2023-05-25 17:42:58 (GMT)
commit023de565d33cdb095c0d5665e408493087e4d458 (patch)
tree8f52e06801201ec59cb11dab088dbd9a289f1be2
parentcf7b7600c669ea162e0c3960c3e4e3a5d04f3274 (diff)
downloadCMake-023de565d33cdb095c0d5665e408493087e4d458.zip
CMake-023de565d33cdb095c0d5665e408493087e4d458.tar.gz
CMake-023de565d33cdb095c0d5665e408493087e4d458.tar.bz2
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.
-rw-r--r--Help/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE.rst13
-rw-r--r--Help/manual/cmake-env-variables.7.rst1
-rw-r--r--Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst7
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake4
-rw-r--r--Tests/RunCMake/ParseImplicitLinkInfo/ExcludeDirs.cmake10
-rw-r--r--Tests/RunCMake/ParseImplicitLinkInfo/Inspect.cmake12
-rw-r--r--Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake8
7 files changed, 54 insertions, 1 deletions
diff --git a/Help/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE.rst b/Help/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE.rst
new file mode 100644
index 0000000..36c79fa
--- /dev/null
+++ b/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.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index f7ae94d..197e56e 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/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
diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
index 081c4da..7e008df 100644
--- a/Help/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES.rst
+++ b/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
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 3fd54cc..d665cd1 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/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)
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/ExcludeDirs.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/ExcludeDirs.cmake
new file mode 100644
index 0000000..6cece68
--- /dev/null
+++ b/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()
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/Inspect.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/Inspect.cmake
new file mode 100644
index 0000000..42e1c67
--- /dev/null
+++ b/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}")
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake
index 713e2e7..c7655d2 100644
--- a/Tests/RunCMake/ParseImplicitLinkInfo/RunCMakeTest.cmake
+++ b/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()