Merge topic 'link-deduplicate-libs'

7b99c42e57 Link step: Enable to configure deduplication of libraries
07501c1678 Link Step: Introduce EntriesProcessing class

Acked-by: Kitware Robot <kwrobot@kitware.com>
Tested-by: buildbot <buildbot@kitware.com>
Acked-by: scivision <michael@scivision.dev>
Merge-request: !8946
This commit is contained in:
Brad King
2023-11-13 14:51:31 +00:00
committed by Kitware Robot
125 changed files with 763 additions and 67 deletions

View File

@@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
Policies Introduced by CMake 3.29
=================================
.. toctree::
:maxdepth: 1
CMP0156: De-duplicate libraries on link lines based on linker capabilities. </policy/CMP0156>
Policies Introduced by CMake 3.28
=================================

47
Help/policy/CMP0156.rst Normal file
View File

@@ -0,0 +1,47 @@
CMP0156
-------
.. versionadded:: 3.29
De-duplicate libraries on link lines based on linker capabilities.
Traditional linkers maintain a set of undefined symbols during linking. The
linker processes each file in the order in which it appears on the command
line, until the set of undefined symbols becomes empty. An object file is
linked into the output object when it is encountered, with its undefined
symbols added to the set. Upon encountering an archive file a traditional
linker searches the objects contained therein, and processes those that satisfy
symbols in the unresolved set.
Handling mutually dependent archives may be awkward when using a traditional
linker. Archive files may have to be specified multiple times.
Some linkers (for instance Apple or Windows linkers, as well as``LLVM LLD``)
records all symbols found in objects and archives as it iterates over command
line arguments. When one of these linkers encounters an undefined symbol that
can be resolved by an object file contained in a previously processed archive
file, it immediately extracts and links it into the output object.
CMake 3.28 and below may generate link lines that repeat static libraries as
a traditional linker would need, even when using a linker does not need it.
They may also de-duplicate shared libraries by keeping their last occurrence,
which on Windows platforms can change DLL load order.
CMake 3.29 and above prefer to apply different strategies based on linker
capabilities. So, when targeting Apple and Windows platforms, all
libraries are de-duplicated. Moreover, on Windows platforms, libraries
are de-duplicated by keeping their fist occurrence, thus respecting the
project-specified order. This policy provides compatibility with projects
that have not been updated to expect the latter behavior.
The ``OLD`` behavior for this policy is to always repeat static libraries
as if using a traditional linker, and always de-duplicate shared libraries
by keeping the last occurrence of each. The ``NEW`` behavior for this policy
is to apply different strategies based on linker capabilities.
This policy was introduced in CMake version 3.29. Use the
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
Unlike many policies, CMake version |release| does *not* warn
when this policy is not set and simply uses ``OLD`` behavior.
.. include:: DEPRECATED.txt

View File

@@ -0,0 +1,5 @@
link-deduplicate-libs
---------------------
* CMake learned to de-duplicate libraries on link lines based on linker
capabilities. See policy :policy:`CMP0156`.

View File

@@ -16,6 +16,8 @@ macro(__aix_compiler_gnu lang)
set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
endif()

View File

@@ -17,6 +17,7 @@ macro(__aix_compiler_xl lang)
set(CMAKE_SHARED_MODULE_${lang}_FLAGS " ")
set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
set(_OBJECTS " <OBJECTS>")
if(DEFINED CMAKE_XL_CreateExportList AND CMAKE_XL_CreateExportList STREQUAL "")

View File

@@ -15,6 +15,8 @@ macro(__apple_compiler_clang lang)
set(CMAKE_${lang}_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
endif()
set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=ALL)
set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK "-framework <LIBRARY>")
set(CMAKE_${lang}_LINK_LIBRARY_USING_FRAMEWORK_SUPPORTED TRUE)

View File

@@ -54,6 +54,8 @@ macro(__windows_compiler_clang_gnu lang)
set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "")
set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD UNICITY=ALL)
# linker selection
set(CMAKE_${lang}_USING_LINKER_DEFAULT "-fuse-ld=lld-link")
set(CMAKE_${lang}_USING_LINKER_SYSTEM "-fuse-ld=link")

View File

