platform_build_soong/ui/build/kati.go
Dan Willemsen 2997123f73 Refactor Kati logic
Make the cleanspec & Android.mk runs of kati use much of the same code
and arguments.

Also renames 'Kati' to 'KatiBuild' in many cases, in the the expectation
that we'll have a 'KatiPackage' step in the future.

Use --no_ninja_prelude and move local_pool & _kati_always_build_ into
the combined ninja file. This will reduce the need to re-read makefiles
when Goma is enabled, and it allows us to include more than one
Kati-generated ninja file in the build graph.

Bug: 116968624
Test: build_test on downstream branches
Change-Id: Ibdac689b81f62dc293647fad917d84946f2c3cfa
2018-09-28 23:09:24 -07:00

142 lines
4.1 KiB
Go

// 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"
"path/filepath"
"strings"
"android/soong/ui/status"
)
var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_")
const katiBuildSuffix = ""
const katiCleanspecSuffix = "-cleanspec"
// 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.KatiBuildNinjaFile(), "ninja")+"suf", []byte(katiSuffix), 0777); err != nil {
ctx.Println("Error writing suffix file:", err)
}
} else {
config.SetKatiSuffix(katiSuffix)
}
}
func runKati(ctx Context, config Config, extraSuffix string, args []string) {
executable := config.PrebuiltBuildTool("ckati")
args = append([]string{
"--ninja",
"--ninja_dir=" + config.OutDir(),
"--ninja_suffix=" + config.KatiSuffix() + extraSuffix,
"--no_ninja_prelude",
"--regen",
"--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
"--detect_android_echo",
"--color_warnings",
"--gen_all_targets",
"--use_find_emulator",
"--werror_find_emulator",
"--no_builtin_rules",
"--werror_suffix_rules",
"--warn_real_to_phony",
"--warn_phony_looks_real",
"--kati_stats",
}, args...)
args = append(args,
"SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
"TARGET_DEVICE_DIR="+config.TargetDeviceDir())
cmd := Command(ctx, config, "ckati", executable, args...)
cmd.Sandbox = katiSandbox
pipe, err := cmd.StdoutPipe()
if err != nil {
ctx.Fatalln("Error getting output pipe for ckati:", err)
}
cmd.Stderr = cmd.Stdout
cmd.StartOrFatal()
status.KatiReader(ctx.Status.StartTool(), pipe)
cmd.WaitOrFatal()
}
func runKatiBuild(ctx Context, config Config) {
ctx.BeginTrace("kati build")
defer ctx.EndTrace()
args := []string{
"--writable", config.OutDir() + "/",
"--writable", config.DistDir() + "/",
"-f", "build/make/core/main.mk",
}
// PDK builds still uses a few implicit rules
if !config.IsPdkBuild() {
args = append(args, "--werror_implicit_rules")
}
if !config.BuildBrokenDupRules() {
args = append(args, "--werror_overriding_commands")
}
if !config.BuildBrokenPhonyTargets() {
args = append(args,
"--werror_real_to_phony",
"--werror_phony_looks_real",
"--werror_writable")
}
args = append(args, config.KatiArgs()...)
args = append(args, "SOONG_ANDROID_MK="+config.SoongAndroidMk())
runKati(ctx, config, katiBuildSuffix, args)
}
func runKatiCleanSpec(ctx Context, config Config) {
ctx.BeginTrace("kati cleanspec")
defer ctx.EndTrace()
runKati(ctx, config, katiCleanspecSuffix, []string{
"--werror_implicit_rules",
"--werror_overriding_commands",
"-f", "build/make/core/cleanbuild.mk",
})
}