diff options
38 files changed, 323 insertions, 5 deletions
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index a82adda..94a2429 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -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. diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 9ad856d..10dbe10 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -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 diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index a79747f..cc10950 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -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 diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index b5c1d89..b449aa1 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst @@ -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. diff --git a/Help/prop_tgt/LINK_LIBRARIES_STRATEGY.rst b/Help/prop_tgt/LINK_LIBRARIES_STRATEGY.rst new file mode 100644 index 0000000..bba707c --- /dev/null +++ b/Help/prop_tgt/LINK_LIBRARIES_STRATEGY.rst @@ -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. diff --git a/Help/release/dev/link-strategy.rst b/Help/release/dev/link-strategy.rst new file mode 100644 index 0000000..ab626d1 --- /dev/null +++ b/Help/release/dev/link-strategy.rst @@ -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. diff --git a/Help/variable/CMAKE_LINK_LIBRARIES_STRATEGY.rst b/Help/variable/CMAKE_LINK_LIBRARIES_STRATEGY.rst new file mode 100644 index 0000000..1ba6b27 --- /dev/null +++ b/Help/variable/CMAKE_LINK_LIBRARIES_STRATEGY.rst @@ -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`. diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index ae33c12..70e992e 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -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 diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 55f0032..8b8aba4 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -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; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index dd194ed..26ff326 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -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; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index da0091b..f220837 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -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 diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 40db51b..ba8776f 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -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) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout-reverse.txt b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout-reverse.txt new file mode 100644 index 0000000..7e46d1ba --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout-reverse.txt @@ -0,0 +1 @@ +^Library 'B' was linked first\.$ diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout.txt b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout.txt new file mode 100644 index 0000000..6ef12eb --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-run-stdout.txt @@ -0,0 +1 @@ +^Library 'A' was linked first\.$ diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-stderr.txt b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-stderr.txt new file mode 100644 index 0000000..1d8f4ba --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER-stderr.txt @@ -0,0 +1,7 @@ +target \[main\] link dependency ordering: + target \[A\] + target \[B\] + target \[C\] + target \[A\] + +target \[main\] link line: diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER.cmake new file mode 100644 index 0000000..f3dc096 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-PRESERVE_ORDER.cmake @@ -0,0 +1,2 @@ +set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER) +include(Basic-common.cmake) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-run-stdout.txt b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-run-stdout.txt new file mode 100644 index 0000000..7e46d1ba --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-run-stdout.txt @@ -0,0 +1 @@ +^Library 'B' was linked first\.$ diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-stderr.txt b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-stderr.txt new file mode 100644 index 0000000..54b02bd --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER-stderr.txt @@ -0,0 +1,6 @@ +target \[main\] link dependency ordering: + target \[B\] + target \[C\] + target \[A\] + +target \[main\] link line: diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER.cmake new file mode 100644 index 0000000..8e62377 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-REORDER.cmake @@ -0,0 +1,2 @@ +set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER) +include(Basic-common.cmake) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic-common.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Basic-common.cmake new file mode 100644 index 0000000..8dbbd39 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic-common.cmake @@ -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}>") diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Basic.c b/Tests/RunCMake/LinkLibrariesStrategy/Basic.c new file mode 100644 index 0000000..124d489 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Basic.c @@ -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(); +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/BasicA.c b/Tests/RunCMake/LinkLibrariesStrategy/BasicA.c new file mode 100644 index 0000000..d3fe95d --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/BasicA.c @@ -0,0 +1,4 @@ +int BasicA(void) +{ + return 0; +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/BasicB.c b/Tests/RunCMake/LinkLibrariesStrategy/BasicB.c new file mode 100644 index 0000000..fd7a120 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/BasicB.c @@ -0,0 +1,5 @@ +extern int BasicA(void); +int BasicB(void) +{ + return BasicA(); +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/BasicC.c b/Tests/RunCMake/LinkLibrariesStrategy/BasicC.c new file mode 100644 index 0000000..7171dd1 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/BasicC.c @@ -0,0 +1,5 @@ +extern int BasicA(void); +int BasicC(void) +{ + return BasicA(); +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/BasicX.c b/Tests/RunCMake/LinkLibrariesStrategy/BasicX.c new file mode 100644 index 0000000..39f7863 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/BasicX.c @@ -0,0 +1,7 @@ +#include <stdio.h> + +int BasicX(void) +{ + printf("Library '%s' was linked first.\n", BASIC_ID); + return 0; +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/CMakeLists.txt b/Tests/RunCMake/LinkLibrariesStrategy/CMakeLists.txt new file mode 100644 index 0000000..dda37d8 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.30) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER-stderr.txt b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER-stderr.txt new file mode 100644 index 0000000..2637f93 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER-stderr.txt @@ -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: diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER.cmake new file mode 100644 index 0000000..9f694db --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-PRESERVE_ORDER.cmake @@ -0,0 +1,2 @@ +set(CMAKE_LINK_LIBRARIES_STRATEGY PRESERVE_ORDER) +include(Duplicate-common.cmake) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER-stderr.txt b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER-stderr.txt new file mode 100644 index 0000000..2353288 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER-stderr.txt @@ -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: diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER.cmake new file mode 100644 index 0000000..cc51e0a --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-REORDER.cmake @@ -0,0 +1,2 @@ +set(CMAKE_LINK_LIBRARIES_STRATEGY REORDER) +include(Duplicate-common.cmake) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-common.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-common.cmake new file mode 100644 index 0000000..5050a0a --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate-common.cmake @@ -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 diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Duplicate.c b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Duplicate.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Inspect.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Inspect.cmake new file mode 100644 index 0000000..fd5da91 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Inspect.cmake @@ -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}") diff --git a/Tests/RunCMake/LinkLibrariesStrategy/RunCMakeTest.cmake b/Tests/RunCMake/LinkLibrariesStrategy/RunCMakeTest.cmake new file mode 100644 index 0000000..1b02355 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/RunCMakeTest.cmake @@ -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) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Unknown-result.txt b/Tests/RunCMake/LinkLibrariesStrategy/Unknown-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Unknown-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Unknown-stderr.txt b/Tests/RunCMake/LinkLibrariesStrategy/Unknown-stderr.txt new file mode 100644 index 0000000..3081f32 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Unknown-stderr.txt @@ -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\) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/Unknown.cmake b/Tests/RunCMake/LinkLibrariesStrategy/Unknown.cmake new file mode 100644 index 0000000..d3ad586 --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/Unknown.cmake @@ -0,0 +1,5 @@ +enable_language(C) + +set(CMAKE_LINK_LIBRARIES_STRATEGY unknown) + +add_executable(main main.c) diff --git a/Tests/RunCMake/LinkLibrariesStrategy/main.c b/Tests/RunCMake/LinkLibrariesStrategy/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/LinkLibrariesStrategy/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} |