@@ -513,6 +513,8 @@ macro(__windows_compiler_msvc lang)
set(CMAKE_${lang}_DEPFILE_FORMAT msvc)
endif()
set(CMAKE_${lang}_LINK_LIBRARIES_PROCESSING ORDER=FORWARD UNICITY=ALL)
# linker selection
set(CMAKE_${lang}_USING_LINKER_SYSTEM "${CMAKE_LINKER_LINK}")
set(CMAKE_${lang}_USING_LINKER_LLD "${CMAKE_LINKER_LLD}")

View File

@@ -16,6 +16,8 @@
#include <cm/string_view>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmComputeComponentGraph.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
@@ -26,6 +28,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
@@ -232,6 +235,204 @@ bool IsGroupFeatureSupported(cmMakefile* makefile,
cmStrCat("CMAKE_LINK_GROUP_USING_", feature, "_SUPPORTED");
return makefile->GetDefinition(featureSupported).IsOn();
}
class EntriesProcessing
{
public:
using LinkEntry = cmComputeLinkDepends::LinkEntry;
using EntryVector = cmComputeLinkDepends::EntryVector;
EntriesProcessing(const cmGeneratorTarget* target,
const std::string& linkLanguage, EntryVector& entries,
EntryVector& finalEntries)
: Entries(entries)
, FinalEntries(finalEntries)
{
const auto* makefile = target->Makefile;
switch (target->GetPolicyStatusCMP0156()) {
case cmPolicies::WARN:
if (!makefile->GetCMakeInstance()->GetIsInTryCompile() &&
makefile->PolicyOptionalWarningEnabled(
"CMAKE_POLICY_WARNING_CMP0156")) {
makefile->GetCMakeInstance()->IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0156),
"\nSince the policy is not set, legacy libraries "
"de-duplication strategy will be applied."),
target->GetBacktrace());
}
CM_FALLTHROUGH;
case cmPolicies::OLD:
// rely on default initialization of the class
break;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
makefile->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0156),
target->GetBacktrace());
CM_FALLTHROUGH;
case cmPolicies::NEW: {
if (auto libProcessing = makefile->GetDefinition(cmStrCat(
"CMAKE_", linkLanguage, "_LINK_LIBRARIES_PROCESSING"))) {
cmsys::RegularExpression processingOption{
"^(ORDER|UNICITY)=(FORWARD|REVERSE|ALL|NONE|SHARED)$"
};
std::string errorMessage;
for (auto const& option : cmList{ libProcessing }) {
if (processingOption.find(option)) {
if (processingOption.match(1) == "ORDER") {
if (processingOption.match(2) == "FORWARD") {
this->Order = Forward;
} else if (processingOption.match(2) == "REVERSE") {
this->Order = Reverse;
} else {
errorMessage += cmStrCat(" ", option, '\n');
}
} else if (processingOption.match(1) == "UNICITY") {
if (processingOption.match(2) == "ALL") {
this->Unicity = All;
} else if (processingOption.match(2) == "NONE") {
this->Unicity = None;
} else if (processingOption.match(2) == "SHARED") {
this->Unicity = Shared;
} else {
errorMessage += cmStrCat(" ", option, '\n');
}
}
} else {
errorMessage += cmStrCat(" ", option, '\n');
}
}
if (!errorMessage.empty()) {
makefile->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Erroneous option(s) for 'CMAKE_", linkLanguage,
"_LINK_LIBRARIES_PROCESSING':\n", errorMessage),
target->GetBacktrace());
}
}
}
}
}
void AddGroups(const std::map<size_t, std::vector<size_t>>& groups)
{
if (!groups.empty()) {
this->Groups = &groups;
// record all libraries as part of groups to ensure correct
// deduplication: libraries as part of groups are always kept.
for (const auto& group : groups) {
for (auto index : group.second) {
this->Emitted.insert(index);
}
}
}
}
void AddLibraries(const std::vector<size_t>& libEntries)
{
if (this->Order == Reverse) {
// Iterate in reverse order so we can keep only the last occurrence
// of a library.
this->AddLibraries(cmReverseRange(libEntries));
} else {
this->AddLibraries(cmMakeRange(libEntries));
}
}
void AddObjects(const std::vector<size_t>& objectEntries)
{
// Place explicitly linked object files in the front. The linker will
// always use them anyway, and they may depend on symbols from libraries.
if (this->Order == Reverse) {
// Append in reverse order at the end since we reverse the final order.
for (auto index : cmReverseRange(objectEntries)) {
this->FinalEntries.emplace_back(this->Entries[index]);
}
} else {
// Append in reverse order to ensure correct final order
for (auto index : cmReverseRange(objectEntries)) {
this->FinalEntries.emplace(this->FinalEntries.begin(),
this->Entries[index]);
}
}
}
void Finalize()
{
if (this->Order == Reverse) {
// Reverse the resulting order since we iterated in reverse.
std::reverse(this->FinalEntries.begin(), this->FinalEntries.end());
}
// expand groups
if (this->Groups != nullptr) {
for (const auto& group : *this->Groups) {
const LinkEntry& groupEntry = this->Entries[group.first];
auto it = this->FinalEntries.begin();
while (true) {
it = std::find_if(it, this->FinalEntries.end(),
[&groupEntry](const LinkEntry& entry) -> bool {
return groupEntry.Item == entry.Item;
});
if (it == this->FinalEntries.end()) {
break;
}
it->Item.Value = "</LINK_GROUP>";
for (auto index = group.second.rbegin();
index != group.second.rend(); ++index) {
it = this->FinalEntries.insert(it, this->Entries[*index]);
}
it = this->FinalEntries.insert(it, groupEntry);
it->Item.Value = "<LINK_GROUP>";
}
}
}
}
private:
enum OrderKind
{
Forward,
Reverse
};
enum UnicityKind
{
None,
Shared,
All
};
bool IncludeEntry(LinkEntry const& entry) const
{
return this->Unicity == None ||
(this->Unicity == Shared &&
(entry.Target == nullptr ||
entry.Target->GetType() != cmStateEnums::SHARED_LIBRARY)) ||
(this->Unicity == All && entry.Kind != LinkEntry::Library);
}
template <typename Range>
void AddLibraries(const Range& libEntries)
{
for (auto index : libEntries) {
LinkEntry const& entry = this->Entries[index];
if (this->IncludeEntry(entry) || this->Emitted.insert(index).second) {
this->FinalEntries.emplace_back(entry);
}
}
}
OrderKind Order = Reverse;
UnicityKind Unicity = Shared;
EntryVector& Entries;
EntryVector& FinalEntries;
std::set<size_t> Emitted;
const std::map<size_t, std::vector<size_t>>* Groups = nullptr;
};
}
const std::string cmComputeLinkDepends::LinkEntry::DEFAULT = "DEFAULT";
@@ -380,49 +581,14 @@ cmComputeLinkDepends::Compute()
this->OrderLinkEntries();
// Compute the final set of link entries.
// Iterate in reverse order so we can keep only the last occurrence
// of a shared library.
std::set<size_t> emitted;
for (size_t i : cmReverseRange(this->FinalLinkOrder)) {
LinkEntry const& e = this->EntryList[i];
cmGeneratorTarget const* t = e.Target;
// Entries that we know the linker will re-use do not need to be repeated.
bool uniquify = t && t->GetType() == cmStateEnums::SHARED_LIBRARY;
if (!uniquify || emitted.insert(i).second) {
this->FinalLinkEntries.push_back(e);
}
}
// Place explicitly linked object files in the front. The linker will
// always use them anyway, and they may depend on symbols from libraries.
// Append in reverse order since we reverse the final order below.
for (size_t i : cmReverseRange(this->ObjectEntries)) {
this->FinalLinkEntries.emplace_back(this->EntryList[i]);
}
// Reverse the resulting order since we iterated in reverse.
std::reverse(this->FinalLinkEntries.begin(), this->FinalLinkEntries.end());
// Expand group items
if (!this->GroupItems.empty()) {
for (const auto& group : this->GroupItems) {
const LinkEntry& groupEntry = this->EntryList[group.first];
auto it = this->FinalLinkEntries.begin();
while (true) {
it = std::find_if(it, this->FinalLinkEntries.end(),
[&groupEntry](const LinkEntry& entry) -> bool {
return groupEntry.Item == entry.Item;
});
if (it == this->FinalLinkEntries.end()) {
break;
}
it->Item.Value = "</LINK_GROUP>";
for (auto i = group.second.rbegin(); i != group.second.rend(); ++i) {
it = this->FinalLinkEntries.insert(it, this->EntryList[*i]);
}
it = this->FinalLinkEntries.insert(it, groupEntry);
it->Item.Value = "<LINK_GROUP>";
}
}
}
EntriesProcessing entriesProcessing{ this->Target, this->LinkLanguage,
this->EntryList,
this->FinalLinkEntries };
// Add groups first, to ensure that libraries of the groups are always kept.
entriesProcessing.AddGroups(this->GroupItems);
entriesProcessing.AddLibraries(this->FinalLinkOrder);
entriesProcessing.AddObjects(this->ObjectEntries);
entriesProcessing.Finalize();
// Display the final set.
if (this->DebugMode) {

View File

@@ -473,7 +473,11 @@ class cmMakefile;
SELECT(POLICY, CMP0155, \
"C++ sources in targets with at least C++20 are scanned for " \
"imports when supported.", \
3, 28, 0, cmPolicies::WARN)
3, 28, 0, cmPolicies::WARN) \
SELECT( \
POLICY, CMP0156, \
"De-duplicate libraries on link lines based on linker capabilities.", 3, \
29, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -513,7 +517,8 @@ class cmMakefile;
F(CMP0131) \
F(CMP0142) \
F(CMP0154) \
F(CMP0155)
F(CMP0155) \
F(CMP0156)
#define CM_FOR_EACH_CUSTOM_COMMAND_POLICY(F) \
F(CMP0116) \

View File

@@ -0,0 +1,27 @@
enable_language(C)
# ensure link is successful in case of circular dependency
add_library(lib1 STATIC lib1.c)
add_library(lib2 STATIC lib2.c)
target_link_libraries(lib1 PRIVATE lib2)
target_link_libraries(lib2 PRIVATE lib1)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib1)
if (APPLE_TEST)
target_link_options(main PRIVATE "LINKER:-fatal_warnings")
else()
target_link_options(main PRIVATE "$<$<AND:$<NOT:$<TARGET_POLICY:CMP0156>>,$<C_COMPILER_ID:AppleClang>,$<VERSION_GREATER_EQUAL:$<C_COMPILER_VERSION>,15.0>>:LINKER:-no_warn_duplicate_libraries>")
endif()
add_library(lib3 SHARED lib3.c)
add_library(lib4 STATIC lib4.c)
target_link_libraries(lib4 PRIVATE lib3)
# link specifying a shared library not directly used by the target
# on Windows, with CMP0156=NEW, lib3 is specified before lib4 on link step
add_executable(main2 main2.c)
target_link_libraries(main2 PRIVATE lib3 lib4)

