فهرست منبع

ENH: check in initial conv library stuff

Bill Hoffman 18 سال پیش
والد
کامیت
ca0230a33e

+ 61 - 4
Source/cmGlobalXCodeGenerator.cxx

@@ -124,6 +124,20 @@ void cmGlobalXCodeGenerator::EnableLanguage(std::vector<std::string>const&
   mf->AddDefinition("CMAKE_GENERATOR_CXX", "g++");
   mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
   this->cmGlobalGenerator::EnableLanguage(lang, mf);
+    const char* osxArch = 
+      mf->GetDefinition("CMAKE_OSX_ARCHITECTURES");
+  const char* sysroot = 
+      mf->GetDefinition("CMAKE_OSX_SYSROOT");
+  if(osxArch && sysroot)
+    {
+    std::cerr <<"EnableLanguage archs\n";
+    this->Architectures.clear();
+    cmSystemTools::ExpandListArgument(std::string(osxArch),
+                                      this->Architectures);
+    }
+  else
+    std::cerr <<"no EnableLanguage archs\n";
+
 }
 
 //----------------------------------------------------------------------------
@@ -2156,9 +2170,6 @@ void cmGlobalXCodeGenerator
       this->CurrentMakefile->GetDefinition("CMAKE_OSX_SYSROOT");
   if(osxArch && sysroot)
     {
-    this->Architectures.clear();
-    cmSystemTools::ExpandListArgument(std::string(osxArch),
-                                      this->Architectures);
     if(this->Architectures.size() > 1)
       {
       buildSettings->AddAttribute("SDKROOT", 
@@ -2217,7 +2228,6 @@ void cmGlobalXCodeGenerator
   this->RootObject->AddAttribute("targets", allTargets);
 }
 
-
 //----------------------------------------------------------------------------
 void 
 cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
@@ -2555,6 +2565,52 @@ std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p)
   return ret;
 }
 
+void cmGlobalXCodeGenerator::
+GetTargetObjectFileDirectories(cmTarget* target,
+                               std::vector<std::string>& 
+                               dirs)
+{
+  std::string dir = this->CurrentMakefile->GetCurrentOutputDirectory();
+  dir += "/";
+  dir += target->GetName();
+  dir += ".build/";
+  dir += this->GetCMakeCFGInitDirectory();
+  dir += "/";
+  if(target->GetType() != cmTarget::EXECUTABLE)
+    {
+    dir += "lib";
+    }
+  dir += target->GetName();
+  if(target->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    dir += ".a";
+    }
+  if(target->GetType() == cmTarget::SHARED_LIBRARY)
+    {
+    dir += ".dylib";
+    }
+  if(target->GetType() == cmTarget::MODULE_LIBRARY)
+    {
+    dir += ".so";
+    }
+  dir += ".build/Objects-normal/";
+  std::string dirsave = dir;
+  if(this->Architectures.size())
+    {
+    for(std::vector<std::string>::iterator i = this->Architectures.begin(); 
+        i != this->Architectures.end(); ++i)
+      {
+      dir += *i;
+      dirs.push_back(dir);
+      dir = dirsave;
+      }
+    }
+  else
+    {
+    dirs.push_back(dir);
+    }
+}
+
 //----------------------------------------------------------------------------
 void
 cmGlobalXCodeGenerator
@@ -2567,6 +2623,7 @@ cmGlobalXCodeGenerator
     {
     if(config)
       {
+
       dir += prefix;
       dir += config;
       dir += suffix;

+ 5 - 1
Source/cmGlobalXCodeGenerator.h

@@ -82,13 +82,16 @@ public:
   ///! What is the configurations directory variable called?
   virtual const char* GetCMakeCFGInitDirectory()  { return "."; }
 
+  void GetTargetObjectFileDirectories(cmTarget* target,
+                                      std::vector<std::string>& 
+                                      dirs);
+  void SetCurrentLocalGenerator(cmLocalGenerator*);
 private: 
   cmXCodeObject* CreateOrGetPBXGroup(cmTarget& cmtarget,
                                      cmSourceGroup* sg);
   void CreateGroups(cmLocalGenerator* root,
                     std::vector<cmLocalGenerator*>&
                     generators);
-  void SetCurrentLocalGenerator(cmLocalGenerator*);
   std::string XCodeEscapePath(const char* p);
   std::string ConvertToRelativeForXCode(const char* p);
   std::string ConvertToRelativeForMake(const char* p);
@@ -158,6 +161,7 @@ private:
                           const char* varNameLang,
                           const char* varNameSuffix,
                           const char* default_flags);
+
 protected:
   virtual const char* GetInstallTargetName()      { return "install"; }
   virtual const char* GetPackageTargetName()      { return "package"; }

+ 12 - 0
Source/cmLocalGenerator.cxx

@@ -2399,3 +2399,15 @@ std::string cmLocalGenerator::EscapeForShell(const char* str, bool makeVars,
     }
   return std::string(&arg[0]);
 }
