VS10: Refactor link options collection

Avoid collecting the link options twice.  Collect them once in a
LinkOptions member and use it from both places.  We already do this for
compiler options with the ClOptions member.
This commit is contained in:
Brad King 2012-10-26 10:16:45 -04:00
parent 259cff94ff
commit c65a2ea6a8
4 changed files with 76 additions and 81 deletions

View File

@ -177,3 +177,14 @@ void cmIDEOptions::RemoveFlag(const char* flag)
{ {
this->FlagMap.erase(flag); this->FlagMap.erase(flag);
} }
//----------------------------------------------------------------------------
const char* cmIDEOptions::GetFlag(const char* flag)
{
std::map<cmStdString, cmStdString>::iterator i = this->FlagMap.find(flag);
if(i != this->FlagMap.end())
{
return i->second.c_str();
}
return 0;
}

View File

@ -29,6 +29,7 @@ public:
void AddDefines(const char* defines); void AddDefines(const char* defines);
void AddFlag(const char* flag, const char* value); void AddFlag(const char* flag, const char* value);
void RemoveFlag(const char* flag); void RemoveFlag(const char* flag);
const char* GetFlag(const char* flag);
protected: protected:
// create a map of xml tags to the values they should have in the output // create a map of xml tags to the values they should have in the output

View File

