diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx index 8106e7eb6..d8f35f155 100644 --- a/Source/cmLocalVisualStudio10Generator.cxx +++ b/Source/cmLocalVisualStudio10Generator.cxx @@ -19,6 +19,51 @@ #include "cmMakefile.h" #include "cmVisualStudio10TargetGenerator.h" #include "cmGlobalVisualStudio7Generator.h" +#include +#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(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); +} diff --git a/Source/cmLocalVisualStudio10Generator.h b/Source/cmLocalVisualStudio10Generator.h index ac2e6ec3a..d7d0f243d 100644 --- a/Source/cmLocalVisualStudio10Generator.h +++ b/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 diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 2d951ecb9..34547af19 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -72,17 +72,17 @@ public: virtual std::string GetTargetDirectory(cmTarget const&) const; cmSourceFile* CreateVCProjBuildRule(); void WriteStampFiles(); - void ComputeMaxDirectoryLength(std::string& maxdir, - cmTarget& target); - -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); + void ComputeMaxDirectoryLength(std::string& maxdir, + cmTarget& target); + + virtual void ReadAndStoreExternalGUID(const char* name, + const char* path); +private: + typedef cmLocalVisualStudio7GeneratorOptions Options; + typedef cmLocalVisualStudio7GeneratorFCInfo FCInfo; std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags, const char* configName); void FixGlobalTargets(); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 289510fa0..9a89150b3 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/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("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("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("", 3); (*this->BuildFileStream) - << this->GlobalGenerator->GetGUID(dt->GetName()) + << this->GlobalGenerator->GetGUID(name.c_str()) << "\n"; this->WriteString("\n", 2); } diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 81e15f8bf..7039cfb9f 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/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; diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx index 179dc5b73..7a57d90d4 100644 --- a/Source/cmVisualStudioGeneratorOptions.cxx +++ b/Source/cmVisualStudioGeneratorOptions.cxx @@ -3,6 +3,15 @@ #include #include "cmVisualStudio10TargetGenerator.h" +inline std::string cmVisualStudio10GeneratorOptionsEscapeForXML(const char* s) +{ + std::string ret = s; + cmSystemTools::ReplaceString(ret, "&", "&"); + cmSystemTools::ReplaceString(ret, "<", "<"); + cmSystemTools::ReplaceString(ret, ">", ">"); + 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()); } diff --git a/Tests/PrecompiledHeader/CMakeLists.txt b/Tests/PrecompiledHeader/CMakeLists.txt index b0b7989ba..00c398049 100644 --- a/Tests/PrecompiledHeader/CMakeLists.txt +++ b/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") diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt index 04c3f1015..f154b6ff4 100644 --- a/Tests/Preprocess/CMakeLists.txt +++ b/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 ';' diff --git a/Tests/VSExternalInclude/CMakeLists.txt b/Tests/VSExternalInclude/CMakeLists.txt index 5f4a6aa91..4814cc859 100644 --- a/Tests/VSExternalInclude/CMakeLists.txt +++ b/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) +