+void 
+cmLocalGenerator::GetTargetObjectFileDirectories(cmTarget* target,
+                                                 std::vector<std::string>& 
+                                                 dirs)
+{
+  cmSystemTools::Error("GetTargetObjectFileDirectories called on cmLocalGenerator");
+}
+
+std::string cmLocalGenerator::GetSourceObjectName(cmSourceFile& sf)
+{
+  return sf.GetSourceName();
+}

+ 11 - 1
Source/cmLocalGenerator.h

@@ -214,7 +214,17 @@ public:
 
   /** Backwards-compatibility version of EscapeForShell.  */
   std::string EscapeForShellOldStyle(const char* str);
-
+  
+  /** Return the directories into which object files will be put.
+   *  There maybe more than one for fat binary systems like OSX.
+   */
+  virtual void 
+  GetTargetObjectFileDirectories(cmTarget* target,
+                                 std::vector<std::string>& 
+                                 dirs);
+  // return the source name for the object file
+  virtual std::string GetSourceObjectName(cmSourceFile& );
+  
 protected:
 
   /** Construct a comment for a custom command.  */

+ 11 - 0
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -1920,3 +1920,14 @@ void cmLocalUnixMakefileGenerator3
       }
     }
 }
+
+
+void cmLocalUnixMakefileGenerator3
+::GetTargetObjectFileDirectories(cmTarget* target,
+                                 std::vector<std::string>& dirs)
+{
+  std::string dir = this->Makefile->GetCurrentOutputDirectory();
+  dir += "/";
+  dir += this->GetTargetDirectory(*target);
+  dirs.push_back(dir);
+}

+ 3 - 1
Source/cmLocalUnixMakefileGenerator3.h

@@ -246,7 +246,9 @@ public:
     {
     return !this->SkipAssemblySourceRules;
     }
-
+  // Get the directories into which the .o files will go for this target
+  void GetTargetObjectFileDirectories(cmTarget* target,
+                                      std::vector<std::string>& dirs);
 protected:
   // these two methods just compute reasonable values for LibraryOutputPath
   // and ExecutableOutputPath

+ 12 - 0
Source/cmLocalVisualStudio6Generator.cxx

@@ -1472,3 +1472,15 @@ void cmLocalVisualStudio6Generator
     options += "\n";
     }
 }
+
+
+void cmLocalVisualStudio6Generator
+::GetTargetObjectFileDirectories(cmTarget* target,
+                                 std::vector<std::string>& 
+                                 dirs)
+{
+  std::string dir = this->Makefile->GetCurrentOutputDirectory();
+  dir += "/";
+  dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory();
+  dirs.push_back(dir);
+}

+ 3 - 1
Source/cmLocalVisualStudio6Generator.h

@@ -61,7 +61,9 @@ public:
     {
     return this->CreatedProjectNames;
     }
-
+  void GetTargetObjectFileDirectories(cmTarget* target,
+                                      std::vector<std::string>& 
+                                      dirs);
 private:
   std::string DSPHeaderTemplate;
   std::string DSPFooterTemplate;

+ 13 - 0
Source/cmLocalVisualStudio7Generator.cxx

@@ -1949,3 +1949,16 @@ cmLocalVisualStudio7GeneratorOptions
     fout << "\"" << suffix;
     }
 }
+void cmLocalVisualStudio7Generator::
+GetTargetObjectFileDirectories(cmTarget* target,
+                               std::vector<std::string>& 
+                               dirs)
+{
+  std::string dir = this->Makefile->GetCurrentOutputDirectory();
+  dir += "/";
+  dir += this->GetTargetDirectory(*target);
+  dir += "/";
+  dir += this->GetGlobalGenerator()->GetCMakeCFGInitDirectory();
+  std::cerr << dir << "\n";
+  dirs.push_back(dir);
+}

+ 4 - 0
Source/cmLocalVisualStudio7Generator.h

@@ -66,6 +66,10 @@ public:
   void SetVersion8() {this->Version = 8;}
   void SetPlatformName(const char* n) { this->PlatformName = n;}
   virtual void ConfigureFinalPass();
+  void GetTargetObjectFileDirectories(cmTarget* target,
+                                      std::vector<std::string>& 
+                                      dirs);
+
 private:
   typedef cmLocalVisualStudio7GeneratorOptions Options;
   void ReadAndStoreExternalGUID(const char* name,

+ 2 - 1
Source/cmLocalVisualStudioGenerator.cxx

@@ -15,7 +15,7 @@
 
 =========================================================================*/
 #include "cmLocalVisualStudioGenerator.h"
-
+#include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
@@ -178,3 +178,4 @@ cmLocalVisualStudioGenerator
     }
   return script;
 }