View File

@@ -0,0 +1,5 @@
cmake_policy(SET CMP0156 NEW)
set(APPLE_TEST TRUE)
include (CMP0156-Common.cmake)

View File

@@ -0,0 +1,4 @@
cmake_policy(SET CMP0156 NEW)
include (CMP0156-Common.cmake)

View File

@@ -0,0 +1 @@
.+

View File

@@ -0,0 +1,3 @@
ld: warning: ignoring duplicate libraries: '.*liblib1.a', '.*liblib2.a'
ld: fatal warning\(s\) induced error \(-fatal_warnings\)
clang: error: linker command failed with exit code 1 \(use -v to see invocation\)

View File

@@ -0,0 +1,5 @@
cmake_policy(SET CMP0156 OLD)
set(APPLE_TEST TRUE)
include (CMP0156-Common.cmake)

View File

@@ -0,0 +1,4 @@
cmake_policy(SET CMP0156 OLD)
include (CMP0156-Common.cmake)

View File

@@ -0,0 +1,35 @@
CMake Warning \(dev\) at CMP0156-Common.cmake:[0-9]+ \(add_library\):
Policy CMP0156 is not set: De-duplicate libraries on link lines based on
linker capabilities. Run "cmake --help-policy CMP0156" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
Since the policy is not set, legacy libraries de-duplication strategy will
be applied.
Call Stack \(most recent call first\):
CMP0156-WARN.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\) at CMP0156-Common.cmake:[0-9]+ \(add_library\):
Policy CMP0156 is not set: De-duplicate libraries on link lines based on
linker capabilities. Run "cmake --help-policy CMP0156" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
Since the policy is not set, legacy libraries de-duplication strategy will
be applied.
Call Stack \(most recent call first\):
CMP0156-WARN.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning \(dev\) at CMP0156-Common.cmake:[0-9]+ \(add_executable\):
Policy CMP0156 is not set: De-duplicate libraries on link lines based on
linker capabilities. Run "cmake --help-policy CMP0156" for policy details.
Use the cmake_policy command to set the policy and suppress this warning.
Since the policy is not set, legacy libraries de-duplication strategy will
be applied.
Call Stack \(most recent call first\):
CMP0156-WARN.cmake:[0-9]+ \(include\)
CMakeLists.txt:[0-9]+ \(include\)
This warning is for project developers. Use -Wno-dev to suppress it.

