ENH: Implemented utility targets. This involved pulling part of the custom command rule implementation out into shared methods.
This commit is contained in:
parent
729c5644cf
commit
477f328aed
|
@ -86,6 +86,10 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
|
||||||
{
|
{
|
||||||
this->GenerateTargetRuleFile(t->second);
|
this->GenerateTargetRuleFile(t->second);
|
||||||
}
|
}
|
||||||
|
else if(t->second.GetType() == cmTarget::UTILITY)
|
||||||
|
{
|
||||||
|
this->GenerateUtilityRuleFile(t->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the rule files for each custom command.
|
// Generate the rule files for each custom command.
|
||||||
|
@ -93,9 +97,9 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
|
||||||
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
|
for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
|
||||||
i != sources.end(); ++i)
|
i != sources.end(); ++i)
|
||||||
{
|
{
|
||||||
if((*i)->GetCustomCommand())
|
if(const cmCustomCommand* cc = (*i)->GetCustomCommand())
|
||||||
{
|
{
|
||||||
this->GenerateCustomRuleFile(*(*i));
|
this->GenerateCustomRuleFile(*cc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,18 +516,10 @@ cmLocalUnixMakefileGenerator2
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
::GenerateCustomRuleFile(const cmSourceFile& source)
|
::GenerateCustomRuleFile(const cmCustomCommand& cc)
|
||||||
{
|
{
|
||||||
// Get the custom command for the source.
|
|
||||||
if(!source.GetCustomCommand())
|
|
||||||
{
|
|
||||||
cmSystemTools::Error("GenerateCustomRuleFile called for non-custom source.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const cmCustomCommand& cc = *source.GetCustomCommand();
|
|
||||||
|
|
||||||
// Create a directory for custom rule files.
|
// Create a directory for custom rule files.
|
||||||
std::string dir = "CMakeCustomCommands.dir";
|
std::string dir = "CMakeCustomRules.dir";
|
||||||
cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
|
cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
|
||||||
|
|
||||||
// Construct the name of the rule file.
|
// Construct the name of the rule file.
|
||||||
|
@ -545,8 +541,6 @@ cmLocalUnixMakefileGenerator2
|
||||||
// This rule should be included by the makefile.
|
// This rule should be included by the makefile.
|
||||||
m_IncludeRuleFiles.push_back(ruleFileName);
|
m_IncludeRuleFiles.push_back(ruleFileName);
|
||||||
|
|
||||||
// TODO: Convert outputs/dependencies (arguments?) to relative paths.
|
|
||||||
|
|
||||||
// Open the rule file. This should be copy-if-different because the
|
// Open the rule file. This should be copy-if-different because the
|
||||||
// rules may depend on this file itself.
|
// rules may depend on this file itself.
|
||||||
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
|
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
|
||||||
|
@ -560,51 +554,13 @@ cmLocalUnixMakefileGenerator2
|
||||||
ruleFileStream
|
ruleFileStream
|
||||||
<< "# Custom command rule file for " << customName.c_str() << ".\n\n";
|
<< "# Custom command rule file for " << customName.c_str() << ".\n\n";
|
||||||
|
|
||||||
// Build the command line in a single string.
|
// Collect the commands.
|
||||||
std::vector<std::string> commands;
|
std::vector<std::string> commands;
|
||||||
std::string cmd = cc.GetCommand();
|
this->AddCustomCommands(commands, cc);
|
||||||
cmSystemTools::ReplaceString(cmd, "/./", "/");
|
|
||||||
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
|
|
||||||
if(cc.GetArguments().size() > 0)
|
|
||||||
{
|
|
||||||
cmd += " ";
|
|
||||||
cmd += cc.GetArguments();
|
|
||||||
}
|
|
||||||
commands.push_back(cmd);
|
|
||||||
|
|
||||||
// Collect the dependencies.
|
// Collect the dependencies.
|
||||||
std::vector<std::string> depends;
|
std::vector<std::string> depends;
|
||||||
for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
|
this->AddCustomDepends(depends, cc);
|
||||||
d != cc.GetDepends().end(); ++d)
|
|
||||||
{
|
|
||||||
// Get the dependency with variables expanded.
|
|
||||||
std::string dep = *d;
|
|
||||||
m_Makefile->ExpandVariablesInString(dep);
|
|
||||||
|
|
||||||
// If the rule depends on a target CMake knows how to build,
|
|
||||||
// convert it to the path where it will be built.
|
|
||||||
std::string libPath = dep + "_CMAKE_PATH";
|
|
||||||
const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
|
|
||||||
if(cacheValue && *cacheValue)
|
|
||||||
{
|
|
||||||
libPath = cacheValue;
|
|
||||||
if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH") &&
|
|
||||||
m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")[0] != '\0')
|
|
||||||
{
|
|
||||||
libPath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
|
|
||||||
}
|
|
||||||
libPath += "/";
|
|
||||||
libPath += dep;
|
|
||||||
libPath += cmSystemTools::GetExecutableExtension();
|
|
||||||
dep = libPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup the dependency and add it.
|
|
||||||
cmSystemTools::ReplaceString(dep, "/./", "/");
|
|
||||||
cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
|
|
||||||
dep = this->ConvertToRelativeOutputPath(dep.c_str());
|
|
||||||
depends.push_back(dep.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a dependency on the rule file itself.
|
// Add a dependency on the rule file itself.
|
||||||
depends.push_back(ruleFileName);
|
depends.push_back(ruleFileName);
|
||||||
|
@ -622,6 +578,60 @@ cmLocalUnixMakefileGenerator2
|
||||||
cc.GetOutput().c_str(), depends, commands);
|
cc.GetOutput().c_str(), depends, commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmLocalUnixMakefileGenerator2
|
||||||
|
::GenerateUtilityRuleFile(const cmTarget& target)
|
||||||
|
{
|
||||||
|
// Create a directory for utility rule files.
|
||||||
|
std::string dir = "CMakeCustomRules.dir";
|
||||||
|
cmSystemTools::MakeDirectory(this->ConvertToFullPath(dir).c_str());
|
||||||
|
|
||||||
|
// Construct the name of the rule file.
|
||||||
|
std::string ruleFileName = dir;
|
||||||
|
ruleFileName += "/";
|
||||||
|
ruleFileName += target.GetName();
|
||||||
|
ruleFileName += ".make";
|
||||||
|
|
||||||
|
// This rule should be included by the makefile.
|
||||||
|
m_IncludeRuleFiles.push_back(ruleFileName);
|
||||||
|
|
||||||
|
// Open the rule file. This should be copy-if-different because the
|
||||||
|
// rules may depend on this file itself.
|
||||||
|
std::string ruleFileNameFull = this->ConvertToFullPath(ruleFileName);
|
||||||
|
cmGeneratedFileStream ruleFileStream(ruleFileNameFull.c_str());
|
||||||
|
ruleFileStream.SetCopyIfDifferent(true);
|
||||||
|
if(!ruleFileStream)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->WriteDisclaimer(ruleFileStream);
|
||||||
|
ruleFileStream
|
||||||
|
<< "# Utility rule file for " << target.GetName() << ".\n\n";
|
||||||
|
|
||||||
|
// TODO: Pre-build and pre-link rules.
|
||||||
|
|
||||||
|
// Collect the commands and dependencies.
|
||||||
|
std::vector<std::string> commands;
|
||||||
|
std::vector<std::string> depends;
|
||||||
|
|
||||||
|
// Utility targets store their rules in post-build commands.
|
||||||
|
for(std::vector<cmCustomCommand>::const_iterator
|
||||||
|
i = target.GetPostBuildCommands().begin();
|
||||||
|
i != target.GetPostBuildCommands().end(); ++i)
|
||||||
|
{
|
||||||
|
this->AddCustomCommands(commands, *i);
|
||||||
|
this->AddCustomDepends(depends, *i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a dependency on the rule file itself.
|
||||||
|
depends.push_back(ruleFileName);
|
||||||
|
|
||||||
|
// Write the rule.
|
||||||
|
this->WriteMakeRule(ruleFileStream, 0, 0,
|
||||||
|
target.GetName(), depends, commands);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string
|
std::string
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
|
@ -2135,6 +2145,64 @@ cmLocalUnixMakefileGenerator2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmLocalUnixMakefileGenerator2
|
||||||
|
::AddCustomDepends(std::vector<std::string>& depends,
|
||||||
|
const cmCustomCommand& cc)
|
||||||
|
{
|
||||||
|
// TODO: Convert outputs/dependencies (arguments?) to relative paths.
|
||||||
|
for(std::vector<std::string>::const_iterator d = cc.GetDepends().begin();
|
||||||
|
d != cc.GetDepends().end(); ++d)
|
||||||
|
{
|
||||||
|
// Get the dependency.
|
||||||
|
std::string dep = *d;
|
||||||
|
|
||||||
|
// If the dependency is a target CMake knows how to build, convert
|
||||||
|
// it to the path where it will be built.
|
||||||
|
std::string libPath = dep + "_CMAKE_PATH";
|
||||||
|
const char* cacheValue = m_Makefile->GetDefinition(libPath.c_str());
|
||||||
|
if(cacheValue && *cacheValue)
|
||||||
|
{
|
||||||
|
libPath = cacheValue;
|
||||||
|
if (m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH") &&
|
||||||
|
m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH")[0] != '\0')
|
||||||
|
{
|
||||||
|
libPath = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH");
|
||||||
|
}
|
||||||
|
libPath += "/";
|
||||||
|
libPath += dep;
|
||||||
|
libPath += cmSystemTools::GetExecutableExtension();
|
||||||
|
dep = libPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup the dependency and add it.
|
||||||
|
cmSystemTools::ReplaceString(dep, "/./", "/");
|
||||||
|
cmSystemTools::ReplaceString(dep, "/$(IntDir)/", "/");
|
||||||
|
depends.push_back(dep.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
cmLocalUnixMakefileGenerator2
|
||||||
|
::AddCustomCommands(std::vector<std::string>& commands,
|
||||||
|
const cmCustomCommand& cc)
|
||||||
|
{
|
||||||
|
// TODO: Convert outputs/dependencies (arguments?) to relative paths.
|
||||||
|
|
||||||
|
// Build the command line in a single string.
|
||||||
|
std::string cmd = cc.GetCommand();
|
||||||
|
cmSystemTools::ReplaceString(cmd, "/./", "/");
|
||||||
|
cmd = this->ConvertToRelativeOutputPath(cmd.c_str());
|
||||||
|
if(cc.GetArguments().size() > 0)
|
||||||
|
{
|
||||||
|
cmd += " ";
|
||||||
|
cmd += cc.GetArguments();
|
||||||
|
}
|
||||||
|
commands.push_back(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
std::string
|
std::string
|
||||||
cmLocalUnixMakefileGenerator2
|
cmLocalUnixMakefileGenerator2
|
||||||
|
|
|
@ -66,7 +66,8 @@ protected:
|
||||||
void GenerateTargetRuleFile(const cmTarget& target);
|
void GenerateTargetRuleFile(const cmTarget& target);
|
||||||
void GenerateObjectRuleFile(const cmTarget& target,
|
void GenerateObjectRuleFile(const cmTarget& target,
|
||||||
const cmSourceFile& source);
|
const cmSourceFile& source);
|
||||||
void GenerateCustomRuleFile(const cmSourceFile& source);
|
void GenerateCustomRuleFile(const cmCustomCommand& cc);
|
||||||
|
void GenerateUtilityRuleFile(const cmTarget& target);
|
||||||
std::string GenerateDependsMakeFile(const char* file);
|
std::string GenerateDependsMakeFile(const char* file);
|
||||||
void WriteMakeRule(std::ostream& os,
|
void WriteMakeRule(std::ostream& os,
|
||||||
const char* comment,
|
const char* comment,
|
||||||
|
@ -145,6 +146,10 @@ protected:
|
||||||
void AppendLibDepends(const cmTarget& target,
|
void AppendLibDepends(const cmTarget& target,
|
||||||
std::vector<std::string>& depends);
|
std::vector<std::string>& depends);
|
||||||
void AppendLibDepend(std::vector<std::string>& depends, const char* name);
|
void AppendLibDepend(std::vector<std::string>& depends, const char* name);
|
||||||
|
void AddCustomDepends(std::vector<std::string>& depends,
|
||||||
|
const cmCustomCommand& cc);
|
||||||
|
void AddCustomCommands(std::vector<std::string>& commands,
|
||||||
|
const cmCustomCommand& cc);
|
||||||
std::string GetRecursiveMakeCall(const char* tgt);
|
std::string GetRecursiveMakeCall(const char* tgt);
|
||||||
void WriteJumpAndBuildRules(std::ostream& makefileStream);
|
void WriteJumpAndBuildRules(std::ostream& makefileStream);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue