LINK_LIBRARIES_STRATEGY: Rename strategies to clarify expectations

Since commit 7abd3137b7 (Linking: Optionally reorder direct dependencies
from LINK_LIBRARIES, 2024-09-19, v3.31.0-rc1~53^2) the strategy name
`PRESERVE_ORDER` has led users to expect that it strictly preserves
order.  While the part of the link line generation logic controlled by
`LINK_LIBRARIES_STRATEGY` does preserve order, it is not the last step.
Toolchain-specific de-duplication can cause the order to change on the
actual link line generated in the build system.

Rename the strategies:

* `PRESERVE_ORDER` => `REORDER_MINIMALLY`
* `REORDER`        => `REORDER_FREELY`

The new names make it clear that reordering is always possible, just to
varying degrees.  Update the `LINK_LIBRARIES_STRATEGY` documentation to
clarify that the strategies do not directly control the final link line.

Fixes: #26400
Issue: #26271
This commit is contained in:
Brad King
2024-10-25 09:53:57 -04:00
parent ebd038613e
commit 39fd396421
27 changed files with 32 additions and 29 deletions

View File

@@ -15,7 +15,8 @@ target's direct link dependencies, typically populated by calls to
propagated from those entries of :prop_tgt:`LINK_LIBRARIES` that name propagated from those entries of :prop_tgt:`LINK_LIBRARIES` that name
library targets by following the transitive closure of their library targets by following the transitive closure of their
:prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. CMake supports multiple :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. CMake supports multiple
strategies for passing direct and indirect link dependencies to the linker. strategies for nominally ordering direct and indirect link dependencies,
which are then filtered for `Toolchain-Specific Behavior`_.
Consider this example for the strategies below: Consider this example for the strategies below:
@@ -31,7 +32,7 @@ Consider this example for the strategies below:
The supported strategies are: The supported strategies are:
``PRESERVE_ORDER`` ``REORDER_MINIMALLY``
Entries of :prop_tgt:`LINK_LIBRARIES` always appear first and in their Entries of :prop_tgt:`LINK_LIBRARIES` always appear first and in their
original order. Indirect link dependencies not satisfied by the original order. Indirect link dependencies not satisfied by the
original entries may be reordered and de-duplicated with respect to original entries may be reordered and de-duplicated with respect to
@@ -46,13 +47,13 @@ The supported strategies are:
In the above example, this strategy computes a link line for ``main`` In the above example, this strategy computes a link line for ``main``
by starting with its original entries ``A B C``, and then appends by starting with its original entries ``A B C``, and then appends
another ``A`` to satisfy the dependencies of ``B`` and ``C`` on ``A``. another ``A`` to satisfy the dependencies of ``B`` and ``C`` on ``A``.
The final order produced by this strategy is ``A B C A``. The nominal order produced by this strategy is ``A B C A``.
Note that additional filtering for `Toolchain-Specific Behavior`_ Note that additional filtering for `Toolchain-Specific Behavior`_
may de-duplicate ``A`` on the actual linker invocation in the may de-duplicate ``A`` on the actual linker invocation in the
generated build system, resulting in either ``A B C`` or ``B C A``. generated build system, resulting in either ``A B C`` or ``B C A``.
``REORDER`` ``REORDER_FREELY``
Entries of :prop_tgt:`LINK_LIBRARIES` may be reordered, de-duplicated, Entries of :prop_tgt:`LINK_LIBRARIES` may be reordered, de-duplicated,
and intermixed with indirect link dependencies. This may result in and intermixed with indirect link dependencies. This may result in
more efficient link lines, but does not give projects any control of more efficient link lines, but does not give projects any control of
@@ -61,16 +62,18 @@ The supported strategies are:
In the above example, this strategy computes a link line for ``main`` In the above example, this strategy computes a link line for ``main``
by re-ordering its original entries ``A B C`` to satisfy the by re-ordering its original entries ``A B C`` to satisfy the
dependencies of ``B`` and ``C`` on ``A``. dependencies of ``B`` and ``C`` on ``A``.
The final order produced by this strategy is ``B C A``. The nominal order produced by this strategy is ``B C A``.
Toolchain-Specific Behavior Toolchain-Specific Behavior
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Regardless of the strategy used, the actual linker invocation for After one of the above strategies produces a nominal order among
some platforms may de-duplicate entries based on linker capabilities. direct and indirect link dependencies, the actual linker invocation
in the generated build system may de-duplicate entries based on
platform-specific requirements and linker capabilities.
See policy :policy:`CMP0156`. See policy :policy:`CMP0156`.
For example, if the ``PRESERVE_ORDER`` strategy produces ``A B C A``, For example, if the ``REORDER_MINIMALLY`` strategy produces ``A B C A``,
the actual link line may de-duplicate ``A`` as follows: the actual link line may de-duplicate ``A`` as follows:
* If ``A`` is a static library and the linker re-scans automatically, * If ``A`` is a static library and the linker re-scans automatically,