@ -109,6 +109,11 @@ cmVisualStudio10TargetGenerator::~cmVisualStudio10TargetGenerator()
{ {
delete i->second; delete i->second;
} }
for(OptionsMap::iterator i = this->LinkOptions.begin();
i != this->LinkOptions.end(); ++i)
{
delete i->second;
}
if(!this->BuildFileStream) if(!this->BuildFileStream)
{ {
return; return;
@ -181,6 +186,10 @@ void cmVisualStudio10TargetGenerator::Generate()
{ {
return; return;
} }
if(!this->ComputeLinkOptions())
{
return;
}
} }
cmMakefile* mf = this->Target->GetMakefile(); cmMakefile* mf = this->Target->GetMakefile();
std::string path = mf->GetStartOutputDirectory(); std::string path = mf->GetStartOutputDirectory();
@ -1077,7 +1086,6 @@ void
cmVisualStudio10TargetGenerator:: cmVisualStudio10TargetGenerator::
OutputLinkIncremental(std::string const& configName) OutputLinkIncremental(std::string const& configName)
{ {
std::string CONFIG = cmSystemTools::UpperCase(configName);
// static libraries and things greater than modules do not need // static libraries and things greater than modules do not need
// to set this option // to set this option
if(this->Target->GetType() == cmTarget::STATIC_LIBRARY if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
@ -1085,72 +1093,19 @@ OutputLinkIncremental(std::string const& configName)
{ {
return; return;
} }
const char* linkType = "SHARED"; Options& linkOptions = *(this->LinkOptions[configName]);
if(this->Target->GetType() == cmTarget::EXECUTABLE)
{
linkType = "EXE";
}
// assume incremental linking const char* incremental = linkOptions.GetFlag("LinkIncremental");
const char* incremental = "true";
const char* linkLanguage =
this->Target->GetLinkerLanguage(configName.c_str());
if(!linkLanguage)
{
cmSystemTools::Error
("CMake can not determine linker language for target:",
this->Name.c_str());
return;
}
std::string linkFlagVarBase = "CMAKE_";
linkFlagVarBase += linkType;
linkFlagVarBase += "_LINKER_FLAGS";
std::string flags = this->
Target->GetMakefile()->GetRequiredDefinition(linkFlagVarBase.c_str());
std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
flags += this->
Target->GetMakefile()->GetRequiredDefinition(linkFlagVar.c_str());
if(strcmp(linkLanguage, "C") == 0 || strcmp(linkLanguage, "CXX") == 0
|| strcmp(linkLanguage, "Fortran") == 0)
{
std::string baseFlagVar = "CMAKE_";
baseFlagVar += linkLanguage;
baseFlagVar += "_FLAGS";
flags += this->
Target->GetMakefile()->GetRequiredDefinition(baseFlagVar.c_str());
std::string flagVar = baseFlagVar + std::string("_") + CONFIG;
flags +=
Target->GetMakefile()->GetRequiredDefinition(flagVar.c_str());
}
const char* targetLinkFlags = this->Target->GetProperty("LINK_FLAGS");
if(targetLinkFlags)
{
flags += " ";
flags += targetLinkFlags;
}
std::string flagsProp = "LINK_FLAGS_";
flagsProp += CONFIG;
if(const char* flagsConfig = this->Target->GetProperty(flagsProp.c_str()))
{
flags += " ";
flags += flagsConfig;
}
if(flags.find("INCREMENTAL:NO") != flags.npos)
{
incremental = "false";
}
this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3); this->WritePlatformConfigTag("LinkIncremental", configName.c_str(), 3);
*this->BuildFileStream << incremental *this->BuildFileStream << (incremental?incremental:"true")
<< "</LinkIncremental>\n"; << "</LinkIncremental>\n";
linkOptions.RemoveFlag("LinkIncremental");
const char* manifest = "true"; const char* manifest = linkOptions.GetFlag("GenerateManifest");
if(flags.find("MANIFEST:NO") != flags.npos)
{
manifest = "false";
}
this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3); this->WritePlatformConfigTag("GenerateManifest", configName.c_str(), 3);
*this->BuildFileStream << manifest *this->BuildFileStream << (manifest?manifest:"true")
<< "</GenerateManifest>\n"; << "</GenerateManifest>\n";
linkOptions.RemoveFlag("GenerateManifest");
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -1343,18 +1298,36 @@ cmVisualStudio10TargetGenerator::WriteLibOptions(std::string const& config)
} }
} }
//----------------------------------------------------------------------------
void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& bool cmVisualStudio10TargetGenerator::ComputeLinkOptions()
config)
{ {
if(this->Target->GetType() == cmTarget::EXECUTABLE ||
// static libraries and things greater than modules do not need this->Target->GetType() == cmTarget::SHARED_LIBRARY ||
// to set this option this->Target->GetType() == cmTarget::MODULE_LIBRARY)
if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
|| this->Target->GetType() > cmTarget::MODULE_LIBRARY)
{ {
return; std::vector<std::string> const* configs =
this->GlobalGenerator->GetConfigurations();
for(std::vector<std::string>::const_iterator i = configs->begin();
i != configs->end(); ++i)
{
if(!this->ComputeLinkOptions(*i))
{
return false;
} }
}
}
return true;
}
//----------------------------------------------------------------------------
bool
cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config)
{
cmsys::auto_ptr<Options> pOptions(
new Options(this->LocalGenerator, Options::Linker,
cmVSGetLinkFlagTable(this->LocalGenerator), 0, this));
Options& linkOptions = *pOptions;
const char* linkLanguage = const char* linkLanguage =
this->Target->GetLinkerLanguage(config.c_str()); this->Target->GetLinkerLanguage(config.c_str());
if(!linkLanguage) if(!linkLanguage)
@ -1362,10 +1335,9 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
cmSystemTools::Error cmSystemTools::Error
("CMake can not determine linker language for target:", ("CMake can not determine linker language for target:",
this->Name.c_str()); this->Name.c_str());
return; return false;
} }
this->WriteString("<Link>\n", 2);
std::string CONFIG = cmSystemTools::UpperCase(config); std::string CONFIG = cmSystemTools::UpperCase(config);
const char* linkType = "SHARED"; const char* linkType = "SHARED";
@ -1387,7 +1359,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
flags += " "; flags += " ";
flags += stackVal; flags += stackVal;
} }
// assume incremental linking
std::string linkFlagVarBase = "CMAKE_"; std::string linkFlagVarBase = "CMAKE_";
linkFlagVarBase += linkType; linkFlagVarBase += linkType;
linkFlagVarBase += "_LINKER_FLAGS"; linkFlagVarBase += "_LINKER_FLAGS";
@ -1411,10 +1382,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
flags += " "; flags += " ";
flags += flagsConfig; flags += flagsConfig;
} }
cmVisualStudioGeneratorOptions
linkOptions(this->LocalGenerator,
cmVisualStudioGeneratorOptions::Linker,
cmVSGetLinkFlagTable(this->LocalGenerator), 0, this);
if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") ) if ( this->Target->GetPropertyAsBool("WIN32_EXECUTABLE") )
{ {
flags += " /SUBSYSTEM:WINDOWS"; flags += " /SUBSYSTEM:WINDOWS";
@ -1423,8 +1390,6 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
{ {
flags += " /SUBSYSTEM:CONSOLE"; flags += " /SUBSYSTEM:CONSOLE";
} }
cmSystemTools::ReplaceString(flags, "/INCREMENTAL:YES", "");
cmSystemTools::ReplaceString(flags, "/INCREMENTAL:NO", "");
std::string standardLibsVar = "CMAKE_"; std::string standardLibsVar = "CMAKE_";
standardLibsVar += linkLanguage; standardLibsVar += linkLanguage;
standardLibsVar += "_STANDARD_LIBRARIES"; standardLibsVar += "_STANDARD_LIBRARIES";
@ -1452,7 +1417,7 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
cmSystemTools::Error cmSystemTools::Error
("CMake can not compute cmComputeLinkInformation for target:", ("CMake can not compute cmComputeLinkInformation for target:",
this->Name.c_str()); this->Name.c_str());
return; return false;
} }
// add the libraries for the target to libs string // add the libraries for the target to libs string
cmComputeLinkInformation& cli = *pcli; cmComputeLinkInformation& cli = *pcli;
@ -1521,7 +1486,22 @@ void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const&
this->GeneratorTarget->ModuleDefinitionFile.c_str()); this->GeneratorTarget->ModuleDefinitionFile.c_str());
} }
linkOptions.RemoveFlag("GenerateManifest"); this->LinkOptions[config] = pOptions.release();
return true;
}
//----------------------------------------------------------------------------
void
cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config)
{
if(this->Target->GetType() == cmTarget::STATIC_LIBRARY
|| this->Target->GetType() > cmTarget::MODULE_LIBRARY)
{
return;
}
Options& linkOptions = *(this->LinkOptions[config]);
this->WriteString("<Link>\n", 2);
linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", ""); linkOptions.OutputAdditionalOptions(*this->BuildFileStream, " ", "");
linkOptions.OutputFlagMap(*this->BuildFileStream, " "); linkOptions.OutputFlagMap(*this->BuildFileStream, " ");

View File

@ -68,6 +68,8 @@ private:
std::vector<std::string> const & includes); std::vector<std::string> const & includes);
void WriteRCOptions(std::string const& config, void WriteRCOptions(std::string const& config,
std::vector<std::string> const & includes); std::vector<std::string> const & includes);
bool ComputeLinkOptions();
bool ComputeLinkOptions(std::string const& config);
void WriteLinkOptions(std::string const& config); void WriteLinkOptions(std::string const& config);
void WriteMidlOptions(std::string const& config, void WriteMidlOptions(std::string const& config,
std::vector<std::string> const & includes); std::vector<std::string> const & includes);
@ -95,6 +97,7 @@ private:
typedef cmVisualStudioGeneratorOptions Options; typedef cmVisualStudioGeneratorOptions Options;
typedef std::map<cmStdString, Options*> OptionsMap; typedef std::map<cmStdString, Options*> OptionsMap;
OptionsMap ClOptions; OptionsMap ClOptions;
OptionsMap LinkOptions;
std::string PathToVcxproj; std::string PathToVcxproj;
cmTarget* Target; cmTarget* Target;
cmGeneratorTarget* GeneratorTarget; cmGeneratorTarget* GeneratorTarget;