diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index e593e0c5b..50835e295 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -11,6 +11,8 @@ ============================================================================*/ #include "cmExportBuildFileGenerator.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" //---------------------------------------------------------------------------- cmExportBuildFileGenerator::cmExportBuildFileGenerator() @@ -194,27 +196,72 @@ cmExportBuildFileGenerator //---------------------------------------------------------------------------- void cmExportBuildFileGenerator::HandleMissingTarget( - std::string& link_libs, std::vector&, - cmMakefile*, cmTarget* depender, cmTarget* dependee) + std::string& link_libs, std::vector& missingTargets, + cmMakefile* mf, cmTarget* depender, cmTarget* dependee) { // The target is not in the export. if(!this->AppendMode) { - // We are not appending, so all exported targets should be - // known here. This is probably user-error. - this->ComplainAboutMissingTarget(depender, dependee); + const std::string name = dependee->GetName(); + std::vector namespaces = this->FindNamespaces(mf, name); + + int targetOccurrences = (int)namespaces.size(); + if (targetOccurrences == 1) + { + std::string missingTarget = namespaces[0]; + + missingTarget += dependee->GetExportName(); + link_libs += missingTarget; + missingTargets.push_back(missingTarget); + return; + } + else + { + // We are not appending, so all exported targets should be + // known here. This is probably user-error. + this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + } } // Assume the target will be exported by another command. // Append it with the export namespace. link_libs += this->Namespace; link_libs += dependee->GetExportName(); +// if generate time {} +} + + +//---------------------------------------------------------------------------- +std::vector +cmExportBuildFileGenerator +::FindNamespaces(cmMakefile* mf, const std::string& name) +{ + std::vector namespaces; + cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); + + std::map& exportSets + = gg->GetBuildExportSets(); + + for(std::map::const_iterator + expIt = exportSets.begin(); expIt != exportSets.end(); ++expIt) + { + const cmExportBuildFileGenerator* exportSet = expIt->second; + std::vector const& targets = exportSet->GetTargets(); + + if (std::find(targets.begin(), targets.end(), name) != targets.end()) + { + namespaces.push_back(exportSet->GetNamespace()); + } + } + + return namespaces; } //---------------------------------------------------------------------------- void cmExportBuildFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee) + cmTarget* dependee, + int occurrences) { if(cmSystemTools::GetErrorOccuredFlag()) { @@ -223,9 +270,17 @@ cmExportBuildFileGenerator cmOStringStream e; e << "export called with target \"" << depender->GetName() - << "\" which requires target \"" << dependee->GetName() - << "\" that is not in the export list.\n" - << "If the required target is not easy to reference in this call, " + << "\" which requires target \"" << dependee->GetName() << "\" "; + if (occurrences == 0) + { + e << "that is not in the export set.\n"; + } + else + { + e << "that is not in this export set, but " << occurrences + << " times in others.\n"; + } + e << "If the required target is not easy to reference in this call, " << "consider using the APPEND option with multiple separate calls."; this->Makefile->GetCMakeInstance() diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 0392d8026..2fbd98f66 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -60,7 +60,8 @@ protected: cmTarget* dependee); void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + cmTarget* dependee, + int occurrences); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const char* config, @@ -70,6 +71,9 @@ protected: std::string InstallNameDir(cmTarget* target, const std::string& config); + std::vector + FindNamespaces(cmMakefile* mf, const std::string& name); + std::vector Targets; std::vector Exports; cmMakefile* Makefile;