summaryrefslogtreecommitdiffstats
path: root/src/depfile_parser.cc
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-10-08 13:14:58 (GMT)
committerBrad King <brad.king@kitware.com>2018-11-19 15:23:51 (GMT)
commit8a9edb110354d5468ab42685cfece6a073146f27 (patch)
treeffe78231c4bdc8ad7e3a277a2b6b4f1822f5de0a /src/depfile_parser.cc
parent4a4f9d40e178a9a9e88f4cd502d2be49bf7938d8 (diff)
downloadNinja-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.cc')
-rw-r--r--src/depfile_parser.cc30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc
index 7724eed..405289f 100644
--- a/src/depfile_parser.cc
+++ b/src/depfile_parser.cc
@@ -14,6 +14,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.
@@ -37,6 +43,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;
@@ -219,8 +227,23 @@ yy22:
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_) {
@@ -234,6 +257,9 @@ yy22:
// 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) {