View File

@@ -0,0 +1,4 @@
set(CMAKE_POLICY_WARNING_CMP0156 TRUE)
include (CMP0156-Common.cmake)

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.27)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@@ -0,0 +1,26 @@
include(RunCMake)
# CMP0156 control how libraries are specified for the link step
# a sensible configuration is how circular dependency is handled
macro(run_cmake_and_build test)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
set(RunCMake_TEST_OUTPUT_MERGE TRUE)
run_cmake(${test})
set(RunCMake_TEST_NO_CLEAN TRUE)
run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
unset(RunCMake_TEST_NO_CLEAN)
unset(RunCMake_TEST_BINARY_DIR)
unset(RunCMake_TEST_OUTPUT_MERGE)
endmacro()
run_cmake(CMP0156-WARN)
run_cmake_and_build(CMP0156-OLD)
run_cmake_and_build(CMP0156-NEW)
if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
AND CMAKE_C_COMPILER_VERSION GREATER_EQUAL "15.0")
# special case for Apple: with CMP0156=OLD, linker will warning on duplicate libraries
run_cmake_and_build(CMP0156-OLD-AppleClang)
run_cmake_and_build(CMP0156-NEW-AppleClang)
endif()

View File

@@ -0,0 +1,7 @@
extern void lib2(void);
void lib1(void)
{
lib2();
}