+

+ 3 - 1
Source/cmLocalVisualStudioGenerator.h

@@ -33,7 +33,9 @@ class cmLocalVisualStudioGenerator : public cmLocalGenerator
 public:
   cmLocalVisualStudioGenerator();
   virtual ~cmLocalVisualStudioGenerator();
-
+  /** Return the directories into which object files will be put.
+   *  There maybe more than one for fat binary systems like OSX.
+   */
 protected:
 
   /** Construct a script from the given list of command lines.  */

+ 25 - 0
Source/cmLocalXCodeGenerator.cxx

@@ -1,4 +1,6 @@
 #include "cmLocalXCodeGenerator.h"
+#include "cmGlobalXCodeGenerator.h"
+#include "cmSourceFile.h"
 
 cmLocalXCodeGenerator::cmLocalXCodeGenerator()
 {
@@ -11,3 +13,26 @@ cmLocalXCodeGenerator::~cmLocalXCodeGenerator()
 {
 }
 
+void cmLocalXCodeGenerator::
+GetTargetObjectFileDirectories(cmTarget* target,
+                               std::vector<std::string>& 
+                               dirs)
+{
+  cmGlobalXCodeGenerator* g = (cmGlobalXCodeGenerator*)this->GetGlobalGenerator();
+  g->SetCurrentLocalGenerator(this);
+  g->GetTargetObjectFileDirectories(target,
+                                    dirs);
+}
+  
+  // return the source name for the object file
+std::string cmLocalXCodeGenerator::GetSourceObjectName(cmSourceFile& sf )
+{
+  std::string ret = sf.GetSourceName();
+  std::string::size_type pos = ret.find("/");
+  if(pos == ret.npos)
+    {
+    return ret;
+    }
+  return ret.substr(pos+1);
+}
+  

+ 5 - 0
Source/cmLocalXCodeGenerator.h

@@ -32,6 +32,11 @@ public:
   cmLocalXCodeGenerator();
 
   virtual ~cmLocalXCodeGenerator();
+  void GetTargetObjectFileDirectories(cmTarget* target,
+                                      std::vector<std::string>& 
+                                      dirs);
+  // return the source name for the object file
+  virtual std::string GetSourceObjectName(cmSourceFile& );
 private:
 
 };

+ 0 - 1
Source/cmMakefileTargetGenerator.cxx

@@ -1275,4 +1275,3 @@ void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total,
   current += this->NumberOfProgressActions;
   delete progressFileStream;
 }
-

+ 1 - 1
Source/cmMakefileTargetGenerator.h

@@ -60,7 +60,7 @@ public:
     return this->NumberOfProgressActions;}
 
   const char *GetTargetName() { return this->TargetName.c_str(); }
-
+  cmTarget* GetTarget() { return this->Target;}
 protected:
 
   // create the file and directory etc

+ 63 - 3
Source/cmTarget.cxx

@@ -256,6 +256,14 @@ void cmTarget::DefineProperties(cmake *cm)
      "in contrast to a console application for example. This changes "
      "how the executable will be linked.");
 
+  cm->DefineProperty
+    ("OBJECT_FILES", cmProperty::TARGET, 
+     "Used to get the resulting list of object files that make up a "
+     "target.",
+     "This can be used to put object files from one library "
+     "into another library. It is a read only property.  It "
+     "converts the source list for the target into a list of full "
+     "paths to object names that will be produced by the target.");
 
   // define some properties without documentation
   cm->DefineProperty("DEBUG_OUTPUT_NAME", cmProperty::TARGET,0,0);
