diff options
author | Brad King <brad.king@kitware.com> | 2015-08-27 14:07:32 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-08-27 14:07:32 (GMT) |
commit | 27e4b21dfa926a522bb32674b8836ebb79d51bc5 (patch) | |
tree | 833b5c282f4a5c8ab6ee76bfcfad1317ee3ee085 | |
parent | 445077cbd2343050250eb0d541633010db659312 (diff) | |
parent | c2b7336ff3122c57a235aeaa1699ba5627ecf3ce (diff) | |
download | CMake-27e4b21dfa926a522bb32674b8836ebb79d51bc5.zip CMake-27e4b21dfa926a522bb32674b8836ebb79d51bc5.tar.gz CMake-27e4b21dfa926a522bb32674b8836ebb79d51bc5.tar.bz2 |
Merge topic 'use-generator-target'
c2b7336f cmGeneratorTarget: Move GetConfigCommonSourceFiles from cmTarget.
69329fff cmGeneratorTarget: Move GetLanguages from cmTarget.
0431f2c4 cmGeneratorTarget: Move ComputeLinkImplementationLanguages from cmTarget.
abe9505d cmGeneratorTarget: Move HaveBuildTreeRPath from cmTarget.
d4a24c0e cmGeneratorTarget: Move GetLinkImplementation from cmTarget.
83981cf5 cmTarget: Add GetLinkImplMap method.
771e79a2 cmLinkItem: Add cmOptionalLinkImplementation type.
3846ebcf cmLinkItem: Add cmLinkImplementation type.
a7f5d70d cmGeneratorTarget: Move compile defintions processing from cmTarget.
d051086c cmGeneratorTarget: Move compile features processing from cmTarget.
db4cb92b cmGeneratorTarget: Move compile options processing from cmTarget.
e6ccbf6f cmGeneratorTarget: Move include directory processing from cmTarget.
8bfb0c53 cmGeneratorTarget: Move link iface helpers from cmTarget.
2cb3e574 cmGeneratorTarget: Move GetImportLinkInterface from cmTarget.
6d3d099b cmGeneratorTarget: Move ComputeLinkInterfaceLibraries from cmTarget.
0db9d927 cmGeneratorTarget: Move GetLinkInterfaceLibraries from cmTarget.
...
25 files changed, 1527 insertions, 1371 deletions
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 1e02ae4..1b5c9f4 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -362,9 +362,11 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe) // Follow the item's dependencies. if(entry.Target) { + cmGeneratorTarget* gtgt = + this->GlobalGenerator->GetGeneratorTarget(entry.Target); // Follow the target dependencies. - if(cmTarget::LinkInterface const* iface = - entry.Target->GetLinkInterface(this->Config, this->Target->Target)) + if(cmLinkInterface const* iface = + gtgt->GetLinkInterface(this->Config, this->Target->Target)) { const bool isIface = entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY; @@ -398,7 +400,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe) //---------------------------------------------------------------------------- void cmComputeLinkDepends -::FollowSharedDeps(int depender_index, cmTarget::LinkInterface const* iface, +::FollowSharedDeps(int depender_index, cmLinkInterface const* iface, bool follow_interface) { // Follow dependencies if we have not followed them already. @@ -461,8 +463,10 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) // Target items may have their own dependencies. if(entry.Target) { - if(cmTarget::LinkInterface const* iface = - entry.Target->GetLinkInterface(this->Config, this->Target->Target)) + cmGeneratorTarget* gtgt = + this->GlobalGenerator->GetGeneratorTarget(entry.Target); + if(cmLinkInterface const* iface = + gtgt->GetLinkInterface(this->Config, this->Target->Target)) { // Follow public and private dependencies transitively. this->FollowSharedDeps(index, iface, true); @@ -552,8 +556,8 @@ void cmComputeLinkDepends::AddVarLinkEntries(int depender_index, void cmComputeLinkDepends::AddDirectLinkEntries() { // Add direct link dependencies in this configuration. - cmTarget::LinkImplementation const* impl = - this->Target->Target->GetLinkImplementation(this->Config); + cmLinkImplementation const* impl = + this->Target->GetLinkImplementation(this->Config); this->AddLinkEntries(-1, impl->Libraries); for(std::vector<cmLinkItem>::const_iterator wi = impl->WrongConfigLibraries.begin(); @@ -932,8 +936,10 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl) { if(cmTarget const* target = this->EntryList[*ni].Target) { - if(cmTarget::LinkInterface const* iface = - target->GetLinkInterface(this->Config, this->Target->Target)) + cmGeneratorTarget* gtgt = + this->GlobalGenerator->GetGeneratorTarget(target); + if(cmLinkInterface const* iface = + gtgt->GetLinkInterface(this->Config, this->Target->Target)) { if(iface->Multiplicity > count) { diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index b925a4f..2cbb430 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -102,7 +102,7 @@ private: std::queue<SharedDepEntry> SharedDepQueue; std::set<int> SharedDepFollowed; void FollowSharedDeps(int depender_index, - cmTarget::LinkInterface const* iface, + cmLinkInterface const* iface, bool follow_interface = false); void QueueSharedDependencies(int depender_index, std::vector<cmLinkItem> const& deps); diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index 6c3822f..4b70e5e 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1925,7 +1925,7 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs, (outputRuntime && this->Target->Target->HaveInstallTreeRPATH() && linking_for_install); bool use_build_rpath = - (outputRuntime && this->Target->Target->HaveBuildTreeRPATH(this->Config) && + (outputRuntime && this->Target->HaveBuildTreeRPATH(this->Config) && !linking_for_install); bool use_link_rpath = outputRuntime && linking_for_install && diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index c4a03a0..9e37c35 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -252,8 +252,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) } } - cmTarget::LinkImplementation const* impl = - depender->Target->GetLinkImplementation(*it); + cmLinkImplementation const* impl = depender->GetLinkImplementation(*it); // A target should not depend on itself. emitted.insert(depender->GetName()); @@ -296,8 +295,8 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, std::set<std::string> &emitted) { cmGeneratorTarget const* depender = this->Targets[depender_index]; - if(cmTarget::LinkInterface const* iface = - dependee->Target->GetLinkInterface(config, + if(cmLinkInterface const* iface = + dependee->GetLinkInterface(config, depender->Target)) { for(std::vector<cmLinkItem>::const_iterator diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index cae60b7..9a7d73f 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -796,9 +796,8 @@ cmExportFileGenerator std::vector<std::string>& missingTargets) { // Add the transitive link dependencies for this configuration. - cmTarget::LinkInterface const* iface = target->Target->GetLinkInterface( - config, - target->Target); + cmLinkInterface const* iface = target->GetLinkInterface(config, + target->Target); if (!iface) { return; @@ -909,9 +908,8 @@ cmExportFileGenerator } // Add the transitive link dependencies for this configuration. - if(cmTarget::LinkInterface const* iface = - target->Target - ->GetLinkInterface(config, target->Target)) + if(cmLinkInterface const* iface = + target->GetLinkInterface(config, target->Target)) { this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 933a256..dfd51c7 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -609,7 +609,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout, // the compilerdefines for this target std::vector<std::string> cdefs; - target->GetCompileDefinitions(cdefs, buildType, "C"); + gtgt->GetCompileDefinitions(cdefs, buildType, "C"); // Expand the list. for(std::vector<std::string>::const_iterator di = cdefs.begin(); diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 03bc83a..31b6766 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -1108,8 +1108,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode if(isInterfaceProperty) { - if(cmTarget::LinkInterfaceLibraries const* iface = - target->GetLinkInterfaceLibraries(context->Config, headTarget, true)) + if(cmLinkInterfaceLibraries const* iface = + gtgt->GetLinkInterfaceLibraries(context->Config, headTarget, true)) { linkedTargetsContent = getLinkedTargetsContent(iface->Libraries, target, diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 25fc8a7..4a1a7a2 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -34,6 +34,18 @@ #define UNORDERED_SET std::set #endif +class cmGeneratorTarget::TargetPropertyEntry { + static cmLinkImplItem NoLinkImplItem; +public: + TargetPropertyEntry(cmsys::auto_ptr<cmCompiledGeneratorExpression> cge, + cmLinkImplItem const& item = NoLinkImplItem) + : ge(cge), LinkImplItem(item) + {} + const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge; + cmLinkImplItem const& LinkImplItem; +}; +cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem; + //---------------------------------------------------------------------------- void reportBadObjLib(std::vector<cmSourceFile*> const& badObjLib, cmGeneratorTarget const* target, cmake *cm) @@ -227,18 +239,64 @@ struct TagVisitor } }; +void CreatePropertyGeneratorExpressions( + cmStringRange const& entries, + cmBacktraceRange const& backtraces, + std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items, + bool evaluateForBuildsystem = false) +{ + std::vector<cmListFileBacktrace>::const_iterator btIt = backtraces.begin(); + for (std::vector<std::string>::const_iterator it = entries.begin(); + it != entries.end(); ++it, ++btIt) + { + cmGeneratorExpression ge(*btIt); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*it); + cge->SetEvaluateForBuildsystem(evaluateForBuildsystem); + items.push_back(new cmGeneratorTarget::TargetPropertyEntry(cge)); + } +} + //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg) : Target(t), - SourceFileFlagsConstructed(false) + SourceFileFlagsConstructed(false), + PolicyWarnedCMP0022(false), + DebugIncludesDone(false), + DebugCompileOptionsDone(false), + DebugCompileFeaturesDone(false), + DebugCompileDefinitionsDone(false) { this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = lg; this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); + + CreatePropertyGeneratorExpressions( + t->GetIncludeDirectoriesEntries(), + t->GetIncludeDirectoriesBacktraces(), + this->IncludeDirectoriesEntries); + + CreatePropertyGeneratorExpressions( + t->GetCompileOptionsEntries(), + t->GetCompileOptionsBacktraces(), + this->CompileOptionsEntries); + + CreatePropertyGeneratorExpressions( + t->GetCompileFeaturesEntries(), + t->GetCompileFeaturesBacktraces(), + this->CompileFeaturesEntries); + + CreatePropertyGeneratorExpressions( + t->GetCompileDefinitionsEntries(), + t->GetCompileDefinitionsBacktraces(), + this->CompileDefinitionsEntries); } cmGeneratorTarget::~cmGeneratorTarget() { + cmDeleteAll(this->IncludeDirectoriesEntries); + cmDeleteAll(this->CompileOptionsEntries); + cmDeleteAll(this->CompileFeaturesEntries); + cmDeleteAll(this->CompileDefinitionsEntries); cmDeleteAll(this->LinkInformation); this->LinkInformation.clear(); } @@ -851,7 +909,7 @@ cmGeneratorTarget::NeedRelinkBeforeInstall(const std::string& config) const // If either a build or install tree rpath is set then the rpath // will likely change between the build tree and install tree and // this target must be relinked. - return this->Target->HaveBuildTreeRPATH(config) + return this->HaveBuildTreeRPATH(config) || this->Target->HaveInstallTreeRPATH(); } @@ -1172,9 +1230,11 @@ public: { return; } - - cmTarget::LinkInterface const* iface = - item.Target->GetLinkInterface(this->Config, this->HeadTarget); + cmGeneratorTarget* gtgt = + this->Target->GetLocalGenerator()->GetGlobalGenerator() + ->GetGeneratorTarget(item.Target); + cmLinkInterface const* iface = + gtgt->GetLinkInterface(this->Config, this->HeadTarget); if(!iface) { return; } for(std::vector<std::string>::const_iterator @@ -1275,8 +1335,8 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config, { // Get languages built in this target. UNORDERED_SET<std::string> languages; - cmTarget::LinkImplementation const* impl = - this->Target->GetLinkImplementation(config); + cmLinkImplementation const* impl = + this->GetLinkImplementation(config); assert(impl); for(std::vector<std::string>::const_iterator li = impl->Languages.begin(); li != impl->Languages.end(); ++li) @@ -1505,20 +1565,22 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string> &result, void processILibs(const std::string& config, cmTarget const* headTarget, cmLinkItem const& item, + cmGlobalGenerator* gg, std::vector<cmTarget const*>& tgts, std::set<cmTarget const*>& emitted) { if (item.Target && emitted.insert(item.Target).second) { tgts.push_back(item.Target); - if(cmTarget::LinkInterfaceLibraries const* iface = - item.Target->GetLinkInterfaceLibraries(config, headTarget, true)) + cmGeneratorTarget* gt = gg->GetGeneratorTarget(item.Target); + if(cmLinkInterfaceLibraries const* iface = + gt->GetLinkInterfaceLibraries(config, headTarget, true)) { for(std::vector<cmLinkItem>::const_iterator it = iface->Libraries.begin(); it != iface->Libraries.end(); ++it) { - processILibs(config, headTarget, *it, tgts, emitted); + processILibs(config, headTarget, *it, gg, tgts, emitted); } } } @@ -1543,7 +1605,9 @@ cmGeneratorTarget::GetLinkImplementationClosure( it = impl->Libraries.begin(); it != impl->Libraries.end(); ++it) { - processILibs(config, this->Target, *it, tgts , emitted); + processILibs(config, this->Target, *it, + this->LocalGenerator->GetGlobalGenerator(), + tgts , emitted); } } return tgts; @@ -1957,13 +2021,536 @@ cmGeneratorTarget::GetCreateRuleVariable(std::string const& lang, } return ""; } +//---------------------------------------------------------------------------- +static void processIncludeDirectories(cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries, + std::vector<std::string> &includes, + UNORDERED_SET<std::string> &uniqueIncludes, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string& config, bool debugIncludes, + const std::string& language) +{ + cmMakefile *mf = tgt->Target->GetMakefile(); + + for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator + it = entries.begin(), end = entries.end(); it != end; ++it) + { + cmLinkImplItem const& item = (*it)->LinkImplItem; + std::string const& targetName = item; + bool const fromImported = item.Target && item.Target->IsImported(); + bool const checkCMP0027 = item.FromGenex; + std::vector<std::string> entryIncludes; + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, + config, + false, + tgt->Target, + dagChecker, language), + entryIncludes); + + std::string usedIncludes; + for(std::vector<std::string>::iterator + li = entryIncludes.begin(); li != entryIncludes.end(); ++li) + { + if (fromImported + && !cmSystemTools::FileExists(li->c_str())) + { + std::ostringstream e; + cmake::MessageType messageType = cmake::FATAL_ERROR; + if (checkCMP0027) + { + switch(tgt->Target->GetPolicyStatusCMP0027()) + { + case cmPolicies::WARN: + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n"; + case cmPolicies::OLD: + messageType = cmake::AUTHOR_WARNING; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::NEW: + break; + } + } + e << "Imported target \"" << targetName << "\" includes " + "non-existent path\n \"" << *li << "\"\nin its " + "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n" + "* The path was deleted, renamed, or moved to another " + "location.\n" + "* An install or uninstall procedure did not complete " + "successfully.\n" + "* The installation package was faulty and references files it " + "does not provide.\n"; + tgt->GetLocalGenerator()->IssueMessage(messageType, e.str()); + return; + } + + if (!cmSystemTools::FileIsFullPath(li->c_str())) + { + std::ostringstream e; + bool noMessage = false; + cmake::MessageType messageType = cmake::FATAL_ERROR; + if (!targetName.empty()) + { + e << "Target \"" << targetName << "\" contains relative " + "path in its INTERFACE_INCLUDE_DIRECTORIES:\n" + " \"" << *li << "\""; + } + else + { + switch(tgt->Target->GetPolicyStatusCMP0021()) + { + case cmPolicies::WARN: + { + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n"; + messageType = cmake::AUTHOR_WARNING; + } + break; + case cmPolicies::OLD: + noMessage = true; + case cmPolicies::REQUIRED_IF_USED: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::NEW: + // Issue the fatal message. + break; + } + e << "Found relative path while evaluating include directories of " + "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n"; + } + if (!noMessage) + { + tgt->GetLocalGenerator()->IssueMessage(messageType, e.str()); + if (messageType == cmake::FATAL_ERROR) + { + return; + } + } + } + + if (!cmSystemTools::IsOff(li->c_str())) + { + cmSystemTools::ConvertToUnixSlashes(*li); + } + std::string inc = *li; + + if(uniqueIncludes.insert(inc).second) + { + includes.push_back(inc); + if (debugIncludes) + { + usedIncludes += " * " + inc + "\n"; + } + } + } + if (!usedIncludes.empty()) + { + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used includes for target ") + + tgt->GetName() + ":\n" + + usedIncludes, (*it)->ge->GetBacktrace()); + } + } +} + + +//---------------------------------------------------------------------------- +static void AddInterfaceEntries( + cmGeneratorTarget const* thisTarget, std::string const& config, + std::string const& prop, + std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries) +{ + if(cmLinkImplementationLibraries const* impl = + thisTarget->Target->GetLinkImplementationLibraries(config)) + { + for (std::vector<cmLinkImplItem>::const_iterator + it = impl->Libraries.begin(), end = impl->Libraries.end(); + it != end; ++it) + { + if(it->Target) + { + std::string genex = + "$<TARGET_PROPERTY:" + *it + "," + prop + ">"; + cmGeneratorExpression ge(it->Backtrace); + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex); + cge->SetEvaluateForBuildsystem(true); + entries.push_back( + new cmGeneratorTarget::TargetPropertyEntry(cge, *it)); + } + } + } +} //---------------------------------------------------------------------------- std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(const std::string& config, const std::string& lang) const { - return this->Target->GetIncludeDirectories(config, lang); + std::vector<std::string> includes; + UNORDERED_SET<std::string> uniqueIncludes; + + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugIncludes = !this->DebugIncludesDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "INCLUDE_DIRECTORIES") + != debugProperties.end(); + + if (this->Makefile->IsConfigured()) + { + this->DebugIncludesDone = true; + } + + processIncludeDirectories(this, + this->IncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes, + lang); + + std::vector<cmGeneratorTarget::TargetPropertyEntry*> + linkInterfaceIncludeDirectoriesEntries; + AddInterfaceEntries( + this, config, "INTERFACE_INCLUDE_DIRECTORIES", + linkInterfaceIncludeDirectoriesEntries); + + if(this->Makefile->IsOn("APPLE")) + { + cmLinkImplementationLibraries const* impl = + this->Target->GetLinkImplementationLibraries(config); + for(std::vector<cmLinkImplItem>::const_iterator + it = impl->Libraries.begin(); + it != impl->Libraries.end(); ++it) + { + std::string libDir = cmSystemTools::CollapseFullPath(*it); + + static cmsys::RegularExpression + frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$"); + if(!frameworkCheck.find(libDir)) + { + continue; + } + + libDir = frameworkCheck.match(1); + + cmGeneratorExpression ge; + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(libDir.c_str()); + linkInterfaceIncludeDirectoriesEntries + .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge)); + } + } + + processIncludeDirectories(this, + linkInterfaceIncludeDirectoriesEntries, + includes, + uniqueIncludes, + &dagChecker, + config, + debugIncludes, + lang); + + cmDeleteAll(linkInterfaceIncludeDirectoriesEntries); + + return includes; +} + +//---------------------------------------------------------------------------- +static void processCompileOptionsInternal(cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + UNORDERED_SET<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string& config, bool debugOptions, const char *logName, + std::string const& language) +{ + cmMakefile *mf = tgt->Target->GetMakefile(); + + for (std::vector<cmGeneratorTarget::TargetPropertyEntry*>::const_iterator + it = entries.begin(), end = entries.end(); it != end; ++it) + { + std::vector<std::string> entryOptions; + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, + config, + false, + tgt->Target, + dagChecker, + language), + entryOptions); + std::string usedOptions; + for(std::vector<std::string>::iterator + li = entryOptions.begin(); li != entryOptions.end(); ++li) + { + std::string const& opt = *li; + + if(uniqueOptions.insert(opt).second) + { + options.push_back(opt); + if (debugOptions) + { + usedOptions += " * " + opt + "\n"; + } + } + } + if (!usedOptions.empty()) + { + mf->GetCMakeInstance()->IssueMessage(cmake::LOG, + std::string("Used compile ") + logName + + std::string(" for target ") + + tgt->GetName() + ":\n" + + usedOptions, (*it)->ge->GetBacktrace()); + } + } +} + +//---------------------------------------------------------------------------- +static void processCompileOptions(cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + UNORDERED_SET<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string& config, bool debugOptions, + std::string const& language) +{ + processCompileOptionsInternal(tgt, entries, options, uniqueOptions, + dagChecker, config, debugOptions, "options", + language); +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetCompileOptions(std::vector<std::string> &result, + const std::string& config, + const std::string& language) const +{ + UNORDERED_SET<std::string> uniqueOptions; + + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), + "COMPILE_OPTIONS", 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugOptions = !this->DebugCompileOptionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_OPTIONS") + != debugProperties.end(); + + if (this->Makefile->IsConfigured()) + { + this->DebugCompileOptionsDone = true; + } + + processCompileOptions(this, + this->CompileOptionsEntries, + result, + uniqueOptions, + &dagChecker, + config, + debugOptions, + language); + + std::vector<cmGeneratorTarget::TargetPropertyEntry*> + linkInterfaceCompileOptionsEntries; + + AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_OPTIONS", + linkInterfaceCompileOptionsEntries); + + processCompileOptions(this, + linkInterfaceCompileOptionsEntries, + result, + uniqueOptions, + &dagChecker, + config, + debugOptions, + language); + + cmDeleteAll(linkInterfaceCompileOptionsEntries); +} + +//---------------------------------------------------------------------------- +static void processCompileFeatures(cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + UNORDERED_SET<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string& config, bool debugOptions) +{ + processCompileOptionsInternal(tgt, entries, options, uniqueOptions, + dagChecker, config, debugOptions, "features", + std::string()); +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string> &result, + const std::string& config) const +{ + UNORDERED_SET<std::string> uniqueFeatures; + + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), + "COMPILE_FEATURES", + 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugFeatures = !this->DebugCompileFeaturesDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_FEATURES") + != debugProperties.end(); + + if (this->Makefile->IsConfigured()) + { + this->DebugCompileFeaturesDone = true; + } + + processCompileFeatures(this, + this->CompileFeaturesEntries, + result, + uniqueFeatures, + &dagChecker, + config, + debugFeatures); + + std::vector<cmGeneratorTarget::TargetPropertyEntry*> + linkInterfaceCompileFeaturesEntries; + AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_FEATURES", + linkInterfaceCompileFeaturesEntries); + + processCompileFeatures(this, + linkInterfaceCompileFeaturesEntries, + result, + uniqueFeatures, + &dagChecker, + config, + debugFeatures); + + cmDeleteAll(linkInterfaceCompileFeaturesEntries); +} + +//---------------------------------------------------------------------------- +static void processCompileDefinitions(cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*> &entries, + std::vector<std::string> &options, + UNORDERED_SET<std::string> &uniqueOptions, + cmGeneratorExpressionDAGChecker *dagChecker, + const std::string& config, bool debugOptions, + std::string const& language) +{ + processCompileOptionsInternal(tgt, entries, options, uniqueOptions, + dagChecker, config, debugOptions, + "definitions", language); +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetCompileDefinitions(std::vector<std::string> &list, + const std::string& config, + const std::string& language) const +{ + UNORDERED_SET<std::string> uniqueOptions; + + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), + "COMPILE_DEFINITIONS", 0, 0); + + std::vector<std::string> debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugDefines = !this->DebugCompileDefinitionsDone + && std::find(debugProperties.begin(), + debugProperties.end(), + "COMPILE_DEFINITIONS") + != debugProperties.end(); + + if (this->Makefile->IsConfigured()) + { + this->DebugCompileDefinitionsDone = true; + } + + processCompileDefinitions(this, + this->CompileDefinitionsEntries, + list, + uniqueOptions, + &dagChecker, + config, + debugDefines, + language); + + std::vector<cmGeneratorTarget::TargetPropertyEntry*> + linkInterfaceCompileDefinitionsEntries; + AddInterfaceEntries( + this, config, "INTERFACE_COMPILE_DEFINITIONS", + linkInterfaceCompileDefinitionsEntries); + if (!config.empty()) + { + std::string configPropName = "COMPILE_DEFINITIONS_" + + cmSystemTools::UpperCase(config); + const char *configProp = this->Target->GetProperty(configPropName); + if (configProp) + { + switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) + { + case cmPolicies::WARN: + { + std::ostringstream e; + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043); + this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, + e.str()); + } + case cmPolicies::OLD: + { + cmGeneratorExpression ge; + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = + ge.Parse(configProp); + linkInterfaceCompileDefinitionsEntries + .push_back(new cmGeneratorTarget::TargetPropertyEntry(cge)); + } + break; + case cmPolicies::NEW: + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + break; + } + } + } + + processCompileDefinitions(this, + linkInterfaceCompileDefinitionsEntries, + list, + uniqueOptions, + &dagChecker, + config, + debugDefines, + language); + + cmDeleteAll(linkInterfaceCompileDefinitionsEntries); } //---------------------------------------------------------------------------- @@ -3354,3 +3941,613 @@ cmGeneratorTarget::ReportPropertyOrigin(const std::string &p, this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, areport); } + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names, + std::vector<cmLinkItem>& items) const +{ + for(std::vector<std::string>::const_iterator i = names.begin(); + i != names.end(); ++i) + { + std::string name = this->Target->CheckCMP0004(*i); + if(name == this->GetName() || name.empty()) + { + continue; + } + items.push_back(cmLinkItem(name, this->Target->FindTargetToLink(name))); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ExpandLinkItems(std::string const& prop, + std::string const& value, + std::string const& config, + cmTarget const* headTarget, + bool usage_requirements_only, + std::vector<cmLinkItem>& items, + bool& hadHeadSensitiveCondition) const +{ + cmGeneratorExpression ge; + cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0); + // The $<LINK_ONLY> expression may be in a link interface to specify private + // link dependencies that are otherwise excluded from usage requirements. + if(usage_requirements_only) + { + dagChecker.SetTransitivePropertiesOnly(); + } + std::vector<std::string> libs; + cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); + cmSystemTools::ExpandListArgument(cge->Evaluate( + this->Makefile, + config, + false, + headTarget, + this->Target, &dagChecker), libs); + this->LookupLinkItems(libs, items); + hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); +} + +//---------------------------------------------------------------------------- +cmLinkInterface const* +cmGeneratorTarget::GetLinkInterface(const std::string& config, + cmTarget const* head) const +{ + // Imported targets have their own link interface. + if(this->IsImported()) + { + return this->GetImportLinkInterface(config, head, false); + } + + // Link interfaces are not supported for executables that do not + // export symbols. + if(this->GetType() == cmTarget::EXECUTABLE && + !this->Target->IsExecutableWithExports()) + { + return 0; + } + + // Lookup any existing link interface for this configuration. + cmHeadToLinkInterfaceMap& hm = + this->GetHeadToLinkInterfaceMap(config); + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + + cmOptionalLinkInterface& iface = hm[head]; + if(!iface.LibrariesDone) + { + iface.LibrariesDone = true; + this->ComputeLinkInterfaceLibraries( + config, iface, head, false); + } + if(!iface.AllDone) + { + iface.AllDone = true; + if(iface.Exists) + { + this->ComputeLinkInterface(config, iface, head); + } + } + + return iface.Exists? &iface : 0; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ComputeLinkInterface(const std::string& config, + cmOptionalLinkInterface &iface, + cmTarget const* headTarget) const +{ + if(iface.ExplicitLibraries) + { + if(this->GetType() == cmTarget::SHARED_LIBRARY + || this->GetType() == cmTarget::STATIC_LIBRARY + || this->GetType() == cmTarget::INTERFACE_LIBRARY) + { + // Shared libraries may have runtime implementation dependencies + // on other shared libraries that are not in the interface. + UNORDERED_SET<std::string> emitted; + for(std::vector<cmLinkItem>::const_iterator + li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li) + { + emitted.insert(*li); + } + if (this->GetType() != cmTarget::INTERFACE_LIBRARY) + { + cmLinkImplementation const* impl = + this->GetLinkImplementation(config); + for(std::vector<cmLinkImplItem>::const_iterator + li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) + { + if(emitted.insert(*li).second) + { + if(li->Target) + { + // This is a runtime dependency on another shared library. + if(li->Target->GetType() == cmTarget::SHARED_LIBRARY) + { + iface.SharedDeps.push_back(*li); + } + } + else + { + // TODO: Recognize shared library file names. Perhaps this + // should be moved to cmComputeLinkInformation, but that creates + // a chicken-and-egg problem since this list is needed for its + // construction. + } + } + } + } + } + } + else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN + || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD) + { + // The link implementation is the default link interface. + cmLinkImplementationLibraries const* + impl = this->Target->GetLinkImplementationLibrariesInternal(config, + headTarget); + iface.ImplementationIsInterface = true; + iface.WrongConfigLibraries = impl->WrongConfigLibraries; + } + + if(this->Target->LinkLanguagePropagatesToDependents()) + { + // Targets using this archive need its language runtime libraries. + if(cmLinkImplementation const* impl = + this->GetLinkImplementation(config)) + { + iface.Languages = impl->Languages; + } + } + + if(this->GetType() == cmTarget::STATIC_LIBRARY) + { + // Construct the property name suffix for this configuration. + std::string suffix = "_"; + if(!config.empty()) + { + suffix += cmSystemTools::UpperCase(config); + } + else + { + suffix += "NOCONFIG"; + } + + // How many repetitions are needed if this library has cyclic + // dependencies? + std::string propName = "LINK_INTERFACE_MULTIPLICITY"; + propName += suffix; + if(const char* config_reps = this->GetProperty(propName)) + { + sscanf(config_reps, "%u", &iface.Multiplicity); + } + else if(const char* reps = + this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) + { + sscanf(reps, "%u", &iface.Multiplicity); + } + } +} + +//---------------------------------------------------------------------------- +const cmLinkInterfaceLibraries * +cmGeneratorTarget::GetLinkInterfaceLibraries(const std::string& config, + cmTarget const* head, + bool usage_requirements_only) const +{ + // Imported targets have their own link interface. + if(this->IsImported()) + { + return this->GetImportLinkInterface(config, head, + usage_requirements_only); + } + + // Link interfaces are not supported for executables that do not + // export symbols. + if(this->GetType() == cmTarget::EXECUTABLE && + !this->Target->IsExecutableWithExports()) + { + return 0; + } + + // Lookup any existing link interface for this configuration. + std::string CONFIG = cmSystemTools::UpperCase(config); + cmHeadToLinkInterfaceMap& hm = + (usage_requirements_only ? + this->GetHeadToLinkInterfaceUsageRequirementsMap(config) : + this->GetHeadToLinkInterfaceMap(config)); + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + + cmOptionalLinkInterface& iface = hm[head]; + if(!iface.LibrariesDone) + { + iface.LibrariesDone = true; + this->ComputeLinkInterfaceLibraries( + config, iface, head, usage_requirements_only); + } + + return iface.Exists? &iface : 0; +} + +//---------------------------------------------------------------------------- +void +cmGeneratorTarget::ComputeLinkInterfaceLibraries( + const std::string& config, + cmOptionalLinkInterface& iface, + cmTarget const* headTarget, + bool usage_requirements_only) const +{ + // Construct the property name suffix for this configuration. + std::string suffix = "_"; + if(!config.empty()) + { + suffix += cmSystemTools::UpperCase(config); + } + else + { + suffix += "NOCONFIG"; + } + + // An explicit list of interface libraries may be set for shared + // libraries and executables that export symbols. + const char* explicitLibraries = 0; + std::string linkIfaceProp; + if(this->Target->GetPolicyStatusCMP0022() != cmPolicies::OLD && + this->Target->GetPolicyStatusCMP0022() != cmPolicies::WARN) + { + // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. + linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; + explicitLibraries = this->GetProperty(linkIfaceProp); + } + else if(this->GetType() == cmTarget::SHARED_LIBRARY || + this->Target->IsExecutableWithExports()) + { + // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a + // shared lib or executable. + + // Lookup the per-configuration property. + linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; + linkIfaceProp += suffix; + explicitLibraries = this->GetProperty(linkIfaceProp); + + // If not set, try the generic property. + if(!explicitLibraries) + { + linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; + explicitLibraries = this->GetProperty(linkIfaceProp); + } + } + + if(explicitLibraries && + this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN && + !this->PolicyWarnedCMP0022) + { + // Compare the explicitly set old link interface properties to the + // preferred new link interface property one and warn if different. + const char* newExplicitLibraries = + this->GetProperty("INTERFACE_LINK_LIBRARIES"); + if (newExplicitLibraries + && strcmp(newExplicitLibraries, explicitLibraries) != 0) + { + std::ostringstream w; + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" + "Target \"" << this->GetName() << "\" has an " + "INTERFACE_LINK_LIBRARIES property which differs from its " << + linkIfaceProp << " properties." + "\n" + "INTERFACE_LINK_LIBRARIES:\n" + " " << newExplicitLibraries << "\n" << + linkIfaceProp << ":\n" + " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n"; + this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->PolicyWarnedCMP0022 = true; + } + } + + // There is no implicit link interface for executables or modules + // so if none was explicitly set then there is no link interface. + if(!explicitLibraries && + (this->GetType() == cmTarget::EXECUTABLE || + (this->GetType() == cmTarget::MODULE_LIBRARY))) + { + return; + } + iface.Exists = true; + iface.ExplicitLibraries = explicitLibraries; + + if(explicitLibraries) + { + // The interface libraries have been explicitly set. + this->ExpandLinkItems(linkIfaceProp, explicitLibraries, + config, + headTarget, usage_requirements_only, + iface.Libraries, + iface.HadHeadSensitiveCondition); + } + else if (this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN + || this->Target->GetPolicyStatusCMP0022() == cmPolicies::OLD) + // If CMP0022 is NEW then the plain tll signature sets the + // INTERFACE_LINK_LIBRARIES, so if we get here then the project + // cleared the property explicitly and we should not fall back + // to the link implementation. + { + // The link implementation is the default link interface. + cmLinkImplementationLibraries const* impl = + this->Target->GetLinkImplementationLibrariesInternal(config, + headTarget); + iface.Libraries.insert(iface.Libraries.end(), + impl->Libraries.begin(), impl->Libraries.end()); + if(this->Target->GetPolicyStatusCMP0022() == cmPolicies::WARN && + !this->PolicyWarnedCMP0022 && !usage_requirements_only) + { + // Compare the link implementation fallback link interface to the + // preferred new link interface property and warn if different. + std::vector<cmLinkItem> ifaceLibs; + static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; + if(const char* newExplicitLibraries = this->GetProperty(newProp)) + { + bool hadHeadSensitiveConditionDummy = false; + this->ExpandLinkItems(newProp, newExplicitLibraries, config, + headTarget, usage_requirements_only, + ifaceLibs, hadHeadSensitiveConditionDummy); + } + if (ifaceLibs != iface.Libraries) + { + std::string oldLibraries = cmJoin(impl->Libraries, ";"); + std::string newLibraries = cmJoin(ifaceLibs, ";"); + if(oldLibraries.empty()) + { oldLibraries = "(empty)"; } + if(newLibraries.empty()) + { newLibraries = "(empty)"; } + + std::ostringstream w; + w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" + "Target \"" << this->GetName() << "\" has an " + "INTERFACE_LINK_LIBRARIES property. " + "This should be preferred as the source of the link interface " + "for this library but because CMP0022 is not set CMake is " + "ignoring the property and using the link implementation " + "as the link interface instead." + "\n" + "INTERFACE_LINK_LIBRARIES:\n" + " " << newLibraries << "\n" + "Link implementation:\n" + " " << oldLibraries << "\n"; + this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, w.str()); + this->PolicyWarnedCMP0022 = true; + } + } + } +} + +//---------------------------------------------------------------------------- +const cmLinkInterface * +cmGeneratorTarget::GetImportLinkInterface(const std::string& config, + cmTarget const* headTarget, + bool usage_requirements_only) const +{ + cmTarget::ImportInfo const* info = this->Target->GetImportInfo(config); + if(!info) + { + return 0; + } + + std::string CONFIG = cmSystemTools::UpperCase(config); + cmHeadToLinkInterfaceMap& hm = + (usage_requirements_only ? + this->GetHeadToLinkInterfaceUsageRequirementsMap(config) : + this->GetHeadToLinkInterfaceMap(config)); + + // If the link interface does not depend on the head target + // then return the one we computed first. + if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) + { + return &hm.begin()->second; + } + + cmOptionalLinkInterface& iface = hm[headTarget]; + if(!iface.AllDone) + { + iface.AllDone = true; + iface.Multiplicity = info->Multiplicity; + cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); + this->ExpandLinkItems(info->LibrariesProp, info->Libraries, + config, + headTarget, usage_requirements_only, + iface.Libraries, + iface.HadHeadSensitiveCondition); + std::vector<std::string> deps; + cmSystemTools::ExpandListArgument(info->SharedDeps, deps); + this->LookupLinkItems(deps, iface.SharedDeps); + } + + return &iface; +} + +cmHeadToLinkInterfaceMap& +cmGeneratorTarget::GetHeadToLinkInterfaceMap(const std::string &config) const +{ + std::string CONFIG = cmSystemTools::UpperCase(config); + return this->LinkInterfaceMap[CONFIG]; +} + +cmHeadToLinkInterfaceMap& +cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap( + const std::string &config) const +{ + std::string CONFIG = cmSystemTools::UpperCase(config); + return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG]; +} + +//---------------------------------------------------------------------------- +const cmLinkImplementation * +cmGeneratorTarget::GetLinkImplementation(const std::string& config) const +{ + // There is no link implementation for imported targets. + if(this->Target->IsImported()) + { + return 0; + } + + cmOptionalLinkImplementation& impl = this->Target->GetLinkImplMap(config); + if(!impl.LibrariesDone) + { + impl.LibrariesDone = true; + this->Target->ComputeLinkImplementationLibraries(config, impl, + this->Target); + } + if(!impl.LanguagesDone) + { + impl.LanguagesDone = true; + this->ComputeLinkImplementationLanguages(config, impl); + } + return &impl; +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::GetConfigCommonSourceFiles( + std::vector<cmSourceFile*>& files) const +{ + std::vector<std::string> configs; + this->Makefile->GetConfigurations(configs); + if (configs.empty()) + { + configs.push_back(""); + } + + std::vector<std::string>::const_iterator it = configs.begin(); + const std::string& firstConfig = *it; + this->Target->GetSourceFiles(files, firstConfig); + + for ( ; it != configs.end(); ++it) + { + std::vector<cmSourceFile*> configFiles; + this->Target->GetSourceFiles(configFiles, *it); + if (configFiles != files) + { + std::string firstConfigFiles; + const char* sep = ""; + for (std::vector<cmSourceFile*>::const_iterator fi = files.begin(); + fi != files.end(); ++fi) + { + firstConfigFiles += sep; + firstConfigFiles += (*fi)->GetFullPath(); + sep = "\n "; + } + + std::string thisConfigFiles; + sep = ""; + for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin(); + fi != configFiles.end(); ++fi) + { + thisConfigFiles += sep; + thisConfigFiles += (*fi)->GetFullPath(); + sep = "\n "; + } + std::ostringstream e; + e << "Target \"" << this->GetName() + << "\" has source files which vary by " + "configuration. This is not supported by the \"" + << this->GlobalGenerator->GetName() + << "\" generator.\n" + "Config \"" << firstConfig << "\":\n" + " " << firstConfigFiles << "\n" + "Config \"" << *it << "\":\n" + " " << thisConfigFiles << "\n"; + this->LocalGenerator->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages, + const std::string& config) const +{ + std::vector<cmSourceFile*> sourceFiles; + this->GetSourceFiles(sourceFiles, config); + for(std::vector<cmSourceFile*>::const_iterator + i = sourceFiles.begin(); i != sourceFiles.end(); ++i) + { + const std::string& lang = (*i)->GetLanguage(); + if(!lang.empty()) + { + languages.insert(lang); + } + } + + std::vector<cmGeneratorTarget*> objectLibraries; + std::vector<cmSourceFile const*> externalObjects; + if (!this->Makefile->IsConfigured()) + { + std::vector<cmTarget*> objectTargets; + this->Target->GetObjectLibrariesCMP0026(objectTargets); + objectLibraries.reserve(objectTargets.size()); + for (std::vector<cmTarget*>::const_iterator it = objectTargets.begin(); + it != objectTargets.end(); ++it) + { + objectLibraries.push_back(this->GlobalGenerator + ->GetGeneratorTarget(*it)); + } + } + else + { + this->GetExternalObjects(externalObjects, config); + for(std::vector<cmSourceFile const*>::const_iterator + i = externalObjects.begin(); i != externalObjects.end(); ++i) + { + std::string objLib = (*i)->GetObjectLibrary(); + if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) + { + objectLibraries.push_back(this->GlobalGenerator + ->GetGeneratorTarget(tgt)); + } + } + } + for(std::vector<cmGeneratorTarget*>::const_iterator + i = objectLibraries.begin(); i != objectLibraries.end(); ++i) + { + (*i)->GetLanguages(languages, config); + } +} + +//---------------------------------------------------------------------------- +void cmGeneratorTarget::ComputeLinkImplementationLanguages( + const std::string& config, + cmOptionalLinkImplementation& impl) const +{ + // This target needs runtime libraries for its source languages. + std::set<std::string> languages; + // Get languages used in our source files. + this->GetLanguages(languages, config); + // Copy the set of langauges to the link implementation. + impl.Languages.insert(impl.Languages.begin(), + languages.begin(), languages.end()); +} + +//---------------------------------------------------------------------------- +bool cmGeneratorTarget::HaveBuildTreeRPATH(const std::string& config) const +{ + if (this->Target->GetPropertyAsBool("SKIP_BUILD_RPATH")) + { + return false; + } + if(cmLinkImplementationLibraries const* impl = + this->Target->GetLinkImplementationLibraries(config)) + { + return !impl->Libraries.empty(); + } + return false; +} diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 15b3335..2c8467f 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -12,7 +12,7 @@ #ifndef cmGeneratorTarget_h #define cmGeneratorTarget_h -#include "cmStandardIncludes.h" +#include "cmLinkItem.h" class cmCustomCommand; class cmGlobalGenerator; @@ -106,6 +106,21 @@ public: const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p, const std::string& config) const; + cmLinkInterface const* GetLinkInterface(const std::string& config, + cmTarget const* headTarget) const; + void ComputeLinkInterface(const std::string& config, + cmOptionalLinkInterface& iface, + cmTarget const* head) const; + + cmLinkInterfaceLibraries const* + GetLinkInterfaceLibraries(const std::string& config, + cmTarget const* headTarget, + bool usage_requirements_only) const; + + void ComputeLinkInterfaceLibraries(const std::string& config, + cmOptionalLinkInterface &iface, + cmTarget const* head, + bool usage_requirements_only) const; /** Get the full path to the target according to the settings in its makefile and the configuration type. */ @@ -183,6 +198,25 @@ public: LinkClosure const* GetLinkClosure(const std::string& config) const; void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const; + cmLinkImplementation const* + GetLinkImplementation(const std::string& config) const; + + void ComputeLinkImplementationLanguages(const std::string& config, + cmOptionalLinkImplementation& impl + ) const; + + // Compute the set of languages compiled by the target. This is + // computed every time it is called because the languages can change + // when source file properties are changed and we do not have enough + // information to forward these property changes to the targets + // until we have per-target object file properties. + void GetLanguages(std::set<std::string>& languages, + std::string const& config) const; + + bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const; + + bool HaveBuildTreeRPATH(const std::string& config) const; + /** Full path with trailing slash to the top-level directory holding object files for this target. Includes the build time config name placeholder if needed for the generator. */ @@ -202,6 +236,17 @@ public: std::vector<std::string> GetIncludeDirectories( const std::string& config, const std::string& lang) const; + void GetCompileOptions(std::vector<std::string> &result, + const std::string& config, + const std::string& language) const; + + void GetCompileFeatures(std::vector<std::string> &features, + const std::string& config) const; + + void GetCompileDefinitions(std::vector<std::string> &result, + const std::string& config, + const std::string& language) const; + bool IsSystemIncludeDirectory(const std::string& dir, const std::string& config) const; @@ -317,6 +362,8 @@ public: const std::string &report, const std::string &compatibilityType) const; + class TargetPropertyEntry; + private: friend class cmTargetTraceDependencies; struct SourceEntry { std::vector<cmSourceFile*> Depends; }; @@ -375,9 +422,41 @@ private: }; mutable std::map<std::string, LinkImplClosure> LinkImplClosureMap; + typedef std::map<std::string, cmHeadToLinkInterfaceMap> + LinkInterfaceMapType; + mutable LinkInterfaceMapType LinkInterfaceMap; + mutable LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; + + cmHeadToLinkInterfaceMap& + GetHeadToLinkInterfaceMap(std::string const& config) const; + cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap( + std::string const& config) const; + + cmLinkInterface const* + GetImportLinkInterface(const std::string& config, cmTarget const* head, + bool usage_requirements_only) const; + + std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; + std::vector<TargetPropertyEntry*> CompileOptionsEntries; + std::vector<TargetPropertyEntry*> CompileFeaturesEntries; + std::vector<TargetPropertyEntry*> CompileDefinitionsEntries; + + void ExpandLinkItems(std::string const& prop, std::string const& value, + std::string const& config, cmTarget const* headTarget, + bool usage_requirements_only, + std::vector<cmLinkItem>& items, + bool& hadHeadSensitiveCondition) const; + void LookupLinkItems(std::vector<std::string> const& names, + std::vector<cmLinkItem>& items) const; + typedef std::pair<std::string, bool> OutputNameKey; typedef std::map<OutputNameKey, std::string> OutputNameMapType; mutable OutputNameMapType OutputNameMap; + mutable bool PolicyWarnedCMP0022; + mutable bool DebugIncludesDone; + mutable bool DebugCompileOptionsDone; + mutable bool DebugCompileFeaturesDone; + mutable bool DebugCompileDefinitionsDone; public: std::vector<cmTarget const*> const& diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 1e57c33..846b6e2 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -330,7 +330,8 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions( const std::string &config, const std::string &language) { std::vector<std::string> compileDefinitions; - this->Target->GetCompileDefinitions(compileDefinitions, config, language); + this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, + config, language); for (std::vector<std::string>::const_iterator cdI = compileDefinitions.begin(); cdI != compileDefinitions.end(); ++cdI) @@ -343,7 +344,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config, const std::string &language) { std::vector<std::string> includes = - this->Target->GetIncludeDirectories(config, language); + this->GeneratorTarget->GetIncludeDirectories(config, language); for (std::vector<std::string>::const_iterator includes_i = includes.begin(); includes_i != includes.end(); ++includes_i) { @@ -558,7 +559,7 @@ bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config, { bool output; std::vector<std::string> options; - this->Target->GetCompileOptions(options, config, language); + this->GeneratorTarget->GetCompileOptions(options, config, language); output = options.end() == std::find(options.begin(), options.end(), "-kernel"); return output; @@ -587,7 +588,7 @@ bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload( { std::vector<std::string> options; bool output = false; - this->Target->GetCompileOptions(options, config, language); + this->GeneratorTarget->GetCompileOptions(options, config, language); for (std::vector<std::string>::const_iterator options_i = options.begin(); options_i != options.end(); ++options_i) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index bdd5b5a..46c1ccc 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1550,7 +1550,6 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes, ti != targets.end(); ++ti) { cmTarget* t = &ti->second; - t->Compute(); cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg); this->GeneratorTargets[t] = gt; generatorTargets[t] = gt; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 92bef67..605ece2 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -1145,7 +1145,8 @@ bool cmGlobalUnixMakefileGenerator3 ::NeedRequiresStep(cmTarget const& target) { std::set<std::string> languages; - target.GetLanguages(languages, + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&target); + gtgt->GetLanguages(languages, target.GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE")); for(std::set<std::string>::const_iterator l = languages.begin(); l != languages.end(); ++l) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 51dcab0..28f0425 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -254,7 +254,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget() mf->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false, no_working_directory, no_depends, noCommandLines); - tgt->Compute(); + cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg); mf->AddGeneratorTarget(tgt, gt); diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index b0aa243..2bf04b4 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -90,7 +90,7 @@ bool cmGlobalVisualStudioGenerator::Compute() AddUtilityCommand("ALL_BUILD", true, no_working_dir, no_depends, no_commands, false, "Build all projects"); - allBuild->Compute(); + cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]); allBuild->GetMakefile()->AddGeneratorTarget(allBuild, gt); @@ -836,17 +836,19 @@ void RegisterVisualStudioMacros(const std::string& macrosFile, bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(cmTarget const& target) { + cmGeneratorTarget* gt = this->GetGeneratorTarget(&target); + // check to see if this is a fortran build std::set<std::string> languages; { // Issue diagnostic if the source files depend on the config. std::vector<cmSourceFile*> sources; - if (!target.GetConfigCommonSourceFiles(sources)) + if (!gt->GetConfigCommonSourceFiles(sources)) { return false; } } - target.GetLanguages(languages, ""); + gt->GetLanguages(languages, ""); if(languages.size() == 1) { if(*languages.begin() == "Fortran") diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4ba29f5..eb547bd 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -463,7 +463,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, cmTarget* allbuild = mf->AddUtilityCommand("ALL_BUILD", true, no_depends, no_working_directory, "echo", "Build all projects"); - allbuild->Compute(); + cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root); mf->AddGeneratorTarget(allbuild, allBuildGt); @@ -498,7 +498,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, true, no_depends, no_working_directory, "make", "-f", file.c_str()); - check->Compute(); + cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root); mf->AddGeneratorTarget(check, checkGt); } @@ -1124,7 +1124,7 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, // organize the sources std::vector<cmSourceFile*> classes; - if (!cmtarget.GetConfigCommonSourceFiles(classes)) + if (!gtgt->GetConfigCommonSourceFiles(classes)) { return false; } @@ -1383,8 +1383,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget) if(llang.empty()) { return; } // If the language is compiled as a source trust Xcode to link with it. - cmTarget::LinkImplementation const* impl = - cmtarget.GetLinkImplementation("NOCONFIG"); + cmLinkImplementation const* impl = + gtgt->GetLinkImplementation("NOCONFIG"); for(std::vector<std::string>::const_iterator li = impl->Languages.begin(); li != impl->Languages.end(); ++li) { @@ -1505,7 +1505,8 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, } std::vector<cmSourceFile*> classes; - if (!cmtarget.GetConfigCommonSourceFiles(classes)) + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget); + if (!gtgt->GetConfigCommonSourceFiles(classes)) { return; } @@ -1805,7 +1806,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, // Compute the compilation flags for each language. std::set<std::string> languages; - target.GetLanguages(languages, configName); + cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); + gtgt->GetLanguages(languages, configName); std::map<std::string, std::string> cflags; for (std::set<std::string>::iterator li = languages.begin(); li != languages.end(); ++li) @@ -1827,7 +1829,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, AddCompileOptions(flags, &target, lang, configName); } - cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target); std::string llang = gtgt->GetLinkerLanguage(configName); if(binary && llang.empty()) { @@ -1855,7 +1856,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, this->AppendDefines(ppDefs, exportMacro); } std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName, "C"); + gtgt->GetCompileDefinitions(targetDefines, configName, "C"); this->AppendDefines(ppDefs, targetDefines); buildSettings->AddAttribute ("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList()); @@ -2557,7 +2558,8 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget) if(cmtarget.GetType() == cmTarget::UTILITY) { std::vector<cmSourceFile*> sources; - if (!cmtarget.GetConfigCommonSourceFiles(sources)) + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget); + if (!gtgt->GetConfigCommonSourceFiles(sources)) { return 0; } @@ -3085,7 +3087,8 @@ bool cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, } std::vector<cmSourceFile*> classes; - if (!cmtarget.GetConfigCommonSourceFiles(classes)) + cmGeneratorTarget* gtgt = this->GetGeneratorTarget(&cmtarget); + if (!gtgt->GetConfigCommonSourceFiles(classes)) { return false; } diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h index a5427de..10dd465 100644 --- a/Source/cmLinkItem.h +++ b/Source/cmLinkItem.h @@ -56,4 +56,66 @@ struct cmLinkImplementationLibraries std::vector<cmLinkItem> WrongConfigLibraries; }; +struct cmLinkInterfaceLibraries +{ + // Libraries listed in the interface. + std::vector<cmLinkItem> Libraries; +}; + +struct cmLinkInterface: public cmLinkInterfaceLibraries +{ + // Languages whose runtime libraries must be linked. + std::vector<std::string> Languages; + + // Shared library dependencies needed for linking on some platforms. + std::vector<cmLinkItem> SharedDeps; + + // Number of repetitions of a strongly connected component of two + // or more static libraries. + int Multiplicity; + + // Libraries listed for other configurations. + // Needed only for OLD behavior of CMP0003. + std::vector<cmLinkItem> WrongConfigLibraries; + + bool ImplementationIsInterface; + + cmLinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {} +}; + +struct cmOptionalLinkInterface: public cmLinkInterface +{ + cmOptionalLinkInterface(): + LibrariesDone(false), AllDone(false), + Exists(false), HadHeadSensitiveCondition(false), + ExplicitLibraries(0) {} + bool LibrariesDone; + bool AllDone; + bool Exists; + bool HadHeadSensitiveCondition; + const char* ExplicitLibraries; +}; + +struct cmHeadToLinkInterfaceMap: + public std::map<cmTarget const*, cmOptionalLinkInterface> +{ +}; + +struct cmLinkImplementation: public cmLinkImplementationLibraries +{ + // Languages whose runtime libraries must be linked. + std::vector<std::string> Languages; +}; + +// Cache link implementation computation from each configuration. +struct cmOptionalLinkImplementation: public cmLinkImplementation +{ + cmOptionalLinkImplementation(): + LibrariesDone(false), LanguagesDone(false), + HadHeadSensitiveCondition(false) {} + bool LibrariesDone; + bool LanguagesDone; + bool HadHeadSensitiveCondition; +}; + #endif diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1e8fd3e..7ce4819 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1079,7 +1079,8 @@ void cmLocalGenerator::AddCompileDefinitions(std::set<std::string>& defines, const std::string& lang) { std::vector<std::string> targetDefines; - target->GetCompileDefinitions(targetDefines, config, lang); + cmGeneratorTarget* gtgt = this->GlobalGenerator->GetGeneratorTarget(target); + gtgt->GetCompileDefinitions(targetDefines, config, lang); this->AppendDefines(defines, targetDefines); } @@ -1090,6 +1091,10 @@ void cmLocalGenerator::AddCompileOptions( ) { std::string langFlagRegexVar = std::string("CMAKE_")+lang+"_FLAG_REGEX"; + + cmGeneratorTarget* gtgt = + this->GlobalGenerator->GetGeneratorTarget(target); + if(const char* langFlagRegexStr = this->Makefile->GetDefinition(langFlagRegexVar)) { @@ -1100,7 +1105,7 @@ void cmLocalGenerator::AddCompileOptions( { cmSystemTools::ParseWindowsCommandLine(targetFlags, opts); } - target->GetCompileOptions(opts, config, lang); + gtgt->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { @@ -1121,7 +1126,7 @@ void cmLocalGenerator::AddCompileOptions( this->AppendFlags(flags, targetFlags); } std::vector<std::string> opts; - target->GetCompileOptions(opts, config, lang); + gtgt->GetCompileOptions(opts, config, lang); for(std::vector<std::string>::const_iterator i = opts.begin(); i != opts.end(); ++i) { @@ -1130,7 +1135,7 @@ void cmLocalGenerator::AddCompileOptions( } } std::vector<std::string> features; - target->GetCompileFeatures(features, config); + gtgt->GetCompileFeatures(features, config); for(std::vector<std::string>::const_iterator it = features.begin(); it != features.end(); ++it) { diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index ce370bc..589105e 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1257,7 +1257,9 @@ cmLocalUnixMakefileGenerator3 { // Get the set of source languages in the target. std::set<std::string> languages; - target.GetLanguages(languages, + cmGeneratorTarget *gtgt = + this->GlobalGenerator->GetGeneratorTarget(&target); + gtgt->GetLanguages(languages, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); fout << "\n" << "# Per-language clean rules from dependency scanning.\n" diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 0d07536..3a44367 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -305,9 +305,12 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, // We may be modifying the source groups temporarily, so make a copy. std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + // get the classes from the source lists then add them to the groups std::vector<cmSourceFile*> classes; - if (!target.GetConfigCommonSourceFiles(classes)) + if (!gt->GetConfigCommonSourceFiles(classes)) { return; } diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 5de6d37..55ad852 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -763,7 +763,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, targetOptions.Parse(defineFlags.c_str()); targetOptions.ParseFinish(); std::vector<std::string> targetDefines; - target.GetCompileDefinitions(targetDefines, configName, "CXX"); + gt->GetCompileDefinitions(targetDefines, configName, "CXX"); targetOptions.AddDefines(targetDefines); targetOptions.SetVerboseMakefile( this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")); @@ -1469,10 +1469,13 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, // We may be modifying the source groups temporarily, so make a copy. std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); + cmGeneratorTarget* gt = + this->GlobalGenerator->GetGeneratorTarget(&target); + // get the classes from the source lists then add them to the groups this->ModuleDefinitionFile = ""; std::vector<cmSourceFile*> classes; - if (!target.GetConfigCommonSourceFiles(classes)) + if (!gt->GetConfigCommonSourceFiles(classes)) { return; } @@ -1514,8 +1517,6 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, { // VS >= 8 support per-config source locations so we // list object library content as external objects. - cmGeneratorTarget* gt = - this->GlobalGenerator->GetGeneratorTarget(&target); std::vector<std::string> objs; gt->UseObjectLibraries(objs, ""); if(!objs.empty()) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 0b3df90..cf88a74 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -276,7 +276,7 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags() { // write language flags for target std::set<std::string> languages; - this->Target->GetLanguages(languages, + this->GeneratorTarget->GetLanguages(languages, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")); // put the compiler in the rules.make file so that if it changes // things rebuild diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index f85e70e..0a4b546 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -403,7 +403,9 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg, ) { std::vector<cmSourceFile*> srcFiles; - target->GetConfigCommonSourceFiles(srcFiles); + cmGeneratorTarget* gtgt = + lg->GetGlobalGenerator()->GetGeneratorTarget(target); + gtgt->GetConfigCommonSourceFiles(srcFiles); for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) @@ -474,8 +476,6 @@ bool cmQtAutoGenerators::InitializeAutogenTarget(cmLocalGenerator* lg, /*byproducts=*/rcc_output, depends, commandLines, false, autogenComment.c_str()); - autogenTarget->Compute(); - cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg); makefile->AddGeneratorTarget(autogenTarget, gt); @@ -663,7 +663,10 @@ void cmQtAutoGenerators::SetupSourceFiles(cmTarget const* target) const char* sepHeaders = ""; std::vector<cmSourceFile*> srcFiles; - target->GetConfigCommonSourceFiles(srcFiles); + cmGeneratorTarget *gtgt = target->GetMakefile() + ->GetGlobalGenerator() + ->GetGeneratorTarget(target); + gtgt->GetConfigCommonSourceFiles(srcFiles); const char *skipMocSep = ""; const char *skipUicSep = ""; @@ -1048,7 +1051,10 @@ void cmQtAutoGenerators::SetupAutoRccTarget(cmTarget const* target) cmMakefile *makefile = target->GetMakefile(); std::vector<cmSourceFile*> srcFiles; - target->GetConfigCommonSourceFiles(srcFiles); + cmGeneratorTarget *gtgt = target->GetMakefile() + ->GetGlobalGenerator() + ->GetGeneratorTarget(target); + gtgt->GetConfigCommonSourceFiles(srcFiles); std::string qrcInputs; const char* qrcInputsSep = ""; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 747f465..4affc8d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -77,13 +77,11 @@ public: cmTargetInternals() : Backtrace() { - this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; } cmTargetInternals(cmTargetInternals const&) : Backtrace() { - this->PolicyWarnedCMP0022 = false; this->UtilityItemsDone = false; } ~cmTargetInternals(); @@ -91,64 +89,14 @@ public: // The backtrace when the target was created. cmListFileBacktrace Backtrace; - // Cache link interface computation from each configuration. - struct OptionalLinkInterface: public cmTarget::LinkInterface - { - OptionalLinkInterface(): - LibrariesDone(false), AllDone(false), - Exists(false), HadHeadSensitiveCondition(false), - ExplicitLibraries(0) {} - bool LibrariesDone; - bool AllDone; - bool Exists; - bool HadHeadSensitiveCondition; - const char* ExplicitLibraries; - }; - void ComputeLinkInterface(cmTarget const* thisTarget, - const std::string& config, - OptionalLinkInterface& iface, - cmTarget const* head) const; - void ComputeLinkInterfaceLibraries(cmTarget const* thisTarget, - const std::string& config, - OptionalLinkInterface& iface, - cmTarget const* head, - bool usage_requirements_only); - - struct HeadToLinkInterfaceMap: - public std::map<cmTarget const*, OptionalLinkInterface> {}; - typedef std::map<std::string, HeadToLinkInterfaceMap> - LinkInterfaceMapType; - LinkInterfaceMapType LinkInterfaceMap; - LinkInterfaceMapType LinkInterfaceUsageRequirementsOnlyMap; - bool PolicyWarnedCMP0022; - typedef std::map<std::string, cmTarget::OutputInfo> OutputInfoMapType; OutputInfoMapType OutputInfoMap; typedef std::map<std::string, cmTarget::ImportInfo> ImportInfoMapType; ImportInfoMapType ImportInfoMap; - // Cache link implementation computation from each configuration. - struct OptionalLinkImplementation: public cmTarget::LinkImplementation - { - OptionalLinkImplementation(): - LibrariesDone(false), LanguagesDone(false), - HadHeadSensitiveCondition(false) {} - bool LibrariesDone; - bool LanguagesDone; - bool HadHeadSensitiveCondition; - }; - void ComputeLinkImplementationLibraries(cmTarget const* thisTarget, - const std::string& config, - OptionalLinkImplementation& impl, - cmTarget const* head) const; - void ComputeLinkImplementationLanguages(cmTarget const* thisTarget, - const std::string& config, - OptionalLinkImplementation& impl - ) const; - struct HeadToLinkImplementationMap: - public std::map<cmTarget const*, OptionalLinkImplementation> {}; + public std::map<cmTarget const*, cmOptionalLinkImplementation> {}; typedef std::map<std::string, HeadToLinkImplementationMap> LinkImplMapType; LinkImplMapType LinkImplMap; @@ -172,16 +120,12 @@ public: }; std::vector<std::string> IncludeDirectoriesEntries; std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces; - std::vector<TargetPropertyEntry*> IncludeDirectoriesItems; std::vector<std::string> CompileOptionsEntries; std::vector<cmListFileBacktrace> CompileOptionsBacktraces; - std::vector<TargetPropertyEntry*> CompileOptionsItems; std::vector<std::string> CompileFeaturesEntries; std::vector<cmListFileBacktrace> CompileFeaturesBacktraces; - std::vector<TargetPropertyEntry*> CompileFeaturesItems; std::vector<std::string> CompileDefinitionsEntries; std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces; - std::vector<TargetPropertyEntry*> CompileDefinitionsItems; std::vector<TargetPropertyEntry*> SourceEntries; std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; @@ -210,10 +154,6 @@ cmTarget::cmTarget() this->IsApple = false; this->IsImportedTarget = false; this->BuildInterfaceIncludesAppended = false; - this->DebugIncludesDone = false; - this->DebugCompileOptionsDone = false; - this->DebugCompileFeaturesDone = false; - this->DebugCompileDefinitionsDone = false; this->DebugSourcesDone = false; this->LinkImplementationLanguageIsContextDependent = true; } @@ -456,29 +396,6 @@ void CreatePropertyGeneratorExpressions( } } -void cmTarget::Compute() -{ - CreatePropertyGeneratorExpressions( - this->Internal->IncludeDirectoriesEntries, - this->Internal->IncludeDirectoriesBacktraces, - this->Internal->IncludeDirectoriesItems); - - CreatePropertyGeneratorExpressions( - this->Internal->CompileOptionsEntries, - this->Internal->CompileOptionsBacktraces, - this->Internal->CompileOptionsItems); - - CreatePropertyGeneratorExpressions( - this->Internal->CompileFeaturesEntries, - this->Internal->CompileFeaturesBacktraces, - this->Internal->CompileFeaturesItems); - - CreatePropertyGeneratorExpressions( - this->Internal->CompileDefinitionsEntries, - this->Internal->CompileDefinitionsBacktraces, - this->Internal->CompileDefinitionsItems); -} - //---------------------------------------------------------------------------- void cmTarget::AddUtility(const std::string& u, cmMakefile *makefile) { @@ -538,8 +455,6 @@ void cmTarget::ClearLinkMaps() { this->LinkImplementationLanguageIsContextDependent = true; this->Internal->LinkImplMap.clear(); - this->Internal->LinkInterfaceMap.clear(); - this->Internal->LinkInterfaceUsageRequirementsOnlyMap.clear(); this->Internal->SourceFilesMap.clear(); } @@ -810,62 +725,6 @@ void cmTarget::GetSourceFiles(std::vector<std::string> &files, } //---------------------------------------------------------------------------- -bool -cmTarget::GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const -{ - std::vector<std::string> configs; - this->Makefile->GetConfigurations(configs); - if (configs.empty()) - { - configs.push_back(""); - } - - std::vector<std::string>::const_iterator it = configs.begin(); - const std::string& firstConfig = *it; - this->GetSourceFiles(files, firstConfig); - - for ( ; it != configs.end(); ++it) - { - std::vector<cmSourceFile*> configFiles; - this->GetSourceFiles(configFiles, *it); - if (configFiles != files) - { - std::string firstConfigFiles; - const char* sep = ""; - for (std::vector<cmSourceFile*>::const_iterator fi = files.begin(); - fi != files.end(); ++fi) - { - firstConfigFiles += sep; - firstConfigFiles += (*fi)->GetFullPath(); - sep = "\n "; - } - - std::string thisConfigFiles; - sep = ""; - for (std::vector<cmSourceFile*>::const_iterator fi = configFiles.begin(); - fi != configFiles.end(); ++fi) - { - thisConfigFiles += sep; - thisConfigFiles += (*fi)->GetFullPath(); - sep = "\n "; - } - std::ostringstream e; - e << "Target \"" << this->Name << "\" has source files which vary by " - "configuration. This is not supported by the \"" - << this->Makefile->GetGlobalGenerator()->GetName() - << "\" generator.\n" - "Config \"" << firstConfig << "\":\n" - " " << firstConfigFiles << "\n" - "Config \"" << *it << "\":\n" - " " << thisConfigFiles << "\n"; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - return false; - } - } - return true; -} - -//---------------------------------------------------------------------------- void cmTarget::GetSourceFiles(std::vector<cmSourceFile*> &files, const std::string& config) const { @@ -1354,6 +1213,46 @@ cmTarget::AddSystemIncludeDirectories(const std::set<std::string> &incs) this->SystemIncludeDirectories.insert(incs.begin(), incs.end()); } +cmStringRange cmTarget::GetIncludeDirectoriesEntries() const +{ + return cmMakeRange(this->Internal->IncludeDirectoriesEntries); +} + +cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const +{ + return cmMakeRange(this->Internal->IncludeDirectoriesBacktraces); +} + +cmStringRange cmTarget::GetCompileOptionsEntries() const +{ + return cmMakeRange(this->Internal->CompileOptionsEntries); +} + +cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const +{ + return cmMakeRange(this->Internal->CompileOptionsBacktraces); +} + +cmStringRange cmTarget::GetCompileFeaturesEntries() const +{ + return cmMakeRange(this->Internal->CompileFeaturesEntries); +} + +cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const +{ + return cmMakeRange(this->Internal->CompileFeaturesBacktraces); +} + +cmStringRange cmTarget::GetCompileDefinitionsEntries() const +{ + return cmMakeRange(this->Internal->CompileDefinitionsEntries); +} + +cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const +{ + return cmMakeRange(this->Internal->CompileDefinitionsBacktraces); +} + #if defined(_WIN32) && !defined(__CYGWIN__) //---------------------------------------------------------------------------- void @@ -1951,510 +1850,6 @@ void cmTarget::InsertCompileDefinition(std::string const& entry, } //---------------------------------------------------------------------------- -static void processIncludeDirectories(cmTarget const* tgt, - const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, - std::vector<std::string> &includes, - UNORDERED_SET<std::string> &uniqueIncludes, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugIncludes, - const std::string& language) -{ - cmMakefile *mf = tgt->GetMakefile(); - - for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator - it = entries.begin(), end = entries.end(); it != end; ++it) - { - cmLinkImplItem const& item = (*it)->LinkImplItem; - std::string const& targetName = item; - bool const fromImported = item.Target && item.Target->IsImported(); - bool const checkCMP0027 = item.FromGenex; - std::vector<std::string> entryIncludes; - cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, - config, - false, - tgt, - dagChecker, language), - entryIncludes); - - std::string usedIncludes; - for(std::vector<std::string>::iterator - li = entryIncludes.begin(); li != entryIncludes.end(); ++li) - { - if (fromImported - && !cmSystemTools::FileExists(li->c_str())) - { - std::ostringstream e; - cmake::MessageType messageType = cmake::FATAL_ERROR; - if (checkCMP0027) - { - switch(tgt->GetPolicyStatusCMP0027()) - { - case cmPolicies::WARN: - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0027) << "\n"; - case cmPolicies::OLD: - messageType = cmake::AUTHOR_WARNING; - break; - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::NEW: - break; - } - } - e << "Imported target \"" << targetName << "\" includes " - "non-existent path\n \"" << *li << "\"\nin its " - "INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:\n" - "* The path was deleted, renamed, or moved to another " - "location.\n" - "* An install or uninstall procedure did not complete " - "successfully.\n" - "* The installation package was faulty and references files it " - "does not provide.\n"; - tgt->GetMakefile()->IssueMessage(messageType, e.str()); - return; - } - - if (!cmSystemTools::FileIsFullPath(li->c_str())) - { - std::ostringstream e; - bool noMessage = false; - cmake::MessageType messageType = cmake::FATAL_ERROR; - if (!targetName.empty()) - { - e << "Target \"" << targetName << "\" contains relative " - "path in its INTERFACE_INCLUDE_DIRECTORIES:\n" - " \"" << *li << "\""; - } - else - { - switch(tgt->GetPolicyStatusCMP0021()) - { - case cmPolicies::WARN: - { - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0021) << "\n"; - messageType = cmake::AUTHOR_WARNING; - } - break; - case cmPolicies::OLD: - noMessage = true; - case cmPolicies::REQUIRED_IF_USED: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::NEW: - // Issue the fatal message. - break; - } - e << "Found relative path while evaluating include directories of " - "\"" << tgt->GetName() << "\":\n \"" << *li << "\"\n"; - } - if (!noMessage) - { - tgt->GetMakefile()->IssueMessage(messageType, e.str()); - if (messageType == cmake::FATAL_ERROR) - { - return; - } - } - } - - if (!cmSystemTools::IsOff(li->c_str())) - { - cmSystemTools::ConvertToUnixSlashes(*li); - } - std::string inc = *li; - - if(uniqueIncludes.insert(inc).second) - { - includes.push_back(inc); - if (debugIncludes) - { - usedIncludes += " * " + inc + "\n"; - } - } - } - if (!usedIncludes.empty()) - { - mf->GetCMakeInstance()->IssueMessage(cmake::LOG, - std::string("Used includes for target ") - + tgt->GetName() + ":\n" - + usedIncludes, (*it)->ge->GetBacktrace()); - } - } -} - -//---------------------------------------------------------------------------- -std::vector<std::string> -cmTarget::GetIncludeDirectories(const std::string& config, - const std::string& language) const -{ - std::vector<std::string> includes; - UNORDERED_SET<std::string> uniqueIncludes; - - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), - "INCLUDE_DIRECTORIES", 0, 0); - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugIncludes = !this->DebugIncludesDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "INCLUDE_DIRECTORIES") - != debugProperties.end(); - - if (this->Makefile->IsConfigured()) - { - this->DebugIncludesDone = true; - } - - processIncludeDirectories(this, - this->Internal->IncludeDirectoriesItems, - includes, - uniqueIncludes, - &dagChecker, - config, - debugIncludes, - language); - - std::vector<cmTargetInternals::TargetPropertyEntry*> - linkInterfaceIncludeDirectoriesEntries; - this->Internal->AddInterfaceEntries( - this, config, "INTERFACE_INCLUDE_DIRECTORIES", - linkInterfaceIncludeDirectoriesEntries); - - if(this->Makefile->IsOn("APPLE")) - { - cmLinkImplementationLibraries const* impl = - this->GetLinkImplementationLibraries(config); - for(std::vector<cmLinkImplItem>::const_iterator - it = impl->Libraries.begin(); - it != impl->Libraries.end(); ++it) - { - std::string libDir = cmSystemTools::CollapseFullPath(*it); - - static cmsys::RegularExpression - frameworkCheck("(.*\\.framework)(/Versions/[^/]+)?/[^/]+$"); - if(!frameworkCheck.find(libDir)) - { - continue; - } - - libDir = frameworkCheck.match(1); - - cmGeneratorExpression ge; - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(libDir.c_str()); - linkInterfaceIncludeDirectoriesEntries - .push_back(new cmTargetInternals::TargetPropertyEntry(cge)); - } - } - - processIncludeDirectories(this, - linkInterfaceIncludeDirectoriesEntries, - includes, - uniqueIncludes, - &dagChecker, - config, - debugIncludes, - language); - - cmDeleteAll(linkInterfaceIncludeDirectoriesEntries); - - return includes; -} - -//---------------------------------------------------------------------------- -static void processCompileOptionsInternal(cmTarget const* tgt, - const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, - std::vector<std::string> &options, - UNORDERED_SET<std::string> &uniqueOptions, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions, const char *logName, - std::string const& language) -{ - cmMakefile *mf = tgt->GetMakefile(); - - for (std::vector<cmTargetInternals::TargetPropertyEntry*>::const_iterator - it = entries.begin(), end = entries.end(); it != end; ++it) - { - std::vector<std::string> entryOptions; - cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(mf, - config, - false, - tgt, - dagChecker, - language), - entryOptions); - std::string usedOptions; - for(std::vector<std::string>::iterator - li = entryOptions.begin(); li != entryOptions.end(); ++li) - { - std::string const& opt = *li; - - if(uniqueOptions.insert(opt).second) - { - options.push_back(opt); - if (debugOptions) - { - usedOptions += " * " + opt + "\n"; - } - } - } - if (!usedOptions.empty()) - { - mf->GetCMakeInstance()->IssueMessage(cmake::LOG, - std::string("Used compile ") + logName - + std::string(" for target ") - + tgt->GetName() + ":\n" - + usedOptions, (*it)->ge->GetBacktrace()); - } - } -} - -//---------------------------------------------------------------------------- -static void processCompileOptions(cmTarget const* tgt, - const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, - std::vector<std::string> &options, - UNORDERED_SET<std::string> &uniqueOptions, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions, - std::string const& language) -{ - processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "options", - language); -} - -//---------------------------------------------------------------------------- -void cmTarget::GetCompileOptions(std::vector<std::string> &result, - const std::string& config, - const std::string& language) const -{ - UNORDERED_SET<std::string> uniqueOptions; - - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), - "COMPILE_OPTIONS", 0, 0); - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugOptions = !this->DebugCompileOptionsDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "COMPILE_OPTIONS") - != debugProperties.end(); - - if (this->Makefile->IsConfigured()) - { - this->DebugCompileOptionsDone = true; - } - - processCompileOptions(this, - this->Internal->CompileOptionsItems, - result, - uniqueOptions, - &dagChecker, - config, - debugOptions, - language); - - std::vector<cmTargetInternals::TargetPropertyEntry*> - linkInterfaceCompileOptionsEntries; - - this->Internal->AddInterfaceEntries( - this, config, "INTERFACE_COMPILE_OPTIONS", - linkInterfaceCompileOptionsEntries); - - processCompileOptions(this, - linkInterfaceCompileOptionsEntries, - result, - uniqueOptions, - &dagChecker, - config, - debugOptions, - language); - - cmDeleteAll(linkInterfaceCompileOptionsEntries); -} - -//---------------------------------------------------------------------------- -static void processCompileDefinitions(cmTarget const* tgt, - const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, - std::vector<std::string> &options, - UNORDERED_SET<std::string> &uniqueOptions, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions, - std::string const& language) -{ - processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, - "definitions", language); -} - -//---------------------------------------------------------------------------- -void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, - const std::string& config, - const std::string& language) const -{ - UNORDERED_SET<std::string> uniqueOptions; - - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), - "COMPILE_DEFINITIONS", 0, 0); - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugDefines = !this->DebugCompileDefinitionsDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "COMPILE_DEFINITIONS") - != debugProperties.end(); - - if (this->Makefile->IsConfigured()) - { - this->DebugCompileDefinitionsDone = true; - } - - processCompileDefinitions(this, - this->Internal->CompileDefinitionsItems, - list, - uniqueOptions, - &dagChecker, - config, - debugDefines, - language); - - std::vector<cmTargetInternals::TargetPropertyEntry*> - linkInterfaceCompileDefinitionsEntries; - this->Internal->AddInterfaceEntries( - this, config, "INTERFACE_COMPILE_DEFINITIONS", - linkInterfaceCompileDefinitionsEntries); - if (!config.empty()) - { - std::string configPropName = "COMPILE_DEFINITIONS_" - + cmSystemTools::UpperCase(config); - const char *configProp = this->GetProperty(configPropName); - if (configProp) - { - switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) - { - case cmPolicies::WARN: - { - std::ostringstream e; - e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0043); - this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, - e.str()); - } - case cmPolicies::OLD: - { - cmGeneratorExpression ge; - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(configProp); - linkInterfaceCompileDefinitionsEntries - .push_back(new cmTargetInternals::TargetPropertyEntry(cge)); - } - break; - case cmPolicies::NEW: - case cmPolicies::REQUIRED_ALWAYS: - case cmPolicies::REQUIRED_IF_USED: - break; - } - } - } - - processCompileDefinitions(this, - linkInterfaceCompileDefinitionsEntries, - list, - uniqueOptions, - &dagChecker, - config, - debugDefines, - language); - - cmDeleteAll(linkInterfaceCompileDefinitionsEntries); -} - -//---------------------------------------------------------------------------- -static void processCompileFeatures(cmTarget const* tgt, - const std::vector<cmTargetInternals::TargetPropertyEntry*> &entries, - std::vector<std::string> &options, - UNORDERED_SET<std::string> &uniqueOptions, - cmGeneratorExpressionDAGChecker *dagChecker, - const std::string& config, bool debugOptions) -{ - processCompileOptionsInternal(tgt, entries, options, uniqueOptions, - dagChecker, config, debugOptions, "features", - std::string()); -} - -//---------------------------------------------------------------------------- -void cmTarget::GetCompileFeatures(std::vector<std::string> &result, - const std::string& config) const -{ - UNORDERED_SET<std::string> uniqueFeatures; - - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), - "COMPILE_FEATURES", - 0, 0); - - std::vector<std::string> debugProperties; - const char *debugProp = - this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); - if (debugProp) - { - cmSystemTools::ExpandListArgument(debugProp, debugProperties); - } - - bool debugFeatures = !this->DebugCompileFeaturesDone - && std::find(debugProperties.begin(), - debugProperties.end(), - "COMPILE_FEATURES") - != debugProperties.end(); - - if (this->Makefile->IsConfigured()) - { - this->DebugCompileFeaturesDone = true; - } - - processCompileFeatures(this, - this->Internal->CompileFeaturesItems, - result, - uniqueFeatures, - &dagChecker, - config, - debugFeatures); - - std::vector<cmTargetInternals::TargetPropertyEntry*> - linkInterfaceCompileFeaturesEntries; - this->Internal->AddInterfaceEntries( - this, config, "INTERFACE_COMPILE_FEATURES", - linkInterfaceCompileFeaturesEntries); - - processCompileFeatures(this, - linkInterfaceCompileFeaturesEntries, - result, - uniqueFeatures, - &dagChecker, - config, - debugFeatures); - - cmDeleteAll(linkInterfaceCompileFeaturesEntries); -} - -//---------------------------------------------------------------------------- void cmTarget::MaybeInvalidatePropertyCache(const std::string& prop) { // Wipe out maps caching information affected by this property. @@ -3096,51 +2491,6 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const } //---------------------------------------------------------------------------- -void cmTarget::ExpandLinkItems(std::string const& prop, - std::string const& value, - std::string const& config, - cmTarget const* headTarget, - bool usage_requirements_only, - std::vector<cmLinkItem>& items, - bool& hadHeadSensitiveCondition) const -{ - cmGeneratorExpression ge; - cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), prop, 0, 0); - // The $<LINK_ONLY> expression may be in a link interface to specify private - // link dependencies that are otherwise excluded from usage requirements. - if(usage_requirements_only) - { - dagChecker.SetTransitivePropertiesOnly(); - } - std::vector<std::string> libs; - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value); - cmSystemTools::ExpandListArgument(cge->Evaluate( - this->Makefile, - config, - false, - headTarget, - this, &dagChecker), libs); - this->LookupLinkItems(libs, items); - hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition(); -} - -//---------------------------------------------------------------------------- -void cmTarget::LookupLinkItems(std::vector<std::string> const& names, - std::vector<cmLinkItem>& items) const -{ - for(std::vector<std::string>::const_iterator i = names.begin(); - i != names.end(); ++i) - { - std::string name = this->CheckCMP0004(*i); - if(name == this->GetName() || name.empty()) - { - continue; - } - items.push_back(cmLinkItem(name, this->FindTargetToLink(name))); - } -} - -//---------------------------------------------------------------------------- const char* cmTarget::GetSuffixVariableInternal(bool implib) const { switch(this->GetType()) @@ -3404,21 +2754,6 @@ void cmTarget::SetPropertyDefault(const std::string& property, } //---------------------------------------------------------------------------- -bool cmTarget::HaveBuildTreeRPATH(const std::string& config) const -{ - if (this->GetPropertyAsBool("SKIP_BUILD_RPATH")) - { - return false; - } - if(cmLinkImplementationLibraries const* impl = - this->GetLinkImplementationLibraries(config)) - { - return !impl->Libraries.empty(); - } - return false; -} - -//---------------------------------------------------------------------------- bool cmTarget::HaveInstallTreeRPATH() const { const char* install_rpath = this->GetProperty("INSTALL_RPATH"); @@ -3740,50 +3075,6 @@ cmTarget::GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const } //---------------------------------------------------------------------------- -void cmTarget::GetLanguages(std::set<std::string>& languages, - const std::string& config) const -{ - std::vector<cmSourceFile*> sourceFiles; - this->GetSourceFiles(sourceFiles, config); - for(std::vector<cmSourceFile*>::const_iterator - i = sourceFiles.begin(); i != sourceFiles.end(); ++i) - { - const std::string& lang = (*i)->GetLanguage(); - if(!lang.empty()) - { - languages.insert(lang); - } - } - - std::vector<cmTarget*> objectLibraries; - std::vector<cmSourceFile const*> externalObjects; - if (!this->Makefile->IsConfigured()) - { - this->GetObjectLibrariesCMP0026(objectLibraries); - } - else - { - cmGeneratorTarget* gt = this->Makefile->GetGlobalGenerator() - ->GetGeneratorTarget(this); - gt->GetExternalObjects(externalObjects, config); - for(std::vector<cmSourceFile const*>::const_iterator - i = externalObjects.begin(); i != externalObjects.end(); ++i) - { - std::string objLib = (*i)->GetObjectLibrary(); - if (cmTarget* tgt = this->Makefile->FindTargetToUse(objLib)) - { - objectLibraries.push_back(tgt); - } - } - } - for(std::vector<cmTarget*>::const_iterator - i = objectLibraries.begin(); i != objectLibraries.end(); ++i) - { - (*i)->GetLanguages(languages, config); - } -} - -//---------------------------------------------------------------------------- cmTarget::ImportInfo const* cmTarget::GetImportInfo(const std::string& config) const { @@ -4133,393 +3424,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config, } //---------------------------------------------------------------------------- -cmTarget::LinkInterface const* cmTarget::GetLinkInterface( - const std::string& config, - cmTarget const* head) const -{ - // Imported targets have their own link interface. - if(this->IsImported()) - { - return this->GetImportLinkInterface(config, head, false); - } - - // Link interfaces are not supported for executables that do not - // export symbols. - if(this->GetType() == cmTarget::EXECUTABLE && - !this->IsExecutableWithExports()) - { - return 0; - } - - // Lookup any existing link interface for this configuration. - std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::HeadToLinkInterfaceMap& hm = - this->Internal->LinkInterfaceMap[CONFIG]; - - // If the link interface does not depend on the head target - // then return the one we computed first. - if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) - { - return &hm.begin()->second; - } - - cmTargetInternals::OptionalLinkInterface& iface = hm[head]; - if(!iface.LibrariesDone) - { - iface.LibrariesDone = true; - this->Internal->ComputeLinkInterfaceLibraries( - this, config, iface, head, false); - } - if(!iface.AllDone) - { - iface.AllDone = true; - if(iface.Exists) - { - this->Internal->ComputeLinkInterface(this, config, iface, head); - } - } - - return iface.Exists? &iface : 0; -} - -//---------------------------------------------------------------------------- -cmTarget::LinkInterfaceLibraries const* -cmTarget::GetLinkInterfaceLibraries(const std::string& config, - cmTarget const* head, - bool usage_requirements_only) const -{ - // Imported targets have their own link interface. - if(this->IsImported()) - { - return this->GetImportLinkInterface(config, head, usage_requirements_only); - } - - // Link interfaces are not supported for executables that do not - // export symbols. - if(this->GetType() == cmTarget::EXECUTABLE && - !this->IsExecutableWithExports()) - { - return 0; - } - - // Lookup any existing link interface for this configuration. - std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::HeadToLinkInterfaceMap& hm = - (usage_requirements_only ? - this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : - this->Internal->LinkInterfaceMap[CONFIG]); - - // If the link interface does not depend on the head target - // then return the one we computed first. - if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) - { - return &hm.begin()->second; - } - - cmTargetInternals::OptionalLinkInterface& iface = hm[head]; - if(!iface.LibrariesDone) - { - iface.LibrariesDone = true; - this->Internal->ComputeLinkInterfaceLibraries( - this, config, iface, head, usage_requirements_only); - } - - return iface.Exists? &iface : 0; -} - -//---------------------------------------------------------------------------- -cmTarget::LinkInterface const* -cmTarget::GetImportLinkInterface(const std::string& config, - cmTarget const* headTarget, - bool usage_requirements_only) const -{ - cmTarget::ImportInfo const* info = this->GetImportInfo(config); - if(!info) - { - return 0; - } - - std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::HeadToLinkInterfaceMap& hm = - (usage_requirements_only ? - this->Internal->LinkInterfaceUsageRequirementsOnlyMap[CONFIG] : - this->Internal->LinkInterfaceMap[CONFIG]); - - // If the link interface does not depend on the head target - // then return the one we computed first. - if(!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) - { - return &hm.begin()->second; - } - - cmTargetInternals::OptionalLinkInterface& iface = hm[headTarget]; - if(!iface.AllDone) - { - iface.AllDone = true; - iface.Multiplicity = info->Multiplicity; - cmSystemTools::ExpandListArgument(info->Languages, iface.Languages); - this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config, - headTarget, usage_requirements_only, - iface.Libraries, - iface.HadHeadSensitiveCondition); - std::vector<std::string> deps; - cmSystemTools::ExpandListArgument(info->SharedDeps, deps); - this->LookupLinkItems(deps, iface.SharedDeps); - } - - return &iface; -} - -//---------------------------------------------------------------------------- -void -cmTargetInternals::ComputeLinkInterfaceLibraries( - cmTarget const* thisTarget, - const std::string& config, - OptionalLinkInterface& iface, - cmTarget const* headTarget, - bool usage_requirements_only) -{ - // Construct the property name suffix for this configuration. - std::string suffix = "_"; - if(!config.empty()) - { - suffix += cmSystemTools::UpperCase(config); - } - else - { - suffix += "NOCONFIG"; - } - - // An explicit list of interface libraries may be set for shared - // libraries and executables that export symbols. - const char* explicitLibraries = 0; - std::string linkIfaceProp; - if(thisTarget->GetPolicyStatusCMP0022() != cmPolicies::OLD && - thisTarget->GetPolicyStatusCMP0022() != cmPolicies::WARN) - { - // CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES. - linkIfaceProp = "INTERFACE_LINK_LIBRARIES"; - explicitLibraries = thisTarget->GetProperty(linkIfaceProp); - } - else if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY || - thisTarget->IsExecutableWithExports()) - { - // CMP0022 OLD behavior is to use LINK_INTERFACE_LIBRARIES if set on a - // shared lib or executable. - - // Lookup the per-configuration property. - linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; - linkIfaceProp += suffix; - explicitLibraries = thisTarget->GetProperty(linkIfaceProp); - - // If not set, try the generic property. - if(!explicitLibraries) - { - linkIfaceProp = "LINK_INTERFACE_LIBRARIES"; - explicitLibraries = thisTarget->GetProperty(linkIfaceProp); - } - } - - if(explicitLibraries && - thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && - !this->PolicyWarnedCMP0022) - { - // Compare the explicitly set old link interface properties to the - // preferred new link interface property one and warn if different. - const char* newExplicitLibraries = - thisTarget->GetProperty("INTERFACE_LINK_LIBRARIES"); - if (newExplicitLibraries - && strcmp(newExplicitLibraries, explicitLibraries) != 0) - { - std::ostringstream w; - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" - "Target \"" << thisTarget->GetName() << "\" has an " - "INTERFACE_LINK_LIBRARIES property which differs from its " << - linkIfaceProp << " properties." - "\n" - "INTERFACE_LINK_LIBRARIES:\n" - " " << newExplicitLibraries << "\n" << - linkIfaceProp << ":\n" - " " << (explicitLibraries ? explicitLibraries : "(empty)") << "\n"; - thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); - this->PolicyWarnedCMP0022 = true; - } - } - - // There is no implicit link interface for executables or modules - // so if none was explicitly set then there is no link interface. - if(!explicitLibraries && - (thisTarget->GetType() == cmTarget::EXECUTABLE || - (thisTarget->GetType() == cmTarget::MODULE_LIBRARY))) - { - return; - } - iface.Exists = true; - iface.ExplicitLibraries = explicitLibraries; - - if(explicitLibraries) - { - // The interface libraries have been explicitly set. - thisTarget->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, - headTarget, usage_requirements_only, - iface.Libraries, - iface.HadHeadSensitiveCondition); - } - else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN - || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) - // If CMP0022 is NEW then the plain tll signature sets the - // INTERFACE_LINK_LIBRARIES, so if we get here then the project - // cleared the property explicitly and we should not fall back - // to the link implementation. - { - // The link implementation is the default link interface. - cmLinkImplementationLibraries const* impl = - thisTarget->GetLinkImplementationLibrariesInternal(config, headTarget); - iface.Libraries.insert(iface.Libraries.end(), - impl->Libraries.begin(), impl->Libraries.end()); - if(thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN && - !this->PolicyWarnedCMP0022 && !usage_requirements_only) - { - // Compare the link implementation fallback link interface to the - // preferred new link interface property and warn if different. - std::vector<cmLinkItem> ifaceLibs; - static const std::string newProp = "INTERFACE_LINK_LIBRARIES"; - if(const char* newExplicitLibraries = thisTarget->GetProperty(newProp)) - { - bool hadHeadSensitiveConditionDummy = false; - thisTarget->ExpandLinkItems(newProp, newExplicitLibraries, config, - headTarget, usage_requirements_only, - ifaceLibs, hadHeadSensitiveConditionDummy); - } - if (ifaceLibs != iface.Libraries) - { - std::string oldLibraries = cmJoin(impl->Libraries, ";"); - std::string newLibraries = cmJoin(ifaceLibs, ";"); - if(oldLibraries.empty()) - { oldLibraries = "(empty)"; } - if(newLibraries.empty()) - { newLibraries = "(empty)"; } - - std::ostringstream w; - w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n" - "Target \"" << thisTarget->GetName() << "\" has an " - "INTERFACE_LINK_LIBRARIES property. " - "This should be preferred as the source of the link interface " - "for this library but because CMP0022 is not set CMake is " - "ignoring the property and using the link implementation " - "as the link interface instead." - "\n" - "INTERFACE_LINK_LIBRARIES:\n" - " " << newLibraries << "\n" - "Link implementation:\n" - " " << oldLibraries << "\n"; - thisTarget->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str()); - this->PolicyWarnedCMP0022 = true; - } - } - } -} - -//---------------------------------------------------------------------------- -void cmTargetInternals::ComputeLinkInterface(cmTarget const* thisTarget, - const std::string& config, - OptionalLinkInterface& iface, - cmTarget const* headTarget) const -{ - if(iface.ExplicitLibraries) - { - if(thisTarget->GetType() == cmTarget::SHARED_LIBRARY - || thisTarget->GetType() == cmTarget::STATIC_LIBRARY - || thisTarget->GetType() == cmTarget::INTERFACE_LIBRARY) - { - // Shared libraries may have runtime implementation dependencies - // on other shared libraries that are not in the interface. - UNORDERED_SET<std::string> emitted; - for(std::vector<cmLinkItem>::const_iterator - li = iface.Libraries.begin(); li != iface.Libraries.end(); ++li) - { - emitted.insert(*li); - } - if (thisTarget->GetType() != cmTarget::INTERFACE_LIBRARY) - { - cmTarget::LinkImplementation const* impl = - thisTarget->GetLinkImplementation(config); - for(std::vector<cmLinkImplItem>::const_iterator - li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) - { - if(emitted.insert(*li).second) - { - if(li->Target) - { - // This is a runtime dependency on another shared library. - if(li->Target->GetType() == cmTarget::SHARED_LIBRARY) - { - iface.SharedDeps.push_back(*li); - } - } - else - { - // TODO: Recognize shared library file names. Perhaps this - // should be moved to cmComputeLinkInformation, but that creates - // a chicken-and-egg problem since this list is needed for its - // construction. - } - } - } - } - } - } - else if (thisTarget->GetPolicyStatusCMP0022() == cmPolicies::WARN - || thisTarget->GetPolicyStatusCMP0022() == cmPolicies::OLD) - { - // The link implementation is the default link interface. - cmLinkImplementationLibraries const* - impl = thisTarget->GetLinkImplementationLibrariesInternal(config, - headTarget); - iface.ImplementationIsInterface = true; - iface.WrongConfigLibraries = impl->WrongConfigLibraries; - } - - if(thisTarget->LinkLanguagePropagatesToDependents()) - { - // Targets using this archive need its language runtime libraries. - if(cmTarget::LinkImplementation const* impl = - thisTarget->GetLinkImplementation(config)) - { - iface.Languages = impl->Languages; - } - } - - if(thisTarget->GetType() == cmTarget::STATIC_LIBRARY) - { - // Construct the property name suffix for this configuration. - std::string suffix = "_"; - if(!config.empty()) - { - suffix += cmSystemTools::UpperCase(config); - } - else - { - suffix += "NOCONFIG"; - } - - // How many repetitions are needed if this library has cyclic - // dependencies? - std::string propName = "LINK_INTERFACE_MULTIPLICITY"; - propName += suffix; - if(const char* config_reps = thisTarget->GetProperty(propName)) - { - sscanf(config_reps, "%u", &iface.Multiplicity); - } - else if(const char* reps = - thisTarget->GetProperty("LINK_INTERFACE_MULTIPLICITY")) - { - sscanf(reps, "%u", &iface.Multiplicity); - } - } -} - -//---------------------------------------------------------------------------- void cmTargetInternals::AddInterfaceEntries( cmTarget const* thisTarget, std::string const& config, std::string const& prop, std::vector<TargetPropertyEntry*>& entries) @@ -4545,32 +3449,12 @@ void cmTargetInternals::AddInterfaceEntries( } } -//---------------------------------------------------------------------------- -cmTarget::LinkImplementation const* -cmTarget::GetLinkImplementation(const std::string& config) const +cmOptionalLinkImplementation& +cmTarget::GetLinkImplMap(std::string const& config) const { - // There is no link implementation for imported targets. - if(this->IsImported()) - { - return 0; - } - // Populate the link implementation for this configuration. std::string CONFIG = cmSystemTools::UpperCase(config); - cmTargetInternals::OptionalLinkImplementation& - impl = this->Internal->LinkImplMap[CONFIG][this]; - if(!impl.LibrariesDone) - { - impl.LibrariesDone = true; - this->Internal - ->ComputeLinkImplementationLibraries(this, config, impl, this); - } - if(!impl.LanguagesDone) - { - impl.LanguagesDone = true; - this->Internal->ComputeLinkImplementationLanguages(this, config, impl); - } - return &impl; + return Internal->LinkImplMap[CONFIG][this]; } //---------------------------------------------------------------------------- @@ -4603,39 +3487,36 @@ cmTarget::GetLinkImplementationLibrariesInternal(const std::string& config, return &hm.begin()->second; } - cmTargetInternals::OptionalLinkImplementation& impl = hm[head]; + cmOptionalLinkImplementation& impl = hm[head]; if(!impl.LibrariesDone) { impl.LibrariesDone = true; - this->Internal - ->ComputeLinkImplementationLibraries(this, config, impl, head); + this->ComputeLinkImplementationLibraries(config, impl, head); } return &impl; } //---------------------------------------------------------------------------- -void -cmTargetInternals::ComputeLinkImplementationLibraries( - cmTarget const* thisTarget, +void cmTarget::ComputeLinkImplementationLibraries( const std::string& config, - OptionalLinkImplementation& impl, + cmOptionalLinkImplementation& impl, cmTarget const* head) const { // Collect libraries directly linked in this configuration. for (std::vector<cmValueWithOrigin>::const_iterator - le = this->LinkImplementationPropertyEntries.begin(), - end = this->LinkImplementationPropertyEntries.end(); + le = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); le != end; ++le) { std::vector<std::string> llibs; cmGeneratorExpressionDAGChecker dagChecker( - thisTarget->GetName(), + this->GetName(), "LINK_LIBRARIES", 0, 0); cmGeneratorExpression ge(le->Backtrace); cmsys::auto_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(le->Value); std::string const evaluated = - cge->Evaluate(thisTarget->Makefile, config, false, head, &dagChecker); + cge->Evaluate(this->Makefile, config, false, head, &dagChecker); cmSystemTools::ExpandListArgument(evaluated, llibs); if(cge->GetHadHeadSensitiveCondition()) { @@ -4646,15 +3527,15 @@ cmTargetInternals::ComputeLinkImplementationLibraries( li != llibs.end(); ++li) { // Skip entries that resolve to the target itself or are empty. - std::string name = thisTarget->CheckCMP0004(*li); - if(name == thisTarget->GetName() || name.empty()) + std::string name = this->CheckCMP0004(*li); + if(name == this->GetName() || name.empty()) { - if(name == thisTarget->GetName()) + if(name == this->GetName()) { bool noMessage = false; cmake::MessageType messageType = cmake::FATAL_ERROR; std::ostringstream e; - switch(thisTarget->GetPolicyStatusCMP0038()) + switch(this->GetPolicyStatusCMP0038()) { case cmPolicies::WARN: { @@ -4673,9 +3554,9 @@ cmTargetInternals::ComputeLinkImplementationLibraries( if(!noMessage) { - e << "Target \"" << thisTarget->GetName() << "\" links to itself."; - thisTarget->Makefile->GetCMakeInstance()->IssueMessage( - messageType, e.str(), thisTarget->GetBacktrace()); + e << "Target \"" << this->GetName() << "\" links to itself."; + this->Makefile->GetCMakeInstance()->IssueMessage( + messageType, e.str(), this->GetBacktrace()); if (messageType == cmake::FATAL_ERROR) { return; @@ -4687,7 +3568,7 @@ cmTargetInternals::ComputeLinkImplementationLibraries( // The entry is meant for this configuration. impl.Libraries.push_back( - cmLinkImplItem(name, thisTarget->FindTargetToLink(name), + cmLinkImplItem(name, this->FindTargetToLink(name), le->Backtrace, evaluated != le->Value)); } @@ -4695,51 +3576,35 @@ cmTargetInternals::ComputeLinkImplementationLibraries( for (std::set<std::string>::const_iterator it = seenProps.begin(); it != seenProps.end(); ++it) { - if (!thisTarget->GetProperty(*it)) + if (!this->GetProperty(*it)) { - thisTarget->LinkImplicitNullProperties.insert(*it); + this->LinkImplicitNullProperties.insert(*it); } } - cge->GetMaxLanguageStandard(thisTarget, thisTarget->MaxLanguageStandards); + cge->GetMaxLanguageStandard(this, this->MaxLanguageStandards); } - cmTarget::LinkLibraryType linkType = thisTarget->ComputeLinkType(config); + cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); cmTarget::LinkLibraryVectorType const& oldllibs = - thisTarget->GetOriginalLinkLibraries(); + this->GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin(); li != oldllibs.end(); ++li) { if(li->second != cmTarget::GENERAL && li->second != linkType) { - std::string name = thisTarget->CheckCMP0004(li->first); - if(name == thisTarget->GetName() || name.empty()) + std::string name = this->CheckCMP0004(li->first); + if(name == this->GetName() || name.empty()) { continue; } // Support OLD behavior for CMP0003. impl.WrongConfigLibraries.push_back( - cmLinkItem(name, thisTarget->FindTargetToLink(name))); + cmLinkItem(name, this->FindTargetToLink(name))); } } } //---------------------------------------------------------------------------- -void -cmTargetInternals::ComputeLinkImplementationLanguages( - cmTarget const* thisTarget, - const std::string& config, - OptionalLinkImplementation& impl) const -{ - // This target needs runtime libraries for its source languages. - std::set<std::string> languages; - // Get languages used in our source files. - thisTarget->GetLanguages(languages, config); - // Copy the set of langauges to the link implementation. - impl.Languages.insert(impl.Languages.begin(), - languages.begin(), languages.end()); -} - -//---------------------------------------------------------------------------- cmTarget const* cmTarget::FindTargetToLink(std::string const& name) const { cmTarget const* tgt = this->Makefile->FindTargetToUse(name); @@ -4846,10 +3711,6 @@ cmTargetInternalPointer //---------------------------------------------------------------------------- cmTargetInternalPointer::~cmTargetInternalPointer() { - cmDeleteAll(this->Pointer->IncludeDirectoriesItems); - cmDeleteAll(this->Pointer->CompileOptionsItems); - cmDeleteAll(this->Pointer->CompileFeaturesItems); - cmDeleteAll(this->Pointer->CompileDefinitionsItems); cmDeleteAll(this->Pointer->SourceEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index dccf550..c86ec24 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -132,15 +132,11 @@ public: void AddPostBuildCommand(cmCustomCommand const &cmd) {this->PostBuildCommands.push_back(cmd);} - void Compute(); - /** * Get the list of the source files used by this target */ void GetSourceFiles(std::vector<cmSourceFile*> &files, const std::string& config) const; - bool GetConfigCommonSourceFiles(std::vector<cmSourceFile*>& files) const; - /** * Add sources to the target. */ @@ -233,54 +229,16 @@ public: void GetObjectLibrariesCMP0026(std::vector<cmTarget*>& objlibs) const; - /** The link interface specifies transitive library dependencies and - other information needed by targets that link to this target. */ - struct LinkInterfaceLibraries - { - // Libraries listed in the interface. - std::vector<cmLinkItem> Libraries; - }; - struct LinkInterface: public LinkInterfaceLibraries - { - // Languages whose runtime libraries must be linked. - std::vector<std::string> Languages; - - // Shared library dependencies needed for linking on some platforms. - std::vector<cmLinkItem> SharedDeps; - - // Number of repetitions of a strongly connected component of two - // or more static libraries. - int Multiplicity; - - // Libraries listed for other configurations. - // Needed only for OLD behavior of CMP0003. - std::vector<cmLinkItem> WrongConfigLibraries; - - bool ImplementationIsInterface; - - LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {} - }; - - /** Get the link interface for the given configuration. Returns 0 - if the target cannot be linked. */ - LinkInterface const* GetLinkInterface(const std::string& config, - cmTarget const* headTarget) const; - LinkInterfaceLibraries const* - GetLinkInterfaceLibraries(const std::string& config, - cmTarget const* headTarget, - bool usage_requirements_only) const; - - struct LinkImplementation: public cmLinkImplementationLibraries - { - // Languages whose runtime libraries must be linked. - std::vector<std::string> Languages; - }; - LinkImplementation const* - GetLinkImplementation(const std::string& config) const; - cmLinkImplementationLibraries const* GetLinkImplementationLibraries(const std::string& config) const; + void ComputeLinkImplementationLibraries(const std::string& config, + cmOptionalLinkImplementation& impl, + cmTarget const* head) const; + + cmOptionalLinkImplementation& + GetLinkImplMap(std::string const& config) const; + cmTarget const* FindTargetToLink(std::string const& name) const; /** Strip off leading and trailing whitespace from an item named in @@ -331,7 +289,6 @@ public: bool GetImplibGNUtoMS(std::string const& gnuName, std::string& out, const char* newExt = 0) const; - bool HaveBuildTreeRPATH(const std::string& config) const; bool HaveInstallTreeRPATH() const; // Get the properties @@ -346,18 +303,6 @@ public: If no macro should be defined null is returned. */ const char* GetExportMacro() const; - void GetCompileDefinitions(std::vector<std::string> &result, - const std::string& config, - const std::string& language) const; - - // Compute the set of languages compiled by the target. This is - // computed every time it is called because the languages can change - // when source file properties are changed and we do not have enough - // information to forward these property changes to the targets - // until we have per-target object file properties. - void GetLanguages(std::set<std::string>& languages, - std::string const& config) const; - /** Return whether this target is an executable with symbol exports enabled. */ bool IsExecutableWithExports() const; @@ -401,9 +346,6 @@ public: /** @return whether this target have a well defined output file name. */ bool HaveWellDefinedOutputFiles() const; - std::vector<std::string> GetIncludeDirectories( - const std::string& config, - const std::string& language) const; void InsertInclude(std::string const& entry, cmListFileBacktrace const& bt, bool before = false); @@ -415,12 +357,6 @@ public: void AppendBuildInterfaceIncludes(); - void GetCompileOptions(std::vector<std::string> &result, - const std::string& config, - const std::string& language) const; - void GetCompileFeatures(std::vector<std::string> &features, - const std::string& config) const; - bool IsNullImpliedByLinkLibraries(const std::string &p) const; std::string GetDebugGeneratorExpressions(const std::string &value, @@ -439,6 +375,18 @@ public: return this->MaxLanguageStandards; } + cmStringRange GetIncludeDirectoriesEntries() const; + cmBacktraceRange GetIncludeDirectoriesBacktraces() const; + + cmStringRange GetCompileOptionsEntries() const; + cmBacktraceRange GetCompileOptionsBacktraces() const; + + cmStringRange GetCompileFeaturesEntries() const; + cmBacktraceRange GetCompileFeaturesBacktraces() const; + + cmStringRange GetCompileDefinitionsEntries() const; + cmBacktraceRange GetCompileDefinitionsBacktraces() const; + #if defined(_WIN32) && !defined(__CYGWIN__) const LinkLibraryVectorType &GetLinkLibrariesForVS6() const { return this->LinkLibrariesForVS6;} @@ -553,11 +501,7 @@ private: bool IsApple; bool IsImportedTarget; bool BuildInterfaceIncludesAppended; - mutable bool DebugIncludesDone; - mutable bool DebugCompileOptionsDone; - mutable bool DebugCompileDefinitionsDone; mutable bool DebugSourcesDone; - mutable bool DebugCompileFeaturesDone; mutable bool LinkImplementationLanguageIsContextDependent; #if defined(_WIN32) && !defined(__CYGWIN__) bool LinkLibrariesForVS6Analyzed; @@ -591,23 +535,10 @@ private: void ComputeImportInfo(std::string const& desired_config, ImportInfo& info) const; - - LinkInterface const* - GetImportLinkInterface(const std::string& config, cmTarget const* head, - bool usage_requirements_only) const; - cmLinkImplementationLibraries const* GetLinkImplementationLibrariesInternal(const std::string& config, cmTarget const* head) const; - void ExpandLinkItems(std::string const& prop, std::string const& value, - std::string const& config, cmTarget const* headTarget, - bool usage_requirements_only, - std::vector<cmLinkItem>& items, - bool& hadHeadSensitiveCondition) const; - void LookupLinkItems(std::vector<std::string> const& names, - std::vector<cmLinkItem>& items) const; - std::string ProcessSourceItemCMP0049(const std::string& s); void ClearLinkMaps(); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 823b550..e7716d8 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -965,7 +965,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups() std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups(); std::vector<cmSourceFile*> classes; - if (!this->Target->GetConfigCommonSourceFiles(classes)) + if (!this->GeneratorTarget->GetConfigCommonSourceFiles(classes)) { return; } @@ -1934,7 +1934,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.Parse(flags.c_str()); clOptions.Parse(defineFlags.c_str()); std::vector<std::string> targetDefines; - this->Target->GetCompileDefinitions(targetDefines, + this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName.c_str(), "CXX"); clOptions.AddDefines(targetDefines); if(this->MSTools) |