Преглед изворни кода

ENH: add group support and fix borland error

Bill Hoffman пре 16 година
родитељ
комит
28b1912aa3

+ 4 - 4
Source/cmLocalGenerator.h

@@ -302,6 +302,10 @@ public:
   /** Construct a comment for a custom command.  */
   std::string ConstructComment(const cmCustomCommand& cc,
                                const char* default_comment = "");
+  // Compute object file names.
+  std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
+                                             std::string const& dir_max,
+                                             bool* hasSourceExtension = 0);
 
 protected:
   /** Fill out these strings for the given target.  Libraries to link,
@@ -346,10 +350,6 @@ protected:
     std::ostream& os, const char* config,
     std::vector<std::string> const& configurationTypes);
 
-  // Compute object file names.
-  std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source,
-                                             std::string const& dir_max,
-                                             bool* hasSourceExtension = 0);
   std::string& CreateSafeUniqueObjectFileName(const char* sin,
                                               std::string const& dir_max);
 

+ 1 - 1
Source/cmMakefile.cxx

@@ -1958,7 +1958,7 @@ void cmMakefile::AddSourceGroup(const std::vector<std::string>& name,
   // build the whole source group path
   for(++i; i<=lastElement; ++i)
     {
-    sg->AddChild(cmSourceGroup(name[i].c_str(), 0));
+    sg->AddChild(cmSourceGroup(name[i].c_str(), 0, sg->GetFullName()));
     sg = sg->lookupChild(name[i].c_str());
     }
 

+ 15 - 1
Source/cmSourceGroup.cxx

@@ -23,10 +23,17 @@ public:
 };
 
 //----------------------------------------------------------------------------
-cmSourceGroup::cmSourceGroup(const char* name, const char* regex): Name(name)
+cmSourceGroup::cmSourceGroup(const char* name, const char* regex,
+                             const char* parentName): Name(name)
 {
   this->Internal = new cmSourceGroupInternals;
   this->SetGroupRegex(regex);
+  if(parentName)
+    {
+    this->FullName = parentName;
+    this->FullName += "\\";
+    }
+  this->FullName += this->Name;
 }
 
 //----------------------------------------------------------------------------
@@ -39,6 +46,7 @@ cmSourceGroup::~cmSourceGroup()
 cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
 {
   this->Name = r.Name;
+  this->FullName = r.FullName;
   this->GroupRegex = r.GroupRegex;
   this->GroupFiles = r.GroupFiles;
   this->SourceFiles = r.SourceFiles;
@@ -80,6 +88,12 @@ const char* cmSourceGroup::GetName() const
 {
   return this->Name.c_str();
 }
+
+//----------------------------------------------------------------------------
+const char* cmSourceGroup::GetFullName() const
+{
+  return this->FullName.c_str();
+}
   
 //----------------------------------------------------------------------------
 bool cmSourceGroup::MatchesRegex(const char* name)

+ 9 - 1
Source/cmSourceGroup.h

@@ -37,7 +37,8 @@ class cmSourceGroupInternals;
 class cmSourceGroup
 {
 public:
-  cmSourceGroup(const char* name, const char* regex);
+  cmSourceGroup(const char* name, const char* regex,
+                const char* parentName=0);
   cmSourceGroup(cmSourceGroup const& r);
   ~cmSourceGroup();
   cmSourceGroup& operator=(cmSourceGroup const&);
@@ -66,6 +67,11 @@ public:
    * Get the name of this group.
    */
   const char* GetName() const;
+
+  /**
+   * Get the full path name for group.
+   */
+  const char* GetFullName() const;
   
   /**
    * Check if the given name matches this group's regex.
@@ -107,6 +113,8 @@ private:
    * The name of the source group.
    */
   std::string Name;
