blob: 423bcbc9d6e21f0a4b4c7e999a69819ee2a65eae [file] [log] [blame]
// Copyright 2017 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package build
import (
"crypto/md5"
"fmt"
"io/ioutil"
"os/exec"
"path/filepath"
"strconv"
"strings"
)
var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_")
// genKatiSuffix creates a suffix for kati-generated files so that we can cache
// them based on their inputs. So this should encode all common changes to Kati
// inputs. Currently that includes the TARGET_PRODUCT, kati-processed command
// line arguments, and the directories specified by mm/mmm.
func genKatiSuffix(ctx Context, config Config) {
katiSuffix := "-" + config.TargetProduct()
if args := config.KatiArgs(); len(args) > 0 {
katiSuffix += "-" + spaceSlashReplacer.Replace(strings.Join(args, "_"))
}
if oneShot, ok := config.Environment().Get("ONE_SHOT_MAKEFILE"); ok {
katiSuffix += "-" + spaceSlashReplacer.Replace(oneShot)
}
// If the suffix is too long, replace it with a md5 hash and write a
// file that contains the original suffix.
if len(katiSuffix) > 64 {
shortSuffix := "-" + fmt.Sprintf("%x", md5.Sum([]byte(katiSuffix)))
config.SetKatiSuffix(shortSuffix)
ctx.Verbosef("Kati ninja suffix too long: %q", katiSuffix)
ctx.Verbosef("Replacing with: %q", shortSuffix)
if err := ioutil.WriteFile(strings.TrimSuffix(config.KatiNinjaFile(), "ninja")+"suf", []byte(katiSuffix), 0777); err != nil {
ctx.Println("Error writing suffix file:", err)
}
} else {
config.SetKatiSuffix(katiSuffix)
}
}
func runKati(ctx Context, config Config) {
ctx.BeginTrace("kati")
defer ctx.EndTrace()
genKatiSuffix(ctx, config)
executable := "prebuilts/build-tools/" + config.HostPrebuiltTag() + "/bin/ckati"
args := []string{
"--ninja",
"--ninja_dir=" + config.OutDir(),
"--ninja_suffix=" + config.KatiSuffix(),
"--regen",
"--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
"--detect_android_echo",
}
if !config.Environment().IsFalse("KATI_EMULATE_FIND") {
args = append(args, "--use_find_emulator")
}
// The argument order could be simplified, but currently this matches
// the ordering in Make
args = append(args, "-f", "build/core/main.mk")
args = append(args, config.KatiArgs()...)
args = append(args,
"--gen_all_targets",
"BUILDING_WITH_NINJA=true",
"SOONG_ANDROID_MK="+config.SoongAndroidMk(),
"SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk())
if config.UseGoma() {
args = append(args, "-j"+strconv.Itoa(config.Parallel()))
}
cmd := exec.CommandContext(ctx.Context, executable, args...)
cmd.Env = config.Environment().Environ()
cmd.Stdout = ctx.Stdout()
cmd.Stderr = ctx.Stderr()
ctx.Verboseln(cmd.Path, cmd.Args)
if err := cmd.Run(); err != nil {
if e, ok := err.(*exec.ExitError); ok {
ctx.Fatalln("ckati failed with:", e.ProcessState.String())
} else {
ctx.Fatalln("Failed to run ckati:", err)
}
}
}