diff options
-rw-r--r-- | exec.go | 13 | ||||
-rw-r--r-- | rule_parser.go | 39 | ||||
-rw-r--r-- | rule_parser_test.go | 8 | ||||
-rw-r--r-- | test/order_only.mk | 14 |
4 files changed, 57 insertions, 17 deletions
@@ -177,6 +177,19 @@ func (ex *Executor) build(vars map[string]string, output string) (int64, error) } } + for _, input := range rule.orderOnlyInputs { + if exists(input) { + continue + } + ts, err := ex.build(vars, input) + if err != nil { + return outputTs, err + } + if latest < ts { + latest = ts + } + } + if outputTs >= latest { return outputTs, nil } diff --git a/rule_parser.go b/rule_parser.go index b560876..c7ee1bd 100644 --- a/rule_parser.go +++ b/rule_parser.go @@ -5,21 +5,38 @@ import ( ) type Rule struct { - outputs []string - inputs []string - outputPatterns []string - isDoubleColon bool - isSuffixRule bool - cmds []string - filename string - lineno int - cmdLineno int + outputs []string + inputs []string + orderOnlyInputs []string + outputPatterns []string + isDoubleColon bool + isSuffixRule bool + cmds []string + filename string + lineno int + cmdLineno int } func isPatternRule(s string) bool { return strings.IndexByte(s, '%') >= 0 } +func (r *Rule) parseInputs(s string) { + inputs := splitSpaces(s) + isOrderOnly := false + for _, input := range inputs { + if input == "|" { + isOrderOnly = true + continue + } + if isOrderOnly { + r.orderOnlyInputs = append(r.orderOnlyInputs, input) + } else { + r.inputs = append(r.inputs, input) + } + } +} + func (r *Rule) parse(line string) string { index := strings.IndexByte(line, ':') if index < 0 { @@ -47,7 +64,7 @@ func (r *Rule) parse(line string) string { rest := line[index:] index = strings.IndexByte(rest, ':') if index < 0 { - r.inputs = splitSpaces(rest) + r.parseInputs(rest) return "" } @@ -70,7 +87,7 @@ func (r *Rule) parse(line string) string { if !isPatternRule(r.outputPatterns[0]) { return "*** target pattern contains no '%'." } - r.inputs = splitSpaces(third) + r.parseInputs(third) return "" } diff --git a/rule_parser_test.go b/rule_parser_test.go index dbc166e..f44c589 100644 --- a/rule_parser_test.go +++ b/rule_parser_test.go @@ -72,6 +72,14 @@ func TestRuleParser(t *testing.T) { in: "foo.o: foo.o: %.c", err: "*** target pattern contains no '%'.", }, + { + in: "foo: bar | baz", + want: Rule{ + outputs: []string{"foo"}, + inputs: []string{"bar"}, + orderOnlyInputs: []string{"baz"}, + }, + }, /* TODO { in: "foo.o: %.c: %.c", diff --git a/test/order_only.mk b/test/order_only.mk index 90fc831..b8e0cfd 100644 --- a/test/order_only.mk +++ b/test/order_only.mk @@ -1,11 +1,13 @@ -# TODO(hamaji): Fix. - test1: - touch foo + touch -t 197101010000 foo touch bar -test2: foo - echo PASS +# Note order-only dependency will not appear in $^ +test2: foo | bar + echo PASS_$^ + +# bar is newer than foo but we should not rebuild it. +foo: | bar baz -foo: | bar +baz: touch $@ |