+  // Full path to group
+  std::string FullName;
   
   /**
    * The regular expression matching the files in the group.

+ 129 - 41
Source/cmVisualStudio10TargetGenerator.cxx

@@ -331,35 +331,137 @@ void cmVisualStudio10TargetGenerator::ConvertToWindowsSlash(std::string& s)
     }
 }
 void cmVisualStudio10TargetGenerator::WriteGroups()
-{
-  // This should create a target.vcxproj.filters file
-  // something like this:
+{ 
+  // collect up group information
+  std::vector<cmSourceGroup> sourceGroups = 
+    this->Makefile->GetSourceGroups();
+  std::vector<cmSourceFile*>  classes = this->Target->GetSourceFiles();
+  
+  std::set<cmSourceGroup*> groupsUsed;
+  std::vector<cmSourceFile*> clCompile;
+  std::vector<cmSourceFile*> customBuild;
+  std::vector<cmSourceFile*> none;
   
-/*
-  <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" 
-xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <CustomBuild Include="..\CMakeLists.txt" />
-  </ItemGroup>
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{05072589-c7be-439a-8fd7-5db6ee5008a9}
-      </UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\foo.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\testCCompiler.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-  </ItemGroup>
-</Project>
-*/
+  for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); 
+      s != classes.end(); s++)
+    {
+    cmSourceFile* sf = *s; 
+    std::string const& source = sf->GetFullPath();
+    cmSourceGroup& sourceGroup = 
+      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+    groupsUsed.insert(&sourceGroup);
+    const char* lang = sf->GetLanguage();
+    if(!lang)
+      {
+      lang = "None";
+      }
+    if(lang[0] == 'C')
+      {
+      clCompile.push_back(sf);
+      }
+    else if(sf->GetCustomCommand())
+      {
+      customBuild.push_back(sf);
+      }
+    else
+      {
+      none.push_back(sf);
+      }
+    }
+  // Write out group file
+  std::string path =  this->Makefile->GetStartOutputDirectory();
+  path += "/";
+  path += this->Target->GetName();
+  path += ".vcxproj.filters";
+  cmGeneratedFileStream fout(path.c_str());
+  char magic[] = {0xEF,0xBB, 0xBF};
+  fout.write(magic, 3);
+  cmGeneratedFileStream* save = this->BuildFileStream;
+  this->BuildFileStream = & fout;
+  this->WriteString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+                    "<Project "
+                    "ToolsVersion=\"4.0\" "
+                    "xmlns=\"http://schemas.microsoft.com/"
+                    "developer/msbuild/2003\">\n",
+                    0);
+  this->WriteGroupSources("ClCompile", clCompile, sourceGroups);
+  this->WriteGroupSources("CustomBuild", customBuild, sourceGroups);
+
+  this->WriteString("<ItemGroup>\n", 1);
+  for(std::set<cmSourceGroup*>::iterator g = groupsUsed.begin();
+      g != groupsUsed.end(); ++g)
+    {
+    cmSourceGroup* sg = *g;
+    const char* name = sg->GetFullName();
+    if(strlen(name) != 0)
+      {
+      this->WriteString("<Filter Include=\"", 2);
+      (*this->BuildFileStream) << name << "\">\n";
+      std::string guidName = "SG_Filter_";
+      guidName += name;
+      this->GlobalGenerator->CreateGUID(guidName.c_str());
+      this->WriteString("<UniqueIdentifier>", 3);
+      std::string guid 
+        = this->GlobalGenerator->GetGUID(guidName.c_str());
+      (*this->BuildFileStream) 
+        << "{"
+        << guid << "}"
+        << "</UniqueIdentifier>\n";
+      this->WriteString("</Filter>\n", 2);
+      }
+    }
+  this->WriteString("</ItemGroup>\n", 1);
+  this->WriteGroupSources("None", none, sourceGroups);
+  this->WriteString("</Project>\n", 0);
+  // restore stream pointer
+  this->BuildFileStream = save;
 }
 