View File

@@ -1521,14 +1521,14 @@ void cmComputeLinkDepends::OrderLinkEntries()
// Start with the original link line. // Start with the original link line.
switch (this->Strategy) { switch (this->Strategy) {
case LinkLibrariesStrategy::PRESERVE_ORDER: { case LinkLibrariesStrategy::REORDER_MINIMALLY: {
// Emit the direct dependencies in their original order. // Emit the direct dependencies in their original order.
// This gives projects control over ordering. // This gives projects control over ordering.
for (size_t originalEntry : this->OriginalEntries) { for (size_t originalEntry : this->OriginalEntries) {
this->VisitEntry(originalEntry); this->VisitEntry(originalEntry);
} }
} break; } break;
case LinkLibrariesStrategy::REORDER: { case LinkLibrariesStrategy::REORDER_FREELY: {
// Schedule the direct dependencies for emission in topo order. // Schedule the direct dependencies for emission in topo order.
// This may produce more efficient link lines. // This may produce more efficient link lines.
for (size_t originalEntry : this->OriginalEntries) { for (size_t originalEntry : this->OriginalEntries) {

View File

@@ -29,8 +29,8 @@ class cmake;
enum class LinkLibrariesStrategy enum class LinkLibrariesStrategy
{ {
PRESERVE_ORDER, REORDER_MINIMALLY,
REORDER, REORDER_FREELY,
}; };
/** \class cmComputeLinkDepends /** \class cmComputeLinkDepends

View File

@@ -568,12 +568,12 @@ bool cmComputeLinkInformation::Compute()
return false; return false;
} }
LinkLibrariesStrategy strategy = LinkLibrariesStrategy::PRESERVE_ORDER; LinkLibrariesStrategy strategy = LinkLibrariesStrategy::REORDER_MINIMALLY;
if (cmValue s = this->Target->GetProperty("LINK_LIBRARIES_STRATEGY")) { if (cmValue s = this->Target->GetProperty("LINK_LIBRARIES_STRATEGY")) {
if (*s == "PRESERVE_ORDER"_s) { if (*s == "REORDER_MINIMALLY"_s) {
strategy = LinkLibrariesStrategy::PRESERVE_ORDER; strategy = LinkLibrariesStrategy::REORDER_MINIMALLY;
} else if (*s == "REORDER"_s) { } else if (*s == "REORDER_FREELY"_s) {
strategy = LinkLibrariesStrategy::REORDER; strategy = LinkLibrariesStrategy::REORDER_FREELY;
} else { } else {
this->CMakeInstance->IssueMessage( this->CMakeInstance->IssueMessage(
MessageType::FATAL_ERROR, MessageType::FATAL_ERROR,

View File

@@ -1,2 +0,0 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
include(Basic-common.cmake)

View File

@@ -1,2 +0,0 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
include(Basic-common.cmake)

View File

@@ -0,0 +1,2 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_FREELY)
include(Basic-common.cmake)

View File

@@ -0,0 +1,2 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_MINIMALLY)
include(Basic-common.cmake)

View File

@@ -1,2 +0,0 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
include(Duplicate-common.cmake)

View File

@@ -1,2 +0,0 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
include(Duplicate-common.cmake)

View File

@@ -0,0 +1,2 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_FREELY)
include(Duplicate-common.cmake)

View File

@@ -0,0 +1,2 @@
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_MINIMALLY)
include(Duplicate-common.cmake)

View File

@@ -44,8 +44,8 @@ function(run_strategy case exe)
endforeach() endforeach()
endfunction() endfunction()
run_strategy(Basic-PRESERVE_ORDER "main") run_strategy(Basic-REORDER_MINIMALLY "main")
run_strategy(Basic-REORDER "main") run_strategy(Basic-REORDER_FREELY "main")
run_cmake(Duplicate-PRESERVE_ORDER) run_cmake(Duplicate-REORDER_MINIMALLY)
run_cmake(Duplicate-REORDER) run_cmake(Duplicate-REORDER_FREELY)