Browse Source

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
Alex Neundorf 13 years ago
parent
commit
8b5f448ba6

+ 3 - 1
Source/cmExportBuildFileGenerator.cxx

@@ -72,8 +72,9 @@ cmExportBuildFileGenerator
     if(!properties.empty())
       {
       // Get the rest of the target details.
+      std::vector<std::string> 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);
       }
     }

+ 30 - 7
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<std::string>& 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<std::string> const& libs,
-                        ImportPropertyMap& properties)
+                        ImportPropertyMap& properties,
+                        std::vector<std::string>& 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<std::string>& missingTargets)
+{
+  os << "# Make sure the targets which have been exported in some other \n"
+        "# export set exist.\n";
+  for(unsigned int i=0; i<missingTargets.size(); ++i)
+    {
+    os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
+       << "  MESSAGE(FATAL_ERROR \"Required imported target \\\""
+       << missingTargets[i] << "\\\" not found ! \")\n"
+       << "ENDIF()\n";
+    }
+  os << "\n";
+}
+
+
 //----------------------------------------------------------------------------
 void
 cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)

+ 6 - 2
Source/cmExportFileGenerator.h

@@ -60,17 +60,21 @@ protected:
                                       ImportPropertyMap const& properties,
                                const std::set<std::string>& importedLocations);
   void GenerateImportedFileCheckLoop(std::ostream& os);
+  void GenerateMissingTargetsCheckCode(std::ostream& os,
+                               const std::vector<std::string>& 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<std::string>& missingTargets);
   void SetImportLinkProperty(std::string const& suffix,
                              cmTarget* target, const char* propName,
                              std::vector<std::string> const& libs,
-                             ImportPropertyMap& properties);
+                             ImportPropertyMap& properties,
+                             std::vector<std::string>& missingTargets);
 
   /** Each subclass knows how to generate its kind of export file.  */
   virtual bool GenerateMainFile(std::ostream& os) = 0;

+ 3 - 1
Source/cmExportInstallFileGenerator.cxx

@@ -188,8 +188,9 @@ cmExportInstallFileGenerator
     if(!properties.empty())
       {
       // Get the rest of the target details.
+      std::vector<std::string> 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);