mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
GenEx/LINK_LIBRARY: Add NEEDED_LIBRARY support on Linux
This commit is contained in:
committed by
Brad King
parent
158b64688f
commit
a2e6306c27
@@ -0,0 +1,6 @@
|
||||
link-library-needed-library-linux
|
||||
----------------------------------
|
||||
|
||||
* The :genex:`$<LINK_LIBRARY:NEEDED_LIBRARY,...>` generator expression feature
|
||||
is now supported on Linux with GNU-compatible linkers (GNU ld, gold, LLD,
|
||||
MOLD).
|
||||
@@ -101,6 +101,19 @@
|
||||
Uses the ``-needed_library`` or ``-needed-l`` option as appropriate,
|
||||
with the same linker constraints as ``NEEDED_FRAMEWORK``.
|
||||
|
||||
Linux
|
||||
.. versionadded:: 4.5
|
||||
|
||||
Wraps the library with ``--no-as-needed`` / ``--as-needed`` to force
|
||||
an entry in the binary's ``DT_NEEDED`` list regardless of whether any
|
||||
symbols from the library are directly referenced. When the linker
|
||||
supports ``--push-state`` / ``--pop-state`` (GNU ld >= 2.25, gold,
|
||||
LLD, MOLD), the state-stacking form is used instead to correctly
|
||||
restore the pre-existing ``--as-needed`` state rather than
|
||||
unconditionally enabling it after the library. This feature is only
|
||||
meaningful for shared libraries; applying it to a static library
|
||||
produces a developer warning and has no effect.
|
||||
|
||||
``REEXPORT_LIBRARY``
|
||||
This is similar to the ``REEXPORT_FRAMEWORK`` feature, except it is for use
|
||||
with non-framework targets or libraries (Apple platforms only).
|
||||
|
||||
@@ -57,6 +57,31 @@ function(__cmake_set_whole_archive_feature __linker __linker_options)
|
||||
set(CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED "${CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# NEEDED_LIBRARY Feature for LINK_LIBRARY generator expression
|
||||
## Force a shared library into DT_NEEDED even when no symbols are referenced
|
||||
function(__cmake_set_needed_library_feature __linker __linker_options)
|
||||
unset(__lang)
|
||||
if(ARGC EQUAL "3")
|
||||
set(__lang "${ARGV2}_")
|
||||
endif()
|
||||
|
||||
__cmake_check_linker_pushpop_state("${__linker}" "${__linker_options}" ${ARGV2})
|
||||
|
||||
## NEEDED_LIBRARY: Force DT_NEEDED entry for a shared library
|
||||
if(CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED)
|
||||
set(CMAKE_${__lang}LINK_LIBRARY_USING_NEEDED_LIBRARY "LINKER:--push-state,--no-as-needed"
|
||||
"<LINK_ITEM>"
|
||||
"LINKER:--pop-state" PARENT_SCOPE)
|
||||
else()
|
||||
set(CMAKE_${__lang}LINK_LIBRARY_USING_NEEDED_LIBRARY "LINKER:--no-as-needed"
|
||||
"<LINK_ITEM>"
|
||||
"LINKER:--as-needed" PARENT_SCOPE)
|
||||
endif()
|
||||
set(CMAKE_${__lang}LINK_LIBRARY_USING_NEEDED_LIBRARY_SUPPORTED TRUE PARENT_SCOPE)
|
||||
set(CMAKE_${__lang}LINK_LIBRARY_NEEDED_LIBRARY_ATTRIBUTES LIBRARY_TYPE=SHARED DEDUPLICATION=DEFAULT OVERRIDE=DEFAULT PARENT_SCOPE)
|
||||
set(CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED "${CMAKE_${__lang}LINKER_PUSHPOP_STATE_SUPPORTED}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
## Configure system linker
|
||||
__cmake_set_whole_archive_feature("${CMAKE_LINKER}" "")
|
||||
__cmake_set_needed_library_feature("${CMAKE_LINKER}" "")
|
||||
|
||||
@@ -13,5 +13,8 @@ macro(__linux_linker_gnu lang)
|
||||
__cmake_set_whole_archive_feature("${CMAKE_${lang}_COMPILER_LINKER}"
|
||||
"${CMAKE_${lang}_COMPILER_LINKER_ARCHITECTURE_FLAGS}"
|
||||
"${lang}")
|
||||
__cmake_set_needed_library_feature("${CMAKE_${lang}_COMPILER_LINKER}"
|
||||
"${CMAKE_${lang}_COMPILER_LINKER_ARCHITECTURE_FLAGS}"
|
||||
"${lang}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -123,6 +123,11 @@ if(APPLE AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND CMAKE_C_COMPILER_VERSION GREATER_EQUAL "12")
|
||||
run_cmake_target(apple_library needed_library main-needed_library)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang"))
|
||||
run_cmake(linux_library_external)
|
||||
run_cmake_target(linux_library_external build external)
|
||||
run_cmake_with_options(linux_library "-DRunCMake_BINARY_DIR=${RunCMake_BINARY_DIR}")
|
||||
run_cmake_target(linux_library needed_library main-needed_library)
|
||||
endif()
|
||||
|
||||
# WHOLE_ARCHIVE feature
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
enable_language(C)
|
||||
|
||||
add_library(lib SHARED base.c lib.c)
|
||||
|
||||
# feature NEEDED_LIBRARY
|
||||
add_executable(main-needed_library main.c)
|
||||
target_link_directories(main-needed_library PRIVATE "${RunCMake_BINARY_DIR}/linux_library_external-build"
|
||||
"${RunCMake_BINARY_DIR}/linux_library_external-build/$<CONFIG>")
|
||||
target_link_libraries(main-needed_library PRIVATE "$<LINK_LIBRARY:NEEDED_LIBRARY,lib,external>")
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
enable_language(C)
|
||||
|
||||
add_library(external SHARED unref.c)
|
||||
Reference in New Issue
Block a user