blob: d1240409b091bdbb3b83b2df8d2d00ecb53337d2 [file] [log] [blame]
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +09001// Copyright 2015 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
15package kati
16
17import (
18 "crypto/sha1"
19 "io/ioutil"
20 "time"
21)
22
23type DepGraph struct {
Fumitoshi Ukai0af44522015-06-25 15:26:08 +090024 nodes []*DepNode
25 vars Vars
26 accessedMks []*accessedMakefile
27 exports map[string]bool
28 isCached bool
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090029}
30
31func (g *DepGraph) Nodes() []*DepNode { return g.nodes }
32func (g *DepGraph) Vars() Vars { return g.vars }
33func (g *DepGraph) Exports() map[string]bool { return g.exports }
34func (g *DepGraph) IsCached() bool { return g.isCached }
35
36type LoadOpt struct {
37 Targets []string
38 CommandLineVars []string
39 EnvironmentVars []string
40 UseCache bool
41}
42
43func Load(makefile string, opt LoadOpt) (*DepGraph, error) {
44 startTime := time.Now()
45 if makefile == "" {
46 makefile = DefaultMakefile()
47 }
48
49 if opt.UseCache {
50 g := LoadDepGraphCache(makefile, opt.Targets)
51 if g != nil {
52 return g, nil
53 }
54 }
55
56 bmk := BootstrapMakefile(opt.Targets)
57
58 content, err := ioutil.ReadFile(makefile)
59 if err != nil {
60 return nil, err
61 }
62 mk, err := ParseMakefile(content, makefile)
63 if err != nil {
64 return nil, err
65 }
66
67 for _, stmt := range mk.stmts {
68 stmt.show()
69 }
70
71 mk.stmts = append(bmk.stmts, mk.stmts...)
72
73 vars := make(Vars)
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090074 err = initVars(vars, opt.EnvironmentVars, "environment")
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090075 if err != nil {
76 return nil, err
77 }
Fumitoshi Ukai7bf992d2015-06-25 12:42:19 +090078 err = initVars(vars, opt.CommandLineVars, "command line")
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +090079 if err != nil {
80 return nil, err
81 }
82 er, err := Eval(mk, vars, opt.UseCache)
83 if err != nil {
84 return nil, err
85 }
86 vars.Merge(er.vars)
87
88 LogStats("eval time: %q", time.Since(startTime))
89 LogStats("shell func time: %q %d", shellStats.Duration(), shellStats.Count())
90
91 startTime = time.Now()
92 db := NewDepBuilder(er, vars)
93 LogStats("dep build prepare time: %q", time.Since(startTime))
94
95 startTime = time.Now()
96 nodes, err := db.Eval(opt.Targets)
97 if err != nil {
98 return nil, err
99 }
100 LogStats("dep build time: %q", time.Since(startTime))
Fumitoshi Ukai0af44522015-06-25 15:26:08 +0900101 var accessedMks []*accessedMakefile
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900102 // Always put the root Makefile as the first element.
Fumitoshi Ukai0af44522015-06-25 15:26:08 +0900103 accessedMks = append(accessedMks, &accessedMakefile{
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900104 Filename: makefile,
105 Hash: sha1.Sum(content),
Fumitoshi Ukai0af44522015-06-25 15:26:08 +0900106 State: fileExists,
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900107 })
Fumitoshi Ukai0af44522015-06-25 15:26:08 +0900108 accessedMks = append(accessedMks, er.accessedMks...)
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900109 return &DepGraph{
Fumitoshi Ukai0af44522015-06-25 15:26:08 +0900110 nodes: nodes,
111 vars: vars,
112 accessedMks: accessedMks,
113 exports: er.exports,
Fumitoshi Ukai744bb2b2015-06-25 00:10:52 +0900114 }, nil
115}