From 65a30c69a2f895321e692edb4a1d0de9a2114d6d Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 15 Sep 2012 21:12:59 +0200 Subject: [PATCH 01/17] cmGlobalGenerator.h: some minor coding style fixes - this-> was missing - removed unnecessary semicolons - indented unindented lines Alex --- Source/cmGlobalGenerator.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index ce91793796..b0c70590e0 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -127,8 +127,8 @@ public: void SetCMakeInstance(cmake *cm); ///! Get the CMake instance - cmake *GetCMakeInstance() { return this->CMakeInstance; }; - const cmake *GetCMakeInstance() const { return this->CMakeInstance; }; + cmake *GetCMakeInstance() { return this->CMakeInstance; } + const cmake *GetCMakeInstance() const { return this->CMakeInstance; } void SetConfiguredFilesPath(cmGlobalGenerator* gen); const std::vector& GetLocalGenerators() const { @@ -151,7 +151,7 @@ public: void AddInstallComponent(const char* component); const std::set* GetInstallComponents() const - { return &InstallComponents; } + { return &this->InstallComponents; } ///! Add one installed target to the sets of the exports void AddTargetToExports(const char* exportSet, cmTarget* target, @@ -222,7 +222,7 @@ public: /** Get the manifest of all targets that will be built for each configuration. This is valid during generation only. */ cmTargetManifest const& GetTargetManifest() const - { return this->TargetManifest; } + { return this->TargetManifest; } /** Get the content of a directory. Directory listings are loaded from disk at most once and cached. During the generation step @@ -328,8 +328,7 @@ protected: cmLocalGenerator* CurrentLocalGenerator; // map from project name to vector of local generators in that project std::map > ProjectMap; - std::map > - LocalGeneratorToTargetMap; + std::map > LocalGeneratorToTargetMap; // Set of named installation components requested by the project. std::set InstallComponents; From 6508a8c804264304ee9db4e9239857fa1c663989 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 19 Sep 2012 21:38:29 +0200 Subject: [PATCH 02/17] Modules/readme.txt: fix typo Alex --- Modules/readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/readme.txt b/Modules/readme.txt index 7d61d8d273..ab5eaa1eb8 100644 --- a/Modules/readme.txt +++ b/Modules/readme.txt @@ -124,7 +124,7 @@ If neither the QUIET nor REQUIRED options are given then the FindXXX.cmake module should look for the package and complain without error if the module is not found. -A package can be provide sub-components. +A package can provide sub-components. Those components can be listed after the COMPONENTS (or REQUIRED) or OPTIONAL_COMPONENTS keywords. The set of all listed components will be specified in a XXX_FIND_COMPONENTS variable. From ae4ab62569e9b68d6976cb6ad4c1ad411ed8d3da Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 19 Sep 2012 21:50:55 +0200 Subject: [PATCH 03/17] find_package: add support for a _NOT_FOUND_MESSAGE variable If a config-file sets _FOUND to FALSE, it can now give a reason using the variable _NOT_FOUND_MESSAGE, which is used by cmFindPackage and FPHSA. Alex --- Modules/FindPackageHandleStandardArgs.cmake | 3 +++ Modules/readme.txt | 3 +++ Source/cmFindPackageCommand.cxx | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 888e1097a1..25d8df39fe 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -120,6 +120,9 @@ macro(_FPHSA_HANDLE_FAILURE_CONFIG_MODE) list(GET ${_NAME}_CONSIDERED_VERSIONS ${currentConfigIndex} version) set(configsText "${configsText} ${filename} (version ${version})\n") endforeach() + if (${_NAME}_NOT_FOUND_MESSAGE) + set(configsText "${configsText} Reason given by package: ${${_NAME}_NOT_FOUND_MESSAGE}\n") + endif() _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} ${VERSION_MSG}, checked the following files:\n${configsText}") else() diff --git a/Modules/readme.txt b/Modules/readme.txt index ab5eaa1eb8..4818031d71 100644 --- a/Modules/readme.txt +++ b/Modules/readme.txt @@ -18,6 +18,9 @@ XXX_VERSION_YY Expect Version YY if true. Make sure at most one of thes XXX_WRAP_YY If False, do not try to use the relevent CMake wrapping command. XXX_YY_FOUND If False, optional YY part of XXX sytem is not available. XXX_FOUND Set to false, or undefined, if we haven't found, or don't want to use XXX. +XXX_NOT_FOUND_MESSAGE Should be set by config-files in the case that it has set XXX_FOUND to FALSE. + The contained message will be printed by the find_package() command and by + find_package_handle_standard_args() to inform the user about the problem. XXX_RUNTIME_LIBRARY_DIRS Optionally, the runtime library search path for use when running an executable linked to shared libraries. The list should be used by user code to create the PATH on windows or LD_LIBRARY_PATH on unix. This should not be a cache entry. diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index be47f95d48..c20941aaaa 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1016,6 +1016,9 @@ bool cmFindPackageCommand::HandlePackageMode() std::string foundVar = this->Name; foundVar += "_FOUND"; + std::string notFoundMessageVar = this->Name; + notFoundMessageVar += "_NOT_FOUND_MESSAGE"; + std::string notFoundMessage; // If the directory for the config file was found, try to read the file. bool result = true; @@ -1033,6 +1036,7 @@ bool cmFindPackageCommand::HandlePackageMode() // has set Foo_FOUND to FALSE itself: this->Makefile->RemoveDefinition(foundVar.c_str()); } + this->Makefile->RemoveDefinition(notFoundMessageVar.c_str()); // Set the version variables before loading the config file. // It may override them. @@ -1051,6 +1055,8 @@ bool cmFindPackageCommand::HandlePackageMode() // we get here if the Config file has set Foo_FOUND actively to FALSE found = false; configFileSetFOUNDFalse = true; + notFoundMessage = this->Makefile->GetSafeDefinition( + notFoundMessageVar.c_str()); } } else @@ -1071,6 +1077,10 @@ bool cmFindPackageCommand::HandlePackageMode() " " << this->FileFound << "\n" "but it set " << foundVar << " to FALSE so package \"" << this->Name << "\" is considered to be NOT FOUND."; + if (!notFoundMessage.empty()) + { + e << " Reason given by package: \n" << notFoundMessage << "\n"; + } } // If there are files in ConsideredConfigs, it means that FooConfig.cmake // have been found, but they didn't have appropriate versions. From 81c66c8b88d756a1605aa1aac1de49df77feecdd Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 27 Feb 2012 00:05:17 +0400 Subject: [PATCH 04/17] exports: Move cmTargetExport to a dedicated header file --- Source/CMakeLists.txt | 1 + Source/cmExportInstallFileGenerator.cxx | 1 + Source/cmExportInstallFileGenerator.h | 30 --------------- Source/cmGlobalGenerator.cxx | 2 +- Source/cmTargetExport.h | 51 +++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 Source/cmTargetExport.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e79689b089..cf0d8d22bd 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -251,6 +251,7 @@ set(SRCS cmSystemTools.h cmTarget.cxx cmTarget.h + cmTargetExport.h cmTest.cxx cmTest.h cmTestGenerator.cxx diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index da14dd7877..1e35c6176c 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -14,6 +14,7 @@ #include "cmGeneratedFileStream.h" #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" +#include "cmTargetExport.h" //---------------------------------------------------------------------------- cmExportInstallFileGenerator diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index fb678e8918..ce37515e31 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -91,34 +91,4 @@ protected: std::map ConfigImportFiles; }; -/* - cmTargetExport is used in cmGlobalGenerator to collect the install - generators for targets associated with an export. -*/ -class cmTargetExport -{ -public: - cmTargetExport(cmTarget* tgt, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runtime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* headers - ) : Target(tgt), ArchiveGenerator(archive), - RuntimeGenerator(runtime), LibraryGenerator(library), - FrameworkGenerator(framework), BundleGenerator(bundle), - HeaderGenerator(headers) {} - - cmTarget* Target; - cmInstallTargetGenerator* ArchiveGenerator; - cmInstallTargetGenerator* RuntimeGenerator; - cmInstallTargetGenerator* LibraryGenerator; - cmInstallTargetGenerator* FrameworkGenerator; - cmInstallTargetGenerator* BundleGenerator; - cmInstallFilesGenerator* HeaderGenerator; -private: - cmTargetExport(); -}; - #endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 578fa9ec97..a209ab651d 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -21,7 +21,7 @@ #include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" -#include "cmExportInstallFileGenerator.h" +#include "cmTargetExport.h" #include "cmComputeTargetDepends.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h new file mode 100644 index 0000000000..ad677b04b0 --- /dev/null +++ b/Source/cmTargetExport.h @@ -0,0 +1,51 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmTargetExport_h +#define cmTargetExport_h + +class cmTarget; +class cmInstallTargetGenerator; +class cmInstallFilesGenerator; + +/** \brief A member of an ExportSet + * + * This struct holds pointers to target and all relevant generators. + */ +class cmTargetExport +{ +public: + cmTargetExport(cmTarget* tgt, + cmInstallTargetGenerator* archive, + cmInstallTargetGenerator* runtime, + cmInstallTargetGenerator* library, + cmInstallTargetGenerator* framework, + cmInstallTargetGenerator* bundle, + cmInstallFilesGenerator* headers + ) : Target(tgt), ArchiveGenerator(archive), + RuntimeGenerator(runtime), LibraryGenerator(library), + FrameworkGenerator(framework), BundleGenerator(bundle), + HeaderGenerator(headers) {} + + cmTarget* Target; ///< The target + + ///@name Generators + ///@{ + cmInstallTargetGenerator* ArchiveGenerator; + cmInstallTargetGenerator* RuntimeGenerator; + cmInstallTargetGenerator* LibraryGenerator; + cmInstallTargetGenerator* FrameworkGenerator; + cmInstallTargetGenerator* BundleGenerator; + cmInstallFilesGenerator* HeaderGenerator; + ///@} +}; + +#endif From e846e7031fd16ac3e3418ca3a6871aa3f1b6a822 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 27 Feb 2012 01:04:43 +0400 Subject: [PATCH 05/17] exports: Remove cmTargetExport constructor The constructor was used exactly once. Setting members explicitly makes the code more readable. --- Source/cmGlobalGenerator.cxx | 12 ++---------- Source/cmGlobalGenerator.h | 8 +------- Source/cmInstallCommand.cxx | 20 ++++++++++++++++++++ Source/cmTargetExport.h | 12 ------------ 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index a209ab651d..77274dcdb7 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1467,18 +1467,10 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, - cmTarget* target, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runTime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* headers) + cmTargetExport *te) { - if ((exportSetName) && (*exportSetName) && (target)) + if ((exportSetName) && (*exportSetName) && (te)) { - cmTargetExport* te = new cmTargetExport(target, archive, runTime, library, - framework, bundle, headers); this->ExportSets[exportSetName].push_back(te); } } diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index b0c70590e0..29f11e1b81 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -154,13 +154,7 @@ public: { return &this->InstallComponents; } ///! Add one installed target to the sets of the exports - void AddTargetToExports(const char* exportSet, cmTarget* target, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runTime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* publicHeaders); + void AddTargetToExports(const char* exportSet, cmTargetExport* te); ///! Get the export target set with the given name const std::vector* GetExportSet(const char* name) const; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 401673460f..de92538f96 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -17,6 +17,7 @@ #include "cmInstallTargetGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallCommandArguments.h" +#include "cmTargetExport.h" #include @@ -731,6 +732,24 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) this->Makefile->AddInstallGenerator(publicHeaderGenerator); this->Makefile->AddInstallGenerator(resourceGenerator); + // Add this install rule to an export if one was specified and + // this is not a namelink-only rule. + if(!exports.GetString().empty() && !namelinkOnly) + { + cmTargetExport *te = new cmTargetExport; + te->Target = ⌖ + te->ArchiveGenerator = archiveGenerator; + te->BundleGenerator = bundleGenerator; + te->FrameworkGenerator = frameworkGenerator; + te->HeaderGenerator = publicHeaderGenerator; + te->LibraryGenerator = libraryGenerator; + te->RuntimeGenerator = runtimeGenerator; + this->Makefile->GetLocalGenerator()->GetGlobalGenerator() + ->AddTargetToExports(exports.GetCString(), te); + } + } + + // Add this install rule to an export if one was specified and // this is not a namelink-only rule. if(!exports.GetString().empty() && !namelinkOnly) @@ -743,6 +762,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) } } + // Tell the global generator about any installation component names // specified if (installsArchive) diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h index ad677b04b0..c9d87fb7e1 100644 --- a/Source/cmTargetExport.h +++ b/Source/cmTargetExport.h @@ -23,18 +23,6 @@ class cmInstallFilesGenerator; class cmTargetExport { public: - cmTargetExport(cmTarget* tgt, - cmInstallTargetGenerator* archive, - cmInstallTargetGenerator* runtime, - cmInstallTargetGenerator* library, - cmInstallTargetGenerator* framework, - cmInstallTargetGenerator* bundle, - cmInstallFilesGenerator* headers - ) : Target(tgt), ArchiveGenerator(archive), - RuntimeGenerator(runtime), LibraryGenerator(library), - FrameworkGenerator(framework), BundleGenerator(bundle), - HeaderGenerator(headers) {} - cmTarget* Target; ///< The target ///@name Generators From 4e2347cbf39ab72f9bf4ca8bdac7dbecd0143dde Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 27 Feb 2012 02:15:51 +0400 Subject: [PATCH 06/17] exports: Rename cmGlobalGenerator::AddTargetToExport{s,} This function adds target to one export, not to several exports. --- Source/cmGlobalGenerator.cxx | 2 +- Source/cmGlobalGenerator.h | 2 +- Source/cmInstallCommand.cxx | 16 +--------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 77274dcdb7..15edfec73c 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1466,7 +1466,7 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } } -void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, +void cmGlobalGenerator::AddTargetToExport(const char* exportSetName, cmTargetExport *te) { if ((exportSetName) && (*exportSetName) && (te)) diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 29f11e1b81..5408c7e375 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -154,7 +154,7 @@ public: { return &this->InstallComponents; } ///! Add one installed target to the sets of the exports - void AddTargetToExports(const char* exportSet, cmTargetExport* te); + void AddTargetToExport(const char* exportSet, cmTargetExport* te); ///! Get the export target set with the given name const std::vector* GetExportSet(const char* name) const; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index de92538f96..62fc2ef3b0 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -745,24 +745,10 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) te->LibraryGenerator = libraryGenerator; te->RuntimeGenerator = runtimeGenerator; this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->AddTargetToExports(exports.GetCString(), te); + ->AddTargetToExport(exports.GetCString(), te); } } - - // Add this install rule to an export if one was specified and - // this is not a namelink-only rule. - if(!exports.GetString().empty() && !namelinkOnly) - { - this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->AddTargetToExports(exports.GetCString(), &target, - archiveGenerator, runtimeGenerator, - libraryGenerator, frameworkGenerator, - bundleGenerator, publicHeaderGenerator); - } - } - - // Tell the global generator about any installation component names // specified if (installsArchive) From d13ec1ac31518d5c7875e9fa8b849e42ed66a3a3 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Mon, 27 Feb 2012 10:09:40 +0400 Subject: [PATCH 07/17] exports: Create class cmExportSet Replace direct use of 'std::vector' with a dedicated class. --- Source/CMakeLists.txt | 2 ++ Source/cmExportInstallFileGenerator.cxx | 17 +++++------ Source/cmExportInstallFileGenerator.h | 5 ++-- Source/cmExportSet.cxx | 27 ++++++++++++++++++ Source/cmExportSet.h | 38 +++++++++++++++++++++++++ Source/cmGlobalGenerator.cxx | 36 +++++++++-------------- Source/cmGlobalGenerator.h | 8 +++--- Source/cmInstallExportGenerator.cxx | 3 +- Source/cmInstallExportGenerator.h | 9 ++---- bootstrap | 1 + 10 files changed, 103 insertions(+), 43 deletions(-) create mode 100644 Source/cmExportSet.cxx create mode 100644 Source/cmExportSet.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index cf0d8d22bd..e04b7c9b1e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -176,6 +176,8 @@ set(SRCS cmExportFileGenerator.cxx cmExportInstallFileGenerator.h cmExportInstallFileGenerator.cxx + cmExportSet.h + cmExportSet.cxx cmExtraCodeBlocksGenerator.cxx cmExtraCodeBlocksGenerator.h cmExtraEclipseCDT4Generator.cxx diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 1e35c6176c..ba8b18391f 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -15,6 +15,7 @@ #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmTargetExport.h" +#include "cmExportSet.h" //---------------------------------------------------------------------------- cmExportInstallFileGenerator @@ -36,11 +37,11 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { // Create all the imported targets. - for(std::vector::const_iterator - tei = this->ExportSet->begin(); - tei != this->ExportSet->end(); ++tei) + for(std::vector::const_iterator + tei = this->ExportSet->GetTargetExports()->begin(); + tei != this->ExportSet->GetTargetExports()->end(); ++tei) { - cmTargetExport* te = *tei; + cmTargetExport const* te = *tei; if(this->ExportedTargets.insert(te->Target).second) { this->GenerateImportTargetCode(os, te->Target); @@ -161,12 +162,12 @@ cmExportInstallFileGenerator } // Add each target in the set to the export. - for(std::vector::const_iterator - tei = this->ExportSet->begin(); - tei != this->ExportSet->end(); ++tei) + for(std::vector::const_iterator + tei = this->ExportSet->GetTargetExports()->begin(); + tei != this->ExportSet->GetTargetExports()->end(); ++tei) { // Collect import properties for this target. - cmTargetExport* te = *tei; + cmTargetExport const* te = *tei; ImportPropertyMap properties; std::set importedLocations; this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator, diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index ce37515e31..7b86b16db3 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -18,6 +18,7 @@ class cmInstallExportGenerator; class cmInstallFilesGenerator; class cmInstallTargetGenerator; class cmTargetExport; +class cmExportSet; /** \class cmExportInstallFileGenerator * \brief Generate a file exporting targets from an install tree. @@ -46,7 +47,7 @@ public: /** Set the set of targets to be exported. These are the targets associated with the export name. */ - void SetExportSet(std::vector const* eSet) + void SetExportSet(cmExportSet const* eSet) { this->ExportSet = eSet; } /** Get the per-config file generated for each configuraiton. This @@ -83,7 +84,7 @@ protected: cmInstallExportGenerator* InstallExportGenerator; std::string Name; - std::vector const* ExportSet; + cmExportSet const* ExportSet; std::string ImportPrefix; diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx new file mode 100644 index 0000000000..b86e147c34 --- /dev/null +++ b/Source/cmExportSet.cxx @@ -0,0 +1,27 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmExportSet.h" +#include "cmTargetExport.h" + +cmExportSet::~cmExportSet() +{ + for(unsigned int i = 0; i < this->TargetExports.size(); ++ i) + { + delete this->TargetExports[i]; + } +} + +void cmExportSet::AddTargetExport(cmTargetExport const* te) +{ + this->TargetExports.push_back(te); +} diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h new file mode 100644 index 0000000000..5d4d25ff02 --- /dev/null +++ b/Source/cmExportSet.h @@ -0,0 +1,38 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExportSet_h +#define cmExportSet_h + +#include "cmSystemTools.h" +class cmTargetExport; + +/// A set of targets that were installed with the same EXPORT parameter. +class cmExportSet +{ +public: + /// Construct an empty export set named \a name + cmExportSet(const std::string &name) : Name(name) {} + /// Destructor + ~cmExportSet(); + + void AddTargetExport(cmTargetExport const* tgt); + + std::string const& GetName() const { return this->Name; } + std::vector const* GetTargetExports() const + { return &this->TargetExports; } + +private: + std::vector TargetExports; + std::string Name; +}; + +#endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 15edfec73c..5640af94a1 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -76,12 +76,13 @@ cmGlobalGenerator::~cmGlobalGenerator() } this->ClearGeneratorTargets(); - this->ClearExportSets(); + this->ExportSets.clear(); } void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, cmMakefile *mf, - bool optional) { + bool optional) +{ std::string langComp = "CMAKE_"; langComp += lang; langComp += "_COMPILER"; @@ -817,7 +818,7 @@ void cmGlobalGenerator::Configure() { this->FirstTimeProgress = 0.0f; this->ClearGeneratorTargets(); - this->ClearExportSets(); + this->ExportSets.clear(); // Delete any existing cmLocalGenerators unsigned int i; for (i = 0; i < this->LocalGenerators.size(); ++i) @@ -1467,33 +1468,24 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } void cmGlobalGenerator::AddTargetToExport(const char* exportSetName, - cmTargetExport *te) + cmTargetExport const* te) { - if ((exportSetName) && (*exportSetName) && (te)) + std::map::iterator it = ExportSets.find(exportSetName); + // If EXPORT named exportSetName does not exist, create it. + if (it == ExportSets.end()) { - this->ExportSets[exportSetName].push_back(te); + cmStdString key = exportSetName; + cmExportSet value(key); + it = ExportSets.insert(std::make_pair(key, value)).first; } + it->second.AddTargetExport(te); } //---------------------------------------------------------------------------- -void cmGlobalGenerator::ClearExportSets() -{ - for(std::map >::iterator - setIt = this->ExportSets.begin(); - setIt != this->ExportSets.end(); ++setIt) - { - for(unsigned int i = 0; i < setIt->second.size(); ++i) - { - delete setIt->second[i]; - } - } - this->ExportSets.clear(); -} -const std::vector* cmGlobalGenerator::GetExportSet( - const char* name) const +const cmExportSet *cmGlobalGenerator::GetExportSet(const char* name) const { - std::map >::const_iterator + std::map::const_iterator exportSetIt = this->ExportSets.find(name); if (exportSetIt != this->ExportSets.end()) { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 5408c7e375..568e138aa8 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -18,6 +18,7 @@ #include "cmTarget.h" // For cmTargets #include "cmTargetDepend.h" // For cmTargetDependSet #include "cmSystemTools.h" // for cmSystemTools::OutputOption +#include "cmExportSet.h" // For cmExportSet class cmake; class cmGeneratorTarget; class cmMakefile; @@ -154,9 +155,9 @@ public: { return &this->InstallComponents; } ///! Add one installed target to the sets of the exports - void AddTargetToExport(const char* exportSet, cmTargetExport* te); + void AddTargetToExport(const char* exportSet, cmTargetExport const* te); ///! Get the export target set with the given name - const std::vector* GetExportSet(const char* name) const; + const cmExportSet *GetExportSet(const char* name) const; /** Add a file to the manifest of generated targets for a configuration. */ void AddToManifest(const char* config, std::string const& f); @@ -328,8 +329,7 @@ protected: std::set InstallComponents; bool InstallTargetEnabled; // Sets of named target exports - std::map > ExportSets; - void ClearExportSets(); + std::map ExportSets; // Manifest of all targets that will be built for each configuration. // This is computed just before local generators generate. diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 28a19d7401..a9cd3fe128 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -23,6 +23,7 @@ #include "cmInstallFilesGenerator.h" #include "cmExportInstallFileGenerator.h" +#include "cmExportSet.h" //---------------------------------------------------------------------------- cmInstallExportGenerator::cmInstallExportGenerator( @@ -114,7 +115,7 @@ void cmInstallExportGenerator::ComputeTempDir() void cmInstallExportGenerator::GenerateScript(std::ostream& os) { // Get the export set requested. - ExportSet const* exportSet = + cmExportSet const* exportSet = this->Makefile->GetLocalGenerator()->GetGlobalGenerator() ->GetExportSet(this->Name.c_str()); diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 1ff6e38e61..7b65ab7eba 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -17,8 +17,7 @@ class cmExportInstallFileGenerator; class cmInstallFilesGenerator; class cmInstallTargetGenerator; -class cmTarget; -class cmTargetExport; +class cmExportSet; class cmMakefile; /** \class cmInstallExportGenerator @@ -35,13 +34,11 @@ public: cmMakefile* mf); ~cmInstallExportGenerator(); protected: - typedef std::vector ExportSet; - virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); virtual void GenerateScriptActions(std::ostream& os, Indent const& indent); - void GenerateImportFile(ExportSet const* exportSet); - void GenerateImportFile(const char* config, ExportSet const* exportSet); + void GenerateImportFile(cmExportSet const* exportSet); + void GenerateImportFile(const char* config, cmExportSet const* exportSet); void ComputeTempDir(); std::string Name; diff --git a/bootstrap b/bootstrap index ec5745df31..a9e8a86f05 100755 --- a/bootstrap +++ b/bootstrap @@ -199,6 +199,7 @@ CMAKE_CXX_SOURCES="\ cmMakefile \ cmExportFileGenerator \ cmExportInstallFileGenerator \ + cmExportSet \ cmInstallDirectoryGenerator \ cmGeneratedFileStream \ cmGeneratorTarget \ From 5c898fbd99f6d12e8835a0dd3b229d93812e7533 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 1 Mar 2012 02:02:56 +0400 Subject: [PATCH 08/17] exports: Add cmExportSetMap class This is a map with overloaded operator[] and destructor. --- Source/CMakeLists.txt | 2 ++ Source/cmExportSetMap.cxx | 34 +++++++++++++++++++++++++++++ Source/cmExportSetMap.h | 33 ++++++++++++++++++++++++++++ Source/cmGlobalGenerator.cxx | 29 ------------------------ Source/cmGlobalGenerator.h | 10 +++------ Source/cmInstallCommand.cxx | 3 ++- Source/cmInstallExportGenerator.cxx | 2 +- bootstrap | 1 + 8 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 Source/cmExportSetMap.cxx create mode 100644 Source/cmExportSetMap.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index e04b7c9b1e..186aa6db6d 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -178,6 +178,8 @@ set(SRCS cmExportInstallFileGenerator.cxx cmExportSet.h cmExportSet.cxx + cmExportSetMap.h + cmExportSetMap.cxx cmExtraCodeBlocksGenerator.cxx cmExtraCodeBlocksGenerator.h cmExtraEclipseCDT4Generator.cxx diff --git a/Source/cmExportSetMap.cxx b/Source/cmExportSetMap.cxx new file mode 100644 index 0000000000..96fdb3e4f3 --- /dev/null +++ b/Source/cmExportSetMap.cxx @@ -0,0 +1,34 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmExportSetMap.h" +#include "cmExportSet.h" + +cmExportSet* cmExportSetMap::operator[](const std::string &name) +{ + std::map::iterator it = this->find(name); + if (it == this->end()) // Export set not found + { + it = this->insert(std::make_pair(name, new cmExportSet(name))).first; + } + return it->second; +} + +cmExportSetMap::~cmExportSetMap() +{ + for(std::map::iterator it = this->begin(); + it != this->end(); + ++ it) + { + delete it->second; + } +} diff --git a/Source/cmExportSetMap.h b/Source/cmExportSetMap.h new file mode 100644 index 0000000000..4663c55381 --- /dev/null +++ b/Source/cmExportSetMap.h @@ -0,0 +1,33 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmExportSetMap_h +#define cmExportSetMap_h + +#include "cmSystemTools.h" +class cmExportSet; + +/// A name -> cmExportSet map with overloaded operator[]. +class cmExportSetMap : public std::map +{ +public: + /** \brief Overloaded operator[]. + * + * The operator is overloaded because cmExportSet has no default constructor: + * we do not want unnamed export sets. + */ + cmExportSet* operator[](const std::string &name); + + /// Overloaded destructor deletes all member export sets. + ~cmExportSetMap(); +}; + +#endif diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 5640af94a1..e464381e30 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1467,35 +1467,6 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } } -void cmGlobalGenerator::AddTargetToExport(const char* exportSetName, - cmTargetExport const* te) -{ - std::map::iterator it = ExportSets.find(exportSetName); - // If EXPORT named exportSetName does not exist, create it. - if (it == ExportSets.end()) - { - cmStdString key = exportSetName; - cmExportSet value(key); - it = ExportSets.insert(std::make_pair(key, value)).first; - } - it->second.AddTargetExport(te); -} - -//---------------------------------------------------------------------------- - -const cmExportSet *cmGlobalGenerator::GetExportSet(const char* name) const -{ - std::map::const_iterator - exportSetIt = this->ExportSets.find(name); - if (exportSetIt != this->ExportSets.end()) - { - return &exportSetIt->second; - } - - return 0; -} - - void cmGlobalGenerator::EnableInstallTarget() { this->InstallTargetEnabled = true; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 568e138aa8..71c3a4d804 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -18,14 +18,13 @@ #include "cmTarget.h" // For cmTargets #include "cmTargetDepend.h" // For cmTargetDependSet #include "cmSystemTools.h" // for cmSystemTools::OutputOption -#include "cmExportSet.h" // For cmExportSet +#include "cmExportSetMap.h" // For cmExportSetMap class cmake; class cmGeneratorTarget; class cmMakefile; class cmLocalGenerator; class cmExternalMakefileProjectGenerator; class cmTarget; -class cmTargetExport; class cmInstallTargetGenerator; class cmInstallFilesGenerator; @@ -154,10 +153,7 @@ public: const std::set* GetInstallComponents() const { return &this->InstallComponents; } - ///! Add one installed target to the sets of the exports - void AddTargetToExport(const char* exportSet, cmTargetExport const* te); - ///! Get the export target set with the given name - const cmExportSet *GetExportSet(const char* name) const; + cmExportSetMap& GetExportSets() {return this->ExportSets;} /** Add a file to the manifest of generated targets for a configuration. */ void AddToManifest(const char* config, std::string const& f); @@ -329,7 +325,7 @@ protected: std::set InstallComponents; bool InstallTargetEnabled; // Sets of named target exports - std::map ExportSets; + cmExportSetMap ExportSets; // Manifest of all targets that will be built for each configuration. // This is computed just before local generators generate. diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 62fc2ef3b0..6eaa1035d8 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -18,6 +18,7 @@ #include "cmInstallExportGenerator.h" #include "cmInstallCommandArguments.h" #include "cmTargetExport.h" +#include "cmExportSet.h" #include @@ -745,7 +746,7 @@ bool cmInstallCommand::HandleTargetsMode(std::vector const& args) te->LibraryGenerator = libraryGenerator; te->RuntimeGenerator = runtimeGenerator; this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->AddTargetToExport(exports.GetCString(), te); + ->GetExportSets()[exports.GetString()]->AddTargetExport(te); } } diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index a9cd3fe128..0179cd148c 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -117,7 +117,7 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) // Get the export set requested. cmExportSet const* exportSet = this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->GetExportSet(this->Name.c_str()); + ->GetExportSets()[this->Name]; // Skip empty sets. if(!exportSet) diff --git a/bootstrap b/bootstrap index a9e8a86f05..d51d80f81f 100755 --- a/bootstrap +++ b/bootstrap @@ -200,6 +200,7 @@ CMAKE_CXX_SOURCES="\ cmExportFileGenerator \ cmExportInstallFileGenerator \ cmExportSet \ + cmExportSetMap \ cmInstallDirectoryGenerator \ cmGeneratedFileStream \ cmGeneratorTarget \ From 81cdab5beaffc7665550710b84006a0a7ce76cfa Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 1 Mar 2012 14:52:32 +0400 Subject: [PATCH 09/17] exports: Hold an ExportSet pointer in cm*Export*Generator Get name from this->ExportSet. --- Source/cmExportInstallFileGenerator.cxx | 29 +++++++++++++++---------- Source/cmExportInstallFileGenerator.h | 13 +---------- Source/cmInstallCommand.cxx | 4 +++- Source/cmInstallExportGenerator.cxx | 16 +++++--------- Source/cmInstallExportGenerator.h | 6 +++-- 5 files changed, 30 insertions(+), 38 deletions(-) diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index ba8b18391f..d4f7fd5e64 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -20,7 +20,7 @@ //---------------------------------------------------------------------------- cmExportInstallFileGenerator ::cmExportInstallFileGenerator(cmInstallExportGenerator* iegen): - InstallExportGenerator(iegen) + IEGen(iegen) { } @@ -38,8 +38,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { // Create all the imported targets. for(std::vector::const_iterator - tei = this->ExportSet->GetTargetExports()->begin(); - tei != this->ExportSet->GetTargetExports()->end(); ++tei) + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { cmTargetExport const* te = *tei; if(this->ExportedTargets.insert(te->Target).second) @@ -49,8 +49,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) else { cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\" ...) " - << "includes target \"" << te->Target->GetName() + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\" ...) " << "includes target \"" << te->Target->GetName() << "\" more than once in the export set."; cmSystemTools::Error(e.str().c_str()); return false; @@ -86,7 +87,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config) { // Skip configurations not enabled for this export. - if(!this->InstallExportGenerator->InstallsForConfig(config)) + if(!this->IEGen->InstallsForConfig(config)) { return true; } @@ -142,7 +143,7 @@ cmExportInstallFileGenerator { // Add code to compute the installation prefix relative to the // import file location. - const char* installDest = this->InstallExportGenerator->GetDestination(); + const char* installDest = this->IEGen->GetDestination(); if(!cmSystemTools::FileIsFullPath(installDest)) { std::string dest = installDest; @@ -163,8 +164,8 @@ cmExportInstallFileGenerator // Add each target in the set to the export. for(std::vector::const_iterator - tei = this->ExportSet->GetTargetExports()->begin(); - tei != this->ExportSet->GetTargetExports()->end(); ++tei) + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { // Collect import properties for this target. cmTargetExport const* te = *tei; @@ -311,9 +312,11 @@ void cmExportInstallFileGenerator ::ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen) { - const char* installDest = this->InstallExportGenerator->GetDestination(); + const char* installDest = this->IEGen->GetDestination(); cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\") given absolute " + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\") given absolute " << "DESTINATION \"" << installDest << "\" but the export " << "references an installation of target \"" << itgen->GetTarget()->GetName() << "\" which has relative " @@ -327,7 +330,9 @@ cmExportInstallFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee) { cmOStringStream e; - e << "INSTALL(EXPORT \"" << this->Name << "\" ...) " + e << "INSTALL(EXPORT \"" + << this->IEGen->GetExportSet()->GetName() + << "\" ...) " << "includes target \"" << depender->GetName() << "\" which requires target \"" << dependee->GetName() << "\" that is not in the export set."; diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 7b86b16db3..77b55c887f 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -41,15 +41,6 @@ public: files. */ cmExportInstallFileGenerator(cmInstallExportGenerator* iegen); - /** Set the name of the export associated with the files. This is - the name given to the install(EXPORT) command mode. */ - void SetName(const char* name) { this->Name = name; } - - /** Set the set of targets to be exported. These are the targets - associated with the export name. */ - void SetExportSet(cmExportSet const* eSet) - { this->ExportSet = eSet; } - /** Get the per-config file generated for each configuraiton. This maps from the configuration name to the file temporary location for installation. */ @@ -82,9 +73,7 @@ protected: void ComplainAboutImportPrefix(cmInstallTargetGenerator* itgen); - cmInstallExportGenerator* InstallExportGenerator; - std::string Name; - cmExportSet const* ExportSet; + cmInstallExportGenerator* IEGen; std::string ImportPrefix; diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx index 6eaa1035d8..dcd418b451 100644 --- a/Source/cmInstallCommand.cxx +++ b/Source/cmInstallCommand.cxx @@ -1271,7 +1271,9 @@ bool cmInstallCommand::HandleExportMode(std::vector const& args) // Create the export install generator. cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator( - exp.GetCString(), ica.GetDestination().c_str(), + this->Makefile->GetLocalGenerator() + ->GetGlobalGenerator()->GetExportSets()[exp.GetString()], + ica.GetDestination().c_str(), ica.GetPermissions().c_str(), ica.GetConfigurations(), ica.GetComponent().c_str(), fname.c_str(), name_space.GetCString(), this->Makefile); diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 0179cd148c..caedaf56b6 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -27,7 +27,7 @@ //---------------------------------------------------------------------------- cmInstallExportGenerator::cmInstallExportGenerator( - const char* name, + cmExportSet* exportSet, const char* destination, const char* file_permissions, std::vector const& configurations, @@ -35,7 +35,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( const char* filename, const char* name_space, cmMakefile* mf) :cmInstallGenerator(destination, configurations, component) - ,Name(name) + ,ExportSet(exportSet) ,FilePermissions(file_permissions) ,FileName(filename) ,Namespace(name_space) @@ -114,16 +114,12 @@ void cmInstallExportGenerator::ComputeTempDir() //---------------------------------------------------------------------------- void cmInstallExportGenerator::GenerateScript(std::ostream& os) { - // Get the export set requested. - cmExportSet const* exportSet = - this->Makefile->GetLocalGenerator()->GetGlobalGenerator() - ->GetExportSets()[this->Name]; - // Skip empty sets. - if(!exportSet) + if(ExportSet->GetTargetExports()->empty()) { cmOStringStream e; - e << "INSTALL(EXPORT) given unknown export \"" << this->Name << "\""; + e << "INSTALL(EXPORT) given unknown export \"" + << ExportSet->GetName() << "\""; cmSystemTools::Error(e.str().c_str()); return; } @@ -138,8 +134,6 @@ void cmInstallExportGenerator::GenerateScript(std::ostream& os) this->MainImportFile += this->FileName; // Generate the import file for this export set. - this->EFGen->SetName(this->Name.c_str()); - this->EFGen->SetExportSet(exportSet); this->EFGen->SetExportFile(this->MainImportFile.c_str()); this->EFGen->SetNamespace(this->Namespace.c_str()); if(this->ConfigurationTypes->empty()) diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 7b65ab7eba..8ae271b7eb 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -26,13 +26,15 @@ class cmMakefile; class cmInstallExportGenerator: public cmInstallGenerator { public: - cmInstallExportGenerator(const char* name, + cmInstallExportGenerator(cmExportSet* exportSet, const char* dest, const char* file_permissions, const std::vector& configurations, const char* component, const char* filename, const char* name_space, cmMakefile* mf); ~cmInstallExportGenerator(); + + cmExportSet* GetExportSet() {return ExportSet;} protected: virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); @@ -41,7 +43,7 @@ protected: void GenerateImportFile(const char* config, cmExportSet const* exportSet); void ComputeTempDir(); - std::string Name; + cmExportSet* ExportSet; std::string FilePermissions; std::string FileName; std::string Namespace; From 64b3a6c9cf3f1b64dce357852995a802139afbbd Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Wed, 22 Aug 2012 02:15:42 +0400 Subject: [PATCH 10/17] exports: cmGlobalGenerator::ExportSets destructor will clear it --- Source/cmGlobalGenerator.cxx | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index e464381e30..83a8641af6 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -76,7 +76,6 @@ cmGlobalGenerator::~cmGlobalGenerator() } this->ClearGeneratorTargets(); - this->ExportSets.clear(); } void cmGlobalGenerator::ResolveLanguageCompiler(const std::string &lang, From 999061a4c2000213e6f04695f1f1fe546c86703d Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 15 Sep 2012 21:04:48 +0200 Subject: [PATCH 11/17] exports: store pointers to all installations of each export set This information will be used to check whether a target is exported once or multiple times and to check its namespace. Alex --- Source/cmExportSet.cxx | 5 +++++ Source/cmExportSet.h | 8 ++++++++ Source/cmInstallExportGenerator.cxx | 1 + 3 files changed, 14 insertions(+) diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index b86e147c34..464ad68486 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -25,3 +25,8 @@ void cmExportSet::AddTargetExport(cmTargetExport const* te) { this->TargetExports.push_back(te); } + +void cmExportSet::AddInstallation(cmInstallExportGenerator const* installation) +{ + this->Installations.push_back(installation); +} diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index 5d4d25ff02..91a8bf9531 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h @@ -14,6 +14,7 @@ #include "cmSystemTools.h" class cmTargetExport; +class cmInstallExportGenerator; /// A set of targets that were installed with the same EXPORT parameter. class cmExportSet @@ -26,13 +27,20 @@ public: void AddTargetExport(cmTargetExport const* tgt); + void AddInstallation(cmInstallExportGenerator const* installation); + std::string const& GetName() const { return this->Name; } + std::vector const* GetTargetExports() const { return &this->TargetExports; } + std::vector const* GetInstallations() const + { return &this->Installations; } + private: std::vector TargetExports; std::string Name; + std::vector Installations; }; #endif diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index caedaf56b6..0a645a8fa0 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -42,6 +42,7 @@ cmInstallExportGenerator::cmInstallExportGenerator( ,Makefile(mf) { this->EFGen = new cmExportInstallFileGenerator(this); + exportSet->AddInstallation(this); } //---------------------------------------------------------------------------- From 87f4c01910754199bcdcbc9d564de13d36ba2502 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 15 Sep 2012 21:55:24 +0200 Subject: [PATCH 12/17] exports: accept a missing target if it is exported exactly once If a target is exported, and a library it depends on is not part of the same export set, before this patch cmake errored out. With this patch, it now checks whether the missing target is exported somewhere else exactly once, and accepts in this case (because then it can determine the namespace for the missing target and use this). Alex --- Source/cmExportBuildFileGenerator.cxx | 23 ++++++-- Source/cmExportBuildFileGenerator.h | 3 +- Source/cmExportFileGenerator.cxx | 76 ++++++++++++++++++++++--- Source/cmExportFileGenerator.h | 7 ++- Source/cmExportInstallFileGenerator.cxx | 16 +++++- Source/cmExportInstallFileGenerator.h | 3 +- Source/cmInstallExportGenerator.h | 5 +- 7 files changed, 111 insertions(+), 22 deletions(-) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 32595ee4b2..fd5a4328f2 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -135,7 +135,8 @@ cmExportBuildFileGenerator void cmExportBuildFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee) + cmTarget* dependee, + int occurrences) { if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty()) { @@ -143,10 +144,20 @@ cmExportBuildFileGenerator } cmOStringStream e; - e << "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, " - << "consider using the APPEND option with multiple separate calls."; + if (occurrences == 0) + { + e << "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, " + << "consider using the APPEND option with multiple separate calls."; + } + else + { + e << "called with target \"" << depender->GetName() + << "\" which requires target \"" << dependee->GetName() + << "\" that is exported " << occurrences << " times in other " + << "export ""lists.\n"; + } this->ExportCommand->ErrorMessage = e.str(); } diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 0f37626cc7..69f8407682 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -46,7 +46,8 @@ protected: const char* config, std::string const& suffix); virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + cmTarget* dependee, + int occurrences); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const char* config, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index eb19df5e28..fa6cc9f373 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -11,10 +11,15 @@ ============================================================================*/ #include "cmExportFileGenerator.h" +#include "cmExportSet.h" #include "cmGeneratedFileStream.h" +#include "cmGlobalGenerator.h" +#include "cmInstallExportGenerator.h" +#include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" #include "cmTarget.h" +#include "cmTargetExport.h" #include "cmVersion.h" #include @@ -224,17 +229,28 @@ cmExportFileGenerator } else { - // The target is not in the export. - if(!this->AppendMode) + std::vector namespaces = this->FindNamespaces(mf, *li); + int targetOccurrences = (int)namespaces.size(); + + if (targetOccurrences == 1) { - // We are not appending, so all exported targets should be - // known here. This is probably user-error. - this->ComplainAboutMissingTarget(target, tgt); + link_libs += namespaces[0]; + link_libs += *li; + } + else + { + // 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(target, tgt, targetOccurrences); + } + // Assume the target will be exported by another command. + // Append it with the export namespace. + link_libs += this->Namespace; + link_libs += *li; } - // Assume the target will be exported by another command. - // Append it with the export namespace. - link_libs += this->Namespace; - link_libs += *li; } } else @@ -250,6 +266,48 @@ cmExportFileGenerator properties[prop] = link_libs; } + +//---------------------------------------------------------------------------- +std::vector cmExportFileGenerator::FindNamespaces(cmMakefile* mf, + const std::string& name) +{ + std::vector namespaces; + cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); + const cmExportSetMap& exportSets = gg->GetExportSets(); + + for(cmExportSetMap::const_iterator expIt = exportSets.begin(); + expIt != exportSets.end(); + ++expIt) + { + const cmExportSet* exportSet = expIt->second; + std::vector const* targets = + exportSet->GetTargetExports(); + + bool containsTarget = false; + for(unsigned int i=0; isize(); i++) + { + if (name == (*targets)[i]->Target->GetName()) + { + containsTarget = true; + break; + } + } + + if (containsTarget) + { + std::vector const* installs = + exportSet->GetInstallations(); + for(unsigned int i=0; isize(); i++) + { + namespaces.push_back((*installs)[i]->GetNamespace()); + } + } + } + + return namespaces; +} + + //---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, const char* config) diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index f271e5570e..c9feffdd51 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -83,7 +83,12 @@ protected: /** Each subclass knows how to complain about a target that is missing from an export set. */ virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee) = 0; + cmTarget* dependee, + int occurrences) = 0; + + std::vector FindNamespaces(cmMakefile* mf, + const std::string& name); + // The namespace in which the exports are placed in the generated file. std::string Namespace; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index d4f7fd5e64..ba048b527a 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -327,14 +327,24 @@ cmExportInstallFileGenerator //---------------------------------------------------------------------------- void cmExportInstallFileGenerator -::ComplainAboutMissingTarget(cmTarget* depender, cmTarget* dependee) +::ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee, + int occurrences) { cmOStringStream e; e << "INSTALL(EXPORT \"" << this->IEGen->GetExportSet()->GetName() << "\" ...) " << "includes target \"" << depender->GetName() - << "\" which requires target \"" << dependee->GetName() - << "\" that is not in the export set."; + << "\" which requires target \"" << dependee->GetName() << "\" "; + if (occurrences == 0) + { + e << "that is not in the export set."; + } + else + { + e << "that is not in this export set, but " << occurrences + << " times in others."; + } cmSystemTools::Error(e.str().c_str()); } diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index 77b55c887f..f6f397e871 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -58,7 +58,8 @@ protected: const char* config, std::string const& suffix); virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee); + cmTarget* dependee, + int occurrences); /** Generate a per-configuration file for the targets. */ bool GenerateImportFileConfig(const char* config); diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h index 8ae271b7eb..ee92906fe8 100644 --- a/Source/cmInstallExportGenerator.h +++ b/Source/cmInstallExportGenerator.h @@ -34,7 +34,10 @@ public: cmMakefile* mf); ~cmInstallExportGenerator(); - cmExportSet* GetExportSet() {return ExportSet;} + cmExportSet* GetExportSet() {return this->ExportSet;} + + const std::string& GetNamespace() const { return this->Namespace; } + protected: virtual void GenerateScript(std::ostream& os); virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent); From 8b5f448ba628dc474d3cd22d67db65551acc0846 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sat, 15 Sep 2012 22:38:30 +0200 Subject: [PATCH 13/17] exports: first try at error handling if a target is missing Now, if an imported target depends on a library which must come from some other export set, cmake generates a check which errors out if that target does not exist. I guess instead of completely erroring out it would be better to only make the find_package() fail. Alex --- Source/cmExportBuildFileGenerator.cxx | 4 ++- Source/cmExportFileGenerator.cxx | 37 ++++++++++++++++++++----- Source/cmExportFileGenerator.h | 8 ++++-- Source/cmExportInstallFileGenerator.cxx | 4 ++- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index fd5a4328f2..22ae0e457d 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -72,8 +72,9 @@ cmExportBuildFileGenerator if(!properties.empty()) { // Get the rest of the target details. + std::vector missingTargets; this->SetImportDetailProperties(config, suffix, - target, properties); + target, properties, missingTargets); // TOOD: PUBLIC_HEADER_LOCATION // This should wait until the build feature propagation stuff @@ -82,6 +83,7 @@ cmExportBuildFileGenerator // properties); // Generate code in the export file. + this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, target, properties); } } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index fa6cc9f373..36902a12aa 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -128,7 +128,9 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, void cmExportFileGenerator ::SetImportDetailProperties(const char* config, std::string const& suffix, - cmTarget* target, ImportPropertyMap& properties) + cmTarget* target, ImportPropertyMap& properties, + std::vector& missingTargets + ) { // Get the makefile in which to lookup target information. cmMakefile* mf = target->GetMakefile(); @@ -164,13 +166,13 @@ cmExportFileGenerator { this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", - iface->Languages, properties); + iface->Languages, properties, missingTargets); this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LIBRARIES", - iface->Libraries, properties); + iface->Libraries, properties, missingTargets); this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_DEPENDENT_LIBRARIES", - iface->SharedDeps, properties); + iface->SharedDeps, properties, missingTargets); if(iface->Multiplicity > 0) { std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY"; @@ -189,7 +191,9 @@ cmExportFileGenerator cmTarget* target, const char* propName, std::vector const& libs, - ImportPropertyMap& properties) + ImportPropertyMap& properties, + std::vector& missingTargets + ) { // Skip the property if there are no libraries. if(libs.empty()) @@ -234,8 +238,10 @@ cmExportFileGenerator if (targetOccurrences == 1) { - link_libs += namespaces[0]; - link_libs += *li; + std::string missingTarget = namespaces[0]; + missingTarget += *li; + link_libs += missingTarget; + missingTargets.push_back(missingTarget); } else { @@ -438,6 +444,23 @@ cmExportFileGenerator } +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, + const std::vector& missingTargets) +{ + os << "# Make sure the targets which have been exported in some other \n" + "# export set exist.\n"; + for(unsigned int i=0; i& importedLocations); void GenerateImportedFileCheckLoop(std::ostream& os); + void GenerateMissingTargetsCheckCode(std::ostream& os, + const std::vector& missingTargets); // Collect properties with detailed information about targets beyond // their location on disk. void SetImportDetailProperties(const char* config, std::string const& suffix, cmTarget* target, - ImportPropertyMap& properties); + ImportPropertyMap& properties, + std::vector& missingTargets); void SetImportLinkProperty(std::string const& suffix, cmTarget* target, const char* propName, std::vector const& libs, - ImportPropertyMap& properties); + ImportPropertyMap& properties, + std::vector& missingTargets); /** Each subclass knows how to generate its kind of export file. */ virtual bool GenerateMainFile(std::ostream& os) = 0; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index ba048b527a..94b9f46d60 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -188,8 +188,9 @@ cmExportInstallFileGenerator if(!properties.empty()) { // Get the rest of the target details. + std::vector missingTargets; this->SetImportDetailProperties(config, suffix, - te->Target, properties); + te->Target, properties, missingTargets); // TOOD: PUBLIC_HEADER_LOCATION // This should wait until the build feature propagation stuff @@ -198,6 +199,7 @@ cmExportInstallFileGenerator // properties); // Generate code in the export file. + this->GenerateMissingTargetsCheckCode(os, missingTargets); this->GenerateImportPropertyCode(os, config, te->Target, properties); this->GenerateImportedFileChecksCode(os, te->Target, properties, importedLocations); From 190f2c8253910a9e6870948df58a87950e7b4185 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 25 Sep 2012 19:19:27 +0200 Subject: [PATCH 14/17] exports: fix build with MSVC6 it seems it doesn't like deleting const pointers Alex --- Source/cmExportFileGenerator.cxx | 2 +- Source/cmExportInstallFileGenerator.cxx | 4 ++-- Source/cmExportSet.cxx | 2 +- Source/cmExportSet.h | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 36902a12aa..dc4fa3181c 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -286,7 +286,7 @@ std::vector cmExportFileGenerator::FindNamespaces(cmMakefile* mf, ++expIt) { const cmExportSet* exportSet = expIt->second; - std::vector const* targets = + std::vector const* targets = exportSet->GetTargetExports(); bool containsTarget = false; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 94b9f46d60..cd05e60868 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -37,7 +37,7 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { // Create all the imported targets. - for(std::vector::const_iterator + for(std::vector::const_iterator tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { @@ -163,7 +163,7 @@ cmExportInstallFileGenerator } // Add each target in the set to the export. - for(std::vector::const_iterator + for(std::vector::const_iterator tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) { diff --git a/Source/cmExportSet.cxx b/Source/cmExportSet.cxx index 464ad68486..33b0630379 100644 --- a/Source/cmExportSet.cxx +++ b/Source/cmExportSet.cxx @@ -21,7 +21,7 @@ cmExportSet::~cmExportSet() } } -void cmExportSet::AddTargetExport(cmTargetExport const* te) +void cmExportSet::AddTargetExport(cmTargetExport* te) { this->TargetExports.push_back(te); } diff --git a/Source/cmExportSet.h b/Source/cmExportSet.h index 91a8bf9531..a57aa12044 100644 --- a/Source/cmExportSet.h +++ b/Source/cmExportSet.h @@ -25,20 +25,20 @@ public: /// Destructor ~cmExportSet(); - void AddTargetExport(cmTargetExport const* tgt); + void AddTargetExport(cmTargetExport* tgt); void AddInstallation(cmInstallExportGenerator const* installation); std::string const& GetName() const { return this->Name; } - std::vector const* GetTargetExports() const + std::vector const* GetTargetExports() const { return &this->TargetExports; } std::vector const* GetInstallations() const { return &this->Installations; } private: - std::vector TargetExports; + std::vector TargetExports; std::string Name; std::vector Installations; }; From 0cfd055acda3543d66690b5e92d8ee7c20e0654f Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Fri, 28 Sep 2012 21:47:37 +0200 Subject: [PATCH 15/17] exports: move the handling of missing targets into subclasses Before, cmExportFileGenerator::ComplainAboutMissingTarget() was a virtual function which had to be implemented in the subclasses. It is not anymore. Instead, there is now a virtual function HandleMissingTargets(), which is implemented in the two subclasses. This makes e.g. dealing correctly with APPEND mode easier. Alex --- Source/cmExportBuildFileGenerator.cxx | 42 +++++++++------ Source/cmExportBuildFileGenerator.h | 11 ++-- Source/cmExportFileGenerator.cxx | 66 +---------------------- Source/cmExportFileGenerator.h | 16 +++--- Source/cmExportInstallFileGenerator.cxx | 71 ++++++++++++++++++++++++- Source/cmExportInstallFileGenerator.h | 16 ++++-- 6 files changed, 124 insertions(+), 98 deletions(-) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 22ae0e457d..fb3f39fe6b 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -133,12 +133,30 @@ cmExportBuildFileGenerator } } +//---------------------------------------------------------------------------- +void +cmExportBuildFileGenerator::HandleMissingTarget( + std::string& link_libs, std::vector&, + cmMakefile*, 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); + } + // Assume the target will be exported by another command. + // Append it with the export namespace. + link_libs += this->Namespace; + link_libs += dependee->GetName(); +} + //---------------------------------------------------------------------------- void cmExportBuildFileGenerator ::ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee, - int occurrences) + cmTarget* dependee) { if(!this->ExportCommand || !this->ExportCommand->ErrorMessage.empty()) { @@ -146,20 +164,10 @@ cmExportBuildFileGenerator } cmOStringStream e; - if (occurrences == 0) - { - e << "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, " - << "consider using the APPEND option with multiple separate calls."; - } - else - { - e << "called with target \"" << depender->GetName() - << "\" which requires target \"" << dependee->GetName() - << "\" that is exported " << occurrences << " times in other " - << "export ""lists.\n"; - } + e << "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, " + << "consider using the APPEND option with multiple separate calls."; this->ExportCommand->ErrorMessage = e.str(); } diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h index 69f8407682..726537bfc9 100644 --- a/Source/cmExportBuildFileGenerator.h +++ b/Source/cmExportBuildFileGenerator.h @@ -45,9 +45,14 @@ protected: virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, std::string const& suffix); - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee, - int occurrences); + virtual void HandleMissingTarget(std::string& link_libs, + std::vector& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee); + + void ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee); /** Fill in properties indicating built file locations. */ void SetImportLocationProperty(const char* config, diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index dc4fa3181c..5d95668ce5 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -233,30 +233,7 @@ cmExportFileGenerator } else { - std::vector namespaces = this->FindNamespaces(mf, *li); - int targetOccurrences = (int)namespaces.size(); - - if (targetOccurrences == 1) - { - std::string missingTarget = namespaces[0]; - missingTarget += *li; - link_libs += missingTarget; - missingTargets.push_back(missingTarget); - } - else - { - // 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(target, tgt, targetOccurrences); - } - // Assume the target will be exported by another command. - // Append it with the export namespace. - link_libs += this->Namespace; - link_libs += *li; - } + this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt); } } else @@ -273,47 +250,6 @@ cmExportFileGenerator } -//---------------------------------------------------------------------------- -std::vector cmExportFileGenerator::FindNamespaces(cmMakefile* mf, - const std::string& name) -{ - std::vector namespaces; - cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); - const cmExportSetMap& exportSets = gg->GetExportSets(); - - for(cmExportSetMap::const_iterator expIt = exportSets.begin(); - expIt != exportSets.end(); - ++expIt) - { - const cmExportSet* exportSet = expIt->second; - std::vector const* targets = - exportSet->GetTargetExports(); - - bool containsTarget = false; - for(unsigned int i=0; isize(); i++) - { - if (name == (*targets)[i]->Target->GetName()) - { - containsTarget = true; - break; - } - } - - if (containsTarget) - { - std::vector const* installs = - exportSet->GetInstallations(); - for(unsigned int i=0; isize(); i++) - { - namespaces.push_back((*installs)[i]->GetNamespace()); - } - } - } - - return namespaces; -} - - //---------------------------------------------------------------------------- void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, const char* config) diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 5a99b54253..70bc65de5e 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -84,15 +84,13 @@ protected: const char* config, std::string const& suffix) = 0; - /** Each subclass knows how to complain about a target that is - missing from an export set. */ - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee, - int occurrences) = 0; - - std::vector FindNamespaces(cmMakefile* mf, - const std::string& name); - + /** Each subclass knows how to deal with a target that is missing from an + * export set. */ + virtual void HandleMissingTarget(std::string& link_libs, + std::vector& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee) = 0; // The namespace in which the exports are placed in the generated file. std::string Namespace; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index cd05e60868..7841731726 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -11,11 +11,14 @@ ============================================================================*/ #include "cmExportInstallFileGenerator.h" +#include "cmExportSet.h" +#include "cmExportSetMap.h" #include "cmGeneratedFileStream.h" +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" #include "cmInstallExportGenerator.h" #include "cmInstallTargetGenerator.h" #include "cmTargetExport.h" -#include "cmExportSet.h" //---------------------------------------------------------------------------- cmExportInstallFileGenerator @@ -309,6 +312,72 @@ cmExportInstallFileGenerator } } +//---------------------------------------------------------------------------- +void +cmExportInstallFileGenerator::HandleMissingTarget( + std::string& link_libs, std::vector& missingTargets, + cmMakefile* mf, cmTarget* depender, cmTarget* dependee) +{ + 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 += name; + link_libs += missingTarget; + missingTargets.push_back(missingTarget); + } + else + { + // We are not appending, so all exported targets should be + // known here. This is probably user-error. + this->ComplainAboutMissingTarget(depender, dependee, targetOccurrences); + } +} + +//---------------------------------------------------------------------------- +std::vector +cmExportInstallFileGenerator +::FindNamespaces(cmMakefile* mf, const std::string& name) +{ + std::vector namespaces; + cmGlobalGenerator* gg = mf->GetLocalGenerator()->GetGlobalGenerator(); + const cmExportSetMap& exportSets = gg->GetExportSets(); + + for(cmExportSetMap::const_iterator expIt = exportSets.begin(); + expIt != exportSets.end(); + ++expIt) + { + const cmExportSet* exportSet = expIt->second; + std::vector const* targets = + exportSet->GetTargetExports(); + + bool containsTarget = false; + for(unsigned int i=0; isize(); i++) + { + if (name == (*targets)[i]->Target->GetName()) + { + containsTarget = true; + break; + } + } + + if (containsTarget) + { + std::vector const* installs = + exportSet->GetInstallations(); + for(unsigned int i=0; isize(); i++) + { + namespaces.push_back((*installs)[i]->GetNamespace()); + } + } + } + + return namespaces; +} + + //---------------------------------------------------------------------------- void cmExportInstallFileGenerator diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h index f6f397e871..e719eccd5b 100644 --- a/Source/cmExportInstallFileGenerator.h +++ b/Source/cmExportInstallFileGenerator.h @@ -57,9 +57,19 @@ protected: virtual void GenerateImportTargetsConfig(std::ostream& os, const char* config, std::string const& suffix); - virtual void ComplainAboutMissingTarget(cmTarget* depender, - cmTarget* dependee, - int occurrences); + virtual void HandleMissingTarget(std::string& link_libs, + std::vector& missingTargets, + cmMakefile* mf, + cmTarget* depender, + cmTarget* dependee); + + void ComplainAboutMissingTarget(cmTarget* depender, + cmTarget* dependee, + int occurrences); + + std::vector FindNamespaces(cmMakefile* mf, + const std::string& name); + /** Generate a per-configuration file for the targets. */ bool GenerateImportFileConfig(const char* config); From 6f50a04cc1c4584472f850e06daad7ae20af45c4 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 23 Sep 2012 18:40:40 +0200 Subject: [PATCH 16/17] exports: define a CMAKE_FIND_PACKAGE_NAME var set by find_package() This way the name of the searched package can be accessed in find-modules, config-files and more importantly in generated target export files. This is now used when a target export file detects that a required target does not exist. Alex --- Source/cmExportFileGenerator.cxx | 9 ++++++++- Source/cmFindPackageCommand.cxx | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 5d95668ce5..8dffae43aa 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -389,8 +389,15 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, for(unsigned int i=0; iAddFindDefinition("CMAKE_FIND_PACKAGE_NAME", this->Name.c_str()); + // Store the list of components. std::string components_var = this->Name + "_FIND_COMPONENTS"; this->AddFindDefinition(components_var.c_str(), components.c_str()); From 955b96629e05bf2ddb6c94fa7a130e2b5b744782 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 23 Sep 2012 19:19:55 +0200 Subject: [PATCH 17/17] exports: add a test for exporting dependent targets The test exports two libraries into two separate exports, and then include()s the generated export files. This must not fail. Alex --- Tests/ExportImport/Export/CMakeLists.txt | 12 ++++++++++++ Tests/ExportImport/Export/testLibDepends.c | 4 ++++ Tests/ExportImport/Export/testLibRequired.c | 1 + Tests/ExportImport/Import/A/CMakeLists.txt | 4 ++++ 4 files changed, 21 insertions(+) create mode 100644 Tests/ExportImport/Export/testLibDepends.c create mode 100644 Tests/ExportImport/Export/testLibRequired.c diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index f118c30de7..e19ab88de2 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -87,6 +87,18 @@ target_link_libraries(testLibCycleA testLibCycleB) target_link_libraries(testLibCycleB testLibCycleA) set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3) +# Test exporting dependent libraries into different exports +add_library(testLibRequired testLibRequired.c) +add_library(testLibDepends testLibDepends.c) +target_link_libraries(testLibDepends testLibRequired) + +install(TARGETS testLibRequired EXPORT RequiredExp DESTINATION lib ) +install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired) + +install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib ) +install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends) + + # Install and export from install tree. install( TARGETS diff --git a/Tests/ExportImport/Export/testLibDepends.c b/Tests/ExportImport/Export/testLibDepends.c new file mode 100644 index 0000000000..2849b336df --- /dev/null +++ b/Tests/ExportImport/Export/testLibDepends.c @@ -0,0 +1,4 @@ + +extern int testLibRequired(void); + +int testLibDepends(void) { return testLibRequired(); } diff --git a/Tests/ExportImport/Export/testLibRequired.c b/Tests/ExportImport/Export/testLibRequired.c new file mode 100644 index 0000000000..e126d44e7d --- /dev/null +++ b/Tests/ExportImport/Export/testLibRequired.c @@ -0,0 +1 @@ +int testLibRequired(void) { return 0; } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 650af6adf6..8841792257 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -4,6 +4,10 @@ include(${Import_BINARY_DIR}/../Export/ExportBuildTree.cmake) # Import targets from the exported install tree. include(${CMAKE_INSTALL_PREFIX}/lib/exp/exp.cmake) +# Import two exports, where the Depends one depends on an exported target from the Required one: +include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibRequired/testLibRequiredConfig.cmake) +include(${CMAKE_INSTALL_PREFIX}/lib/cmake/testLibDepends/testLibDependsConfig.cmake) + # Try referencing an executable imported from the install tree. add_custom_command( OUTPUT ${Import_BINARY_DIR}/exp_generated.c