From b0fada9964589462127cfcc45f1c6f003c349ebc Mon Sep 17 00:00:00 2001 From: Marc Chevrier Date: Wed, 2 Mar 2022 17:32:44 +0100 Subject: Genex-LINK_GROUP: Add feature RESCAN Feature RESCAN can be used to manage circular references between static libraries. --- Help/manual/cmake-generator-expressions.7.rst | 10 +++++++--- Help/release/dev/rescan-static-libraries.rst | 5 +++++ .../CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst | 7 +++++++ Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst | 7 +++++++ Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt | 22 ++++++++++++++++++++++ Modules/Platform/Linux.cmake | 8 ++++++++ Modules/Platform/SunOS.cmake | 10 ++++++++++ Modules/Platform/Windows-GNU.cmake | 8 ++++++++ .../RunCMakeTest.cmake | 8 ++++++++ .../cross_refs.cmake | 2 +- .../target_link_libraries-LINK_GROUP/rescan.cmake | 9 +++++++++ 11 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 Help/release/dev/rescan-static-libraries.rst create mode 100644 Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt create mode 100644 Tests/RunCMake/target_link_libraries-LINK_GROUP/rescan.cmake diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 403c06e..0ab4bc2 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -1236,7 +1236,7 @@ Output-Related Expressions expression. The ``library-list`` argument can hold CMake targets or external libraries. - Any ``CMake`` target of type :ref:`OBJECT ` or + Any CMake target of type :ref:`OBJECT ` or :ref:`INTERFACE ` will be ignored by this expression and will be handled in the standard way. @@ -1284,7 +1284,7 @@ Output-Related Expressions target_link_libraries(lib4 PRIVATE lib3 "$") # lib4 will only be linked with lib3 and the group {lib1,lib2} - This example will be "re-written" by ``CMake`` in the following form: + This example will be "re-written" by CMake in the following form: .. code-block:: cmake @@ -1317,7 +1317,7 @@ Output-Related Expressions target_link_libraries(lib3 PRIVATE "$" "$") - This example will be "re-written" by ``CMake`` in the following form: + This example will be "re-written" by CMake in the following form: .. code-block:: cmake @@ -1337,6 +1337,10 @@ Output-Related Expressions So, we have a circular dependency between groups ``{lib1A,lib1B}`` and ``{lib2A,lib2B}``. + CMake pre-defines some features of general interest: + + .. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt + .. genex:: $ Content of ``...`` when the property is exported using :command:`install(EXPORT)`, diff --git a/Help/release/dev/rescan-static-libraries.rst b/Help/release/dev/rescan-static-libraries.rst new file mode 100644 index 0000000..1ab3485 --- /dev/null +++ b/Help/release/dev/rescan-static-libraries.rst @@ -0,0 +1,5 @@ +rescan-static-libraries +----------------------- + +* The :genex:`LINK_GROUP` generator expression gained the ability to manage + circular references between static libraries by using ``RESCAN`` feature. diff --git a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst index b68c94a..f2ef843 100644 --- a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst @@ -18,3 +18,10 @@ See also the associated variable features independent from the link language. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +CMake pre-defines some features of general interest: + +.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst index 8aade01..fad1837 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst @@ -23,3 +23,10 @@ for the linker language, the variable set. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +CMake pre-defines some features of general interest: + +.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt new file mode 100644 index 0000000..7c5b458 --- /dev/null +++ b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt @@ -0,0 +1,22 @@ +**Circular references with static libraries** + +Some linkers are one-pass only so to handle circular references between +static libraries, the following feature can be used: + +``RESCAN`` + The specified static libraries are searched repeatedly until no + new undefined references are created. Normally, an static library is searched + only once in the order that it is specified on the command line. If a symbol + in that library is needed to resolve an undefined symbol referred to by an + object in an library that appears later on the command line, the linker would + not be able to resolve that reference. By grouping the static libraries, they + all be searched repeatedly until all possible references are resolved (use + linker options ``--start-group`` and ``--end-group`` or, on ``SunOS``, + ``-z rescan-start`` and ``-z rescan-end``). + + Using this feature has a significant performance cost. It is best to use it + only when there are unavoidable circular references between two or more static + libraries. + + This feature is available on ``Linux`` and ``SunOS`` platforms as well as + ``Windows`` when ``GNU`` toolchain is used. diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake index b5d5464..95102e1 100644 --- a/Modules/Platform/Linux.cmake +++ b/Modules/Platform/Linux.cmake @@ -19,6 +19,14 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE) set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Wl,-Bdynamic") endforeach() + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + # Debian policy requires that shared libraries be installed without # executable permission. Fedora policy requires that shared libraries # be installed with the executable permission. Since the native tools diff --git a/Modules/Platform/SunOS.cmake b/Modules/Platform/SunOS.cmake index 78eccf7..e01e892 100644 --- a/Modules/Platform/SunOS.cmake +++ b/Modules/Platform/SunOS.cmake @@ -7,6 +7,16 @@ if(CMAKE_SYSTEM MATCHES "SunOS-4") set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") endif() + +# Features for LINK_GROUP generator expression +if (CMAKE_SYSTEM_VERSION VERSION_GREATER "5.9") + ## RESCAN: request the linker to rescan static libraries until there is + ## no pending undefined symbols + set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:-z,rescan-start" "LINKER:-z,rescan-end") + set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) +endif() + + include(Platform/UnixPaths) list(APPEND CMAKE_SYSTEM_PREFIX_PATH diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index 51dc146..3c24c21 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -44,6 +44,14 @@ if("${_help}" MATCHES "GNU ld .* 2\\.1[1-6]") set(__WINDOWS_GNU_LD_RESPONSE 0) endif() + +# Features for LINK_GROUP generator expression +## RESCAN: request the linker to rescan static libraries until there is +## no pending undefined symbols +set(CMAKE_LINK_GROUP_USING_RESCAN "LINKER:--start-group" "LINKER:--end-group") +set(CMAKE_LINK_GROUP_USING_RESCAN_SUPPORTED TRUE) + + macro(__windows_compiler_gnu lang) # Create archiving rules to support large object file lists for static libraries. diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake index eedc5b9..8307bb2 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake @@ -61,3 +61,11 @@ if ((RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode" unset(RunCMake_TEST_OUTPUT_MERGE) endif() + +# Feature RESCAN +if (CMAKE_SYSTEM_NAME STREQUAL "Linux" + OR (CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND (NOT CMAKE_C_COMPILER_ID STREQUAL "SunPro" OR CMAKE_C_COMPILER_VERSION VERSION_GREATER "5.9")) + OR (WIN32 AND CMAKE_C_COMPILER_ID STREQUAL "GNU")) + run_cmake(rescan) + run_cmake_target(rescan link main) +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/cross_refs.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/cross_refs.cmake index 4a2a08c..f5f7857 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/cross_refs.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/cross_refs.cmake @@ -1,7 +1,7 @@ enable_language(C) - set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE) +set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE) if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:--start-group" diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/rescan.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/rescan.cmake new file mode 100644 index 0000000..810b892 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/rescan.cmake @@ -0,0 +1,9 @@ + +enable_language(C) + +# Feature RESCAN +add_library(static1 STATIC func1.c func3.c) +add_library(static2 STATIC func2.c) + +add_executable(main main.c) +target_link_libraries(main PRIVATE "$") -- cgit v0.12