mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-22 07:25:02 +08:00
Linking: Optionally reorder direct dependencies from LINK_LIBRARIES
Traditionally CMake generates link lines by starting with the direct link dependencies specified by `LINK_LIBRARIES` in their original order and then appending indirect dependencies that the direct dependencies do not express. This gives projects control over ordering among independent entries, which can be important when intermixing flags and libraries, or when multiple libraries provide the same symbol. However, it may also result in inefficient link lines. Add support for an alternative strategy that can reorder direct link dependencies to produce more efficient link lines. This is useful for projects that cannot easily specify their targets' direct dependencies in an order that satisfies indirect dependencies. Add a `CMAKE_LINK_LIBRARIES_STRATEGY` variable and corresponding `LINK_LIBRARIES_STRATEGY` target property to select a strategy. Fixes: #26271
This commit is contained in:
@@ -140,6 +140,11 @@ Items containing ``::``, such as ``Foo::Bar``, are assumed to be
|
||||
target names and will cause an error if no such target exists.
|
||||
See policy :policy:`CMP0028`.
|
||||
|
||||
See the :variable:`CMAKE_LINK_LIBRARIES_STRATEGY` variable and
|
||||
corresponding :prop_tgt:`LINK_LIBRARIES_STRATEGY` target property
|
||||
for details on how CMake orders direct link dependencies on linker
|
||||
command lines.
|
||||
|
||||
See the :manual:`cmake-buildsystem(7)` manual for more on defining
|
||||
buildsystem properties.
|
||||
|
||||
|
@@ -336,6 +336,7 @@ Properties on Targets
|
||||
/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG
|
||||
/prop_tgt/LINK_LIBRARIES
|
||||
/prop_tgt/LINK_LIBRARIES_ONLY_TARGETS
|
||||
/prop_tgt/LINK_LIBRARIES_STRATEGY
|
||||
/prop_tgt/LINK_LIBRARY_OVERRIDE
|
||||
/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY
|
||||
/prop_tgt/LINK_OPTIONS
|
||||
|
@@ -491,6 +491,7 @@ Variables that Control the Build
|
||||
/variable/CMAKE_LINK_GROUP_USING_FEATURE
|
||||
/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED
|
||||
/variable/CMAKE_LINK_INTERFACE_LIBRARIES
|
||||
/variable/CMAKE_LINK_LIBRARIES_STRATEGY
|
||||
/variable/CMAKE_LINK_LIBRARY_FEATURE_ATTRIBUTES
|
||||
/variable/CMAKE_LINK_LIBRARY_FILE_FLAG
|
||||
/variable/CMAKE_LINK_LIBRARY_FLAG
|
||||
|
@@ -28,3 +28,8 @@ In advanced use cases, the list of direct link dependencies specified
|
||||
by this property may be updated by usage requirements from dependencies.
|
||||
See the :prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT` and
|
||||
:prop_tgt:`INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE` target properties.
|
||||
|
||||
See the :variable:`CMAKE_LINK_LIBRARIES_STRATEGY` variable and
|
||||
corresponding :prop_tgt:`LINK_LIBRARIES_STRATEGY` target property
|
||||
for details on how CMake orders direct link dependencies on linker
|
||||
command lines.
|
||||
|
11
Help/prop_tgt/LINK_LIBRARIES_STRATEGY.rst
Normal file
11
Help/prop_tgt/LINK_LIBRARIES_STRATEGY.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
LINK_LIBRARIES_STRATEGY
|
||||
-----------------------
|
||||
|
||||
.. versionadded:: 3.31
|
||||
|
||||
Specify a strategy for ordering a target's direct link dependencies
|
||||
on linker command lines.
|
||||
|
||||
See the :variable:`CMAKE_LINK_LIBRARIES_STRATEGY` variable for details
|
||||
and supported values. This property is initialized by the value of that
|
||||
variable when a target is created.
|
7
Help/release/dev/link-strategy.rst
Normal file
7
Help/release/dev/link-strategy.rst
Normal file
@@ -0,0 +1,7 @@
|
||||
link-strategy
|
||||
-------------
|
||||
|
||||
* The :variable:`CMAKE_LINK_LIBRARIES_STRATEGY` variable and
|
||||
corresponding :prop_tgt:`LINK_LIBRARIES_STRATEGY` target
|
||||
property were added to optionally specify the strategy
|
||||
CMake uses to generate link lines.
|
68
Help/variable/CMAKE_LINK_LIBRARIES_STRATEGY.rst
Normal file
68
Help/variable/CMAKE_LINK_LIBRARIES_STRATEGY.rst
Normal file
@@ -0,0 +1,68 @@
|
||||
CMAKE_LINK_LIBRARIES_STRATEGY
|
||||
-----------------------------
|
||||
|
||||
.. versionadded:: 3.31
|
||||
|
||||
Specify a strategy for ordering targets' direct link dependencies
|
||||
on linker command lines.
|
||||
|
||||
The value of this variable initializes the :prop_tgt:`LINK_LIBRARIES_STRATEGY`
|
||||
target property of targets as they are created. Set that property directly
|
||||
to specify a strategy for a single target.
|
||||
|
||||
CMake generates a target's link line using its :ref:`Target Link Properties`.
|
||||
In particular, the :prop_tgt:`LINK_LIBRARIES` target property records the
|
||||
target's direct link dependencies, typically populated by calls to
|
||||
:command:`target_link_libraries`. Indirect link dependencies are
|
||||
propagated from those entries of :prop_tgt:`LINK_LIBRARIES` that name
|
||||
library targets by following the transitive closure of their
|
||||
:prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. CMake supports multiple
|
||||
strategies for passing direct and indirect link dependencies to the linker.
|
||||
|
||||
Consider this example for the strategies below:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
add_library(A STATIC ...)
|
||||
add_library(B STATIC ...)
|
||||
add_library(C STATIC ...)
|
||||
add_executable(main ...)
|
||||
target_link_libraries(B PRIVATE A)
|
||||
target_link_libraries(C PRIVATE A)
|
||||
target_link_libraries(main PRIVATE A B C)
|
||||
|
||||
The supported strategies are:
|
||||
|
||||
``PRESERVE_ORDER``
|
||||
Entries of :prop_tgt:`LINK_LIBRARIES` always appear first and in their
|
||||
original order. Indirect link dependencies not satisfied by the
|
||||
original entries may be reordered and de-duplicated with respect to
|
||||
one another, but are always appended after the original entries.
|
||||
This may result in less efficient link lines, but gives projects
|
||||
control of ordering among independent entries. Such control may be
|
||||
important when intermixing link flags with libraries, or when multiple
|
||||
libraries provide a given symbol.
|
||||
|
||||
This is the default.
|
||||
|
||||
In the above example, this strategy computes a link line for ``main``
|
||||
by starting with its original entries ``A B C``, and then appends
|
||||
another ``A`` to satisfy the dependencies of ``B`` and ``C`` on ``A``.
|
||||
The final order is ``A B C A``.
|
||||
|
||||
``REORDER``
|
||||
Entries of :prop_tgt:`LINK_LIBRARIES` may be reordered, de-duplicated,
|
||||
and intermixed with indirect link dependencies. This may result in
|
||||
more efficient link lines, but does not give projects any control of
|
||||
ordering among independent entries.
|
||||
|
||||
In the above example, this strategy computes a link line for ``main``
|
||||
by re-ordering its original entries ``A B C`` to satisfy the
|
||||
dependencies of ``B`` and ``C`` on ``A``.
|
||||
The final order is ``B C A``.
|
||||
|
||||
.. note::
|
||||
|
||||
Regardless of the strategy used, the actual linker invocation for
|
||||
some platforms may de-duplicate entries based on linker capabilities.
|
||||
See policy :policy:`CMP0156`.
|
@@ -581,7 +581,8 @@ std::string const& cmComputeLinkDepends::LinkEntry::DEFAULT =
|
||||
|
||||
cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
|
||||
const std::string& config,
|
||||
const std::string& linkLanguage)
|
||||
const std::string& linkLanguage,
|
||||
LinkLibrariesStrategy strategy)
|
||||
: Target(target)
|
||||
, Makefile(this->Target->Target->GetMakefile())
|
||||
, GlobalGenerator(this->Target->GetLocalGenerator()->GetGlobalGenerator())
|
||||
@@ -592,6 +593,7 @@ cmComputeLinkDepends::cmComputeLinkDepends(const cmGeneratorTarget* target,
|
||||
, LinkLanguage(linkLanguage)
|
||||
, LinkType(CMP0003_ComputeLinkType(
|
||||
this->Config, this->Makefile->GetCMakeInstance()->GetDebugConfigs()))
|
||||
, Strategy(strategy)
|
||||
|
||||
{
|
||||
// target oriented feature override property takes precedence over
|
||||
@@ -1488,8 +1490,22 @@ void cmComputeLinkDepends::OrderLinkEntries()
|
||||
}
|
||||
|
||||
// Start with the original link line.
|
||||
for (size_t originalEntry : this->OriginalEntries) {
|
||||
this->VisitEntry(originalEntry);
|
||||
switch (this->Strategy) {
|
||||
case LinkLibrariesStrategy::PRESERVE_ORDER: {
|
||||
// Emit the direct dependencies in their original order.
|
||||
// This gives projects control over ordering.
|
||||
for (size_t originalEntry : this->OriginalEntries) {
|
||||
this->VisitEntry(originalEntry);
|
||||
}
|
||||
} break;
|
||||
case LinkLibrariesStrategy::REORDER: {
|
||||
// Schedule the direct dependencies for emission in topo order.
|
||||
// This may produce more efficient link lines.
|
||||
for (size_t originalEntry : this->OriginalEntries) {
|
||||
this->MakePendingComponent(
|
||||
this->CCG->GetComponentMap()[originalEntry]);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
// Now explore anything left pending. Since the component graph is
|
||||
|
@@ -27,6 +27,12 @@ class cmMakefile;
|
||||
class cmSourceFile;
|
||||
class cmake;
|
||||
|
||||
enum class LinkLibrariesStrategy
|
||||
{
|
||||
PRESERVE_ORDER,
|
||||
REORDER,
|
||||
};
|
||||
|
||||
/** \class cmComputeLinkDepends
|
||||
* \brief Compute link dependencies for targets.
|
||||
*/
|
||||
@@ -35,7 +41,8 @@ class cmComputeLinkDepends
|
||||
public:
|
||||
cmComputeLinkDepends(cmGeneratorTarget const* target,
|
||||
const std::string& config,
|
||||
const std::string& linkLanguage);
|
||||
const std::string& linkLanguage,
|
||||
LinkLibrariesStrategy strategy);
|
||||
~cmComputeLinkDepends();
|
||||
|
||||
cmComputeLinkDepends(const cmComputeLinkDepends&) = delete;
|
||||
@@ -94,6 +101,7 @@ private:
|
||||
bool DebugMode = false;
|
||||
std::string LinkLanguage;
|
||||
cmTargetLinkLibraryType LinkType;
|
||||
LinkLibrariesStrategy Strategy;
|
||||
|
||||
EntryVector FinalLinkEntries;
|
||||
std::map<std::string, std::string> LinkLibraryOverride;
|
||||
|
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <cm/memory>
|
||||
#include <cm/optional>
|
||||
#include <cm/string_view>
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
|
||||
@@ -567,8 +568,25 @@ bool cmComputeLinkInformation::Compute()
|
||||
return false;
|
||||
}
|
||||
|
||||
LinkLibrariesStrategy strategy = LinkLibrariesStrategy::PRESERVE_ORDER;
|
||||
if (cmValue s = this->Target->GetProperty("LINK_LIBRARIES_STRATEGY")) {
|
||||
if (*s == "PRESERVE_ORDER"_s) {
|
||||
strategy = LinkLibrariesStrategy::PRESERVE_ORDER;
|
||||
} else if (*s == "REORDER"_s) {
|
||||
strategy = LinkLibrariesStrategy::REORDER;
|
||||
} else {
|
||||
this->CMakeInstance->IssueMessage(
|
||||
MessageType::FATAL_ERROR,
|
||||
cmStrCat("LINK_LIBRARIES_STRATEGY value '", *s,
|
||||
"' is not recognized."),
|
||||
this->Target->GetBacktrace());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the ordered link line items.
|
||||
cmComputeLinkDepends cld(this->Target, this->Config, this->LinkLanguage);
|
||||
cmComputeLinkDepends cld(this->Target, this->Config, this->LinkLanguage,
|
||||
strategy);
|
||||
cld.SetOldLinkDirMode(this->OldLinkDirMode);
|
||||
cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute();
|
||||
FeatureDescriptor const* currentFeature = nullptr;
|
||||
|
@@ -466,6 +466,7 @@ TargetProperty const StaticTargetProperties[] = {
|
||||
{ "LINKER_TYPE"_s, IC::CanCompileSources },
|
||||
{ "ENABLE_EXPORTS"_s, IC::TargetWithSymbolExports },
|
||||
{ "LINK_LIBRARIES_ONLY_TARGETS"_s, IC::NormalNonImportedTarget },
|
||||
{ "LINK_LIBRARIES_STRATEGY"_s, IC::NormalNonImportedTarget },
|
||||
{ "LINK_SEARCH_START_STATIC"_s, IC::CanCompileSources },
|
||||
{ "LINK_SEARCH_END_STATIC"_s, IC::CanCompileSources },
|
||||
// Initialize per-configuration name postfix property from the variable only
|
||||
|
@@ -836,6 +836,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin|Windows)"
|
||||
endif()
|
||||
|
||||
add_RunCMake_test(LinkLibrariesProcessing)
|
||||
add_RunCMake_test(LinkLibrariesStrategy)
|
||||
add_RunCMake_test(File_Archive)
|
||||
add_RunCMake_test(File_Configure)
|
||||
add_RunCMake_test(File_Generate)
|
||||
|
@@ -0,0 +1 @@
|
||||
^Library 'B' was linked first\.$
|
@@ -0,0 +1 @@
|
||||
^Library 'A' was linked first\.$
|
@@ -0,0 +1,7 @@
|
||||
target \[main\] link dependency ordering:
|
||||
target \[A\]
|
||||
target \[B\]
|
||||
target \[C\]
|
||||
target \[A\]
|
||||
|
||||
target \[main\] link line:
|
@@ -0,0 +1,2 @@
|
||||
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
|
||||
include(Basic-common.cmake)
|
@@ -0,0 +1 @@
|
||||
^Library 'B' was linked first\.$
|
@@ -0,0 +1,6 @@
|
||||
target \[main\] link dependency ordering:
|
||||
target \[B\]
|
||||
target \[C\]
|
||||
target \[A\]
|
||||
|
||||
target \[main\] link line:
|
2
Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER.cmake
Normal file
2
Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER.cmake
Normal file
@@ -0,0 +1,2 @@
|
||||
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
|
||||
include(Basic-common.cmake)
|
15
Tests/RunCMake/LinkLibrariesStrategy/Basic-common.cmake
Normal file
15
Tests/RunCMake/LinkLibrariesStrategy/Basic-common.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(A STATIC BasicA.c BasicX.c)
|
||||
add_library(B STATIC BasicB.c BasicX.c)
|
||||
add_library(C STATIC BasicC.c BasicX.c)
|
||||
target_link_libraries(B PRIVATE A)
|
||||
target_link_libraries(C PRIVATE A)
|
||||
target_compile_definitions(A PRIVATE BASIC_ID="A")
|
||||
target_compile_definitions(B PRIVATE BASIC_ID="B")
|
||||
target_compile_definitions(C PRIVATE BASIC_ID="C")
|
||||
|
||||
add_executable(main Basic.c)
|
||||
target_link_libraries(main PRIVATE A B C)
|
||||
set_property(TARGET main PROPERTY LINK_DEPENDS_DEBUG_MODE 1) # undocumented
|
||||
set_property(TARGET main PROPERTY RUNTIME_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}>")
|
11
Tests/RunCMake/LinkLibrariesStrategy/Basic.c
Normal file
11
Tests/RunCMake/LinkLibrariesStrategy/Basic.c
Normal file
@@ -0,0 +1,11 @@
|
||||
extern int BasicB(void);
|
||||
extern int BasicC(void);
|
||||
|
||||
/* Use a symbol provided by a dedicated object file in A, B, and C.
|
||||
The first library linked will determine the return value. */
|
||||
extern int BasicX(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return BasicB() + BasicC() + BasicX();
|
||||
}
|
4
Tests/RunCMake/LinkLibrariesStrategy/BasicA.c
Normal file
4
Tests/RunCMake/LinkLibrariesStrategy/BasicA.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int BasicA(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
5
Tests/RunCMake/LinkLibrariesStrategy/BasicB.c
Normal file
5
Tests/RunCMake/LinkLibrariesStrategy/BasicB.c
Normal file
@@ -0,0 +1,5 @@
|
||||
extern int BasicA(void);
|
||||
int BasicB(void)
|
||||
{
|
||||
return BasicA();
|
||||
}
|
5
Tests/RunCMake/LinkLibrariesStrategy/BasicC.c
Normal file
5
Tests/RunCMake/LinkLibrariesStrategy/BasicC.c
Normal file
@@ -0,0 +1,5 @@
|
||||
extern int BasicA(void);
|
||||
int BasicC(void)
|
||||
{
|
||||
return BasicA();
|
||||
}
|
7
Tests/RunCMake/LinkLibrariesStrategy/BasicX.c
Normal file
7
Tests/RunCMake/LinkLibrariesStrategy/BasicX.c
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int BasicX(void)
|
||||
{
|
||||
printf("Library '%s' was linked first.\n", BASIC_ID);
|
||||
return 0;
|
||||
}
|
3
Tests/RunCMake/LinkLibrariesStrategy/CMakeLists.txt
Normal file
3
Tests/RunCMake/LinkLibrariesStrategy/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
@@ -0,0 +1,15 @@
|
||||
target \[main\] link dependency ordering:
|
||||
item \[-Flag1\]
|
||||
target \[A\]
|
||||
item \[-Flag1\]
|
||||
target \[B\]
|
||||
item \[-Flag2\]
|
||||
target \[C\]
|
||||
item \[-Flag2\]
|
||||
target \[A\]
|
||||
item \[-Flag2\]
|
||||
target \[B\]
|
||||
item \[-Flag3\]
|
||||
target \[C\]
|
||||
|
||||
target \[main\] link line:
|
@@ -0,0 +1,2 @@
|
||||
set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER)
|
||||
include(Duplicate-common.cmake)
|
@@ -0,0 +1,9 @@
|
||||
target \[main\] link dependency ordering:
|
||||
item \[-Flag1\]
|
||||
target \[A\]
|
||||
target \[B\]
|
||||
item \[-Flag2\]
|
||||
target \[C\]
|
||||
item \[-Flag3\]
|
||||
|
||||
target \[main\] link line:
|
@@ -0,0 +1,2 @@
|
||||
set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER)
|
||||
include(Duplicate-common.cmake)
|
12
Tests/RunCMake/LinkLibrariesStrategy/Duplicate-common.cmake
Normal file
12
Tests/RunCMake/LinkLibrariesStrategy/Duplicate-common.cmake
Normal file
@@ -0,0 +1,12 @@
|
||||
enable_language(C)
|
||||
|
||||
add_library(A INTERFACE IMPORTED)
|
||||
add_library(B INTERFACE IMPORTED)
|
||||
add_library(C INTERFACE IMPORTED)
|
||||
set_property(TARGET A PROPERTY IMPORTED_LIBNAME A)
|
||||
set_property(TARGET B PROPERTY IMPORTED_LIBNAME B)
|
||||
set_property(TARGET C PROPERTY IMPORTED_LIBNAME C)
|
||||
|
||||
add_executable(main Duplicate.c)
|
||||
target_link_libraries(main PRIVATE -Flag1 A -Flag1 B -Flag2 C -Flag2 A -Flag2 B -Flag3 C)
|
||||
set_property(TARGET main PROPERTY LINK_DEPENDS_DEBUG_MODE 1) # undocumented
|
4
Tests/RunCMake/LinkLibrariesStrategy/Duplicate.c
Normal file
4
Tests/RunCMake/LinkLibrariesStrategy/Duplicate.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
12
Tests/RunCMake/LinkLibrariesStrategy/Inspect.cmake
Normal file
12
Tests/RunCMake/LinkLibrariesStrategy/Inspect.cmake
Normal file
@@ -0,0 +1,12 @@
|
||||
enable_language(C)
|
||||
|
||||
set(info "")
|
||||
foreach(var
|
||||
CMAKE_C_LINK_LIBRARIES_PROCESSING
|
||||
)
|
||||
if(DEFINED ${var})
|
||||
string(APPEND info "set(${var} \"${${var}}\")\n")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
|
36
Tests/RunCMake/LinkLibrariesStrategy/RunCMakeTest.cmake
Normal file
36
Tests/RunCMake/LinkLibrariesStrategy/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,36 @@
|
||||
cmake_minimum_required(VERSION 3.30)
|
||||
|
||||
include(RunCMake)
|
||||
|
||||
if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
|
||||
else()
|
||||
set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
|
||||
endif()
|
||||
|
||||
# Detect information from the toolchain:
|
||||
# - CMAKE_C_LINK_LIBRARIES_PROCESSING
|
||||
run_cmake(Inspect)
|
||||
include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
|
||||
|
||||
run_cmake(Unknown)
|
||||
|
||||
function(run_strategy case exe)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
|
||||
run_cmake(${case})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
|
||||
if(exe)
|
||||
if("ORDER=REVERSE" IN_LIST CMAKE_C_LINK_LIBRARIES_PROCESSING)
|
||||
set(RunCMake-stdout-file ${case}-run-stdout-reverse.txt)
|
||||
endif()
|
||||
run_cmake_command(${case}-run ${RunCMake_TEST_BINARY_DIR}/${exe})
|
||||
unset(RunCMake-stdout-file)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
run_strategy(Basic-PRESERVE_ORDER "main")
|
||||
run_strategy(Basic-REORDER "main")
|
||||
|
||||
run_cmake(Duplicate-PRESERVE_ORDER)
|
||||
run_cmake(Duplicate-REORDER)
|
1
Tests/RunCMake/LinkLibrariesStrategy/Unknown-result.txt
Normal file
1
Tests/RunCMake/LinkLibrariesStrategy/Unknown-result.txt
Normal file
@@ -0,0 +1 @@
|
||||
1
|
4
Tests/RunCMake/LinkLibrariesStrategy/Unknown-stderr.txt
Normal file
4
Tests/RunCMake/LinkLibrariesStrategy/Unknown-stderr.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
^CMake Error at Unknown.cmake:5 \(add_executable\):
|
||||
LINK_LIBRARIES_STRATEGY value 'unknown' is not recognized\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9] \(include\)
|
5
Tests/RunCMake/LinkLibrariesStrategy/Unknown.cmake
Normal file
5
Tests/RunCMake/LinkLibrariesStrategy/Unknown.cmake
Normal file
@@ -0,0 +1,5 @@
|
||||
enable_language(C)
|
||||
|
||||
set(CMAKE_LINK_LIBRARIES_STRATEGY unknown)
|
||||
|
||||
add_executable(main main.c)
|
4
Tests/RunCMake/LinkLibrariesStrategy/main.c
Normal file
4
Tests/RunCMake/LinkLibrariesStrategy/main.c
Normal file
@@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user