|
|
@@ -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
|
|
|
@@ -1240,9 +1310,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)
|