From bf2ddceb4e55b2b9e3fb749fbee6126340f73f07 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 30 Nov 2012 09:26:09 +0100 Subject: Generate an early-return guard in target Export files. Previously it was necessary for writers of Config files which incude exported target files to write the guard themselves, but this was not immediately obvious or documented. Options for them would be to use a variable, or an INHERITED directory property in an effort to avoid accidental name clashes in all contexts in which find_package can be used. Getting this right requires boiler plate code, so generate a simpler check automatically instead. --- Source/cmExportBuildFileGenerator.cxx | 14 ++++++++++++++ Source/cmExportFileGenerator.cxx | 31 +++++++++++++++++++++++++++++++ Source/cmExportFileGenerator.h | 2 ++ Source/cmExportInstallFileGenerator.cxx | 14 ++++++++++++++ 4 files changed, 61 insertions(+) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index fb3f39f..cd6a7ab 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -22,6 +22,20 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator() //---------------------------------------------------------------------------- bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { + { + std::string expectedTargets; + std::string sep; + for(std::vector::const_iterator + tei = this->Exports->begin(); + tei != this->Exports->end(); ++tei) + { + expectedTargets += sep + this->Namespace + (*tei)->GetName(); + sep = " "; + } + + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + // Create all the imported targets. for(std::vector::const_iterator tei = this->Exports->begin(); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 8dffae4..3f738cc 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -287,6 +287,37 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) } //---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os, + const std::string &expectedTargets) +{ + os << "SET(_targetsDefined)\n" + "SET(_targetsNotDefined)\n" + "SET(_expectedTargets)\n" + "FOREACH(_expectedTarget " << expectedTargets << ")\n" + " LIST(APPEND _expectedTargets ${_expectedTarget})\n" + " IF(NOT TARGET ${_expectedTarget})\n" + " LIST(APPEND _targetsNotDefined ${_expectedTarget})\n" + " ENDIF(NOT TARGET ${_expectedTarget})\n" + " IF(TARGET ${_expectedTarget})\n" + " LIST(APPEND _targetsDefined ${_expectedTarget})\n" + " ENDIF(TARGET ${_expectedTarget})\n" + "ENDFOREACH(_expectedTarget)\n" + "IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" + " SET(CMAKE_IMPORT_FILE_VERSION)\n" + " CMAKE_POLICY(POP)\n" + " RETURN()\n" + "ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" + "IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" + " MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export " + "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n" + "Targets not yet defined: ${_targetsNotDefined}\\n\")\n" + "ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" + "UNSET(_targetsDefined)\n" + "UNSET(_targetsNotDefined)\n" + "UNSET(_expectedTargets)\n" + "\n\n"; +} +//---------------------------------------------------------------------------- void cmExportFileGenerator ::GenerateImportTargetCode(std::ostream& os, cmTarget* target) diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 70bc65d..4a75c52 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -63,6 +63,8 @@ protected: void GenerateMissingTargetsCheckCode(std::ostream& os, const std::vector& missingTargets); + void GenerateExpectedTargetsCode(std::ostream& os, + const std::string &expectedTargets); // Collect properties with detailed information about targets beyond // their location on disk. diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 7841731..6ba7d9f 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -39,6 +39,20 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() //---------------------------------------------------------------------------- bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { + { + std::string expectedTargets; + std::string sep; + for(std::vector::const_iterator + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) + { + expectedTargets += sep + this->Namespace + (*tei)->Target->GetName(); + sep = " "; + } + + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + // Create all the imported targets. for(std::vector::const_iterator tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); -- cgit v0.12