View File

@@ -0,0 +1,7 @@
extern void lib1(void);
void lib2(void)
{
lib1();
}

View File

@@ -0,0 +1,7 @@
#if defined(_WIN32)
__declspec(dllexport)
#endif
void lib3(void)
{
}

View File

@@ -0,0 +1,9 @@
#if defined(_WIN32)
__declspec(dllimport)
#endif
void lib3(void);
void lib4(void)
{
}

View File

@@ -0,0 +1,9 @@
extern void lib1(void);
int main(void)
{
lib1();
return 0;
}

View File

@@ -0,0 +1,9 @@
extern void lib4(void);
int main(void)
{
lib4();
return 0;
}

View File

@@ -170,6 +170,8 @@ if(NOT WIN32 OR CYGWIN)
endif()
add_RunCMake_test(CMP0153)
add_RunCMake_test(CMP0156 -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
@@ -748,6 +750,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(Linux|Darwin|Windows)"
-DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION})
endif()
add_RunCMake_test(LinkLibrariesProcessing)
add_RunCMake_test(File_Archive)
add_RunCMake_test(File_Configure)
add_RunCMake_test(File_Generate)

View File

@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.28...3.29)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)

View File

@@ -0,0 +1,7 @@
CMake Error at InvalidConfiguration1.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
ORDER=
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER= UNICITY=ALL)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1,7 @@
CMake Error at InvalidConfiguration2.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
ORDER
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING UNICITY=ALL ORDER)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1,7 @@
CMake Error at InvalidConfiguration3.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
WRONG=REVERSE
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE UNICITY=ALL)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1,8 @@
CMake Error at InvalidConfiguration4.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
WRONG=REVERSE
UNICITY=WRONG
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING WRONG=REVERSE UNICITY=WRONG)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,7 @@
CMake Error at Invalid_ORDER.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
ORDER=WRONG
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=WRONG UNICITY=ALL)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1,7 @@
CMake Error at Invalid_UNICITY.cmake:[0-9]+ \(add_executable\):
Erroneous option\(s\) for 'CMAKE_C_LINK_LIBRARIES_PROCESSING':
UNICITY=WRONG
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)

