Browse Source

ENH: almost all tests passing in vs 10, commit fixes preprocess and starts vs external project

Bill Hoffman 16 years ago
parent
commit
11d42b3e8f

+ 62 - 0
Source/cmLocalVisualStudio10Generator.cxx

@@ -19,6 +19,51 @@
 #include "cmMakefile.h"
 #include "cmVisualStudio10TargetGenerator.h"
 #include "cmGlobalVisualStudio7Generator.h"
+#include <cm_expat.h>
+#include "cmXMLParser.h"
+class cmVS10XMLParser : public cmXMLParser
+{
+  public:
+  virtual void EndElement(const char* /* name */)
+    {
+    } 
+  virtual void CharacterDataHandler(const char* data, int length)
+    { 
+      if(this->DoGUID )
+        {
+        this->GUID.assign(data, length);
+        this->DoGUID = false;
+        }
+    }
+  virtual void StartElement(const char* name, const char**)
+    {
+      // once the GUID is found do nothing
+      if(this->GUID.size())
+        {
+        return;
+        }
+      if(strcmp("ProjectGUID", name) == 0)
+        {
+        this->DoGUID = true;
+        } 
+    }
+  int InitializeParser()
+    {
+      this->DoGUID = false;
+      int ret = cmXMLParser::InitializeParser();
+      if(ret == 0)
+        {
+        return ret;
+        }
+      // visual studio projects have a strange encoding, but it is 
+      // really utf-8
+      XML_SetEncoding(static_cast<XML_Parser>(this->Parser), "utf-8");
+      return 1;
+    }
+  std::string GUID;
+  bool DoGUID;
+};
+
 
 //----------------------------------------------------------------------------
 cmLocalVisualStudio10Generator::cmLocalVisualStudio10Generator()
@@ -62,3 +107,20 @@ void cmLocalVisualStudio10Generator::Generate()
   this->WriteStampFiles();
 }
 
+
+void cmLocalVisualStudio10Generator
+::ReadAndStoreExternalGUID(const char* name,
+                           const char* path)
+{
+  
+  cmVS10XMLParser parser;
+  parser.ParseFile(path); 
+  std::string guidStoreName = name;
+  guidStoreName += "_GUID_CMAKE";
+  // save the GUID in the cache
+  this->GlobalGenerator->GetCMakeInstance()->
+    AddCacheEntry(guidStoreName.c_str(),
+                  parser.GUID.c_str(),
+                  "Stored GUID",
+                  cmCacheManager::INTERNAL);
+}

+ 2 - 1
Source/cmLocalVisualStudio10Generator.h

@@ -39,7 +39,8 @@ public:
    * Generate the makefile for this directory. 
    */
   virtual void Generate();
-
+  virtual void ReadAndStoreExternalGUID(const char* name,
+                                        const char* path);
 private:
 };
 #endif

+ 5 - 5
Source/cmLocalVisualStudio7Generator.h

@@ -72,17 +72,17 @@ public:
   virtual std::string GetTargetDirectory(cmTarget const&) const;
   cmSourceFile* CreateVCProjBuildRule();
   void WriteStampFiles();
+  // Compute the maximum length full path to the intermediate
+  // files directory for any configuration.  This is used to construct
+  // object file names that do not produce paths that are too long.
   void ComputeMaxDirectoryLength(std::string& maxdir,
                                  cmTarget& target);
 
+  virtual void ReadAndStoreExternalGUID(const char* name,
+                                        const char* path);
 private:
   typedef cmLocalVisualStudio7GeneratorOptions Options;
   typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo;
-  // Compute the maximum length full path to the intermediate
-  // files directory for any configuration.  This is used to construct
-  // object file names that do not produce paths that are too long.
-  void ReadAndStoreExternalGUID(const char* name,
-                                const char* path);
   std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
                                       const char* configName);
   void FixGlobalTargets();

+ 52 - 28
Source/cmVisualStudio10TargetGenerator.cxx

@@ -23,31 +23,46 @@
 #include "cmSourceFile.h"
 #include "cmVisualStudioGeneratorOptions.h"
 #include "cmLocalVisualStudio7Generator.h"
-
 #include "cmVS10CLFlagTable.h"
 #include "cmVS10LinkFlagTable.h"
 #include "cmVS10LibFlagTable.h"
 
 
