summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2007-02-01 16:49:27 (GMT)
committerBrad King <brad.king@kitware.com>2007-02-01 16:49:27 (GMT)
commitd8aa12178dfc29afa46889d332e11b30b770fec3 (patch)
treea2266cc73c31bf3414fcda8f353721bd3875e425 /Source
parentd37abb6b5d013ffcdd88d001e95be4f08e19e4f7 (diff)
downloadCMake-d8aa12178dfc29afa46889d332e11b30b770fec3.zip
CMake-d8aa12178dfc29afa46889d332e11b30b770fec3.tar.gz
CMake-d8aa12178dfc29afa46889d332e11b30b770fec3.tar.bz2
ENH: Reimplemented parsing and mapping of flags into vcproj file attribute options. This cleans up and centralizes a few things. It is in preparation for dealing with precompiled header flags for bug #3512 since they require some special handling.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx653
-rw-r--r--Source/cmLocalVisualStudio7Generator.h5
2 files changed, 377 insertions, 281 deletions
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 0289f97..41eb891 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -24,8 +24,11 @@
#include "cmCacheManager.h"
#include "cmake.h"
+#include <cmsys/System.h>
+
#include <ctype.h> // for isspace
+//----------------------------------------------------------------------------
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
{
this->Version = 7;
@@ -290,6 +293,11 @@ struct cmVS7FlagTable
const char* value; // string value
};
+// A statically allocated string so that user value options can be
+// identified with a single pointer comparison and can never be
+// confused with actual values.
+static const char CMFLAG_USER_VALUE[] = "<USER_VALUE>";
+
// fill the table here currently the comment field is not used for
// anything other than documentation NOTE: Make sure the longer
// commandFlag comes FIRST!
@@ -368,34 +376,72 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] =
{"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE"},
{"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1"},
{"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2"},
- {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "USER_VALUE", ""},
+ {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore",
+ CMFLAG_USER_VALUE},
{0,0,0,0 }
};
+//----------------------------------------------------------------------------
+class cmLocalVisualStudio7GeneratorOptions
+{
+public:
+ // Construct an options table for a given tool.
+ enum Tool
+ {
+ Compiler,
+ Linker
+ };
+ cmLocalVisualStudio7GeneratorOptions(Tool tool);
+
+ // Store options from command line flags.
+ void Parse(const char* flags);
+
+ // Store options for verbose builds.
+ void SetVerboseMakefile(bool verbose);
+
+ // Store definitions and flags.
+ void AddDefine(const std::string& define);
+ void AddFlag(const char* flag, const char* value);
+
+ // Check for specific options.
+ bool UsingUnicode();
+ bool UsingDebugPDB();
+
+ // Write options to output.
+ void OutputPreprocessorDefinitions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix);
+ void OutputFlagMap(std::ostream& fout, const char* indent);
+ void OutputAdditionalOptions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix);
+
+private:
+ // create a map of xml tags to the values they should have in the output
+ // for example, "BufferSecurityCheck" = "TRUE"
+ // first fill this table with the values for the configuration
+ // Debug, Release, etc,
+ // Then parse the command line flags specified in CMAKE_CXX_FLAGS
+ // and CMAKE_C_FLAGS
+ // and overwrite or add new values to this map
+ std::map<cmStdString, cmStdString> FlagMap;
+ // Preprocessor definitions.
+ std::vector<cmStdString> Defines;
+ // Unrecognized flags that get no special handling.
+ cmStdString FlagString;
-
-
-
+ bool DoingDefine;
+ cmVS7FlagTable const* FlagTable;
+ void HandleFlag(const char* flag);
+};
void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
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"
- // first fill this table with the values for the configuration
- // Debug, Release, etc,
- // Then parse the command line flags specified in CMAKE_CXX_FLAGS
- // and CMAKE_C_FLAGS
- // and overwrite or add new values to this map
- std::map<cmStdString, cmStdString> flagMap;
- // since the default is on for this, but if /EHsc is found
- // in the flags it will be turned on and we have /EHSC on by
- // default in the CXX flags, then this is the only way to turn this off
- flagMap["ExceptionHandling"] = "FALSE";
const char* mfcFlag = this->Makefile->GetDefinition("CMAKE_MFC_FLAG");
if(!mfcFlag)
{
@@ -470,6 +516,51 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
flags += targetFlags;
}
+ // Get preprocessor definitions for this directory.
+ std::string defineFlags = this->Makefile->GetDefineFlags();
+
+ // Construct a set of build options for this target.
+ Options targetOptions(Options::Compiler);
+ targetOptions.Parse(flags.c_str());
+ targetOptions.Parse(defineFlags.c_str());
+ targetOptions.SetVerboseMakefile(
+ this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
+
+ // Add a definition for the configuration name.
+ std::string configDefine = "CMAKE_INTDIR=\\\"";
+ configDefine += configName;
+ configDefine += "\\\"";
+ targetOptions.AddDefine(configDefine);
+
+ // Add a definition for the export macro.
+ if(target.GetType() == cmTarget::SHARED_LIBRARY ||
+ target.GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ std::string exportSymbol;
+ if(const char* custom_export_name = target.GetProperty("DEFINE_SYMBOL"))
+ {
+ exportSymbol = custom_export_name;
+ }
+ else
+ {
+ std::string id = libName;
+ id += "_EXPORTS";
+ exportSymbol = cmSystemTools::MakeCindentifier(id.c_str());
+ }
+ targetOptions.AddDefine(exportSymbol);
+ }
+
+ // Override the flag map with cmake-specific settings.
+ if(this->Makefile->IsOn("CMAKE_CXX_USE_RTTI"))
+ {
+ targetOptions.AddFlag("RuntimeTypeInfo", "TRUE");
+ }
+ if(const char* warningLevel =
+ this->Makefile->GetDefinition("CMAKE_CXX_WARNING_LEVEL"))
+ {
+ targetOptions.AddFlag("WarningLevel", warningLevel);
+ }
+
// The intermediate directory name consists of a directory for the
// target and a subdirectory for the configuration name.
std::string intermediateDir = this->GetTargetDirectory(target);
@@ -481,12 +572,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
<< "\t\t\tConfigurationType=\"" << configType << "\"\n"
<< "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
<< "\t\t\tATLMinimizesCRunTimeLibraryUsage=\"FALSE\"\n";
- // if -D_UNICODE or /D_UNICODE is found in the flags
- // change the character set to unicode, if not then
- // default to MBCS
- std::string defs = this->Makefile->GetDefineFlags();
- if(flags.find("D_UNICODE") != flags.npos ||
- defs.find("D_UNICODE") != flags.npos)
+
+ // If unicode is enabled change the character set to unicode, if not
+ // then default to MBCS.
+ if(targetOptions.UsingUnicode())
{
fout << "\t\t\tCharacterSet=\"1\">\n";
}
@@ -496,25 +585,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
}
fout << "\t\t\t<Tool\n"
- << "\t\t\t\tName=\"VCCLCompilerTool\"\n"
- << "\t\t\t\tAdditionalOptions=\"";
- // now fill the flagMap from the command line flags, and
- // if a flag is used, it will be removed from the flags string by
- // this function call
- this->FillFlagMapFromCommandFlags
- (flagMap, &cmLocalVisualStudio7GeneratorFlagTable[0], flags);
- std::string defineFlags = this->Makefile->GetDefineFlags();
-
- // now check the define flags for flags other than -D and
- // put them in the map, the -D flags will be left in the defineFlags
- // variable as -D is not in the flagMap
- this->FillFlagMapFromCommandFlags
- (flagMap, &cmLocalVisualStudio7GeneratorFlagTable[0], defineFlags);
-
- // output remaining flags that were not mapped to anything
- fout << this->EscapeForXML(flags.c_str()).c_str();
- fout << " -DCMAKE_INTDIR=\\&quot;" << configName << "\\&quot;"
- << "\"\n";
+ << "\t\t\t\tName=\"VCCLCompilerTool\"\n";
+ targetOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
fout << "\t\t\t\tAdditionalIncludeDirectories=\"";
std::vector<std::string> includes;
this->GetIncludeDirectories(includes);
@@ -525,48 +597,11 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << ipath << ";";
}
fout << "\"\n";
- // set a few cmake specific flags
- if(this->Makefile->IsOn("CMAKE_CXX_USE_RTTI"))
- {
- flagMap["RuntimeTypeInfo"] = "TRUE";
- }
- if ( this->Makefile->GetDefinition("CMAKE_CXX_WARNING_LEVEL") )
- {
- flagMap["WarningLevel"] =
- this->Makefile->GetDefinition("CMAKE_CXX_WARNING_LEVEL");
- }
-
- // Now copy the flag map into the xml for the file
- for(std::map<cmStdString, cmStdString>::iterator m = flagMap.begin();
- m != flagMap.end(); ++m)
- {
- fout << "\t\t\t\t" << m->first << "=\"" << m->second << "\"\n";
- }
- fout << "\t\t\t\tPreprocessorDefinitions=\"";
- if(target.GetType() == cmTarget::SHARED_LIBRARY
- || target.GetType() == cmTarget::MODULE_LIBRARY)
- {
- std::string exportSymbol;
- if (const char* custom_export_name =
- target.GetProperty("DEFINE_SYMBOL"))
- {
- exportSymbol = custom_export_name;
- }
- else
- {
- std::string id = libName;
- id += "_EXPORTS";
- exportSymbol = cmSystemTools::MakeCindentifier(id.c_str());
- }
- fout << "," << exportSymbol;
- }
- this->OutputDefineFlags(defineFlags.c_str(), fout);
- fout << "\"\n";
+ targetOptions.OutputFlagMap(fout, "\t\t\t\t");
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n");
fout << "\t\t\t\tAssemblerListingLocation=\"" << configName << "\"\n";
fout << "\t\t\t\tObjectFile=\"$(IntDir)\\\"\n";
- std::map<cmStdString, cmStdString>::iterator mi =
- flagMap.find("DebugInformationFormat");
- if(mi != flagMap.end() && mi->second != "1")
+ if(targetOptions.UsingDebugPDB())
{
if(target.GetType() == cmTarget::EXECUTABLE)
{
@@ -605,15 +640,12 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
fout << ipath << ";";
}
// add the -D flags to the RC tool
- fout << "\"\n"
- << "\t\t\t\tPreprocessorDefinitions=\"";
- this->OutputDefineFlags(defineFlags.c_str(), fout);
- fout << "\" />\n";
+ fout << "\"";
+ targetOptions.OutputPreprocessorDefinitions(fout, "\n\t\t\t\t", "");
+ fout << "/>\n";
fout << "\t\t\t<Tool\n\t\t\t\tName=\"VCMIDLTool\"\n";
- fout << "\t\t\t\tPreprocessorDefinitions=\"";
- this->OutputDefineFlags(defineFlags.c_str(), fout);
- fout << "\"\n";
+ targetOptions.OutputPreprocessorDefinitions(fout, "\t\t\t\t", "\n");
fout << "\t\t\t\tMkTypLibCompatible=\"FALSE\"\n";
if( this->PlatformName == "x64" )
{
@@ -651,84 +683,6 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
this->OutputBuildTool(fout, configName, target);
fout << "\t\t</Configuration>\n";
}
-void cmLocalVisualStudio7Generator::ReplaceFlagSetMap(std::string& flags,
- cmVS7FlagTable*
- flagTable,
- std::map<cmStdString,
- cmStdString>& flagMap,
- std::string& option,
- std::string::size_type
- pos)
-{
- std::string value = flagTable->value;
- if(strcmp(flagTable->comment, "USER_VALUE") == 0)
- {
- std::string::size_type len = flags.find(" ", pos);
- if(len != flags.npos)
- {
- len -= option.size();
- }
- value = flags.substr(pos+option.size(), len);
- std::string fullflag = option;
- fullflag += value;
- // remove everything
- cmSystemTools::ReplaceString(flags, fullflag.c_str(), "");
- }
- else
- {
- cmSystemTools::ReplaceString(flags, option.c_str(), "");
- }
- // now put value into flag map
-
- flagMap[flagTable->IDEName] = value;
-}
-
-
-void cmLocalVisualStudio7Generator::FillFlagMapFromCommandFlags(
- std::map<cmStdString, cmStdString>& flagMap,
- cmVS7FlagTable* flagTable,
- std::string& flags)
-{
- std::string replace;
- std::string option;
- while(flagTable->IDEName)
- {
- option.reserve(strlen(flagTable->commandFlag)+2);
- // first do the - version
- option = "-";
- option += flagTable->commandFlag;
- std::string::size_type pos = flags.find(option);
- while(pos != flags.npos)
- {
- this->ReplaceFlagSetMap(flags, flagTable, flagMap,
- option, pos);
- pos = flags.find(option);
- }
- // now do the / version
- option[0] = '/';
- pos = flags.find(option);
- while(pos != flags.npos)
- {
- this->ReplaceFlagSetMap(flags, flagTable, flagMap,
- option, pos);
- pos = flags.find(option);
- }
- // move to next flag
- flagTable++;
- }
-
- // If verbose makefiles have been requested and the /nologo option
- // was not given explicitly in the flags we want to add an attribute
- // to the generated project to disable logo suppression. Otherwise
- // the GUI default is to enable suppression.
- if(this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"))
- {
- if(flagMap.find("SuppressStartupBanner") == flagMap.end())
- {
- flagMap["SuppressStartupBanner"] = "FALSE";
- }
- }
-}
//----------------------------------------------------------------------------
std::string
@@ -789,10 +743,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
extraLinkOptions += " ";
extraLinkOptions += targetLinkFlags;
}
- std::map<cmStdString, cmStdString> flagMap;
- this->FillFlagMapFromCommandFlags
- (flagMap, &cmLocalVisualStudio7GeneratorLinkFlagTable[0],
- extraLinkOptions);
+ Options linkOptions(Options::Linker);
+ linkOptions.Parse(extraLinkOptions.c_str());
switch(target.GetType())
{
case cmTarget::STATIC_LIBRARY:
@@ -855,17 +807,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
standardLibsVar += "_STANDARD_LIBRARIES";
fout << "\t\t\t<Tool\n"
- << "\t\t\t\tName=\"VCLinkerTool\"\n"
- << "\t\t\t\tAdditionalOptions=\"/MACHINE:I386";
- if(extraLinkOptions.size())
- {
- fout << " " << cmLocalVisualStudio7Generator::EscapeForXML(
- extraLinkOptions.c_str()).c_str();
- }
+ << "\t\t\t\tName=\"VCLinkerTool\"\n";
+ linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
// Use the NOINHERIT macro to avoid getting VS project default
// libraries which may be set by the user to something bad.
- fout << "\"\n"
- << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
+ fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
<< " ";
this->OutputLibraries(fout, linkLibs);
@@ -877,11 +823,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
- for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
- i != flagMap.end(); ++i)
- {
- fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n";
- }
+ linkOptions.OutputFlagMap(fout, "\t\t\t\t");
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, linkDirs);
fout << "\"\n";
@@ -943,17 +885,11 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
standardLibsVar += "_STANDARD_LIBRARIES";
fout << "\t\t\t<Tool\n"
- << "\t\t\t\tName=\"VCLinkerTool\"\n"
- << "\t\t\t\tAdditionalOptions=\"";
- if(extraLinkOptions.size())
- {
- fout << " " << cmLocalVisualStudio7Generator::EscapeForXML(
- extraLinkOptions.c_str()).c_str();
- }
+ << "\t\t\t\tName=\"VCLinkerTool\"\n";
+ linkOptions.OutputAdditionalOptions(fout, "\t\t\t\t", "\n");
// Use the NOINHERIT macro to avoid getting VS project default
// libraries which may be set by the user to something bad.
- fout << "\"\n"
- << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
+ fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
<< " ";
this->OutputLibraries(fout, linkLibs);
@@ -965,11 +901,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
fout << "\t\t\t\tOutputFile=\""
<< this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
- for(std::map<cmStdString, cmStdString>::iterator i = flagMap.begin();
- i != flagMap.end(); ++i)
- {
- fout << "\t\t\t\t" << i->first << "=\"" << i->second << "\"\n";
- }
+ linkOptions.OutputFlagMap(fout, "\t\t\t\t");
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, linkDirs);
fout << "\"\n";
@@ -1087,63 +1019,6 @@ cmLocalVisualStudio7Generator
}
}
-//----------------------------------------------------------------------------
-void cmLocalVisualStudio7Generator::OutputDefineFlags(const char* flags,
- std::ostream& fout)
-{
- std::string defs = flags;
- cmSystemTools::ReplaceString(defs, "/D","-D");
- std::string::size_type pos = defs.find("-D");
- bool done = pos == std::string::npos;
- if(!done)
- {
- fout << ",";
- }
- while(!done)
- {
- std::string::size_type nextpos = defs.find("-D", pos+2);
- std::string define;
- if(nextpos != std::string::npos)
- {
- define = defs.substr(pos+2, nextpos - pos -3);
- }
- else
- {
- define = defs.substr(pos+2);
- done = true;
- }
-
- // Remove trailing whitespace from the definition.
- while(!define.empty() && isspace(define[define.size()-1]))
- {
- define = define.substr(0, define.size()-1);
- }
-
- // Double-quotes in the value of the definition must be escaped
- // with a backslash. The entire definition should be quoted in
- // the generated xml attribute to avoid confusing the VS parser.
- define = this->EscapeForXML(define.c_str());
- // if the define has something in it that is not a letter or a number
- // then quote it
- if(define.
- find_first_not_of(
- "-_abcdefghigklmnopqrstuvwxyz1234567890ABCDEFGHIGKLMNOPQRSTUVWXYZ")
- != define.npos)
- {
- fout << "&quot;" << define << "&quot;,";
- }
- else
- {
- fout << define << ",";
- }
- if(!done)
- {
- pos = defs.find("-D", nextpos);
- }
- }
-}
-
-
void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
const char *libName,
cmTarget &target)
@@ -1342,28 +1217,14 @@ void cmLocalVisualStudio7Generator
fout << ">\n";
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << aCompilerTool << "\"\n";
- if(compileFlags.size())
- {
- std::string compileFlagsCopy = compileFlags;
- std::map<cmStdString, cmStdString> fileFlagMap;
- this->FillFlagMapFromCommandFlags
- (fileFlagMap,
- &cmLocalVisualStudio7GeneratorFlagTable[0],
- compileFlagsCopy);
- if(compileFlagsCopy.size() &&
- compileFlagsCopy.find_first_not_of(" ")
- != compileFlagsCopy.npos)
- {
- fout << "\t\t\t\t\tAdditionalOptions=\""
- << this->EscapeForXML(compileFlagsCopy.c_str()) << "\"\n";
- }
- for(std::map<cmStdString,
- cmStdString>::iterator m = fileFlagMap.begin();
- m != fileFlagMap.end(); ++m)
- {
- fout << "\t\t\t\t\t" << m->first << "=\""
- << m->second << "\"\n";
- }
+ if(!compileFlags.empty())
+ {
+ Options fileOptions(Options::Compiler);
+ fileOptions.Parse(compileFlags.c_str());
+ fileOptions.OutputAdditionalOptions(fout, "\t\t\t\t\t", "\n");
+ fileOptions.OutputFlagMap(fout, "\t\t\t\t\t");
+ fileOptions.OutputPreprocessorDefinitions(fout,
+ "\t\t\t\t\t", "\n");
}
if(additionalDeps.length())
{
@@ -1649,8 +1510,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFooter(std::ostream& fout)
<< "</VisualStudioProject>\n";
}
-
-std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
+std::string cmLocalVisualStudio7GeneratorEscapeForXML(const char* s)
{
std::string ret = s;
cmSystemTools::ReplaceString(ret, "&", "&amp;");
@@ -1661,6 +1521,11 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
return ret;
}
+std::string cmLocalVisualStudio7Generator::EscapeForXML(const char* s)
+{
+ return cmLocalVisualStudio7GeneratorEscapeForXML(s);
+}
+
std::string cmLocalVisualStudio7Generator
::ConvertToXMLOutputPath(const char* path)
{
@@ -1794,3 +1659,233 @@ std::string cmLocalVisualStudio7Generator
dir += ".dir";
return dir;
}
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudio7GeneratorOptions
+::cmLocalVisualStudio7GeneratorOptions(Tool tool):
+ DoingDefine(false), FlagTable(0)
+{
+ // Choose the flag table for the requested tool.
+ switch(tool)
+ {
+ case Compiler:
+ this->FlagTable = cmLocalVisualStudio7GeneratorFlagTable; break;
+ case Linker:
+ this->FlagTable = cmLocalVisualStudio7GeneratorLinkFlagTable; break;
+ default: break;
+ }
+
+ // Exception handling is on by default because the platform file has
+ // "/EHsc" in the flags. Normally, that will override this
+ // initialization to off, but the user has the option of removing
+ // the flag to disable exception handling. When the user does
+ // remove the flag we need to override the IDE default of on.
+ this->FlagMap["ExceptionHandling"] = "FALSE";
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7GeneratorOptions::SetVerboseMakefile(bool verbose)
+{
+ // If verbose makefiles have been requested and the /nologo option
+ // was not given explicitly in the flags we want to add an attribute
+ // to the generated project to disable logo suppression. Otherwise
+ // the GUI default is to enable suppression.
+ if(verbose &&
+ this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end())
+ {
+ this->FlagMap["SuppressStartupBanner"] = "FALSE";
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7GeneratorOptions::AddDefine(const std::string& def)
+{
+ this->Defines.push_back(def);
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7GeneratorOptions::AddFlag(const char* flag,
+ const char* value)
+{
+ this->FlagMap[flag] = value;
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalVisualStudio7GeneratorOptions::UsingUnicode()
+{
+ // Look for the a _UNICODE definition.
+ bool use_unicode = false;
+ for(std::vector<cmStdString>::const_iterator di = this->Defines.begin();
+ di != this->Defines.end(); ++di)
+ {
+ if(*di == "_UNICODE")
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmLocalVisualStudio7GeneratorOptions::UsingDebugPDB()
+{
+ std::map<cmStdString, cmStdString>::iterator mi =
+ this->FlagMap.find("DebugInformationFormat");
+ if(mi != this->FlagMap.end() && mi->second != "1")
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7GeneratorOptions::Parse(const char* flags)
+{
+ // Parse the input string as a windows command line since the string
+ // is intended for writing directly into the build files.
+ std::vector<std::string> args;
+ cmSystemTools::ParseWindowsCommandLine(flags, args);
+
+ // Process flags that need to be represented specially in the IDE
+ // project file.
+ for(std::vector<std::string>::iterator ai = args.begin();
+ ai != args.end(); ++ai)
+ {
+ this->HandleFlag(ai->c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmLocalVisualStudio7GeneratorOptions::HandleFlag(const char* flag)
+{
+ // If the last option was -D then this option is the definition.
+ if(this->DoingDefine)
+ {
+ this->DoingDefine = false;
+ this->Defines.push_back(flag);
+ return;
+ }
+
+ // Look for known arguments.
+ if(flag[0] == '-' || flag[0] == '/')
+ {
+ if(flag[1] == 'D')
+ {
+ if(flag[2] == '\0')
+ {
+ // The next argument will have the definition.
+ this->DoingDefine = true;
+ }
+ else
+ {
+ // Store this definition.
+ this->Defines.push_back(flag+2);
+ }
+ return;
+ }
+ else if(this->FlagTable)
+ {
+ // Look for an entry in the flag table matching this flag.
+ for(cmVS7FlagTable const* entry = this->FlagTable;
+ entry->IDEName; ++entry)
+ {
+ if(entry->value == CMFLAG_USER_VALUE)
+ {
+ // This flag table entry accepts a user value.
+ int n = static_cast<int>(strlen(entry->commandFlag));
+ if(strncmp(flag+1, entry->commandFlag, n) == 0)
+ {
+ this->FlagMap[entry->IDEName] = flag+1+n;
+ return;
+ }
+ }
+ else if(strcmp(flag+1, entry->commandFlag) == 0)
+ {
+ // This flag table entry provides a fixed value.
+ this->FlagMap[entry->IDEName] = entry->value;
+ return;
+ }
+ }
+ }
+ }
+
+ // This option is not known. Store it in the output flags.
+ this->FlagString += " ";
+ this->FlagString +=
+ cmSystemTools::EscapeWindowsShellArgument(flag,
+ cmsysSystem_Shell_Flag_VSIDE);
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7GeneratorOptions
+::OutputPreprocessorDefinitions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix)
+{
+ if(this->Defines.empty())
+ {
+ return;
+ }
+
+ fout << prefix << "PreprocessorDefinitions=\"";
+ const char* comma = "";
+ for(std::vector<cmStdString>::const_iterator di = this->Defines.begin();
+ di != this->Defines.end(); ++di)
+ {
+ // Escape this flag for the IDE.
+ std::string define =
+ cmLocalVisualStudio7GeneratorEscapeForXML(di->c_str());
+
+ // Old comment:
+ // Double-quotes in the value of the definition must be escaped
+ // with a backslash. The entire definition should be quoted in
+ // the generated xml attribute to avoid confusing the VS parser.
+
+ // Write this flag. Quote it if the definition is not
+ // alphanumeric.
+ if(define.find_first_not_of(
+ "-_abcdefghigklmnopqrstuvwxyz1234567890ABCDEFGHIGKLMNOPQRSTUVWXYZ")
+ != define.npos)
+ {
+ fout << comma << "&quot;" << define << "&quot;";
+ }
+ else
+ {
+ fout << comma << define;
+ }
+ comma = ",";
+ }
+ fout << "\"" << suffix;
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7GeneratorOptions
+::OutputFlagMap(std::ostream& fout, const char* indent)
+{
+ for(std::map<cmStdString, cmStdString>::iterator m = this->FlagMap.begin();
+ m != this->FlagMap.end(); ++m)
+ {
+ fout << indent << m->first << "=\"" << m->second << "\"\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudio7GeneratorOptions
+::OutputAdditionalOptions(std::ostream& fout,
+ const char* prefix,
+ const char* suffix)
+{
+ if(!this->FlagString.empty())
+ {
+ fout << prefix << "AdditionalOptions=\"";
+ fout <<
+ cmLocalVisualStudio7GeneratorEscapeForXML(this->FlagString.c_str());
+ fout << "\"" << suffix;
+ }
+}
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 69ac27b..3f1369f 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -26,6 +26,8 @@ class cmCustomCommand;
class cmSourceGroup;
struct cmVS7FlagTable;
+class cmLocalVisualStudio7GeneratorOptions;
+
/** \class cmLocalVisualStudio7Generator
* \brief Write Visual Studio .NET project files.
*
@@ -65,6 +67,7 @@ public:
void SetPlatformName(const char* n) { this->PlatformName = n;}
virtual void ConfigureFinalPass();
private:
+ typedef cmLocalVisualStudio7GeneratorOptions Options;
void ReadAndStoreExternalGUID(const char* name,
const char* path);
void ReplaceFlagSetMap(std::string& flags,
@@ -96,8 +99,6 @@ private:
std::string EscapeForXML(const char* s);
std::string ConvertToXMLOutputPath(const char* path);
std::string ConvertToXMLOutputPathSingle(const char* path);
- void OutputDefineFlags(const char* flags,
- std::ostream& fout);
void OutputTargetRules(std::ostream& fout, cmTarget &target,
const char *libName);
void OutputBuildTool(std::ostream& fout, const char* configName,