blob: 423bcbc9d6e21f0a4b4c7e999a69819ee2a65eae [file] [log] [blame]
Dan Willemsen1e704462016-08-21 15:17:17 -07001// Copyright 2017 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 build
16
17import (
18 "crypto/md5"
19 "fmt"
20 "io/ioutil"
21 "os/exec"
22 "path/filepath"
23 "strconv"
24 "strings"
25)
26
27var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_")
28
29// genKatiSuffix creates a suffix for kati-generated files so that we can cache
30// them based on their inputs. So this should encode all common changes to Kati
31// inputs. Currently that includes the TARGET_PRODUCT, kati-processed command
32// line arguments, and the directories specified by mm/mmm.
33func genKatiSuffix(ctx Context, config Config) {
34 katiSuffix := "-" + config.TargetProduct()
35 if args := config.KatiArgs(); len(args) > 0 {
36 katiSuffix += "-" + spaceSlashReplacer.Replace(strings.Join(args, "_"))
37 }
38 if oneShot, ok := config.Environment().Get("ONE_SHOT_MAKEFILE"); ok {
39 katiSuffix += "-" + spaceSlashReplacer.Replace(oneShot)
40 }
41
42 // If the suffix is too long, replace it with a md5 hash and write a
43 // file that contains the original suffix.
44 if len(katiSuffix) > 64 {
45 shortSuffix := "-" + fmt.Sprintf("%x", md5.Sum([]byte(katiSuffix)))
46 config.SetKatiSuffix(shortSuffix)
47
48 ctx.Verbosef("Kati ninja suffix too long: %q", katiSuffix)
49 ctx.Verbosef("Replacing with: %q", shortSuffix)
50
51 if err := ioutil.WriteFile(strings.TrimSuffix(config.KatiNinjaFile(), "ninja")+"suf", []byte(katiSuffix), 0777); err != nil {
52 ctx.Println("Error writing suffix file:", err)
53 }
54 } else {
55 config.SetKatiSuffix(katiSuffix)
56 }
57}
58
59func runKati(ctx Context, config Config) {
Dan Willemsend9f6fa22016-08-21 15:17:17 -070060 ctx.BeginTrace("kati")
61 defer ctx.EndTrace()
62
Dan Willemsen1e704462016-08-21 15:17:17 -070063 genKatiSuffix(ctx, config)
64
65 executable := "prebuilts/build-tools/" + config.HostPrebuiltTag() + "/bin/ckati"
66 args := []string{
67 "--ninja",
68 "--ninja_dir=" + config.OutDir(),
69 "--ninja_suffix=" + config.KatiSuffix(),
70 "--regen",
71 "--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
72 "--detect_android_echo",
73 }
74
75 if !config.Environment().IsFalse("KATI_EMULATE_FIND") {
76 args = append(args, "--use_find_emulator")
77 }
78
79 // The argument order could be simplified, but currently this matches
80 // the ordering in Make
81 args = append(args, "-f", "build/core/main.mk")
82
83 args = append(args, config.KatiArgs()...)
84
85 args = append(args,
86 "--gen_all_targets",
87 "BUILDING_WITH_NINJA=true",
88 "SOONG_ANDROID_MK="+config.SoongAndroidMk(),
89 "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk())
90
91 if config.UseGoma() {
92 args = append(args, "-j"+strconv.Itoa(config.Parallel()))
93 }
94
95 cmd := exec.CommandContext(ctx.Context, executable, args...)
96 cmd.Env = config.Environment().Environ()
97 cmd.Stdout = ctx.Stdout()
98 cmd.Stderr = ctx.Stderr()
99 ctx.Verboseln(cmd.Path, cmd.Args)
100 if err := cmd.Run(); err != nil {
101 if e, ok := err.(*exec.ExitError); ok {
102 ctx.Fatalln("ckati failed with:", e.ProcessState.String())
103 } else {
104 ctx.Fatalln("Failed to run ckati:", err)
105 }
106 }
107}