+void 
+cmVisualStudio10TargetGenerator::
+WriteGroupSources(const char* name,
+                  std::vector<cmSourceFile*> const& sources,
+                  std::vector<cmSourceGroup>& sourceGroups)
+{
+  this->WriteString("<ItemGroup>\n", 1);
+  for(std::vector<cmSourceFile*>::const_iterator s = sources.begin();
+      s != sources.end(); ++s)
+    {
+    cmSourceFile* sf = *s; 
+    std::string const& source = sf->GetFullPath();
+    cmSourceGroup& sourceGroup = 
+      this->Makefile->FindSourceGroup(source.c_str(), sourceGroups);
+    const char* filter = sourceGroup.GetFullName();
+    this->WriteString("<", 2); 
+    std::string path = source;
+    // custom command source are done with relative paths 
+    // so that the custom command display in the GUI
+    // the source groups have to EXACTLY match the string
+    // used in the .vcxproj file
+    if(sf->GetCustomCommand())
+      {
+      path = cmSystemTools::RelativePath(
+        this->Makefile->GetCurrentOutputDirectory(),
+        source.c_str());
+      }
+    this->ConvertToWindowsSlash(path);
+    (*this->BuildFileStream) << name << " Include=\""
+                             << path;
+    if(strlen(filter))
+      {
+      (*this->BuildFileStream) << "\">\n";
+      this->WriteString("<Filter>", 3);
+      (*this->BuildFileStream) << filter << "</Filter>\n";
+      this->WriteString("</", 2);
+      (*this->BuildFileStream) << name << ">\n";
+      }
+    else
+      {
+      (*this->BuildFileStream) << "\" />\n";
+      }
+    }
+  this->WriteString("</ItemGroup>\n", 1);
+}
 
 void cmVisualStudio10TargetGenerator::WriteObjSources()
 { 
@@ -412,6 +514,7 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
       if(lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0))
         {
         std::string sourceFile = (*source)->GetFullPath();
+        this->ConvertToWindowsSlash(sourceFile);
         // output the source file
         this->WriteString("<ClCompile Include=\"", 2);
         (*this->BuildFileStream ) << sourceFile << "\"";
@@ -1025,21 +1128,6 @@ WriteMidlOptions(std::string const& /*config*/,
 {
   this->WriteString("<Midl>\n", 2);
   this->OutputIncludes(includes);
-  // Need this stuff, but there is an midl.xml file...
-  // should we look for .idl language?, and flags?
-  /*
-       <MkTypLibCompatible>false</MkTypLibCompatible>
-      <TargetEnvironment>Win32</TargetEnvironment>
-      <GenerateStublessProxies>true</GenerateStublessProxies>
-      <TypeLibraryName>%(FileName).tlb</TypeLibraryName>
-      <OutputDirectory>$(IntDir)\</OutputDirectory>
-      <HeaderFileName>%(FileName).h</HeaderFileName>
-      <DllDataFileName>
-      </DllDataFileName>
-      <InterfaceIdentifierFileName>%(FileName)_i.c
-      </InterfaceIdentifierFileName>
-      <ProxyFileName>%(FileName)_p.c</ProxyFileName>
-  */
   this->WriteString("</Midl>\n", 2);
 }
   

+ 4 - 0
Source/cmVisualStudio10TargetGenerator.h

@@ -26,6 +26,7 @@ class cmSourceFile;
 class cmCustomCommand;
 class cmLocalVisualStudio7Generator;
 class cmComputeLinkInformation;
+#include "cmSourceGroup.h"
 
 class cmVisualStudio10TargetGenerator
 {
@@ -74,6 +75,9 @@ private:
   void WriteEvent(const char* name, std::vector<cmCustomCommand> & commands,
                   std::string const& configName);
   void ComputeObjectNames();
+  void WriteGroupSources(const char* name,
+                         std::vector<cmSourceFile*> const& sources,
+                         std::vector<cmSourceGroup>& );
 private:
   std::string ModuleDefinitionFile;
   std::string PathToVcxproj;

+ 1 - 1
Tests/SourceGroups/CMakeLists.txt

@@ -31,5 +31,5 @@ source_group(Base\\Sub1\\Base FILES bar.c)
 source_group(EmptyGroup)
 
 
-add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c)
+add_executable(SourceGroups main.c bar.c foo.c sub1/foo.c sub1/foobar.c baz.c README.txt)
 

+ 1 - 0
Tests/SourceGroups/README.txt

@@ -0,0 +1 @@
+