-
 cmVisualStudio10TargetGenerator::
 cmVisualStudio10TargetGenerator(cmTarget* target,
                                 cmGlobalVisualStudio7Generator* gg)
 {
   this->GlobalGenerator = gg;
-  this->GlobalGenerator->CreateGUID(target->GetName());
-  this->GUID = this->GlobalGenerator->GetGUID(target->GetName());
   this->Target = target;
   this->Makefile = target->GetMakefile();
   this->LocalGenerator =  
     (cmLocalVisualStudio7Generator*)
     this->Makefile->GetLocalGenerator();
+  const char* name = this->Target->GetName();
+  if (strncmp(name, "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
+    {
+    cmCustomCommand cc = this->Target->GetPostBuildCommands()[0];
+    const cmCustomCommandLines& cmds = cc.GetCommandLines();
+    this->Name = cmds[0][0];
+    this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
+    }
+  else
+    {
+    this->Name = name;
+    this->GlobalGenerator->CreateGUID(this->Name.c_str());
+    this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str());
+    }
   this->Platform = "|Win32";
   this->ComputeObjectNames();
+  this->BuildFileStream = 0;
 }
 
 cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
 {
+  if(!this->BuildFileStream)
+    {
+    return;
+    }
   if (this->BuildFileStream->Close())
     {
     this->GlobalGenerator
@@ -97,16 +112,17 @@ void cmVisualStudio10TargetGenerator::WriteString(const char* line,
   (*this->BuildFileStream ) << line;
 }
 
+
 void cmVisualStudio10TargetGenerator::Generate()
-{
+{      
   // Tell the global generator the name of the project file
-  this->Target->SetProperty("GENERATOR_FILE_NAME",this->Target->GetName());
+  this->Target->SetProperty("GENERATOR_FILE_NAME",this->Name.c_str());
   this->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
                             ".vcxproj");
   cmMakefile* mf = this->Target->GetMakefile();
   std::string path =  mf->GetStartOutputDirectory();
   path += "/";
-  path += this->Target->GetName();
+  path += this->Name;
   path += ".vcxproj";
   this->BuildFileStream =
     new cmGeneratedFileStream(path.c_str());
@@ -371,7 +387,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   // Write out group file
   std::string path =  this->Makefile->GetStartOutputDirectory();
   path += "/";
-  path += this->Target->GetName();
+  path += this->Name;
   path += ".vcxproj.filters";
   cmGeneratedFileStream fout(path.c_str());
   char magic[] = {0xEF,0xBB, 0xBF};
@@ -434,16 +450,9 @@ WriteGroupSources(const char* name,
     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());
-      }
+    path = cmSystemTools::RelativePath(
+      this->Makefile->GetCurrentOutputDirectory(),
+      source.c_str());
     this->ConvertToWindowsSlash(path);
     (*this->BuildFileStream) << name << " Include=\""
                              << path;
@@ -514,6 +523,9 @@ void cmVisualStudio10TargetGenerator::WriteCLSources()
       if(lang && (strcmp(lang, "C") == 0 || strcmp(lang, "CXX") ==0))
         {
         std::string sourceFile = (*source)->GetFullPath();
+        sourceFile =  cmSystemTools::RelativePath(
+          this->Makefile->GetCurrentOutputDirectory(),
+          sourceFile.c_str());
         this->ConvertToWindowsSlash(sourceFile);
         // output the source file
         this->WriteString("<ClCompile Include=\"", 2);
@@ -642,7 +654,7 @@ bool cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
       {
       if(configDefines.size())
         {
-        configDefines += ",";
+        configDefines += ";";
         }
       configDefines += ccdefs;
       }
@@ -746,7 +758,7 @@ OutputLinkIncremental(std::string const& configName)
     {
     cmSystemTools::Error
       ("CMake can not determine linker language for target:",
-       this->Target->GetName());
+       this->Name.c_str());
     return;
     }
   std::string linkFlagVarBase = "CMAKE_";
@@ -803,7 +815,7 @@ WriteClOptions(std::string const& configName,
       {
       cmSystemTools::Error
         ("CMake can not determine linker language for target:",
-         this->Target->GetName());
+         this->Name.c_str());
       return;
       }
     if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
@@ -944,7 +956,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
     {
     cmSystemTools::Error
       ("CMake can not determine linker language for target:",
-       this->Target->GetName());
+       this->Name.c_str());
     return;
     }
 
@@ -1027,7 +1039,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
     {
     cmSystemTools::Error
       ("CMake can not compute cmComputeLinkInformation for target:",
-       this->Target->GetName());
+       this->Name.c_str());
     return;
     }
   // add the libraries for the target to libs string
@@ -1224,14 +1236,26 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
     cmTarget* dt = *i;
     this->WriteString("<ProjectReference Include=\"", 2);
     cmMakefile* mf = dt->GetMakefile();
-    std::string path =  mf->GetStartOutputDirectory();
-    path += "/";
-    path += dt->GetName();
-    path += ".vcxproj";
+    std::string name = dt->GetName();
+    std::string path;
+    if (strncmp(name.c_str(), "INCLUDE_EXTERNAL_MSPROJECT", 26) == 0)
+      {
+      cmCustomCommand cc = dt->GetPostBuildCommands()[0];
+      const cmCustomCommandLines& cmds = cc.GetCommandLines();
+      path = cmds[0][1];
+      name = cmds[0][0].c_str();
+      }
+    else
+      {
+      path =  mf->GetStartOutputDirectory();
+      path += "/";
+      path += dt->GetName();
+      path += ".vcxproj";
+      }
     (*this->BuildFileStream) << path << "\">\n";
     this->WriteString("<Project>", 3);
     (*this->BuildFileStream) 
-      << this->GlobalGenerator->GetGUID(dt->GetName())
+      << this->GlobalGenerator->GetGUID(name.c_str())
       << "</Project>\n";
     this->WriteString("</ProjectReference>\n", 2);
     }

