mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-06 13:51:33 -06:00
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:
@@ -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,
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ class cmake;
|
|||||||
|
|
||||||
enum class LinkLibrariesStrategy
|
enum class LinkLibrariesStrategy
|
||||||
{
|
{
|
||||||
PRESERVE_ORDER,
|
REORDER_MINIMALLY,
|
||||||
REORDER,
|
REORDER_FREELY,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** \class cmComputeLinkDepends
|
/** \class cmComputeLinkDepends
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
|
|
||||||
include(Basic-common.cmake)
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
|
|
||||||
include(Basic-common.cmake)
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_FREELY)
|
||||||
|
include(Basic-common.cmake)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_MINIMALLY)
|
||||||
|
include(Basic-common.cmake)
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
|
|
||||||
include(Duplicate-common.cmake)
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
|
|
||||||
include(Duplicate-common.cmake)
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_FREELY)
|
||||||
|
include(Duplicate-common.cmake)
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER_MINIMALLY)
|
||||||
|
include(Duplicate-common.cmake)
|
||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user