1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-05-08 22:37:04 +08:00

Optionally exclude implicit link libraries via environment

CMake detects libraries that the compiler driver implicitly passes to
the linker, and stores them in `CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES`
for use in constructing mixed-language link lines.  Some compiler driver
flags add implicitly linked libraries that should not be used during
mixed-language linking because they are handled by similar flags passed
to the other language's compiler driver.  Add an environment variable
that users can set to avoid undesired implicit link libraries in such
scenarios.

Follow the pattern from commit 023de565d3 (Optionally exclude implicit
link directories via environment, 2023-05-25, v3.27.0-rc1~54^2).

Fixes: #26911
This commit is contained in:
Brad King 2025-05-05 11:36:16 -04:00
parent b10a2bf63a
commit 805a40b668
9 changed files with 57 additions and 5 deletions

View File

@ -11,3 +11,6 @@ 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.
See also the :envvar:`CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES_EXCLUDE`
environment variable.

View File

@ -0,0 +1,17 @@
CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES_EXCLUDE
--------------------------------------------
.. versionadded:: 4.1
.. include:: include/ENV_VAR.rst
A :ref:`semicolon-separated list <CMake Language Lists>` of libraries
to exclude from the :variable:`CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES`
variable when it is automatically detected from the ``<LANG>`` compiler.
This may be used to work around detection limitations that result in
extraneous implicit link libraries, e.g., when using compiler driver
flags that affect the set of implicitly linked libraries.
See also the :envvar:`CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES_EXCLUDE`
environment variable.

View File

@ -61,6 +61,7 @@ Environment Variables that Control the Build
/envvar/CMAKE_INSTALL_PREFIX
/envvar/CMAKE_LANG_COMPILER_LAUNCHER
/envvar/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES_EXCLUDE
/envvar/CMAKE_LANG_IMPLICIT_LINK_LIBRARIES_EXCLUDE
/envvar/CMAKE_LANG_LINKER_LAUNCHER
/envvar/CMAKE_MSVCIDE_RUN_PATH
/envvar/CMAKE_NO_VERBOSE

View File

@ -0,0 +1,6 @@
implicit-link-lib-exclude
-------------------------
* The :envvar:`CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES_EXCLUDE` environment
variable was added to optionally exclude specific libraries from the
detected set of :variable:`CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES`.

View File

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

View File

@ -287,7 +287,10 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
list(REMOVE_ITEM implicit_dirs ${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES_EXCLUDE})
endif()
# Filter out implicit link directories excluded by the environment.
# Filter out implicit link information excluded by the environment.
if(DEFINED ENV{CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES_EXCLUDE})
list(REMOVE_ITEM implicit_libs $ENV{CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES_EXCLUDE})
endif()
if(DEFINED ENV{CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES_EXCLUDE})
list(REMOVE_ITEM implicit_dirs $ENV{CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES_EXCLUDE})
endif()

View File

@ -0,0 +1,13 @@
block()
include("${info}")
set(INFO_CMAKE_C_IMPLICIT_LINK_LIBRARIES "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}" PARENT_SCOPE)
endblock()
list(GET INFO_CMAKE_C_IMPLICIT_LINK_LIBRARIES -1 last_lib)
set(ENV{CMAKE_C_IMPLICIT_LINK_LIBRARIES_EXCLUDE} "${last_lib}")
enable_language(C)
message(STATUS "INFO_CMAKE_C_IMPLICIT_LINK_LIBRARIES=[${INFO_CMAKE_C_IMPLICIT_LINK_LIBRARIES}]")
message(STATUS "ENV{CMAKE_C_IMPLICIT_LINK_LIBRARIES_EXCLUDE}=[$ENV{CMAKE_C_IMPLICIT_LINK_LIBRARIES_EXCLUDE}]")
message(STATUS "CMAKE_C_IMPLICIT_LINK_LIBRARIES=[${CMAKE_C_IMPLICIT_LINK_LIBRARIES}]")
if("${last_lib}" IN_LIST CMAKE_C_IMPLICIT_LINK_LIBRARIES)
message(FATAL_ERROR "${last_lib} was not excluded!")
endif()

View File

@ -9,6 +9,7 @@ foreach(var
CMAKE_C_COMPILER_LINKER
CMAKE_C_COMPILER_LINKER_ID
CMAKE_C_COMPILER_LINKER_VERSION
CMAKE_C_IMPLICIT_LINK_LIBRARIES
CMAKE_C_IMPLICIT_LINK_DIRECTORIES
)
if(DEFINED ${var})

View File

@ -10,6 +10,7 @@ run_cmake(ParseImplicitLinkInfo)
# - CMAKE_C_COMPILER_LINKER
# - CMAKE_C_COMPILER_LINKER_ID
# - CMAKE_C_COMPILER_LINKER_VERSION
# - CMAKE_C_IMPLICIT_LINK_LIBRARIES
# - CMAKE_C_IMPLICIT_LINK_DIRECTORIES
run_cmake(Inspect)
set(info "${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
@ -19,6 +20,9 @@ if(CMAKE_HOST_UNIX)
run_cmake_script(DetermineLinkerId)
endif()
if(CMAKE_C_IMPLICIT_LINK_LIBRARIES MATCHES ";")
run_cmake_with_options(ExcludeLibs "-Dinfo=${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
endif()
if(CMAKE_C_IMPLICIT_LINK_DIRECTORIES MATCHES ";")
run_cmake_with_options(ExcludeDirs "-Dinfo=${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
endif()