summaryrefslogtreecommitdiffstats
path: root/Source/cmMakefileTargetGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmMakefileTargetGenerator.cxx')
-rw-r--r--Source/cmMakefileTargetGenerator.cxx79
1 files changed, 74 insertions, 5 deletions
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index c7a7110..641cd23 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -769,8 +769,8 @@ cmMakefileTargetGenerator
}
// Write the rule.
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- outputs, depends, commands, false);
+ this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
+ depends, commands, false);
bool do_preprocess_rules = lang_has_preprocessor &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
@@ -991,6 +991,57 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
depends, commands, true);
}
+//----------------------------------------------------------------------------
+void cmMakefileTargetGenerator::WriteMakeRule(
+ std::ostream& os,
+ const char* comment,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& depends,
+ const std::vector<std::string>& commands,
+ bool symbolic,
+ bool in_help)
+{
+ if (outputs.size() == 0)
+ {
+ return;
+ }
+
+ // We always attach the actual commands to the first output.
+ this->LocalGenerator->WriteMakeRule(os, comment, outputs[0], depends,
+ commands, symbolic, in_help);
+
+ // For single outputs, we are done.
+ if (outputs.size() == 1)
+ {
+ return;
+ }
+
+ // For multiple outputs, make the extra ones depend on the first one.
+ std::vector<std::string> const output_depends(1, outputs[0]);
+ for (std::vector<std::string>::const_iterator o = outputs.begin()+1;
+ o != outputs.end(); ++o)
+ {
+ // Touch the extra output so "make" knows that it was updated,
+ // but only if the output was acually created.
+ std::string const out = this->Convert(*o, cmLocalGenerator::HOME_OUTPUT,
+ cmLocalGenerator::SHELL);
+ std::vector<std::string> output_commands;
+ if (!symbolic)
+ {
+ output_commands.push_back("@$(CMAKE_COMMAND) -E touch_nocreate " + out);
+ }
+ this->LocalGenerator->WriteMakeRule(os, 0, *o, output_depends,
+ output_commands, symbolic, in_help);
+
+ if (!symbolic)
+ {
+ // At build time, remove the first output if this one does not exist
+ // so that "make" will rerun the real commands that create this one.
+ MultipleOutputPairsType::value_type p(*o, outputs[0]);
+ this->MultipleOutputPairs.insert(p);
+ }
+ }
+}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteTargetDependRules()
@@ -1011,6 +1062,25 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
this->LocalGenerator->
WriteDependLanguageInfo(*this->InfoFileStream,*this->Target);
+ // Store multiple output pairs in the depend info file.
+ if(!this->MultipleOutputPairs.empty())
+ {
+ *this->InfoFileStream
+ << "\n"
+ << "# Pairs of files generated by the same build rule.\n"
+ << "set(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
+ for(MultipleOutputPairsType::const_iterator pi =
+ this->MultipleOutputPairs.begin();
+ pi != this->MultipleOutputPairs.end(); ++pi)
+ {
+ *this->InfoFileStream
+ << " " << this->LocalGenerator->EscapeForCMake(pi->first)
+ << " " << this->LocalGenerator->EscapeForCMake(pi->second)
+ << "\n";
+ }
+ *this->InfoFileStream << " )\n\n";
+ }
+
// Store list of targets linked directly or transitively.
{
*this->InfoFileStream
@@ -1206,9 +1276,8 @@ void cmMakefileTargetGenerator
symbolic = sf->GetPropertyAsBool("SYMBOLIC");
}
}
- this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
- outputs, depends, commands,
- symbolic);
+ this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
+ depends, commands, symbolic);
// If the rule has changed make sure the output is rebuilt.
if(!symbolic)