diff options
author | Brad King <brad.king@kitware.com> | 2015-03-09 13:45:51 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-03-09 13:45:51 (GMT) |
commit | 387466dd9508ae57a864cdd8f2c8d8d28140b74c (patch) | |
tree | 31b689ec4ecfa9a1a6d348da62d3b31f151a8d35 /Source/cmMakefileTargetGenerator.cxx | |
parent | bdb00b36133c64a36fbba7fd6c648725062b6732 (diff) | |
parent | 66a9c90c4bb5bf93bd570a423f99486b24b9337d (diff) | |
download | CMake-387466dd9508ae57a864cdd8f2c8d8d28140b74c.zip CMake-387466dd9508ae57a864cdd8f2c8d8d28140b74c.tar.gz CMake-387466dd9508ae57a864cdd8f2c8d8d28140b74c.tar.bz2 |
Merge topic 'custom-command-multiple-outputs'
66a9c90c Makefile: Fix multiple custom command outputs regression (#15116)
Diffstat (limited to 'Source/cmMakefileTargetGenerator.cxx')
-rw-r--r-- | Source/cmMakefileTargetGenerator.cxx | 79 |
1 files changed, 74 insertions, 5 deletions
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 20207f5..e751bc1 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 @@ -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) |