diff options
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 217 |
1 files changed, 134 insertions, 83 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 171c3ed..b3fb132 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -10,15 +10,14 @@ #include <cstdlib> #include <cstring> #include <iterator> -#include <memory> +#include <queue> #include <sstream> #include <unordered_set> #include <utility> +#include <cm/memory> #include <cm/string_view> -#include <queue> - #include "cmsys/RegularExpression.hxx" #include "cmAlgorithms.h" @@ -162,7 +161,8 @@ private: cmListFileBacktrace Backtrace; }; -cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry( +std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry> +CreateTargetPropertyEntry( const std::string& propertyValue, cmListFileBacktrace backtrace = cmListFileBacktrace(), bool evaluateForBuildsystem = false) @@ -172,15 +172,18 @@ cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry( std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propertyValue); cge->SetEvaluateForBuildsystem(evaluateForBuildsystem); - return new TargetPropertyEntryGenex(std::move(cge)); + return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>( + cm::make_unique<TargetPropertyEntryGenex>(std::move(cge))); } - return new TargetPropertyEntryString(propertyValue, std::move(backtrace)); + return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>( + cm::make_unique<TargetPropertyEntryString>(propertyValue, + std::move(backtrace))); } void CreatePropertyGeneratorExpressions( cmStringRange entries, cmBacktraceRange backtraces, - std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items, + std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items, bool evaluateForBuildsystem = false) { auto btIt = backtraces.begin(); @@ -219,13 +222,13 @@ struct EvaluatedTargetPropertyEntry EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( cmGeneratorTarget const* thisTarget, std::string const& config, std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - cmGeneratorTarget::TargetPropertyEntry* entry) + cmGeneratorTarget::TargetPropertyEntry& entry) { - EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace()); - cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config, - thisTarget, dagChecker, lang), + EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace()); + cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config, + thisTarget, dagChecker, lang), ee.Values); - if (entry->GetHadContextSensitiveCondition()) { + if (entry.GetHadContextSensitiveCondition()) { ee.ContextDependent = true; } return ee; @@ -234,13 +237,14 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry( std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries( cmGeneratorTarget const* thisTarget, std::string const& config, std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in) + std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const& + in) { std::vector<EvaluatedTargetPropertyEntry> out; out.reserve(in.size()); - for (cmGeneratorTarget::TargetPropertyEntry* entry : in) { + for (auto& entry : in) { out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang, - dagChecker, entry)); + dagChecker, *entry)); } return out; } @@ -304,23 +308,12 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) this->PolicyMap = t->GetPolicyMap(); } -cmGeneratorTarget::~cmGeneratorTarget() -{ - cmDeleteAll(this->IncludeDirectoriesEntries); - cmDeleteAll(this->CompileOptionsEntries); - cmDeleteAll(this->CompileFeaturesEntries); - cmDeleteAll(this->CompileDefinitionsEntries); - cmDeleteAll(this->LinkOptionsEntries); - cmDeleteAll(this->LinkDirectoriesEntries); - cmDeleteAll(this->PrecompileHeadersEntries); - cmDeleteAll(this->SourceEntries); - cmDeleteAll(this->LinkInformation); -} +cmGeneratorTarget::~cmGeneratorTarget() = default; const char* cmGeneratorTarget::GetSourcesProperty() const { std::vector<std::string> values; - for (TargetPropertyEntry* se : this->SourceEntries) { + for (auto& se : this->SourceEntries) { values.push_back(se->GetInput()); } static std::string value; @@ -655,6 +648,7 @@ void cmGeneratorTarget::ClearSourcesCache() this->KindedSourcesMap.clear(); this->LinkImplementationLanguageIsContextDependent = true; this->Objects.clear(); + this->VisitedConfigsForObjects.clear(); } void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before) @@ -744,7 +738,7 @@ void cmGeneratorTarget::GetObjectSources( { IMPLEMENT_VISIT(SourceKindObjectSource); - if (!this->Objects.empty()) { + if (this->VisitedConfigsForObjects.count(config)) { return; } @@ -753,16 +747,17 @@ void cmGeneratorTarget::GetObjectSources( } this->LocalGenerator->ComputeObjectFilenames(this->Objects, this); + this->VisitedConfigsForObjects.insert(config); } void cmGeneratorTarget::ComputeObjectMapping() { - if (!this->Objects.empty()) { + auto const& configs = this->Makefile->GetGeneratorConfigs(); + std::set<std::string> configSet(configs.begin(), configs.end()); + if (configSet == this->VisitedConfigsForObjects) { return; } - std::vector<std::string> const& configs = - this->Makefile->GetGeneratorConfigs(); for (std::string const& c : configs) { std::vector<cmSourceFile const*> sourceFiles; this->GetObjectSources(sourceFiles, c); @@ -1122,7 +1117,8 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const } bool cmGeneratorTarget::MaybeHaveInterfaceProperty( - std::string const& prop, cmGeneratorExpressionContext* context) const + std::string const& prop, cmGeneratorExpressionContext* context, + bool usage_requirements_only) const { std::string const key = prop + '@' + context->Config; auto i = this->MaybeInterfacePropertyExists.find(key); @@ -1141,7 +1137,7 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty( context->HeadTarget ? context->HeadTarget : this; if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(context->Config, headTarget, - true)) { + usage_requirements_only)) { if (iface->HadHeadSensitiveCondition) { // With a different head target we may get to a library with // this interface property. @@ -1151,7 +1147,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty( // head target, so we can follow them. for (cmLinkItem const& lib : iface->Libraries) { if (lib.Target && - lib.Target->MaybeHaveInterfaceProperty(prop, context)) { + lib.Target->MaybeHaveInterfaceProperty( + prop, context, usage_requirements_only)) { maybeInterfaceProp = true; break; } @@ -1165,12 +1162,14 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty( std::string cmGeneratorTarget::EvaluateInterfaceProperty( std::string const& prop, cmGeneratorExpressionContext* context, - cmGeneratorExpressionDAGChecker* dagCheckerParent) const + cmGeneratorExpressionDAGChecker* dagCheckerParent, + bool usage_requirements_only) const { std::string result; // If the property does not appear transitively at all, we are done. - if (!this->MaybeHaveInterfaceProperty(prop, context)) { + if (!this->MaybeHaveInterfaceProperty(prop, context, + usage_requirements_only)) { return result; } @@ -1202,8 +1201,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( p, context->LG, context, headTarget, &dagChecker, this); } - if (cmLinkInterfaceLibraries const* iface = - this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) { + if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries( + context->Config, headTarget, usage_requirements_only)) { 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 @@ -1217,8 +1216,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty( context->EvaluateForBuildsystem, context->Backtrace, context->Language); std::string libResult = cmGeneratorExpression::StripEmptyListElements( - lib.Target->EvaluateInterfaceProperty(prop, &libContext, - &dagChecker)); + lib.Target->EvaluateInterfaceProperty(prop, &libContext, &dagChecker, + usage_requirements_only)); if (!libResult.empty()) { if (result.empty()) { result = std::move(libResult); @@ -1246,7 +1245,8 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, std::string const& config, std::string const& prop, std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker, - std::vector<EvaluatedTargetPropertyEntry>& entries) + std::vector<EvaluatedTargetPropertyEntry>& entries, + bool usage_requirements_only = true) { if (cmLinkImplementationLibraries const* impl = headTarget->GetLinkImplementationLibraries(config)) { @@ -1259,9 +1259,9 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget, cmGeneratorExpressionContext context( headTarget->GetLocalGenerator(), config, false, headTarget, headTarget, true, lib.Backtrace, lang); - cmExpandList( - lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker), - ee.Values); + cmExpandList(lib.Target->EvaluateInterfaceProperty( + prop, &context, dagChecker, usage_requirements_only), + ee.Values); ee.ContextDependent = context.HadContextSensitiveCondition; entries.emplace_back(std::move(ee)); } @@ -1672,6 +1672,19 @@ void cmGeneratorTarget::ComputeAllConfigSources() const } } +std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const +{ + std::set<std::string> languages; + std::vector<AllConfigSource> const& sources = this->GetAllConfigSources(); + for (AllConfigSource const& si : sources) { + std::string const& lang = si.Source->GetOrDetermineLanguage(); + if (!lang.empty()) { + languages.emplace(lang); + } + } + return languages; +} + std::string cmGeneratorTarget::GetCompilePDBName( const std::string& config) const { @@ -2114,7 +2127,9 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree( // If building directly for installation then the build tree install_name // is the same as the install tree. if (this->MacOSXUseInstallNameDir()) { - return this->GetInstallNameDirForInstallTree(); + std::string installPrefix = + this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"); + return this->GetInstallNameDirForInstallTree(config, installPrefix); } // Use the build tree directory for the target. @@ -2132,7 +2147,8 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree( return ""; } -std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const +std::string cmGeneratorTarget::GetInstallNameDirForInstallTree( + const std::string& config, const std::string& installPrefix) const { if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) { std::string dir; @@ -2140,7 +2156,13 @@ std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) { if (install_name_dir && *install_name_dir) { - dir = cmStrCat(install_name_dir, '/'); + dir = install_name_dir; + cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix); + dir = + cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config); + if (!dir.empty()) { + dir = cmStrCat(dir, '/'); + } } } if (!install_name_dir) { @@ -2492,11 +2514,11 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo( info.WindowsExportAllSymbols = this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"); -#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) +#if !defined(CMAKE_BOOTSTRAP) info.DefFileGenerated = info.WindowsExportAllSymbols || info.Sources.size() > 1; #else - // Our __create_def helper is only available on Windows. + // Our __create_def helper is not available during CMake bootstrap. info.DefFileGenerated = false; #endif if (info.DefFileGenerated) { @@ -3064,7 +3086,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories( cmLinkImplementationLibraries const* impl = this->GetLinkImplementationLibraries(config); for (cmLinkImplItem const& lib : impl->Libraries) { - std::string libDir = cmSystemTools::CollapseFullPath(lib.AsStr()); + std::string libDir = cmSystemTools::CollapseFullPath( + lib.AsStr(), this->Makefile->GetHomeOutputDirectory()); static cmsys::RegularExpression frameworkCheck( "(.*\\.framework)(/Versions/[^/]+)?/[^/]+$"); @@ -3277,10 +3300,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions( CM_FALLTHROUGH; } case cmPolicies::OLD: { - std::unique_ptr<TargetPropertyEntry> entry( - CreateTargetPropertyEntry(configProp)); + std::unique_ptr<TargetPropertyEntry> entry = + CreateTargetPropertyEntry(configProp); entries.emplace_back(EvaluateTargetPropertyEntry( - this, config, language, &dagChecker, entry.get())); + this, config, language, &dagChecker, *entry)); } break; case cmPolicies::NEW: case cmPolicies::REQUIRED_ALWAYS: @@ -3647,7 +3670,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions( this->LinkOptionsEntries); AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language, - &dagChecker, entries); + &dagChecker, entries, + this->GetPolicyStatusCMP0099() != cmPolicies::NEW); processOptions(this, entries, result, uniqueOptions, debugOptions, "link options", OptionsParse::Shell); @@ -3779,10 +3803,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions( if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { std::vector<std::string> options = cmExpandedList(linkOptions); for (const auto& option : options) { - std::unique_ptr<TargetPropertyEntry> entry( - CreateTargetPropertyEntry(option)); - entries.emplace_back(EvaluateTargetPropertyEntry( - this, config, language, &dagChecker, entry.get())); + std::unique_ptr<TargetPropertyEntry> entry = + CreateTargetPropertyEntry(option); + entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language, + &dagChecker, *entry)); } } processOptions(this, entries, result, uniqueOptions, false, @@ -3902,7 +3926,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories( this->LinkDirectoriesEntries); AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language, - &dagChecker, entries); + &dagChecker, entries, + this->GetPolicyStatusCMP0099() != cmPolicies::NEW); processLinkDirectories(this, entries, result, uniqueDirectories, debugDirectories); @@ -3933,14 +3958,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends( if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) { std::vector<std::string> depends = cmExpandedList(linkDepends); for (const auto& depend : depends) { - std::unique_ptr<TargetPropertyEntry> entry( - CreateTargetPropertyEntry(depend)); - entries.emplace_back(EvaluateTargetPropertyEntry( - this, config, language, &dagChecker, entry.get())); + std::unique_ptr<TargetPropertyEntry> entry = + CreateTargetPropertyEntry(depend); + entries.emplace_back(EvaluateTargetPropertyEntry(this, config, language, + &dagChecker, *entry)); } } AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language, - &dagChecker, entries); + &dagChecker, entries, + this->GetPolicyStatusCMP0099() != cmPolicies::NEW); processOptions(this, entries, result, uniqueOptions, false, "link depends", OptionsParse::None); @@ -4720,9 +4746,9 @@ std::string intersect(const std::set<std::string>& s1, } void cmGeneratorTarget::CheckPropertyCompatibility( - cmComputeLinkInformation* info, const std::string& config) const + cmComputeLinkInformation& info, const std::string& config) const { - const cmComputeLinkInformation::ItemVector& deps = info->GetItems(); + const cmComputeLinkInformation::ItemVector& deps = info.GetItems(); std::set<std::string> emittedBools; static const std::string strBool = "COMPATIBLE_INTERFACE_BOOL"; @@ -5067,10 +5093,11 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt, } std::string interfaceProperty = "INTERFACE_" + p; - std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter( - p == "POSITION_INDEPENDENT_CODE" ? new cmGeneratorExpressionInterpreter( - tgt->GetLocalGenerator(), config, tgt) - : nullptr); + std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter; + if (p == "POSITION_INDEPENDENT_CODE") { + genexInterpreter = cm::make_unique<cmGeneratorExpressionInterpreter>( + tgt->GetLocalGenerator(), config, tgt); + } for (cmGeneratorTarget const* theTarget : deps) { // An error should be reported if one dependency @@ -5217,22 +5244,19 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation( auto i = this->LinkInformation.find(key); if (i == this->LinkInformation.end()) { // Compute information for this configuration. - cmComputeLinkInformation* info = - new cmComputeLinkInformation(this, config); - if (!info || !info->Compute()) { - delete info; - info = nullptr; + auto info = cm::make_unique<cmComputeLinkInformation>(this, config); + if (info && !info->Compute()) { + info.reset(); } // Store the information for this configuration. - cmTargetLinkInformationMap::value_type entry(key, info); - i = this->LinkInformation.insert(entry).first; + i = this->LinkInformation.emplace(key, std::move(info)).first; - if (info) { - this->CheckPropertyCompatibility(info, config); + if (i->second) { + this->CheckPropertyCompatibility(*i->second, config); } } - return i->second; + return i->second.get(); } void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const @@ -6330,6 +6354,21 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const return lib; } +bool cmGeneratorTarget::IsDeprecated() const +{ + const char* deprecation = this->GetProperty("DEPRECATION"); + return deprecation && *deprecation; +} + +std::string cmGeneratorTarget::GetDeprecation() const +{ + // find DEPRECATION property + if (const char* deprecation = this->GetProperty("DEPRECATION")) { + return deprecation; + } + return std::string(); +} + void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, const std::string& config) const { @@ -6379,8 +6418,7 @@ bool cmGeneratorTarget::IsCSharpOnly() const this->GetType() != cmStateEnums::EXECUTABLE) { return false; } - std::set<std::string> languages; - this->GetLanguages(languages, ""); + std::set<std::string> languages = this->GetAllConfigCompileLanguages(); // Consider an explicit linker language property, but *not* the // computed linker language that may depend on linked targets. const char* linkLang = this->GetProperty("LINKER_LANGUAGE"); @@ -6601,6 +6639,19 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem( return cmLinkItem(resolved.String, bt); } + // Check deprecation, issue message with `bt` backtrace. + if (resolved.Target->IsDeprecated()) { + std::ostringstream w; + /* clang-format off */ + w << + "The library that is being linked to, " << resolved.Target->GetName() << + ", is marked as being deprecated by the owner. The message provided by " + "the developer is: \n" << resolved.Target->GetDeprecation() << "\n"; + /* clang-format on */ + this->LocalGenerator->GetCMakeInstance()->IssueMessage( + MessageType::AUTHOR_WARNING, w.str(), bt); + } + // Skip targets that will not really be linked. This is probably a // name conflict between an external library and an executable // within the project. |