aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/kati/main.go7
-rw-r--r--dep.go7
-rw-r--r--ninja.go67
3 files changed, 50 insertions, 31 deletions
diff --git a/cmd/kati/main.go b/cmd/kati/main.go
index 4d526be..be78703 100644
--- a/cmd/kati/main.go
+++ b/cmd/kati/main.go
@@ -54,6 +54,7 @@ var (
queryFlag string
eagerCmdEvalFlag bool
generateNinja bool
+ ninjaSuffix string
gomaDir string
findCachePrunes string
findCacheLeafNames string
@@ -82,6 +83,7 @@ func init() {
flag.StringVar(&queryFlag, "query", "", "Show the target info")
flag.BoolVar(&eagerCmdEvalFlag, "eager_cmd_eval", false, "Eval commands first.")
flag.BoolVar(&generateNinja, "ninja", false, "Generate build.ninja.")
+ flag.StringVar(&ninjaSuffix, "ninja_suffix", "", "suffix for ninja files.")
flag.StringVar(&gomaDir, "goma_dir", "", "If specified, use goma to build C/C++ files.")
flag.StringVar(&findCachePrunes, "find_cache_prunes", "",
@@ -297,7 +299,10 @@ func katiMain(args []string) error {
}
if generateNinja {
- return kati.GenerateNinja(g, gomaDir)
+ n := kati.NinjaGenerator{
+ GomaDir: gomaDir,
+ }
+ return n.Save(g, ninjaSuffix, req.Targets)
}
if syntaxCheckOnlyFlag {
diff --git a/dep.go b/dep.go
index 75afd49..69cc417 100644
--- a/dep.go
+++ b/dep.go
@@ -17,6 +17,7 @@ package kati
import (
"fmt"
"path/filepath"
+ "sort"
"strings"
"github.com/golang/glog"
@@ -532,6 +533,12 @@ func (db *depBuilder) Eval(targets []string) ([]*DepNode, error) {
return nil, fmt.Errorf("*** No targets.")
}
targets = append(targets, db.firstRule.outputs[0])
+ var phonys []string
+ for t := range db.phony {
+ phonys = append(phonys, t)
+ }
+ sort.Strings(phonys)
+ targets = append(targets, phonys...)
}
logStats("%d variables", len(db.vars))
diff --git a/ninja.go b/ninja.go
index 7c8f8e7..722fe44 100644
--- a/ninja.go
+++ b/ninja.go
@@ -26,7 +26,11 @@ import (
"time"
)
-type ninjaGenerator struct {
+// NinjaGenerator generates ninja build files from DepGraph.
+type NinjaGenerator struct {
+ // GomaDir is goma directory. If empty, goma will not be used.
+ GomaDir string
+
f *os.File
nodes []*DepNode
exports map[string]bool
@@ -36,19 +40,14 @@ type ninjaGenerator struct {
ruleID int
done map[string]bool
shortNames map[string][]string
- gomaDir string
}
-func newNinjaGenerator(g *DepGraph, gomaDir string) *ninjaGenerator {
- ctx := newExecContext(g.vars, g.vpaths, true)
- return &ninjaGenerator{
- nodes: g.nodes,
- exports: g.exports,
- ctx: ctx,
- done: make(map[string]bool),
- shortNames: make(map[string][]string),
- gomaDir: gomaDir,
- }
+func (n *NinjaGenerator) init(g *DepGraph) {
+ n.nodes = g.nodes
+ n.exports = g.exports
+ n.ctx = newExecContext(g.vars, g.vpaths, true)
+ n.done = make(map[string]bool)
+ n.shortNames = make(map[string][]string)
}
func getDepfileImpl(ss string) (string, error) {
@@ -181,7 +180,7 @@ func gomaCmdForAndroidCompileCmd(cmd string) (string, bool) {
return cmd, ccRE.MatchString(cmd)
}
-func (n *ninjaGenerator) genShellScript(runners []runner) (string, bool) {
+func (n *NinjaGenerator) genShellScript(runners []runner) (string, bool) {
useGomacc := false
var buf bytes.Buffer
for i, r := range runners {
@@ -201,10 +200,10 @@ func (n *ninjaGenerator) genShellScript(runners []runner) (string, bool) {
if cmd == "" {
cmd = "true"
}
- if n.gomaDir != "" {
+ if n.GomaDir != "" {
rcmd, ok := gomaCmdForAndroidCompileCmd(cmd)
if ok {
- cmd = fmt.Sprintf("%s/gomacc %s", n.gomaDir, rcmd)
+ cmd = fmt.Sprintf("%s/gomacc %s", n.GomaDir, rcmd)
useGomacc = true
}
}
@@ -225,16 +224,16 @@ func (n *ninjaGenerator) genShellScript(runners []runner) (string, bool) {
buf.WriteByte(')')
}
}
- return buf.String(), n.gomaDir != "" && !useGomacc
+ return buf.String(), n.GomaDir != "" && !useGomacc
}
-func (n *ninjaGenerator) genRuleName() string {
+func (n *NinjaGenerator) genRuleName() string {
ruleName := fmt.Sprintf("rule%d", n.ruleID)
n.ruleID++
return ruleName
}
-func (n *ninjaGenerator) emitBuild(output, rule, dep string) {
+func (n *NinjaGenerator) emitBuild(output, rule, dep string) {
fmt.Fprintf(n.f, "build %s: %s%s\n", output, rule, dep)
}
@@ -257,7 +256,7 @@ func getDepString(node *DepNode) string {
return dep
}
-func (n *ninjaGenerator) emitNode(node *DepNode) error {
+func (n *NinjaGenerator) emitNode(node *DepNode) error {
if n.done[node.Output] {
return nil
}
@@ -328,8 +327,8 @@ func (n *ninjaGenerator) emitNode(node *DepNode) error {
return nil
}
-func (n *ninjaGenerator) generateShell() (err error) {
- f, err := os.Create("ninja.sh")
+func (n *NinjaGenerator) generateShell(suffix string) (err error) {
+ f, err := os.Create(fmt.Sprintf("ninja%s.sh", suffix))
if err != nil {
return err
}
@@ -352,7 +351,7 @@ func (n *ninjaGenerator) generateShell() (err error) {
fmt.Fprintf(f, "unset %s\n", name)
}
}
- if n.gomaDir == "" {
+ if n.GomaDir == "" {
fmt.Fprintln(f, `exec ninja "$@"`)
} else {
fmt.Fprintln(f, `exec ninja -j300 "$@"`)
@@ -361,8 +360,8 @@ func (n *ninjaGenerator) generateShell() (err error) {
return f.Chmod(0755)
}
-func (n *ninjaGenerator) generateNinja() (err error) {
- f, err := os.Create("build.ninja")
+func (n *NinjaGenerator) generateNinja(suffix, defaultTarget string) (err error) {
+ f, err := os.Create(fmt.Sprintf("build%s.ninja", suffix))
if err != nil {
return err
}
@@ -394,7 +393,7 @@ func (n *ninjaGenerator) generateNinja() (err error) {
fmt.Fprintf(n.f, "\n")
}
- if n.gomaDir != "" {
+ if n.GomaDir != "" {
fmt.Fprintf(n.f, "pool local_pool\n")
fmt.Fprintf(n.f, " depth = %d\n", runtime.NumCPU())
}
@@ -406,6 +405,10 @@ func (n *ninjaGenerator) generateNinja() (err error) {
}
}
+ if defaultTarget != "" {
+ fmt.Fprintf(n.f, "\ndefault %s\n", defaultTarget)
+ }
+
fmt.Fprintf(n.f, "\n# shortcuts:\n")
var names []string
for name := range n.shortNames {
@@ -422,15 +425,19 @@ func (n *ninjaGenerator) generateNinja() (err error) {
return nil
}
-// GenerateNinja generates build.ninja from DepGraph.
-func GenerateNinja(g *DepGraph, gomaDir string) error {
+// Save generates build.ninja from DepGraph.
+func (n *NinjaGenerator) Save(g *DepGraph, suffix string, targets []string) error {
startTime := time.Now()
- n := newNinjaGenerator(g, gomaDir)
- err := n.generateShell()
+ n.init(g)
+ err := n.generateShell(suffix)
if err != nil {
return err
}
- err = n.generateNinja()
+ var defaultTarget string
+ if len(targets) == 0 && len(g.nodes) > 0 {
+ defaultTarget = g.nodes[0].Output
+ }
+ err = n.generateNinja(suffix, defaultTarget)
if err != nil {
return err
}