ソースを参照

Optionally allow IMPORTED targets to be globally visible

Consider the case motivating commit e01cce28 (Allow add_dependencies()
on imported targets, 2010-11-19).  An imported target references a file
generated at build time by a custom target on which it depends.  Had the
file been built directly using add_library or add_executable its target
name would have been visible globally.  Therefore the imported target
representing the file should be globally visible also.

Teach the IMPORTED signature of add_(executable|library) to accept a new
"GLOBAL" option to make the imported target visible globally.
Brad King 13 年 前
コミット
ca39c5cdd1

+ 8 - 1
Source/cmAddExecutableCommand.cxx

@@ -29,6 +29,7 @@ bool cmAddExecutableCommand
   bool use_macbundle = false;
   bool excludeFromAll = false;
   bool importTarget = false;
+  bool importGlobal = false;
   while ( s != args.end() )
     {
     if (*s == "WIN32")
@@ -51,6 +52,11 @@ bool cmAddExecutableCommand
      ++s;
      importTarget = true;
      }
+    else if(importTarget && *s == "GLOBAL")
+      {
+      ++s;
+      importGlobal = true;
+      }
     else
       {
       break;
@@ -92,7 +98,8 @@ bool cmAddExecutableCommand
       }
 
     // Create the imported target.
-    this->Makefile->AddImportedTarget(exename.c_str(), cmTarget::EXECUTABLE);
+    this->Makefile->AddImportedTarget(exename.c_str(), cmTarget::EXECUTABLE,
+                                      importGlobal);
     return true;
     }
 

+ 2 - 2
Source/cmAddExecutableCommand.h

@@ -92,12 +92,12 @@ public:
       "\n"
       "The add_executable command can also create IMPORTED executable "
       "targets using this signature:\n"
-      "  add_executable(<name> IMPORTED)\n"
+      "  add_executable(<name> IMPORTED [GLOBAL])\n"
       "An IMPORTED executable target references an executable file located "
       "outside the project.  "
       "No rules are generated to build it.  "
       "The target name has scope in the directory in which it is created "
-      "and below.  "
+      "and below, but the GLOBAL option extends visibility.  "
       "It may be referenced like any target built within the project.  "
       "IMPORTED executables are useful for convenient reference from "
       "commands like add_custom_command.  "

+ 7 - 1
Source/cmAddLibraryCommand.cxx

@@ -31,6 +31,7 @@ bool cmAddLibraryCommand
     }
   bool excludeFromAll = false;
   bool importTarget = false;
+  bool importGlobal = false;
 
   std::vector<std::string>::const_iterator s = args.begin();
 
@@ -79,6 +80,11 @@ bool cmAddLibraryCommand
       ++s;
       importTarget = true;
       }
+    else if(importTarget && *s == "GLOBAL")
+      {
+      ++s;
+      importGlobal = true;
+      }
     else
       {
       break;
@@ -124,7 +130,7 @@ bool cmAddLibraryCommand
       }
 
     // Create the imported target.
-    this->Makefile->AddImportedTarget(libName.c_str(), type);
+    this->Makefile->AddImportedTarget(libName.c_str(), type, importGlobal);
     return true;
     }
 

+ 3 - 2
Source/cmAddLibraryCommand.h

@@ -96,12 +96,13 @@ public:
       "\n"
       "The add_library command can also create IMPORTED library "
       "targets using this signature:\n"
-      "  add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED)\n"
+      "  add_library(<name> <SHARED|STATIC|MODULE|UNKNOWN> IMPORTED\n"
+      "              [GLOBAL])\n"
       "An IMPORTED library target references a library file located "
       "outside the project.  "
       "No rules are generated to build it.  "
       "The target name has scope in the directory in which it is created "
-      "and below.  "
+      "and below, but the GLOBAL option extends visibility.  "
       "It may be referenced like any target built within the project.  "
       "IMPORTED libraries are useful for convenient reference from "
       "commands like target_link_libraries.  "

+ 14 - 3
Source/cmGlobalGenerator.cxx

@@ -1666,6 +1666,11 @@ cmGlobalGenerator::FindTarget(const char* project, const char* name)
       {
       return i->second;
       }
+    i = this->ImportedTargets.find(name);
+    if ( i != this->ImportedTargets.end() )
+      {
+      return i->second;
+      }
     }
   return 0;
 }
@@ -2046,10 +2051,16 @@ cmGlobalGenerator::GetTargetDirectDepends(cmTarget & target)
   return this->TargetDependencies[&target];
 }
 
-void cmGlobalGenerator::AddTarget(cmTargets::value_type &v)
+void cmGlobalGenerator::AddTarget(cmTarget* t)
 {
-  assert(!v.second.IsImported());
-  this->TotalTargets[v.first] = &v.second;
+  if(t->IsImported())
+    {
+    this->ImportedTargets[t->GetName()] = t;
+    }
+  else
+    {
+    this->TotalTargets[t->GetName()] = t;
+    }
 }
 
 void cmGlobalGenerator::SetExternalMakefileProjectGenerator(

+ 2 - 1
Source/cmGlobalGenerator.h

@@ -230,7 +230,7 @@ public:
   std::set<cmStdString> const& GetDirectoryContent(std::string const& dir,
                                                    bool needDisk = true);
 
-  void AddTarget(cmTargets::value_type &v);
+  void AddTarget(cmTarget* t);
 
   virtual const char* GetAllTargetName()         const { return "ALL_BUILD"; }
   virtual const char* GetInstallTargetName()       const { return "INSTALL"; }
@@ -333,6 +333,7 @@ protected:
 
   // All targets in the entire project.
   std::map<cmStdString,cmTarget *> TotalTargets;
+  std::map<cmStdString,cmTarget *> ImportedTargets;
 
   virtual const char* GetPredefinedTargetsFolder();
   virtual bool UseFolderProperty();

+ 7 - 2
Source/cmMakefile.cxx

@@ -1937,7 +1937,7 @@ cmMakefile::AddNewTarget(cmTarget::TargetType type, const char* name)
   cmTarget& target = it->second;
   target.SetType(type, name);
   target.SetMakefile(this);
-  this->LocalGenerator->GetGlobalGenerator()->AddTarget(*it);
+  this->LocalGenerator->GetGlobalGenerator()->AddTarget(&it->second);
   return &it->second;
 }
 
@@ -3894,7 +3894,8 @@ void cmMakefile::DefineProperties(cmake *cm)
 
 //----------------------------------------------------------------------------
 cmTarget*
-cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
+cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type,
+                              bool global)
 {
   // Create the target.
   cmsys::auto_ptr<cmTarget> target(new cmTarget);
@@ -3904,6 +3905,10 @@ cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type)
 
   // Add to the set of available imported targets.
   this->ImportedTargets[name] = target.get();
+  if(global)
+    {
+    this->LocalGenerator->GetGlobalGenerator()->AddTarget(target.get());
+    }
 
   // Transfer ownership to this cmMakefile object.
   this->ImportedTargetsOwned.push_back(target.get());

+ 2 - 1
Source/cmMakefile.h

@@ -203,7 +203,8 @@ public:
   void RemoveDefineFlag(const char* definition);
 
   /** Create a new imported target with the name and type given.  */
-  cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type);
+  cmTarget* AddImportedTarget(const char* name, cmTarget::TargetType type,
+                              bool global);
 
   cmTarget* AddNewTarget(cmTarget::TargetType type, const char* name);