From fcd1a1a920ed68b06bc082e435b622a8532ac079 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 12 May 2020 11:20:27 -0400 Subject: cmGeneratorTarget: Track when the set of link libs is config-dependent Report in `cmLinkImplementationLibraries` and `cmLinkInterfaceLibraries` whether the list of libraries depends on a genex referencing the configuration. We already track whether a genex references the head target. --- Source/cmGeneratorTarget.cxx | 9 +++++++++ Source/cmGeneratorTarget.h | 1 + Source/cmLinkItem.h | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 62427f6..0381bd9 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -5885,6 +5885,7 @@ void cmGeneratorTarget::ExpandLinkItems( std::string const& prop, std::string const& value, std::string const& config, cmGeneratorTarget const* headTarget, bool usage_requirements_only, std::vector& items, bool& hadHeadSensitiveCondition, + bool& hadContextSensitiveCondition, bool& hadLinkLanguageSensitiveCondition) const { // Keep this logic in sync with ComputeLinkImplementationLibraries. @@ -5903,6 +5904,7 @@ void cmGeneratorTarget::ExpandLinkItems( libs); this->LookupLinkItems(libs, cge->GetBacktrace(), items); hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); + hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition(); hadLinkLanguageSensitiveCondition = cge->GetHadLinkLanguageSensitiveCondition(); } @@ -6407,6 +6409,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config, headTarget, usage_requirements_only, iface.Libraries, iface.HadHeadSensitiveCondition, + iface.HadContextSensitiveCondition, iface.HadLinkLanguageSensitiveCondition); } else if (!cmp0022NEW) // If CMP0022 is NEW then the plain tll signature sets the @@ -6427,10 +6430,12 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries( static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; if (cmProp newExplicitLibraries = this->GetProperty(newProp)) { bool hadHeadSensitiveConditionDummy = false; + bool hadContextSensitiveConditionDummy = false; bool hadLinkLanguageSensitiveConditionDummy = false; this->ExpandLinkItems(newProp, *newExplicitLibraries, config, headTarget, usage_requirements_only, ifaceLibs, hadHeadSensitiveConditionDummy, + hadContextSensitiveConditionDummy, hadLinkLanguageSensitiveConditionDummy); } if (ifaceLibs != iface.Libraries) { @@ -6498,6 +6503,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface( this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, headTarget, usage_requirements_only, iface.Libraries, iface.HadHeadSensitiveCondition, + iface.HadContextSensitiveCondition, iface.HadLinkLanguageSensitiveCondition); std::vector deps = cmExpandedList(info->SharedDeps); this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps); @@ -7020,6 +7026,9 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries( if (cge->GetHadHeadSensitiveCondition()) { impl.HadHeadSensitiveCondition = true; } + if (cge->GetHadContextSensitiveCondition()) { + impl.HadContextSensitiveCondition = true; + } if (cge->GetHadLinkLanguageSensitiveCondition()) { impl.HadLinkLanguageSensitiveCondition = true; } diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 2ef7b43..ff03914 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -989,6 +989,7 @@ private: bool usage_requirements_only, std::vector& items, bool& hadHeadSensitiveCondition, + bool& hadContextSensitiveCondition, bool& hadLinkLanguageSensitiveCondition) const; void LookupLinkItems(std::vector const& names, cmListFileBacktrace const& bt, diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index f27648c..3d92935 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -54,6 +54,9 @@ struct cmLinkImplementationLibraries // Libraries linked directly in other configurations. // Needed only for OLD behavior of CMP0003. std::vector WrongConfigLibraries; + + // Whether the list depends on a genex referencing the configuration. + bool HadContextSensitiveCondition = false; }; struct cmLinkInterfaceLibraries @@ -63,6 +66,9 @@ struct cmLinkInterfaceLibraries // Whether the list depends on a genex referencing the head target. bool HadHeadSensitiveCondition = false; + + // Whether the list depends on a genex referencing the configuration. + bool HadContextSensitiveCondition = false; }; struct cmLinkInterface : public cmLinkInterfaceLibraries -- cgit v0.12 From 8daa140c6a293b14e6f28a8fc84122c2c24296fe Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 12 May 2020 11:37:10 -0400 Subject: cmGeneratorTarget: Factor evaluated target prop entries into struct This will allow storing more than just the list of entries itself. --- Source/cmGeneratorTarget.cxx | 111 +++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 0381bd9..d253bc7 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -238,17 +238,22 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( return ee; } -std::vector EvaluateTargetPropertyEntries( +struct EvaluatedTargetPropertyEntries +{ + std::vector Entries; +}; + +EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( cmGeneratorTarget const* thisTarget, std::string const& config, std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, std::vector> const& in) { - std::vector out; - out.reserve(in.size()); + EvaluatedTargetPropertyEntries out; + out.Entries.reserve(in.size()); for (auto& entry : in) { - out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang, - dagChecker, *entry)); + out.Entries.emplace_back(EvaluateTargetPropertyEntry( + thisTarget, config, lang, dagChecker, *entry)); } return out; } @@ -1333,7 +1338,7 @@ std::string AddSwiftInterfaceIncludeDirectories( void AddSwiftImplicitIncludeDirectories( const cmGeneratorTarget* target, const std::string& config, - std::vector& entries) + EvaluatedTargetPropertyEntries& entries) { if (const auto* libraries = target->GetLinkImplementationLibraries(config)) { cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target, @@ -1357,7 +1362,7 @@ void AddSwiftImplicitIncludeDirectories( config, &dag), entry.Values); - entries.emplace_back(std::move(entry)); + entries.Entries.emplace_back(std::move(entry)); } } } @@ -1368,7 +1373,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, std::string const& config, std::string const& prop, std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector& entries, + EvaluatedTargetPropertyEntries& entries, bool usage_requirements_only = true) { if (cmLinkImplementationLibraries const* impl = @@ -1386,7 +1391,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, prop, &context, dagChecker, usage_requirements_only), ee.Values); ee.ContextDependent = context.HadContextSensitiveCondition; - entries.emplace_back(std::move(ee)); + entries.Entries.emplace_back(std::move(ee)); } } } @@ -1395,7 +1400,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, void AddObjectEntries(cmGeneratorTarget const* headTarget, std::string const& config, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector& entries) + EvaluatedTargetPropertyEntries& entries) { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries(config)) { @@ -1417,14 +1422,14 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget, if (cge->GetHadContextSensitiveCondition()) { ee.ContextDependent = true; } - entries.emplace_back(std::move(ee)); + entries.Entries.emplace_back(std::move(ee)); } } } } bool processSources(cmGeneratorTarget const* tgt, - std::vector& entries, + EvaluatedTargetPropertyEntries& entries, std::vector>& srcs, std::unordered_set& uniqueSrcs, bool debugSources) @@ -1433,7 +1438,7 @@ bool processSources(cmGeneratorTarget const* tgt, bool contextDependent = false; - for (EvaluatedTargetPropertyEntry& entry : entries) { + for (EvaluatedTargetPropertyEntry& entry : entries.Entries) { if (entry.ContextDependent) { contextDependent = true; } @@ -1534,16 +1539,15 @@ std::vector> cmGeneratorTarget::GetSourceFilePaths( cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr, nullptr); - std::vector entries = - EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker, - this->SourceEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, std::string(), &dagChecker, this->SourceEntries); std::unordered_set uniqueSrcs; bool contextDependentDirectSources = processSources(this, entries, files, uniqueSrcs, debugSources); // Collect INTERFACE_SOURCES of all direct link-dependencies. - std::vector linkInterfaceSourcesEntries; + EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries; AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(), &dagChecker, linkInterfaceSourcesEntries); std::vector::size_type numFilesBefore = files.size(); @@ -1554,7 +1558,7 @@ std::vector> cmGeneratorTarget::GetSourceFilePaths( bool contextDependentObjects = false; std::vector::size_type numFilesBefore2 = files.size(); if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) { - std::vector linkObjectsEntries; + EvaluatedTargetPropertyEntries linkObjectsEntries; AddObjectEntries(this, config, &dagChecker, linkObjectsEntries); contextDependentObjects = processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources); @@ -3216,13 +3220,13 @@ std::string cmGeneratorTarget::GetCreateRuleVariable( } namespace { -void processIncludeDirectories( - cmGeneratorTarget const* tgt, - std::vector& entries, - std::vector>& includes, - std::unordered_set& uniqueIncludes, bool debugIncludes) +void processIncludeDirectories(cmGeneratorTarget const* tgt, + EvaluatedTargetPropertyEntries& entries, + std::vector>& includes, + std::unordered_set& uniqueIncludes, + bool debugIncludes) { - for (EvaluatedTargetPropertyEntry& entry : entries) { + for (EvaluatedTargetPropertyEntry& entry : entries.Entries) { cmLinkImplItem const& item = entry.LinkImplItem; std::string const& targetName = item.AsStr(); bool const fromImported = item.Target && item.Target->IsImported(); @@ -3343,9 +3347,8 @@ std::vector> cmGeneratorTarget::GetIncludeDirectories( this->DebugIncludesDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, lang, &dagChecker, - this->IncludeDirectoriesEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, lang, &dagChecker, this->IncludeDirectoriesEntries); if (lang == "Swift") { AddSwiftImplicitIncludeDirectories(this, config, entries); @@ -3371,7 +3374,7 @@ std::vector> cmGeneratorTarget::GetIncludeDirectories( EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace()); ee.Values.emplace_back(std::move(libDir)); - entries.emplace_back(std::move(ee)); + entries.Entries.emplace_back(std::move(ee)); } } @@ -3392,14 +3395,14 @@ const auto DL_BEGIN = ""_s; const auto DL_END = ""_s; void processOptions(cmGeneratorTarget const* tgt, - std::vector const& entries, + EvaluatedTargetPropertyEntries const& entries, std::vector>& options, std::unordered_set& uniqueOptions, bool debugOptions, const char* logName, OptionsParse parse, bool processDeviceOptions = false) { bool splitOption = !processDeviceOptions; - for (EvaluatedTargetPropertyEntry const& entry : entries) { + for (EvaluatedTargetPropertyEntry const& entry : entries.Entries) { std::string usedOptions; for (std::string const& opt : entry.Values) { if (processDeviceOptions && (opt == DL_BEGIN || opt == DL_END)) { @@ -3531,9 +3534,8 @@ std::vector> cmGeneratorTarget::GetCompileOptions( this->DebugCompileOptionsDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, language, &dagChecker, - this->CompileOptionsEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, language, &dagChecker, this->CompileOptionsEntries); AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language, &dagChecker, entries); @@ -3577,9 +3579,8 @@ std::vector> cmGeneratorTarget::GetCompileFeatures( this->DebugCompileFeaturesDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker, - this->CompileFeaturesEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, std::string(), &dagChecker, this->CompileFeaturesEntries); AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES", std::string(), &dagChecker, entries); @@ -3625,9 +3626,8 @@ std::vector> cmGeneratorTarget::GetCompileDefinitions( this->DebugCompileDefinitionsDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, language, &dagChecker, - this->CompileDefinitionsEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, language, &dagChecker, this->CompileDefinitionsEntries); AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language, &dagChecker, entries); @@ -3647,7 +3647,7 @@ std::vector> cmGeneratorTarget::GetCompileDefinitions( case cmPolicies::OLD: { std::unique_ptr entry = CreateTargetPropertyEntry(*configProp); - entries.emplace_back(EvaluateTargetPropertyEntry( + entries.Entries.emplace_back(EvaluateTargetPropertyEntry( this, config, language, &dagChecker, *entry)); } break; case cmPolicies::NEW: @@ -3687,9 +3687,8 @@ std::vector> cmGeneratorTarget::GetPrecompileHeaders( this->DebugPrecompileHeadersDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, language, &dagChecker, - this->PrecompileHeadersEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, language, &dagChecker, this->PrecompileHeadersEntries); AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language, &dagChecker, entries); @@ -4064,9 +4063,8 @@ std::vector> cmGeneratorTarget::GetLinkOptions( this->DebugLinkOptionsDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, language, &dagChecker, - this->LinkOptionsEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, language, &dagChecker, this->LinkOptionsEntries); AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language, &dagChecker, entries, @@ -4205,14 +4203,14 @@ std::vector> cmGeneratorTarget::GetStaticLibraryLinkOptions( cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS", nullptr, nullptr); - std::vector entries; + EvaluatedTargetPropertyEntries entries; if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { std::vector options = cmExpandedList(*linkOptions); for (const auto& option : options) { std::unique_ptr entry = CreateTargetPropertyEntry(option); - entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language, - &dagChecker, *entry)); + entries.Entries.emplace_back(EvaluateTargetPropertyEntry( + this, config, language, &dagChecker, *entry)); } } processOptions(this, entries, result, uniqueOptions, false, @@ -4223,12 +4221,12 @@ std::vector> cmGeneratorTarget::GetStaticLibraryLinkOptions( namespace { void processLinkDirectories(cmGeneratorTarget const* tgt, - std::vector& entries, + EvaluatedTargetPropertyEntries& entries, std::vector>& directories, std::unordered_set& uniqueDirectories, bool debugDirectories) { - for (EvaluatedTargetPropertyEntry& entry : entries) { + for (EvaluatedTargetPropertyEntry& entry : entries.Entries) { cmLinkImplItem const& item = entry.LinkImplItem; std::string const& targetName = item.AsStr(); @@ -4327,9 +4325,8 @@ std::vector> cmGeneratorTarget::GetLinkDirectories( this->DebugLinkDirectoriesDone = true; } - std::vector entries = - EvaluateTargetPropertyEntries(this, config, language, &dagChecker, - this->LinkDirectoriesEntries); + EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries( + this, config, language, &dagChecker, this->LinkDirectoriesEntries); AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language, &dagChecker, entries, @@ -4360,14 +4357,14 @@ std::vector> cmGeneratorTarget::GetLinkDepends( cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr, nullptr); - std::vector entries; + EvaluatedTargetPropertyEntries entries; if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) { std::vector depends = cmExpandedList(*linkDepends); for (const auto& depend : depends) { std::unique_ptr entry = CreateTargetPropertyEntry(depend); - entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language, - &dagChecker, *entry)); + entries.Entries.emplace_back(EvaluateTargetPropertyEntry( + this, config, language, &dagChecker, *entry)); } } AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language, -- cgit v0.12 From 6c5d4522bcc242361895e72c3fcbd91710abb64c Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 12 May 2020 11:27:11 -0400 Subject: INTERFACE_SOURCES: Fix per-config link libs on multi-config generators In multi-config generators we memoize the computed set of source files for a target to avoid repeating the computation when the set does not depend on the configuration. We already track whether generator expressions in `SOURCES` or `INTERFACE_SOURCES` reference the configuration (`$`). However, we previously forgot to track whether the set of libraries whose `INTERFACE_SOURCES` are considered depends on the configuration. This caused multi-config generators to use the first configuration's set of sources for all configurations in cases such as target_link_libraries(tgt PRIVATE $<$:iface_debug>) where the `iface_debug` target has `INTERFACE_SOURCES`. Fix this by also tracking config-dependence of the list of libraries for evaluation of the list of source files. Fixes: #20683 --- Source/cmGeneratorTarget.cxx | 8 +++++++- Tests/ConfigSources/CMakeLists.txt | 38 +++++++++++++++++++++++++++++++++++++- Tests/ConfigSources/main.cpp | 9 +++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 Tests/ConfigSources/main.cpp diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index d253bc7..a44126c 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -241,6 +241,7 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( struct EvaluatedTargetPropertyEntries { std::vector Entries; + bool HadContextSensitiveCondition = false; }; EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries( @@ -1251,6 +1252,9 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries( context->Config, headTarget, usage_requirements_only)) { + context->HadContextSensitiveCondition = + context->HadContextSensitiveCondition || + iface->HadContextSensitiveCondition; for (cmLinkItem const& lib : iface->Libraries) { // Broken code can have a target in its own link interface. // Don't follow such link interface entries so as not to create a @@ -1378,6 +1382,7 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries(config)) { + entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target) { EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace); @@ -1404,6 +1409,7 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget, { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries(config)) { + entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition; for (cmLinkImplItem const& lib : impl->Libraries) { if (lib.Target && lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) { @@ -1436,7 +1442,7 @@ bool processSources(cmGeneratorTarget const* tgt, { cmMakefile* mf = tgt->Target->GetMakefile(); - bool contextDependent = false; + bool contextDependent = entries.HadContextSensitiveCondition; for (EvaluatedTargetPropertyEntry& entry : entries.Entries) { if (entry.ContextDependent) { diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index f5dd276..21f923e 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.0) project(ConfigSources CXX) +# Per-config sources via INTERFACE_SOURCES. add_library(iface INTERFACE) target_sources(iface INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp" @@ -12,10 +13,45 @@ target_compile_definitions(iface INTERFACE "$<$:CFG_DEBUG>" "$<$>:CFG_OTHER>" ) - add_executable(ConfigSources $<$:main_debug.cpp> $<$>:main_other.cpp> $<$:does_not_exist.cpp> ) target_link_libraries(ConfigSources iface) + +# Per-config sources via LINK_LIBRARIES. +add_library(iface_debug INTERFACE) +target_sources(iface_debug INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp" + ) +add_library(iface_other INTERFACE) +target_sources(iface_other INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/iface_other_src.cpp" + ) +add_executable(ConfigSourcesLink main.cpp) +target_compile_definitions(ConfigSourcesLink PRIVATE + "$<$:CFG_DEBUG>" + "$<$>:CFG_OTHER>" + ) +target_link_libraries(ConfigSourcesLink PRIVATE + "$<$:iface_debug>" + "$<$>:iface_other>" + "$<$:iface_does_not_exist>" + ) + +# Per-config sources via INTERFACE_LINK_LIBRARIES. +add_library(ConfigSourcesIface INTERFACE) +target_link_libraries(ConfigSourcesIface INTERFACE + "$<$:iface_debug>" + "$<$>:iface_other>" + "$<$:iface_does_not_exist>" + ) +add_executable(ConfigSourcesLinkIface main.cpp) +target_compile_definitions(ConfigSourcesLinkIface PRIVATE + "$<$:CFG_DEBUG>" + "$<$>:CFG_OTHER>" + ) +target_link_libraries(ConfigSourcesLinkIface ConfigSourcesIface) diff --git a/Tests/ConfigSources/main.cpp b/Tests/ConfigSources/main.cpp new file mode 100644 index 0000000..c1cd3b2 --- /dev/null +++ b/Tests/ConfigSources/main.cpp @@ -0,0 +1,9 @@ +#if !defined(CFG_DEBUG) && !defined(CFG_OTHER) +# error "Neither CFG_DEBUG or CFG_OTHER is defined." +#endif +#ifdef CFG_DEBUG +# include "main_debug.cpp" +#endif +#ifdef CFG_OTHER +# include "main_other.cpp" +#endif -- cgit v0.12