+ 1 - 0
Source/cmVisualStudio10TargetGenerator.h

@@ -85,6 +85,7 @@ private:
   cmMakefile* Makefile;
   std::string Platform;
   std::string GUID;
+  std::string Name;
   cmGlobalVisualStudio7Generator* GlobalGenerator;
   cmGeneratedFileStream* BuildFileStream;
   cmLocalVisualStudio7Generator* LocalGenerator;

+ 14 - 1
Source/cmVisualStudioGeneratorOptions.cxx

@@ -3,6 +3,15 @@
 #include <cmsys/System.h>
 #include "cmVisualStudio10TargetGenerator.h"
 
+inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s)
+{
+  std::string ret = s;
+  cmSystemTools::ReplaceString(ret, "&", "&amp;");
+  cmSystemTools::ReplaceString(ret, "<", "&lt;");
+  cmSystemTools::ReplaceString(ret, ">", "&gt;");
+  return ret;
+}
+
 inline std::string cmVisualStudioGeneratorOptionsEscapeForXML(const char* s)
 {
   std::string ret = s;
@@ -321,7 +330,11 @@ cmVisualStudioGeneratorOptions
       define = *di;
       }
     // Escape this flag for the IDE.
-    if(this->Version != 10)
+    if(this->Version == 10)
+      {
+      define = cmVisualStudio10GeneratorOptionsEscapeForXML(define.c_str());
+      }
+    else
       {
       define = cmVisualStudioGeneratorOptionsEscapeForXML(define.c_str());
       }

+ 4 - 1
Tests/PrecompiledHeader/CMakeLists.txt

@@ -9,10 +9,13 @@ ENDIF(NOT MSVC)
 # Compute a custom name for the precompiled header.
 IF(CMAKE_CONFIGURATION_TYPES)
   SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH/${CMAKE_CFG_INTDIR}")
+  FOREACH(cfg ${CMAKE_CONFIGURATION_TYPES})
+    FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH/${cfg})
+  ENDFOREACH()
 ELSE(CMAKE_CONFIGURATION_TYPES)
   SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH")
+  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH)
 ENDIF(CMAKE_CONFIGURATION_TYPES)
-FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH)
 
 # The VS6 IDE does not support renaming .pch files with /Fp.
 IF("${CMAKE_GENERATOR}" MATCHES "Visual Studio 6")

+ 6 - 2
Tests/Preprocess/CMakeLists.txt

@@ -34,6 +34,9 @@ endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 7$")
 if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
   set(PP_VS 1)
 endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+if("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
+  set(PP_VS100 1)
+endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio 10")
 
 # Some tests below check the PP_* variables set above.  They are meant
 # to test the case that the build tool is at fault.  Other tests below
@@ -49,7 +52,7 @@ endif("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
 # must not have it escaped inside the configured header.
 set(STRING_EXTRA "")
 
-if(NOT BORLAND AND NOT PP_VS70)
+if(NOT BORLAND AND NOT PP_VS70 AND NOT PP_VS100)
   # Borland, VS70 IDE: ;
   # The Borland compiler will simply not accept a non-escaped semicolon
   # on the command line.  If it is escaped \; then the escape character
@@ -57,8 +60,9 @@ if(NOT BORLAND AND NOT PP_VS70)
   #
   # The VS 7.0 IDE separates definitions on semicolons and commas with
   # no regard for quotes.  Fortunately VS 7.1 and above are okay.
+  # VS 10 seems to also not like semicolons
   set(SEMICOLON "\;")
-endif(NOT BORLAND AND NOT PP_VS70)
+endif()
 
 if(NOT PP_VS6)
   # VS 6 IDE: spaces and '"', '$', or ';'

+ 4 - 1
Tests/VSExternalInclude/CMakeLists.txt

@@ -6,7 +6,9 @@ IF(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
 ELSE(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
   SET(PROJECT_EXT vcproj)
 ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio 6")
-
+IF(${CMAKE_GENERATOR} MATCHES "Visual Studio 10")
+  SET(PROJECT_EXT vcxproj)
+ENDIF()
 
 # make sure directories exists
 SET(LIB1_BINARY_DIR ${VSExternalInclude_BINARY_DIR}/Lib1)
@@ -38,3 +40,4 @@ ADD_EXECUTABLE(VSExternalInclude ${SOURCES})
 
 # target depends on lib2
 ADD_DEPENDENCIES(VSExternalInclude lib2)
+