From a4263c9f6447e526886d6af301b84c9097c097fa Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 10 Oct 2013 11:18:10 +0200 Subject: export(): Handle multiple dependent export sets. The export-sets topic, merged in commit 49c7b649 (Merge topic 'export-sets', 2012-10-01) changed install(EXPORT) to allow exporting targets whose dependents are exported separately to different locations. Doing the same for export() was not possible because the export() command was executed at configure-time. Now that export() is also executed at generate-time, make it possible to export to multiple dependent export sets. --- Source/cmExportBuildFileGenerator.cxx | 73 ++++++++++++++++++++++++++++++----- Source/cmExportBuildFileGenerator.h | 6 ++- 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index e593e0c..50835e2 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 0392d80..2fbd98f 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; -- cgit v0.12