From aa47caab2db3961bfdd53036e5637df208b319d4 Mon Sep 17 00:00:00 2001 From: Bill Hoffman Date: Wed, 13 Jul 2005 11:21:30 -0400 Subject: [PATCH] FIX: apply patch from bug# 1965 --- Source/cmLocalVisualStudio6Generator.cxx | 294 ++++++----- Source/cmLocalVisualStudio6Generator.h | 3 +- Source/cmLocalVisualStudio7Generator.cxx | 626 ++++++++++++----------- Source/cmLocalVisualStudio7Generator.h | 2 + Source/cmMakefile.cxx | 435 +++++++++------- Source/cmMakefile.h | 26 +- Source/cmSourceGroup.cxx | 85 +++ Source/cmSourceGroup.h | 23 + Source/cmSourceGroupCommand.cxx | 74 ++- 9 files changed, 940 insertions(+), 628 deletions(-) diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 8ac9e7bef..c08cd6674 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -207,8 +207,8 @@ void cmLocalVisualStudio6Generator::AddDSPBuildRule() void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, - const char *libName, - cmTarget &target) + const char *libName, + cmTarget &target) { // if we should add regen rule then... const char *suppRegenRule = @@ -316,112 +316,129 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout, for(std::vector::const_iterator sg = sourceGroups.begin(); sg != sourceGroups.end(); ++sg) { - const std::vector &sourceFiles = - sg->GetSourceFiles(); - // If the group is empty, don't write it at all. - if(sourceFiles.empty()) - { - continue; - } - - // If the group has a name, write the header. - std::string name = sg->GetName(); - if(name != "") - { - this->WriteDSPBeginGroup(fout, name.c_str(), ""); - } - - // Loop through each source in the source group. - for(std::vector::const_iterator sf = - sourceFiles.begin(); sf != sourceFiles.end(); ++sf) - { - std::string source = (*sf)->GetFullPath(); - const cmCustomCommand *command = - (*sf)->GetCustomCommand(); - std::string compileFlags; - std::vector depends; - const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"); - if(cflags) - { - compileFlags = cflags; - } - const char* lang = - m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); - if(lang && strcmp(lang, "CXX") == 0) - { - // force a C++ file type - compileFlags += " /TP "; - } - - // Check for extra object-file dependencies. - const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS"); - if(dependsValue) - { - cmSystemTools::ExpandListArgument(dependsValue, depends); - } - if (source != libName || target.GetType() == cmTarget::UTILITY) - { - fout << "# Begin Source File\n\n"; - - // Tell MS-Dev what the source is. If the compiler knows how to - // build it, then it will. - fout << "SOURCE=" << - this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n"; - if(!depends.empty()) - { - // Write out the dependencies for the rule. - fout << "USERDEP__HACK="; - for(std::vector::const_iterator d = depends.begin(); - d != depends.end(); ++d) - { - fout << "\\\n\t" << - this->ConvertToOptionallyRelativeOutputPath(d->c_str()); - } - fout << "\n"; - } - if (command) - { - std::string script = - this->ConstructScript(command->GetCommandLines(), "\\\n\t"); - const char* comment = command->GetComment(); - const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; - this->WriteCustomRule(fout, source.c_str(), script.c_str(), - (*comment?comment:"Custom Rule"), - command->GetDepends(), - command->GetOutput(), flags); - } - else if(compileFlags.size()) - { - for(std::vector::iterator i - = m_Configurations.begin(); i != m_Configurations.end(); ++i) - { - if (i == m_Configurations.begin()) - { - fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl; - } - else - { - fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl; - } - fout << "\n# ADD CPP " << compileFlags << "\n\n"; - } - fout << "!ENDIF\n\n"; - } - fout << "# End Source File\n"; - } - } - - // If the group has a name, write the footer. - if(name != "") - { - this->WriteDSPEndGroup(fout); - } + this->WriteGroup(&(*sg), target, fout, libName); } // Write the DSP file's footer. this->WriteDSPFooter(fout); } +void cmLocalVisualStudio6Generator::WriteGroup(const cmSourceGroup *sg, cmTarget target, std::ostream &fout, const char *libName) +{ + const std::vector &sourceFiles = + sg->GetSourceFiles(); + // If the group is empty, don't write it at all. + + if(sourceFiles.empty()) + { + return; + } + + // If the group has a name, write the header. + std::string name = sg->GetName(); + if(name != "") + { + this->WriteDSPBeginGroup(fout, name.c_str(), ""); + } + + // Loop through each source in the source group. + for(std::vector::const_iterator sf = + sourceFiles.begin(); sf != sourceFiles.end(); ++sf) + { + std::string source = (*sf)->GetFullPath(); + const cmCustomCommand *command = + (*sf)->GetCustomCommand(); + std::string compileFlags; + std::vector depends; + const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"); + if(cflags) + { + compileFlags = cflags; + } + const char* lang = + m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); + if(lang && strcmp(lang, "CXX") == 0) + { + // force a C++ file type + compileFlags += " /TP "; + } + + // Check for extra object-file dependencies. + const char* dependsValue = (*sf)->GetProperty("OBJECT_DEPENDS"); + if(dependsValue) + { + cmSystemTools::ExpandListArgument(dependsValue, depends); + } + if (source != libName || target.GetType() == cmTarget::UTILITY) + { + fout << "# Begin Source File\n\n"; + + // Tell MS-Dev what the source is. If the compiler knows how to + // build it, then it will. + fout << "SOURCE=" << + this->ConvertToOptionallyRelativeOutputPath(source.c_str()) << "\n\n"; + if(!depends.empty()) + { + // Write out the dependencies for the rule. + fout << "USERDEP__HACK="; + for(std::vector::const_iterator d = depends.begin(); + d != depends.end(); ++d) + { + fout << "\\\n\t" << + this->ConvertToOptionallyRelativeOutputPath(d->c_str()); + } + fout << "\n"; + } + if (command) + { + std::string script = + this->ConstructScript(command->GetCommandLines(), "\\\n\t"); + const char* comment = command->GetComment(); + const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; + this->WriteCustomRule(fout, source.c_str(), script.c_str(), + (*comment?comment:"Custom Rule"), + command->GetDepends(), + command->GetOutput(), flags); + } + else if(compileFlags.size()) + { + for(std::vector::iterator i + = m_Configurations.begin(); i != m_Configurations.end(); ++i) + { + if (i == m_Configurations.begin()) + { + fout << "!IF \"$(CFG)\" == " << i->c_str() << std::endl; + } + else + { + fout << "!ELSEIF \"$(CFG)\" == " << i->c_str() << std::endl; + } + fout << "\n# ADD CPP " << compileFlags << "\n\n"; + } + fout << "!ENDIF\n\n"; + } + fout << "# End Source File\n"; + } + } + + std::vector children = sg->GetGroupChildren(); + + for(unsigned int i=0;iWriteGroup(&children[i], target, fout, libName); + } + + + + + // If the group has a name, write the footer. + if(name != "") + { + this->WriteDSPEndGroup(fout); + } + +} + void cmLocalVisualStudio6Generator @@ -458,13 +475,13 @@ cmLocalVisualStudio6Generator } void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout, - const char* source, - const char* command, - const char* comment, - const std::vector& depends, - const char *output, - const char* flags - ) + const char* source, + const char* command, + const char* comment, + const std::vector& depends, + const char *output, + const char* flags + ) { std::vector::iterator i; for(i = m_Configurations.begin(); i != m_Configurations.end(); ++i) @@ -544,8 +561,8 @@ void cmLocalVisualStudio6Generator::WriteCustomRule(std::ostream& fout, void cmLocalVisualStudio6Generator::WriteDSPBeginGroup(std::ostream& fout, - const char* group, - const char* filter) + const char* group, + const char* filter) { fout << "# Begin Group \"" << group << "\"\n" "# PROP Default_Filter \"" << filter << "\"\n"; @@ -763,9 +780,11 @@ void cmLocalVisualStudio6Generator libPath = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"); } std::string exePath = ""; + std::string exePathDebug = ""; if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")) { exePath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"); + } if(libPath.size()) { @@ -952,13 +971,37 @@ void cmLocalVisualStudio6Generator extraLinkOptions = m_Makefile->GetRequiredDefinition("CMAKE_EXE_LINKER_FLAGS"); + // if the executable has an output name then add the appropriate flag if (target.GetProperty("OUTPUT_NAME")) { + std::string outputname = target.GetProperty("OUTPUT_NAME"); libMultiLineOptions += "# ADD LINK32 /out:"; - libMultiLineOptions += target.GetProperty("OUTPUT_NAME"); + libMultiLineOptions += outputname; libMultiLineOptions += " \n"; } + else + { + + libMultiLineOptions += "# ADD LINK32 /out:\""; + + if(exePath != "") + libMultiLineOptions += exePath + "/" + libName + ".exe"; + else + libMultiLineOptions += std::string(libName) + ".exe"; + + libMultiLineOptions += "\"\n"; + + + libMultiLineOptionsForDebug += "# ADD LINK32 /out:\""; + + if(exePath != "") + libMultiLineOptionsForDebug += exePath + "/" + libName + "D.exe"; + else + libMultiLineOptionsForDebug += std::string(libName) + "D.exe"; + + libMultiLineOptionsForDebug += "\"\n"; + } } if(target.GetType() == cmTarget::SHARED_LIBRARY) { @@ -1087,16 +1130,35 @@ void cmLocalVisualStudio6Generator cmSystemTools::ReplaceString(line, "LIBRARY_OUTPUT_PATH", removeQuotes( this->ConvertToOptionallyRelativeOutputPath(libPath.c_str())).c_str()); - cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATH", - removeQuotes( - this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + + + if (!m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH_OVERRIDE") || exePath == "") + { + cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATH", + removeQuotes( + this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + } else + { + cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATHRelease", + removeQuotes( + this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATHDebug", + removeQuotes( + this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATHMinSizeRel", + removeQuotes( + this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + cmSystemTools::ReplaceString(line, "EXECUTABLE_OUTPUT_PATHRelWithDebInfo", + removeQuotes( + this->ConvertToOptionallyRelativeOutputPath(exePath.c_str())).c_str()); + } cmSystemTools::ReplaceString(line, "EXTRA_DEFINES", m_Makefile->GetDefineFlags()); const char* debugPostfix = m_Makefile->GetDefinition("CMAKE_DEBUG_POSTFIX"); cmSystemTools::ReplaceString(line, "DEBUG_POSTFIX", - debugPostfix?debugPostfix:""); + debugPostfix?debugPostfix:""); // store flags for each configuration std::string flags = " "; std::string flagsRelease = " "; diff --git a/Source/cmLocalVisualStudio6Generator.h b/Source/cmLocalVisualStudio6Generator.h index bf09f5cb9..035b51635 100644 --- a/Source/cmLocalVisualStudio6Generator.h +++ b/Source/cmLocalVisualStudio6Generator.h @@ -90,7 +90,8 @@ private: void AddUtilityCommandHack(cmTarget& target, int count, std::vector& depends, const cmCustomCommandLines& commandLines); - + void WriteGroup(const cmSourceGroup *sg, cmTarget target, + std::ostream &fout, const char *libName); std::string CreateTargetRules(cmTarget &target, const char *libName); std::string m_IncludeOptions; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index d081d208f..04a36f17e 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -285,9 +285,9 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, - const char* configName, - const char *libName, - cmTarget &target) + const char* configName, + const char *libName, + cmTarget &target) { // create a map of xml tags to the values they should have in the output // for example, "BufferSecurityCheck" = "TRUE" @@ -386,7 +386,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, flags += flagsDebug; pre = "WIN32,_DEBUG,_WINDOWS"; std::string libpath = m_LibraryOutputPath + - "$(OutDir)/" + libName + debugPostfix + ".pdb"; + "$(OutDir)/" + libName + debugPostfix + ".pdb"; programDatabase = "\t\t\t\tProgramDatabaseFileName=\""; programDatabase += libpath; programDatabase += "\""; @@ -416,7 +416,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, pre = "WIN32,_WINDOWS"; flags += flagsDebugRel; std::string libpath = m_LibraryOutputPath + - "$(OutDir)/" + libName + debugPostfix + ".pdb"; + "$(OutDir)/" + libName + debugPostfix + ".pdb"; programDatabase = "\t\t\t\tProgramDatabaseFileName=\""; programDatabase += libpath; programDatabase += "\""; @@ -508,7 +508,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, fout << "\t\t\t\tObjectFile=\"" << configName << "\\\"\n"; if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) { - fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; + fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; } if(programDatabase.size()) @@ -574,9 +574,9 @@ void cmLocalVisualStudio7Generator::FillFlagMapFromCommandFlags( void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, - const char* configName, - const char *libName, - cmTarget &target) + const char* configName, + const char *libName, + cmTarget &target) { std::string temp; std::string debugPostfix = ""; @@ -616,185 +616,191 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, { case cmTarget::STATIC_LIBRARY: { - std::string libpath = m_LibraryOutputPath + - "$(OutDir)/" + libName + debugPostfix + ".lib"; - fout << "\t\t\tConvertToXMLOutputPathSingle(libpath.c_str()) << ".\"/>\n"; - break; + std::string libpath = m_LibraryOutputPath + + "$(OutDir)/" + libName + debugPostfix + ".lib"; + fout << "\t\t\tConvertToXMLOutputPathSingle(libpath.c_str()) << ".\"/>\n"; + break; } case cmTarget::SHARED_LIBRARY: case cmTarget::MODULE_LIBRARY: + { + fout << "\t\t\tOutputLibraries(fout, configName, libName, target); - fout << "\"\n"; - temp = m_LibraryOutputPath; - temp += configName; - temp += "/"; - temp += libName; - temp += debugPostfix; - temp += ".dll"; - fout << "\t\t\t\tOutputFile=\"" - << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; - for(std::map::iterator i = flagMap.begin(); - i != flagMap.end(); ++i) - { - fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n"; - } - - if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) - { - fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; - } - else - { - fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n"; - } - - fout << "\t\t\t\tAdditionalLibraryDirectories=\""; - this->OutputLibraryDirectories(fout, configName, libName, target); - fout << "\"\n"; - this->OutputModuleDefinitionFile(fout, target); - temp = m_LibraryOutputPath; - temp += "$(OutDir)/"; - temp += libName; - temp += debugPostfix; - temp += ".pdb"; - fout << "\t\t\t\tProgramDatabaseFile=\"" << - this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; - if(strcmp(configName, "Debug") == 0 - || strcmp(configName, "RelWithDebInfo") == 0) - { - fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; - } - const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); - if(!linkLanguage) - { - cmSystemTools::Error("CMake can not determine linker language for target:", - target.GetName()); - return; - } - std::string stackVar = "CMAKE_"; - stackVar += linkLanguage; - stackVar += "_STACK_SIZE"; - const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); - if(stackVal) - { - fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n"; - } - temp = m_LibraryOutputPath; - temp += configName; - temp += "/"; - temp += libName; - temp += debugPostfix; - temp += ".lib"; - fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n"; + fout << " " << cmLocalVisualStudio7Generator::EscapeForXML( + extraLinkOptions.c_str()).c_str(); } - break; + fout << "\"\n" + << "\t\t\t\tAdditionalDependencies=\" odbc32.lib odbccp32.lib "; + this->OutputLibraries(fout, configName, libName, target); + fout << "\"\n"; + temp = m_LibraryOutputPath; + temp += configName; + temp += "/"; + temp += libName; + temp += debugPostfix; + temp += ".dll"; + fout << "\t\t\t\tOutputFile=\"" + << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; + for(std::map::iterator i = flagMap.begin(); + i != flagMap.end(); ++i) + { + fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n"; + } + + if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) + { + fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; + } + else + { + fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n"; + } + + fout << "\t\t\t\tAdditionalLibraryDirectories=\""; + this->OutputLibraryDirectories(fout, configName, libName, target); + fout << "\"\n"; + this->OutputModuleDefinitionFile(fout, target); + temp = m_LibraryOutputPath; + temp += "$(OutDir)/"; + temp += libName; + temp += debugPostfix; + temp += ".pdb"; + fout << "\t\t\t\tProgramDatabaseFile=\"" << + this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; + if(strcmp(configName, "Debug") == 0 + || strcmp(configName, "RelWithDebInfo") == 0) + { + fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; + } + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + if(!linkLanguage) + { + cmSystemTools::Error("CMake can not determine linker language for target:", + target.GetName()); + return; + } + std::string stackVar = "CMAKE_"; + stackVar += linkLanguage; + stackVar += "_STACK_SIZE"; + const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); + if(stackVal) + { + fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n"; + } + temp = m_LibraryOutputPath; + temp += configName; + temp += "/"; + temp += libName; + temp += debugPostfix; + temp += ".lib"; + fout << "\t\t\t\tImportLibrary=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n"; + } + break; case cmTarget::EXECUTABLE: - { + { - fout << "\t\t\tGetRequiredDefinition("CMAKE_STANDARD_LIBRARIES") - << " "; - this->OutputLibraries(fout, configName, libName, target); - fout << "\"\n"; - temp = m_ExecutableOutputPath; - temp += configName; - temp += "/"; - - // do we have a different executable name? - if (target.GetProperty("OUTPUT_NAME")) - { - temp += target.GetProperty("OUTPUT_NAME"); - } - else - { - temp += libName; - } - temp += ".exe"; - fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; - for(std::map::iterator i = flagMap.begin(); - i != flagMap.end(); ++i) - { - fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n"; - } - if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) - { - fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; - } - else - { - fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n"; - } - - fout << "\t\t\t\tAdditionalLibraryDirectories=\""; - this->OutputLibraryDirectories(fout, configName, libName, target); - fout << "\"\n"; - fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath - << "$(OutDir)\\" << libName << ".pdb\"\n"; - if(strcmp(configName, "Debug") == 0 - || strcmp(configName, "RelWithDebInfo") == 0) - { - fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; - } - if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) - { - fout << "\t\t\t\tSubSystem=\"2\"\n"; - } - else - { - fout << "\t\t\t\tSubSystem=\"1\"\n"; - } - const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); - if(!linkLanguage) - { - cmSystemTools::Error("CMake can not determine linker language for target:", - target.GetName()); - return; - } - std::string stackVar = "CMAKE_"; - stackVar += linkLanguage; - stackVar += "_STACK_SIZE"; - const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); - if(stackVal) - { - fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; - } - fout << "/>\n"; - break; + fout << "\t\t\tGetRequiredDefinition("CMAKE_STANDARD_LIBRARIES") + << " "; + this->OutputLibraries(fout, configName, libName, target); + fout << "\"\n"; + temp = m_ExecutableOutputPath; + + if (!m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH_OVERRIDE")) + temp += configName; + + temp += "/"; + + // do we have a different executable name? + if (target.GetProperty("OUTPUT_NAME")) + { + temp += target.GetProperty("OUTPUT_NAME"); + } + else + { + temp += libName; + } + + temp += debugPostfix; + + temp += ".exe"; + fout << "\t\t\t\tOutputFile=\"" << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n"; + for(std::map::iterator i = flagMap.begin(); + i != flagMap.end(); ++i) + { + fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n"; + } + if(m_Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE")) + { + fout << "\t\t\t\tSuppressStartupBanner=\"FALSE\"\n"; + } + else + { + fout << "\t\t\t\tSuppressStartupBanner=\"TRUE\"\n"; + } + + fout << "\t\t\t\tAdditionalLibraryDirectories=\""; + this->OutputLibraryDirectories(fout, configName, libName, target); + fout << "\"\n"; + fout << "\t\t\t\tProgramDatabaseFile=\"" << m_LibraryOutputPath + << "$(OutDir)\\" << libName << ".pdb\"\n"; + if(strcmp(configName, "Debug") == 0 + || strcmp(configName, "RelWithDebInfo") == 0) + { + fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; + } + if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) + { + fout << "\t\t\t\tSubSystem=\"2\"\n"; + } + else + { + fout << "\t\t\t\tSubSystem=\"1\"\n"; + } + const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator()); + if(!linkLanguage) + { + cmSystemTools::Error("CMake can not determine linker language for target:", + target.GetName()); + return; + } + std::string stackVar = "CMAKE_"; + stackVar += linkLanguage; + stackVar += "_STACK_SIZE"; + const char* stackVal = m_Makefile->GetDefinition(stackVar.c_str()); + if(stackVal) + { + fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\""; + } + fout << "/>\n"; + break; + } case cmTarget::UTILITY: break; } } void cmLocalVisualStudio7Generator::OutputModuleDefinitionFile(std::ostream& fout, - cmTarget &target) + cmTarget &target) { std::vector const& classes = target.GetSourceFiles(); for(std::vector::const_iterator i = classes.begin(); @@ -812,9 +818,9 @@ void cmLocalVisualStudio7Generator::OutputModuleDefinitionFile(std::ostream& fou } void cmLocalVisualStudio7Generator::OutputLibraryDirectories(std::ostream& fout, - const char*, - const char*, - cmTarget &tgt) + const char*, + const char*, + cmTarget &tgt) { bool hasone = false; if(m_LibraryOutputPath.size()) @@ -865,9 +871,9 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(std::ostream& fout, } void cmLocalVisualStudio7Generator::OutputLibraries(std::ostream& fout, - const char* configName, - const char* libName, - cmTarget &target) + const char* configName, + const char* libName, + cmTarget &target) { const cmTarget::LinkLibraries& libs = target.GetLinkLibraries(); cmTarget::LinkLibraries::const_iterator j; @@ -988,135 +994,149 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout, // Loop through every source group. - for(std::vector::const_iterator sg = sourceGroups.begin(); - sg != sourceGroups.end(); ++sg) + for(unsigned int i = 0; i < sourceGroups.size(); ++i) { - const std::vector &sourceFiles = - sg->GetSourceFiles(); - // If the group is empty, don't write it at all. - if(sourceFiles.empty()) - { - continue; - } - - // If the group has a name, write the header. - std::string name = sg->GetName(); - if(name != "") - { - this->WriteVCProjBeginGroup(fout, name.c_str(), ""); - } - - // Loop through each source in the source group. - for(std::vector::const_iterator sf = - sourceFiles.begin(); sf != sourceFiles.end(); ++sf) - { - std::string source = (*sf)->GetFullPath(); - const cmCustomCommand *command = (*sf)->GetCustomCommand(); - std::string compileFlags; - std::string additionalDeps; + cmSourceGroup sg = sourceGroups[i]; + this->WriteGroup(&sg, target, fout, libName, configs); + } - // Check for extra compiler flags. - const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"); - if(cflags) - { - compileFlags = cflags; - } - const char* lang = - m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); - if(lang && strcmp(lang, "CXX") == 0) - { - // force a C++ file type - compileFlags += " /TP "; - } - // Check for extra object-file dependencies. - const char* deps = (*sf)->GetProperty("OBJECT_DEPENDS"); - if(deps) - { - std::vector depends; - cmSystemTools::ExpandListArgument(deps, depends); - if(!depends.empty()) - { - std::vector::iterator i = depends.begin(); - additionalDeps = this->ConvertToXMLOutputPath(i->c_str()); - for(++i;i != depends.end(); ++i) - { - additionalDeps += ";"; - additionalDeps += this->ConvertToXMLOutputPath(i->c_str()); - } - } - } - if (source != libName || target.GetType() == cmTarget::UTILITY) - { - fout << "\t\t\tConvertToXMLOutputPathSingle(source.c_str()); - // Tell MS-Dev what the source is. If the compiler knows how to - // build it, then it will. - fout << "\t\t\t\tRelativePath=\"" << d << "\">\n"; - if (command) - { - // Construct the entire set of commands in one string. - std::string script = this->ConstructScript(command->GetCommandLines()); - const char* comment = command->GetComment(); - const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; - this->WriteCustomRule(fout, source.c_str(), script.c_str(), - (*comment?comment:"Custom Rule"), - command->GetDepends(), - command->GetOutput(), flags); - } - else if(compileFlags.size() || additionalDeps.length()) - { - const char* aCompilerTool = "VCCLCompilerTool"; - std::string ext = (*sf)->GetSourceExtension(); - ext = cmSystemTools::LowerCase(ext); - if(ext == "idl") - { - aCompilerTool = "VCMIDLTool"; - } - if(ext == "rc") - { - aCompilerTool = "VCResourceCompilerTool"; - } - if(ext == "def") - { - aCompilerTool = "VCCustomBuildTool"; - } - for(std::vector::iterator i = configs->begin(); - i != configs->end(); ++i) - { - fout << "\t\t\t\t\n" - << "\t\t\t\t\tEscapeForXML(compileFlags.c_str()) << "\"\n"; - } - if(additionalDeps.length()) - { - fout << "\t\t\t\t\tAdditionalDependencies=\"" - << additionalDeps.c_str() << "\"\n"; - } - fout << "\t\t\t\t\t/>\n" - << "\t\t\t\t\n"; - } - } - fout << "\t\t\t\n"; - } - } + //} - // If the group has a name, write the footer. - if(name != "") - { - this->WriteVCProjEndGroup(fout); - } - } fout << "\t\n"; // Write the VCProj file's footer. this->WriteVCProjFooter(fout); } +void cmLocalVisualStudio7Generator::WriteGroup(const cmSourceGroup *sg, cmTarget target, std::ostream &fout, const char *libName, std::vector *configs) +{ + const std::vector &sourceFiles = + sg->GetSourceFiles(); + // If the group is empty, don't write it at all. + if(sourceFiles.empty()) + { + return; + } + + // If the group has a name, write the header. + std::string name = sg->GetName(); + if(name != "") + { + this->WriteVCProjBeginGroup(fout, name.c_str(), ""); + } + + // Loop through each source in the source group. + for(std::vector::const_iterator sf = + sourceFiles.begin(); sf != sourceFiles.end(); ++sf) + { + std::string source = (*sf)->GetFullPath(); + const cmCustomCommand *command = (*sf)->GetCustomCommand(); + std::string compileFlags; + std::string additionalDeps; + + // Check for extra compiler flags. + const char* cflags = (*sf)->GetProperty("COMPILE_FLAGS"); + if(cflags) + { + compileFlags = cflags; + } + const char* lang = + m_GlobalGenerator->GetLanguageFromExtension((*sf)->GetSourceExtension().c_str()); + if(lang && strcmp(lang, "CXX") == 0) + { + // force a C++ file type + compileFlags += " /TP "; + } + // Check for extra object-file dependencies. + const char* deps = (*sf)->GetProperty("OBJECT_DEPENDS"); + if(deps) + { + std::vector depends; + cmSystemTools::ExpandListArgument(deps, depends); + if(!depends.empty()) + { + std::vector::iterator i = depends.begin(); + additionalDeps = this->ConvertToXMLOutputPath(i->c_str()); + for(++i;i != depends.end(); ++i) + { + additionalDeps += ";"; + additionalDeps += this->ConvertToXMLOutputPath(i->c_str()); + } + } + } + if (source != libName || target.GetType() == cmTarget::UTILITY) + { + fout << "\t\t\tConvertToXMLOutputPathSingle(source.c_str()); + // Tell MS-Dev what the source is. If the compiler knows how to + // build it, then it will. + fout << "\t\t\t\tRelativePath=\"" << d << "\">\n"; + if (command) + { + // Construct the entire set of commands in one string. + std::string script = this->ConstructScript(command->GetCommandLines()); + const char* comment = command->GetComment(); + const char* flags = compileFlags.size() ? compileFlags.c_str(): 0; + this->WriteCustomRule(fout, source.c_str(), script.c_str(), + (*comment?comment:"Custom Rule"), + command->GetDepends(), + command->GetOutput(), flags); + } + else if(compileFlags.size() || additionalDeps.length()) + { + const char* aCompilerTool = "VCCLCompilerTool"; + std::string ext = (*sf)->GetSourceExtension(); + ext = cmSystemTools::LowerCase(ext); + if(ext == "idl") + { + aCompilerTool = "VCMIDLTool"; + } + if(ext == "rc") + { + aCompilerTool = "VCResourceCompilerTool"; + } + if(ext == "def") + { + aCompilerTool = "VCCustomBuildTool"; + } + for(std::vector::iterator i = configs->begin(); + i != configs->end(); ++i) + { + fout << "\t\t\t\t\n" + << "\t\t\t\t\tEscapeForXML(compileFlags.c_str()) << "\"\n"; + } + if(additionalDeps.length()) + { + fout << "\t\t\t\t\tAdditionalDependencies=\"" + << additionalDeps.c_str() << "\"\n"; + } + fout << "\t\t\t\t\t/>\n" + << "\t\t\t\t\n"; + } + } + fout << "\t\t\t\n"; + } + } + + std::vector children = sg->GetGroupChildren(); + + for(unsigned int i=0;iWriteGroup(&children[i], target, fout, libName, configs); + } + + // If the group has a name, write the footer. + if(name != "") + { + this->WriteVCProjEndGroup(fout); + } +} void cmLocalVisualStudio7Generator:: WriteCustomRule(std::ostream& fout, @@ -1172,7 +1192,7 @@ WriteCustomRule(std::ostream& fout, } if(exePath.size()) { - libPath = exePath; + libPath = exePath; } else { @@ -1207,8 +1227,8 @@ WriteCustomRule(std::ostream& fout, void cmLocalVisualStudio7Generator::WriteVCProjBeginGroup(std::ostream& fout, - const char* group, - const char* ) + const char* group, + const char* ) { fout << "\t\t *configs); + std::vector m_CreatedProjectNames; std::string m_LibraryOutputPath; std::string m_ExecutableOutputPath; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f4cd035d9..1bd21154a 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -241,8 +241,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) { cmOStringStream error; error << "Error in cmake code at\n" - << lff.m_FilePath << ":" << lff.m_Line << ":\n" - << rm->GetError(); + << lff.m_FilePath << ":" << lff.m_Line << ":\n" + << rm->GetError(); cmSystemTools::Error(error.str().c_str()); return false; } @@ -250,8 +250,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) usedCommand->SetMakefile(this); bool keepCommand = false; if(usedCommand->GetEnabled() && !cmSystemTools::GetFatalErrorOccured() && - (!this->GetCMakeInstance()->GetScriptMode() || - usedCommand->IsScriptable())) + (!this->GetCMakeInstance()->GetScriptMode() || + usedCommand->IsScriptable())) { if(!usedCommand->InvokeInitialPass(lff.m_Arguments)) { @@ -277,8 +277,8 @@ bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff) { cmOStringStream error; error << "Error in cmake code at\n" - << lff.m_FilePath << ":" << lff.m_Line << ":\n" - << "Command " << usedCommand->GetName() << " not scriptable" << std::endl; + << lff.m_FilePath << ":" << lff.m_Line << ":\n" + << "Command " << usedCommand->GetName() << " not scriptable" << std::endl; cmSystemTools::Error(error.str().c_str()); result = false; cmSystemTools::SetFatalErrorOccured(); @@ -367,7 +367,7 @@ bool cmMakefile::ReadListFile(const char* filename_in, const char *external_in) if(!external && m_cmStartDirectory == m_cmHomeDirectory) { if(cmSystemTools::LowerCase( - cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt") + cmSystemTools::GetFilenameName(filename)) == "cmakelists.txt") { requireProjectCommand = true; } @@ -418,7 +418,7 @@ void cmMakefile::AddCommand(cmCommand* wg) this->GetCMakeInstance()->AddCommand(wg); } - // Set the make file +// Set the make file void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg) { m_LocalGenerator = lg; @@ -439,7 +439,7 @@ void cmMakefile::FinalPass() } - // Generate the output file +// Generate the output file void cmMakefile::ConfigureFinalPass() { this->FinalPass(); @@ -725,7 +725,7 @@ void cmMakefile::RemoveDefineFlag(const char* flag) void cmMakefile::AddLinkLibrary(const char* lib, cmTarget::LinkLibraryType llt) { m_LinkLibraries.push_back( - std::pair(lib,llt)); + std::pair(lib,llt)); } void cmMakefile::AddLinkLibraryForTarget(const char *target, @@ -892,7 +892,7 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before) // order dependency of the include path. std::vector::iterator i = std::find(m_IncludeDirectories.begin(), - m_IncludeDirectories.end(), inc); + m_IncludeDirectories.end(), inc); if(i == m_IncludeDirectories.end()) { if (before) @@ -945,7 +945,7 @@ void cmMakefile::AddCacheDefinition(const char* name, const char* value, cmCacheManager::CacheIterator it = this->GetCacheManager()->GetCacheIterator(name); if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) && - it.Initialized()) + it.Initialized()) { val = it.GetValue(); if ( type == cmCacheManager::PATH || type == cmCacheManager::FILEPATH ) @@ -1002,7 +1002,7 @@ void cmMakefile::AddCacheDefinition(const char* name, bool value, const char* do cmCacheManager::CacheIterator it = this->GetCacheManager()->GetCacheIterator(name); if(!it.IsAtEnd() && (it.GetType() == cmCacheManager::UNINITIALIZED) && - it.Initialized()) + it.Initialized()) { val = it.GetValueAsBool(); } @@ -1093,8 +1093,8 @@ void cmMakefile::AddLibrary(const char* lname, int shared, { case 0: this->GetCacheManager()->AddCacheEntry(ltname.c_str(),"STATIC", - "Whether a library is static, shared or module.", - cmCacheManager::INTERNAL); + "Whether a library is static, shared or module.", + cmCacheManager::INTERNAL); break; case 1: this->GetCacheManager()-> @@ -1120,7 +1120,7 @@ void cmMakefile::AddLibrary(const char* lname, int shared, } cmTarget* cmMakefile::AddExecutable(const char *exeName, - const std::vector &srcs) + const std::vector &srcs) { cmTarget target; target.SetType(cmTarget::EXECUTABLE, exeName); @@ -1180,30 +1180,88 @@ cmSourceGroup* cmMakefile::GetSourceGroup(const char* name) if(sgName == name) { return &(*sg); + } + else + { + cmSourceGroup *target = sg->lookupChild(name); + + if(target) + { + return target; + } } } return 0; } -void cmMakefile::AddSourceGroup(const char* name, const char* regex) +void cmMakefile::AddSourceGroup(const char* name, const char* regex, const char *parent) { // First see if the group exists. If so, replace its regular expression. - for(std::vector::iterator sg = m_SourceGroups.begin(); - sg != m_SourceGroups.end(); ++sg) + for(unsigned int i=0;iGetName(); - if(sgName == name) + if(!parent) { - if ( regex ) + if(sgName == name) { - // We only want to set the regular expression. If there are already - // source files in the group, we don't want to remove them. - sg->SetGroupRegex(regex); + if ( regex ) + { + // We only want to set the regular expression. If there are already + // source files in the group, we don't want to remove them. + sg->SetGroupRegex(regex); + } + return; + } + } + else + { + if(sgName == parent) + { + cmSourceGroup *localtarget = sg->lookupChild(name); + if(localtarget) + { + if ( regex ) + { + // We only want to set the regular expression. If there are already + // source files in the group, we don't want to remove them. + localtarget->SetGroupRegex(regex); + } + } + else + { + sg->AddChild(cmSourceGroup(name, regex)); + } + return; + } + else + { + cmSourceGroup *localtarget = sg->lookupChild(parent); + + if(localtarget) + { + cmSourceGroup *addtarget = localtarget->lookupChild(name); + + if(addtarget) + { + if ( regex ) + { + // We only want to set the regular expression. If there are already + // source files in the group, we don't want to remove them. + addtarget->SetGroupRegex(regex); + } + } + else + { + localtarget->AddChild(cmSourceGroup(name, regex)); + } + return; + } } - return; } } - + // The group doesn't exist. Add it. m_SourceGroups.push_back(cmSourceGroup(name, regex)); } @@ -1221,12 +1279,12 @@ void cmMakefile::ExpandVariables() { // Now expand variables in the include and link strings for(std::vector::iterator d = m_IncludeDirectories.begin(); - d != m_IncludeDirectories.end(); ++d) + d != m_IncludeDirectories.end(); ++d) { this->ExpandVariablesInString(*d); } for(std::vector::iterator d = m_LinkDirectories.begin(); - d != m_LinkDirectories.end(); ++d) + d != m_LinkDirectories.end(); ++d) { this->ExpandVariablesInString(*d); } @@ -1426,158 +1484,158 @@ const char *cmMakefile::ExpandVariablesInString(std::string& source, if ( notParsed ) { - // start by look for $ or @ in the string - std::string::size_type markerPos; - if(atOnly) - { - markerPos = source.find_first_of("@"); - } - else - { - markerPos = source.find_first_of("$@"); - } - // if not found, or found as the last character, then leave quickly as - // nothing needs to be expanded - if((markerPos == std::string::npos) || (markerPos >= source.size()-1)) - { - return source.c_str(); - } - // current position - std::string::size_type currentPos =0; // start at 0 - std::string result; // string with replacements - // go until the the end of the string - while((markerPos != std::string::npos) && (markerPos < source.size()-1)) - { - // grab string from currentPos to the start of the variable - // and add it to the result - result += source.substr(currentPos, markerPos - currentPos); - char endVariableMarker; // what is the end of the variable @ or } - int markerStartSize = 1; // size of the start marker 1 or 2 or 5 - if(!atOnly && source[markerPos] == '$') - { - // ${var} case - if(source[markerPos+1] == '{') - { - endVariableMarker = '}'; - markerStartSize = 2; - } - // $ENV{var} case - else if(markerPos+4 < source.size() && - source[markerPos+4] == '{' && - !source.substr(markerPos+1, 3).compare("ENV")) - { - endVariableMarker = '}'; - markerStartSize = 5; - } - else - { - // bogus $ with no { so add $ to result and move on - result += '$'; // add bogus $ back into string - currentPos = markerPos+1; // move on - endVariableMarker = ' '; // set end var to space so we can tell bogus - } - } - else - { - // @VAR case - endVariableMarker = '@'; - } - // if it was a valid variable (started with @ or ${ or $ENV{ ) - if(endVariableMarker != ' ') - { - markerPos += markerStartSize; // move past marker - // find the end variable marker starting at the markerPos - std::string::size_type endVariablePos = - source.find(endVariableMarker, markerPos); - if(endVariablePos == std::string::npos) - { - // no end marker found so add the bogus start - if(endVariableMarker == '@') - { - result += '@'; - } - else - { - result += (markerStartSize == 5 ? "$ENV{" : "${"); - } - currentPos = markerPos; - } - else - { - // good variable remove it - std::string var = source.substr(markerPos, endVariablePos - markerPos); - bool found = false; - if (markerStartSize == 5) // $ENV{ - { - char *ptr = getenv(var.c_str()); - if (ptr) - { - if (escapeQuotes) - { - result += cmSystemTools::EscapeQuotes(ptr); - } - else - { - result += ptr; - } - found = true; - } - } - else - { - const char* lookup = this->GetDefinition(var.c_str()); - if(lookup) - { - if (escapeQuotes) - { - result += cmSystemTools::EscapeQuotes(lookup); - } - else - { - result += lookup; - } - found = true; - } - else if(filename && (var == "CMAKE_CURRENT_LIST_FILE")) - { - result += filename; - found = true; - } - else if(line >= 0 && (var == "CMAKE_CURRENT_LIST_LINE")) - { - cmOStringStream ostr; - ostr << line; - result += ostr.str(); - found = true; - } - } - // if found add to result, if not, then it gets blanked - if (!found) - { - // if no definition is found then add the var back - if(!removeEmpty && endVariableMarker == '@') - { - result += "@"; - result += var; - result += "@"; - } - } - // lookup var, and replace it - currentPos = endVariablePos+1; - } - } + // start by look for $ or @ in the string + std::string::size_type markerPos; if(atOnly) { - markerPos = source.find_first_of("@", currentPos); + markerPos = source.find_first_of("@"); } else { - markerPos = source.find_first_of("$@", currentPos); + markerPos = source.find_first_of("$@"); } + // if not found, or found as the last character, then leave quickly as + // nothing needs to be expanded + if((markerPos == std::string::npos) || (markerPos >= source.size()-1)) + { + return source.c_str(); + } + // current position + std::string::size_type currentPos =0; // start at 0 + std::string result; // string with replacements + // go until the the end of the string + while((markerPos != std::string::npos) && (markerPos < source.size()-1)) + { + // grab string from currentPos to the start of the variable + // and add it to the result + result += source.substr(currentPos, markerPos - currentPos); + char endVariableMarker; // what is the end of the variable @ or } + int markerStartSize = 1; // size of the start marker 1 or 2 or 5 + if(!atOnly && source[markerPos] == '$') + { + // ${var} case + if(source[markerPos+1] == '{') + { + endVariableMarker = '}'; + markerStartSize = 2; + } + // $ENV{var} case + else if(markerPos+4 < source.size() && + source[markerPos+4] == '{' && + !source.substr(markerPos+1, 3).compare("ENV")) + { + endVariableMarker = '}'; + markerStartSize = 5; + } + else + { + // bogus $ with no { so add $ to result and move on + result += '$'; // add bogus $ back into string + currentPos = markerPos+1; // move on + endVariableMarker = ' '; // set end var to space so we can tell bogus + } + } + else + { + // @VAR case + endVariableMarker = '@'; + } + // if it was a valid variable (started with @ or ${ or $ENV{ ) + if(endVariableMarker != ' ') + { + markerPos += markerStartSize; // move past marker + // find the end variable marker starting at the markerPos + std::string::size_type endVariablePos = + source.find(endVariableMarker, markerPos); + if(endVariablePos == std::string::npos) + { + // no end marker found so add the bogus start + if(endVariableMarker == '@') + { + result += '@'; + } + else + { + result += (markerStartSize == 5 ? "$ENV{" : "${"); + } + currentPos = markerPos; + } + else + { + // good variable remove it + std::string var = source.substr(markerPos, endVariablePos - markerPos); + bool found = false; + if (markerStartSize == 5) // $ENV{ + { + char *ptr = getenv(var.c_str()); + if (ptr) + { + if (escapeQuotes) + { + result += cmSystemTools::EscapeQuotes(ptr); + } + else + { + result += ptr; + } + found = true; + } + } + else + { + const char* lookup = this->GetDefinition(var.c_str()); + if(lookup) + { + if (escapeQuotes) + { + result += cmSystemTools::EscapeQuotes(lookup); + } + else + { + result += lookup; + } + found = true; + } + else if(filename && (var == "CMAKE_CURRENT_LIST_FILE")) + { + result += filename; + found = true; + } + else if(line >= 0 && (var == "CMAKE_CURRENT_LIST_LINE")) + { + cmOStringStream ostr; + ostr << line; + result += ostr.str(); + found = true; + } + } + // if found add to result, if not, then it gets blanked + if (!found) + { + // if no definition is found then add the var back + if(!removeEmpty && endVariableMarker == '@') + { + result += "@"; + result += var; + result += "@"; + } + } + // lookup var, and replace it + currentPos = endVariablePos+1; + } + } + if(atOnly) + { + markerPos = source.find_first_of("@", currentPos); + } + else + { + markerPos = source.find_first_of("$@", currentPos); + } + } + result += source.substr(currentPos); // pick up the rest of the string + source = result; } - result += source.substr(currentPos); // pick up the rest of the string - source = result; - } return source.c_str(); } @@ -1651,9 +1709,10 @@ cmMakefile::FindSourceGroup(const char* source, for(std::vector::reverse_iterator sg = groups.rbegin(); sg != groups.rend(); ++sg) { - if(sg->MatchesFiles(source)) + cmSourceGroup *result = sg->MatchChildrenFiles(source); + if(result) { - return *sg; + return *result; } } @@ -1661,12 +1720,14 @@ cmMakefile::FindSourceGroup(const char* source, for(std::vector::reverse_iterator sg = groups.rbegin(); sg != groups.rend(); ++sg) { - if(sg->MatchesRegex(source)) + cmSourceGroup *result = sg->MatchChildrenRegex(source); + if(result) { - return *sg; + return *result; } } - + + // Shouldn't get here, but just in case, return the default group. return groups.front(); } @@ -1914,12 +1975,12 @@ cmSourceFile* cmMakefile::GetOrCreateSource(const char* sourceName, if ( cmSystemTools::GetFilenameLastExtension(srcTreeFile.c_str()).size() == 0) { if (cmSystemTools::DoesFileExistWithExtensions( - srcTreeFile.c_str(), this->GetSourceExtensions())) + srcTreeFile.c_str(), this->GetSourceExtensions())) { src = srcTreeFile; } else if (cmSystemTools::DoesFileExistWithExtensions( - srcTreeFile.c_str(), this->GetHeaderExtensions())) + srcTreeFile.c_str(), this->GetHeaderExtensions())) { src = srcTreeFile; } @@ -2288,7 +2349,7 @@ std::string cmMakefile::GetModulesFile(const char* filename) } //std::string Look through the possible module directories. for(std::vector::iterator i = modulePath.begin(); - i != modulePath.end(); ++i) + i != modulePath.end(); ++i) { std::string itempl = *i; cmSystemTools::ConvertToUnixSlashes(itempl); @@ -2364,7 +2425,7 @@ void cmMakefile::ConfigureString(const std::string& input, } int cmMakefile::ConfigureFile(const char* infile, const char* outfile, - bool copyonly, bool atOnly, bool escapeQuotes) + bool copyonly, bool atOnly, bool escapeQuotes) { int res = 1; if ( !cmSystemTools::FileExists(infile) ) @@ -2388,7 +2449,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, if(copyonly) { if ( !cmSystemTools::CopyFileIfDifferent(sinfile.c_str(), - soutfile.c_str())) + soutfile.c_str())) { return 0; } @@ -2402,7 +2463,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, { cmSystemTools::Error( "Could not open file for write in copy operation ", - tempOutputFile.c_str()); + tempOutputFile.c_str()); cmSystemTools::ReportLastSystemError(""); return 0; } @@ -2428,7 +2489,7 @@ int cmMakefile::ConfigureFile(const char* infile, const char* outfile, fin.close(); fout.close(); if ( !cmSystemTools::CopyFileIfDifferent(tempOutputFile.c_str(), - soutfile.c_str()) ) + soutfile.c_str()) ) { res = 0; } @@ -2451,8 +2512,8 @@ bool cmMakefile::CheckInfiniteLoops() { std::vector::iterator it; for ( it = m_ListFiles.begin(); - it != m_ListFiles.end(); - ++ it ) + it != m_ListFiles.end(); + ++ it ) { if ( this->HasWrittenFile(it->c_str()) ) { diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index a6d42f400..000133e79 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -162,7 +162,7 @@ public: * Add an executable to the build. */ cmTarget* AddExecutable(const char *exename, - const std::vector &srcs); + const std::vector &srcs); /** * Add a utility to the build. A utiltity target is a command that @@ -200,15 +200,15 @@ public: */ std::vector& GetLinkDirectories() { - return m_LinkDirectories; + return m_LinkDirectories; } const std::vector& GetLinkDirectories() const { - return m_LinkDirectories; + return m_LinkDirectories; } void SetLinkDirectories(const std::vector& vec) { - m_LinkDirectories = vec; + m_LinkDirectories = vec; } /** @@ -268,7 +268,7 @@ public: */ const char* GetProjectName() { - return m_ProjectName.c_str(); + return m_ProjectName.c_str(); } /** @@ -280,7 +280,7 @@ public: /** * Add a source group for consideration when adding a new source. */ - void AddSourceGroup(const char* name, const char* regex=0); + void AddSourceGroup(const char* name, const char* regex=0, const char* parent=0); /** * Add an auxiliary directory to the build. @@ -310,12 +310,12 @@ public: void SetHomeDirectory(const char* dir); const char* GetHomeDirectory() const { - return m_cmHomeDirectory.c_str(); + return m_cmHomeDirectory.c_str(); } void SetHomeOutputDirectory(const char* lib); const char* GetHomeOutputDirectory() const { - return m_HomeOutputDirectory.c_str(); + return m_HomeOutputDirectory.c_str(); } //@} @@ -394,7 +394,7 @@ public: } const char* GetComplainRegularExpression() { - return m_ComplainFileRegularExpression.c_str(); + return m_ComplainFileRegularExpression.c_str(); } /** @@ -409,15 +409,15 @@ public: */ std::vector& GetIncludeDirectories() { - return m_IncludeDirectories; + return m_IncludeDirectories; } const std::vector& GetIncludeDirectories() const { - return m_IncludeDirectories; + return m_IncludeDirectories; } void SetIncludeDirectories(const std::vector& vec) { - m_IncludeDirectories = vec; + m_IncludeDirectories = vec; } /** Expand out any arguements in the vector that have ; separated @@ -554,7 +554,7 @@ public: * Copy file but change lines acording to ConfigureString */ int ConfigureFile(const char* infile, const char* outfile, - bool copyonly, bool atOnly, bool escapeQuotes); + bool copyonly, bool atOnly, bool escapeQuotes); /** * find what source group this source is in diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 035b643c2..58069d1c8 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -81,3 +81,88 @@ std::vector& cmSourceGroup::GetSourceFiles() { return m_SourceFiles; } + +//---------------------------------------------------------------------------- +void cmSourceGroup::AddChild(cmSourceGroup child) +{ + m_GroupChildren.push_back(child); +} + +//---------------------------------------------------------------------------- +cmSourceGroup *cmSourceGroup::lookupChild(const char* name) +{ + // initializing iterators + std::vector::iterator iter = m_GroupChildren.begin(); + std::vector::iterator end = m_GroupChildren.end(); + + // st + for(;iter!=end; ++iter) + { + std::string sgName = iter->GetName(); + + // look if descenened is the one were looking for + if(sgName == name) + { + return &(*iter); // if it so return it + } + // if the descendend isn't the one where looking for ask it's traverse + cmSourceGroup *result = iter->lookupChild(name); + + // if one of it's descendeds is the one we're looking for return it + if(result) + { + return result; + } + } + + // if no child with this name was found return NULL + return NULL; +} + +cmSourceGroup *cmSourceGroup::MatchChildrenFiles(const char *name) +{ + // initializing iterators + std::vector::iterator iter = m_GroupChildren.begin(); + std::vector::iterator end = m_GroupChildren.end(); + + if(this->MatchesFiles(name)) + { + return this; + } + for(;iter!=end;++iter) + { + cmSourceGroup *result = iter->MatchChildrenFiles(name); + if(result) + { + return result; + } + } + return 0; +} + + +cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name) +{ + // initializing iterators + std::vector::iterator iter = m_GroupChildren.begin(); + std::vector::iterator end = m_GroupChildren.end(); + + if(this->MatchesRegex(name)) + { + return this; + } + for(;iter!=end; ++iter) + { + cmSourceGroup *result = iter->MatchChildrenRegex(name); + if(result) + { + return result; + } + } + return 0; +} + +std::vector cmSourceGroup::GetGroupChildren() const +{ + return m_GroupChildren; +} diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h index 430802864..6b76bacb0 100644 --- a/Source/cmSourceGroup.h +++ b/Source/cmSourceGroup.h @@ -47,6 +47,16 @@ public: * Add a file name to the explicit list of files for this group. */ void AddGroupFile(const char* name); + + /** + * Add child to this sourcegroup + */ + void AddChild(cmSourceGroup child); + + /** + * Looks up child and returns it + */ + cmSourceGroup *lookupChild(const char *name); /** * Get the name of this group. @@ -62,6 +72,16 @@ public: * Check if the given name matches this group's explicit file list. */ bool MatchesFiles(const char* name); + + /** + * Check if the given name matches this group's explicit file list in children. + */ + cmSourceGroup *MatchChildrenFiles(const char *name); + + /** + * Check if the given name matches this group's regex in children. + */ + cmSourceGroup *MatchChildrenRegex(const char *name); /** * Assign the given source file to this group. Used only by @@ -76,6 +96,7 @@ public: const std::vector& GetSourceFiles() const; std::vector& GetSourceFiles(); + std::vector GetGroupChildren() const; private: /** * The name of the source group. @@ -97,6 +118,8 @@ private: * this group. */ std::vector m_SourceFiles; + + std::vector m_GroupChildren; }; #endif diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx index 131e86c5e..01b969fd4 100644 --- a/Source/cmSourceGroupCommand.cxx +++ b/Source/cmSourceGroupCommand.cxx @@ -16,6 +16,50 @@ =========================================================================*/ #include "cmSourceGroupCommand.h" +inline std::vector tokenize(const std::string& str, + const std::string& sep, + bool skipEmptyTokens) +{ + std::vector tokens; + std::string::size_type tokstart,tokend; + + if (skipEmptyTokens) + { + tokend=0; + } + else + { + tokend=std::string::npos; + } + + do + { + if (skipEmptyTokens) + { + tokstart=str.find_first_not_of(sep,tokend); + } + else + { + tokstart=tokend+1; + } + if (tokstart==std::string::npos) + { + break; // no more tokens + } + tokend=str.find_first_of(sep,tokstart); + if (tokend==std::string::npos) + { + tokens.push_back(str.substr(tokstart)); + } + else + { + tokens.push_back(str.substr(tokstart,tokend-tokstart)); + } + } while (tokend!=std::string::npos); + + return tokens; +} + // cmSourceGroupCommand bool cmSourceGroupCommand::InitialPass(std::vector const& args) { @@ -24,18 +68,32 @@ bool cmSourceGroupCommand::InitialPass(std::vector const& args) this->SetError("called with incorrect number of arguments"); return false; } - - // Get the source group with the given name. - cmSourceGroup* sg = m_Makefile->GetSourceGroup(args[0].c_str()); - if(!sg) + + std::string delimiter = "\\"; + + if(m_Makefile->GetDefinition("SOURCE_GROUP_DELIMITER")) + delimiter = m_Makefile->GetDefinition("SOURCE_GROUP_DELIMITER"); + + std::vector folders = tokenize(args[0], delimiter, true); + + const char *parent = NULL; + + cmSourceGroup* sg = NULL; + + for(unsigned int i=0;iAddSourceGroup(args[0].c_str(), 0); - sg = m_Makefile->GetSourceGroup(args[0].c_str()); + sg = m_Makefile->GetSourceGroup(folders[i].c_str()); + if(!sg) + { + m_Makefile->AddSourceGroup(folders[i].c_str(), 0, parent); + } + sg = m_Makefile->GetSourceGroup(folders[i].c_str()); + parent = folders[i].c_str(); } - + // If only two arguments are given, the pre-1.8 version of the // command is being invoked. - if(args.size() == 2 && args[1] != "FILES") + if(args.size() == 2 && args[1] != "FILES") { sg->SetGroupRegex(args[1].c_str()); return true;