BUG: Fix config test for target install rules

In single-configuration generators a target installation rule should
apply to all configurations for which the INSTALL command was specified.
The configuration in which the target is built does not matter.

In multi-configuration generators each installation rule must be
associated with a particular build configuration to install the proper
file.  The set of configurations for which rules are generated is the
intersection of the build configurations and those for which the INSTALL
command was specified.
This commit is contained in:
Brad King 2008-10-03 10:11:47 -04:00
parent adc880d2eb
commit 7f819903ed
2 changed files with 37 additions and 55 deletions

View File

@ -57,16 +57,8 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
cmSystemTools::Message(msg.str().c_str(), "Warning");
}
// Track indentation.
Indent indent;
// Begin this block of installation.
std::string component_test =
this->CreateComponentTest(this->Component.c_str());
os << indent << "IF(" << component_test << ")\n";
// Compute the build tree directory from which to copy the target.
std::string fromDir;
std::string& fromDir = this->FromDir;
if(this->Target->NeedRelinkBeforeInstall())
{
fromDir = this->Target->GetMakefile()->GetStartOutputDirectory();
@ -79,70 +71,62 @@ void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
fromDir += "/";
}
// Generate a portion of the script for each configuration.
// Perform the main install script generation.
this->cmInstallGenerator::GenerateScript(os);
}
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptConfigs(std::ostream& os,
Indent const& indent)
{
if(this->ConfigurationTypes->empty())
{
this->GenerateScriptForConfig(os, fromDir.c_str(),
this->ConfigurationName,
indent.Next());
// In a single-configuration generator, only the install rule's
// configuration test is important. If that passes, the target is
// installed regardless of for what configuration it was built.
this->cmInstallGenerator::GenerateScriptConfigs(os, indent);
}
else
{
// In a multi-configuration generator, a separate rule is produced
// in a block for each configuration that is built. However, the
// list of configurations is restricted to those for which this
// install rule applies.
for(std::vector<std::string>::const_iterator i =
this->ConfigurationTypes->begin();
i != this->ConfigurationTypes->end(); ++i)
{
this->GenerateScriptForConfig(os, fromDir.c_str(), i->c_str(),
indent.Next());
const char* config = i->c_str();
if(this->InstallsForConfig(config))
{
// Generate a per-configuration block.
std::string config_test = this->CreateConfigTest(config);
os << indent << "IF(" << config_test << ")\n";
this->GenerateScriptForConfig(os, config, indent.Next());
os << indent << "ENDIF(" << config_test << ")\n";
}
}
}
}
// End this block of installation.
os << indent << "ENDIF(" << component_test << ")\n\n";
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptActions(std::ostream& os,
Indent const& indent)
{
// This is reached for single-configuration generators only.
this->GenerateScriptForConfig(os, this->ConfigurationName, indent);
}
//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
const char* fromDir,
const char* config,
Indent const& indent)
{
// Compute the per-configuration directory containing the files.
std::string fromDirConfig = fromDir;
std::string fromDirConfig = this->FromDir;
this->Target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()
->AppendDirectoryForConfig("", config, "/", fromDirConfig);
if(config && *config)
{
// Skip this configuration for config-specific installation that
// does not match it.
if(!this->InstallsForConfig(config))
{
return;
}
// Generate a per-configuration block.
std::string config_test = this->CreateConfigTest(config);
os << indent << "IF(" << config_test << ")\n";
this->GenerateScriptForConfigDir(os, fromDirConfig.c_str(), config,
indent.Next());
os << indent << "ENDIF(" << config_test << ")\n";
}
else
{
this->GenerateScriptForConfigDir(os, fromDirConfig.c_str(), config,
indent);
}
}
//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
::GenerateScriptForConfigDir(std::ostream& os,
const char* fromDirConfig,
const char* config,
Indent const& indent)
{
// Compute the full path to the main installed file for this target.
NameType nameType = this->ImportLibrary? NameImplib : NameNormal;
std::string toInstallPath = this->GetInstallDestination();

View File

@ -66,14 +66,11 @@ public:
protected:
typedef cmInstallGeneratorIndent Indent;
virtual void GenerateScript(std::ostream& os);
virtual void GenerateScriptConfigs(std::ostream& os, Indent const& indent);
virtual void GenerateScriptActions(std::ostream& os, Indent const& indent);
void GenerateScriptForConfig(std::ostream& os,
const char* fromDir,
const char* config,
Indent const& indent);
void GenerateScriptForConfigDir(std::ostream& os,
const char* fromDirConfig,
const char* config,
Indent const& indent);
void AddInstallNamePatchRule(std::ostream& os, Indent const& indent,
const char* config,
const std::string& toDestDirPath);
@ -96,6 +93,7 @@ protected:
std::string FilePermissions;
bool Optional;
NamelinkModeType NamelinkMode;
std::string FromDir;
};
#endif