View File

@@ -0,0 +1,9 @@
enable_language(C)
set(CMAKE_C_LINK_LIBRARIES_PROCESSING ORDER=REVERSE UNICITY=WRONG)
add_library(lib STATIC lib.c)
add_executable(main main.c)
target_link_libraries(main PRIVATE lib)

View File

@@ -0,0 +1,8 @@
include(RunCMake)
run_cmake(Invalid_ORDER)
run_cmake(Invalid_UNICITY)
run_cmake(InvalidConfiguration1)
run_cmake(InvalidConfiguration2)
run_cmake(InvalidConfiguration3)
run_cmake(InvalidConfiguration4)

View File

@@ -0,0 +1,4 @@
void lib(void)
{
}

View File

@@ -0,0 +1,5 @@
int main(void)
{
return 0;
}

View File

@@ -39,6 +39,7 @@
\* CMP0142
\* CMP0154
\* CMP0155
\* CMP0156
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<base3> --SUFFIXGROUP'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base3> --LIBGROUP<base1> --SUFFIXGROUP'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<base3> --SUFFIXGROUP'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base3> --LIBGROUP<base1> --SUFFIXGROUP'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other2${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1${LINK_EXTERN_LIBRARY_SUFFIX}")
set (RunCMake_TEST_FAILED "Not found expected '<base2> --PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<base3> --SUFFIXGROUP <other2> <other1>'.")
endif()
else()
if (NOT actual_stdout MATCHES "${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other2${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1${LINK_EXTERN_LIBRARY_SUFFIX}")
set (RunCMake_TEST_FAILED "Not found expected '<base2> --PREFIXGROUP --LIBGROUP<base3> --SUFFIXGROUP <other2> --PREFIXGROUP --LIBGROUP<base1> --SUFFIXGROUP <other1>'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base1> --LIBFLAG<base3> <other1>'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --LIBFLAG<base1> <other1>'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}other1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --SUFFIXGROUP --LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<other1> --SUFFIXGROUP'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUPother1${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<other1> --SUFFIXGROUP'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base1> --LIBFLAG<base3> <other1>'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --LIBFLAG<base1> <other1>'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUPother1${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP\"?")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --SUFFIXGROUP --LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<other1> --SUFFIXGROUP'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUPother1${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> --PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<other1> --SUFFIXGROUP'.")
endif()
endif()

View File

@@ -0,0 +1,12 @@
include("${RunCMake_BINARY_DIR}/LINK_LIBRARY-CMP0156-NEW-build/LIBRARIES_PROCESSING.cmake")
if (CMAKE_C_LINK_LIBRARIES_PROCESSING MATCHES "ORDER=FORWARD")
if (NOT actual_stdout MATCHES "${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1${LINK_EXTERN_LIBRARY_SUFFIX}\"?")
set (RunCMake_TEST_FAILED "Not found expected '<base1> --LIBFLAG<base3> <other1>'.")
endif()
else()
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base3${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other1${LINK_EXTERN_LIBRARY_SUFFIX}\"?")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base3> <base1> <other1>'.")
endif()
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX}")
set (RunCMake_TEST_FAILED "Not found expected '--LIBFLAG<base1> --LIBFLAG<base2>'.")
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<base2> --SUFFIXGROUP'.")
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?${CMAKE_LINK_LIBRARY_FLAG}other${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP <base1> <other> --SUFFIXGROUP'.")
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBGROUP.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBGROUPother${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBGROUP<base1> --LIBGROUP<other> --SUFFIXGROUP'.")
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-ITEMFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAGother${LINK_EXTERN_LIBRARY_SUFFIX}\"? +\"?(/|-)-ITEMFLAGother\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBFLAG<base1> --ITEMFLAG<base1> --LIBFLAG<other> --ITEMFLAG<other> --SUFFIXGROUP'.")
endif()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "(/|-)-PREFIXGROUP\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-ITEMFLAGother\"? +\"?(/|-)-SUFFIXGROUP")
set (RunCMake_TEST_FAILED "Not found expected '--PREFIXGROUP --LIBFLAG<base1> --ITEMFLAG<other> --SUFFIXGROUP'.")
endif()

Some files were not shown because too many files have changed in this diff Show More