diff options
author | Brad King <brad.king@kitware.com> | 2018-10-08 13:14:58 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-11-19 15:23:51 (GMT) |
commit | 8a9edb110354d5468ab42685cfece6a073146f27 (patch) | |
tree | ffe78231c4bdc8ad7e3a277a2b6b4f1822f5de0a /src/depfile_parser.in.cc | |
parent | 4a4f9d40e178a9a9e88f4cd502d2be49bf7938d8 (diff) | |
download | Ninja-8a9edb110354d5468ab42685cfece6a073146f27.zip Ninja-8a9edb110354d5468ab42685cfece6a073146f27.tar.gz Ninja-8a9edb110354d5468ab42685cfece6a073146f27.tar.bz2 |
Restore depfile toleration of multiple output paths on distinct lines
Prior to introduction of depfile parser handling of multiple rules,
ninja silently accepted a depfile of the form:
out: in1 in2 in3
other: otherIn1 otherIn2 otherIn3
and incorrectly treated `other` and `otherIn*` as additional inputs to
`out`. Now we prefer to reject this just as we already do for a depfile
specifying multiple outputs on one line. However, this can break
existing cases where such a depfile was silently tolerated.
Add a `-w depfilemulti={err,warn}` option to control this behavior,
and make it just a warning by default.
Diffstat (limited to 'src/depfile_parser.in.cc')
-rw-r--r-- | src/depfile_parser.in.cc | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc index d299ee2..f8c94b3 100644 --- a/src/depfile_parser.in.cc +++ b/src/depfile_parser.in.cc @@ -13,6 +13,12 @@ // limitations under the License. #include "depfile_parser.h" +#include "util.h" + +DepfileParser::DepfileParser(DepfileParserOptions options) + : options_(options) +{ +} // A note on backslashes in Makefiles, from reading the docs: // Backslash-newline is the line continuation character. @@ -36,6 +42,8 @@ bool DepfileParser::Parse(string* content, string* err) { char* end = in + content->size(); bool have_target = false; bool have_secondary_target_on_this_rule = false; + bool have_newline_since_primary_target = false; + bool warned_distinct_target_lines = false; bool parsing_targets = true; while (in < end) { bool have_newline = false; @@ -119,8 +127,23 @@ bool DepfileParser::Parse(string* content, string* err) { if (len > 0) { if (is_dependency) { if (have_secondary_target_on_this_rule) { - *err = "depfile has multiple output paths"; - return false; + if (!have_newline_since_primary_target) { + *err = "depfile has multiple output paths"; + return false; + } else if (options_.depfile_distinct_target_lines_action_ == + kDepfileDistinctTargetLinesActionError) { + *err = + "depfile has multiple output paths (on separate lines)" + " [-w depfilemulti=err]"; + return false; + } else { + if (!warned_distinct_target_lines) { + warned_distinct_target_lines = true; + Warning("depfile has multiple output paths (on separate lines); " + "continuing anyway [-w depfilemulti=warn]"); + } + continue; + } } ins_.push_back(StringPiece(filename, len)); } else if (!out_.str_) { @@ -134,6 +157,9 @@ bool DepfileParser::Parse(string* content, string* err) { // A newline ends a rule so the next filename will be a new target. parsing_targets = true; have_secondary_target_on_this_rule = false; + if (have_target) { + have_newline_since_primary_target = true; + } } } if (!have_target) { |