@@ -529,13 +537,20 @@ void cmTarget::TraceVSDependencies(std::string projFile,
 
 void cmTarget::GenerateSourceFilesFromSourceLists( cmMakefile &mf)
 {
+  // only allow this to be called once
+  // there is a lazy evaluation of this in ComputeObjectFiles,
+  // that could break backwards compatibility with projects that
+  // use old style source lists.  
+  if(this->SourceFiles.size() != 0)
+    {
+    return;
+    }
   // this is only done for non install targets
   if ((this->TargetTypeValue == cmTarget::INSTALL_FILES)
       || (this->TargetTypeValue == cmTarget::INSTALL_PROGRAMS))
     {
     return;
     }
-
   // for each src lists add the classes
   for (std::vector<std::string>::const_iterator s = this->SourceLists.begin();
        s != this->SourceLists.end(); ++s)
@@ -1160,6 +1175,49 @@ const char *cmTarget::GetProperty(const char* prop)
   return this->GetProperty(prop, cmProperty::TARGET);
 }
 
+void cmTarget::ComputeObjectFiles()
+{
+  // Force the SourceFiles vector to be populated
+  this->GenerateSourceFilesFromSourceLists(*this->Makefile);
+  std::vector<std::string> dirs;
+  this->Makefile->GetLocalGenerator()->
+    GetTargetObjectFileDirectories(this,
+                                   dirs);
+  std::string objectFiles;
+  std::string objExtensionLookup1 = "CMAKE_";
+  std::string objExtensionLookup2 = "_OUTPUT_EXTENSION";
+  
+  for(std::vector<std::string>::iterator d = dirs.begin();
+      d != dirs.end(); ++d)
+    {
+    for(std::vector<cmSourceFile*>::iterator s = this->SourceFiles.begin();
+        s != this->SourceFiles.end(); ++s)
+      {
+      cmSourceFile* sf = *s;
+      const char* lang = this->Makefile->GetLocalGenerator()->
+        GetGlobalGenerator()->GetLanguageFromExtension(sf->GetSourceExtension().c_str());
+      std::string lookupObj = objExtensionLookup1 + lang;
+      lookupObj += objExtensionLookup2;
+      const char* obj = this->Makefile->GetDefinition(lookupObj.c_str());
+      if(obj)
+        {
+        if(objectFiles.size())
+          {
+          objectFiles += ";";
+          }
+        std::string objFile = *d;
+        objFile += "/";
+        objFile += this->Makefile->GetLocalGenerator()->
+          GetSourceObjectName(*sf);
+        objFile += obj;
+        objectFiles += objFile;
+        }
+      }
+    }
+  this->SetProperty("OBJECT_FILES", objectFiles.c_str());
+}
+
+
 const char *cmTarget::GetProperty(const char* prop,
                                   cmProperty::ScopeType scope)
 {
@@ -1178,7 +1236,10 @@ const char *cmTarget::GetProperty(const char* prop,
     // variable in the location.
     this->SetProperty("LOCATION", this->GetLocation(0));
     }
-
+  if(strcmp(prop, "OBJECT_FILES") == 0)
+    {
+    this->ComputeObjectFiles();
+    }
   // Per-configuration location can be computed.
   int len = static_cast<int>(strlen(prop));
   if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0)
@@ -1186,7 +1247,6 @@ const char *cmTarget::GetProperty(const char* prop,
     std::string configName(prop, len-9);
     this->SetProperty(prop, this->GetLocation(configName.c_str()));
     }
-
   // the type property returns what type the target is
   if (!strcmp(prop,"TYPE"))
     {

+ 3 - 0
Source/cmTarget.h

@@ -261,6 +261,9 @@ public:
 
   // Define the properties
   static void DefineProperties(cmake *cm);
+  
+  // Compute the OBJECT_FILES property only when requested
+  void ComputeObjectFiles();
 
 private:
   /**

+ 19 - 0
Tests/ConvLibrary/CMakeLists.txt

@@ -0,0 +1,19 @@
+project(foo)
+
+# create a source list
+set(foo_sources foo.cxx bar.c sub1/car.cxx) 
+# create a library foo from the sources
+add_library(foo ${foo_sources})
+# get the object files from the target
+get_target_property(OBJECT_FILES foo OBJECT_FILES)
+message("${OBJECT_FILES}")
+# set the object files as generated
+set_source_files_properties(${OBJECT_FILES} PROPERTIES GENERATED true)
+# create a library bar that contains the object files from foo
+add_library(bar ${OBJECT_FILES})
+# set the linker language since bar only has .obj
+set_target_properties(bar PROPERTIES LINKER_LANGUAGE CXX)
+# make sure foo is built before bar
+add_dependencies(bar foo)
+add_executable(bartest bartest.cxx)
+target_link_libraries(bartest bar)

+ 4 - 0
Tests/ConvLibrary/bar.c

@@ -0,0 +1,4 @@
+int bar()
+{
+  return 20;
+}

+ 37 - 0
Tests/ConvLibrary/bartest.cxx

@@ -0,0 +1,37 @@
+extern "C" int bar();
+int foo();
+int car();
+
+#include <stdio.h>
+int main()
+{
+  if(foo() == 10)
+    {
+    printf("foo is 10!\n");
+    }
+  else
+    {
+    printf("foo is not 10 error!\n");
+    return -1;
+    }
+  if(bar() == 20)
+    {
+    printf("bar is 20!\n");
+    }
+  else
+    {
+    printf("bar is not 20 error!\n");
+    return -1;
+    }
+  if(car() == 30)
+    {
+    printf("bar is 30!\n");
+    }
+  else
+    {
+    printf("bar is not 30 error!\n");
+    return -1;
+    }
+  printf("Test past\n");
+  return 0;
+}

+ 4 - 0
Tests/ConvLibrary/foo.cxx

@@ -0,0 +1,4 @@
+int foo()
+{
+  return 10;
+}

+ 4 - 0
Tests/ConvLibrary/sub1/car.cxx

@@ -0,0 +1,4 @@
+int car()
+{
+  return 30;
+}