1// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// This tool reads "make"-like dependency files, and outputs a canonical version
16// that can be used by ninja. Ninja doesn't support multiple output files (even
17// though it doesn't care what the output file is, or whether it matches what is
18// expected).
19package main
20
21import (
22	"bytes"
23	"flag"
24	"fmt"
25	"io/ioutil"
26	"log"
27	"os"
28
29	"android/soong/makedeps"
30)
31
32func main() {
33	flag.Usage = func() {
34		fmt.Fprintf(os.Stderr, "Usage: %s [-o <output>] <depfile.d> [<depfile.d>...]", os.Args[0])
35		flag.PrintDefaults()
36	}
37	output := flag.String("o", "", "Optional output file (defaults to rewriting source if necessary)")
38	flag.Parse()
39
40	if flag.NArg() < 1 {
41		log.Fatal("Expected at least one input file as an argument")
42	}
43
44	var mergedDeps *makedeps.Deps
45	var firstInput []byte
46
47	for i, arg := range flag.Args() {
48		input, err := ioutil.ReadFile(arg)
49		if err != nil {
50			log.Fatalf("Error opening %q: %v", arg, err)
51		}
52
53		deps, err := makedeps.Parse(arg, bytes.NewBuffer(append([]byte(nil), input...)))
54		if err != nil {
55			log.Fatalf("Failed to parse: %v", err)
56		}
57
58		if i == 0 {
59			mergedDeps = deps
60			firstInput = input
61		} else {
62			mergedDeps.Inputs = append(mergedDeps.Inputs, deps.Inputs...)
63		}
64	}
65
66	new := mergedDeps.Print()
67
68	if *output == "" || *output == flag.Arg(0) {
69		if !bytes.Equal(firstInput, new) {
70			err := ioutil.WriteFile(flag.Arg(0), new, 0666)
71			if err != nil {
72				log.Fatalf("Failed to write: %v", err)
73			}
74		}
75	} else {
76		err := ioutil.WriteFile(*output, new, 0666)
77		if err != nil {
78			log.Fatalf("Failed to write to %q: %v", *output, err)
79		}
80	}
81}
82