Merge "Test for dangling rules in make checkbuild"

This commit is contained in:
Treehugger Robot 2017-11-13 22:43:30 +00:00 committed by Gerrit Code Review
commit df93350ccd
5 changed files with 106 additions and 9 deletions

View file

@ -114,7 +114,11 @@ func main() {
} else if os.Args[1] == "--dumpvars-mode" {
dumpVars(buildCtx, config, os.Args[2:])
} else {
build.Build(buildCtx, config, build.BuildAll)
toBuild := build.BuildAll
if config.Checkbuild() {
toBuild |= build.RunBuildTests
}
build.Build(buildCtx, config, toBuild)
}
}

View file

@ -36,6 +36,7 @@ bootstrap_go_package {
"proc_sync.go",
"signal.go",
"soong.go",
"test_build.go",
"util.go",
],
testSrcs: [

View file

@ -68,6 +68,7 @@ const (
BuildSoong = 1 << iota
BuildKati = 1 << iota
BuildNinja = 1 << iota
RunBuildTests = 1 << iota
BuildAll = BuildProductConfig | BuildSoong | BuildKati | BuildNinja
)
@ -172,14 +173,18 @@ func Build(ctx Context, config Config, what int) {
}
}
// Write combined ninja file
createCombinedBuildNinjaFile(ctx, config)
if what&RunBuildTests != 0 {
testForDanglingRules(ctx, config)
}
if what&BuildNinja != 0 {
if !config.SkipMake() {
installCleanIfNecessary(ctx, config)
}
// Write combined ninja file
createCombinedBuildNinjaFile(ctx, config)
// Run ninja
runNinja(ctx, config)
}

View file

@ -37,6 +37,7 @@ type configImpl struct {
parallel int
keepGoing int
verbose bool
checkbuild bool
dist bool
skipMake bool
@ -206,6 +207,8 @@ func (c *configImpl) parseArgs(ctx Context, args []string) {
} else {
if arg == "dist" {
c.dist = true
} else if arg == "checkbuild" {
c.checkbuild = true
}
c.arguments = append(c.arguments, arg)
}
@ -313,6 +316,12 @@ func (c *configImpl) KatiSuffix() string {
panic("SetKatiSuffix has not been called")
}
// Checkbuild returns true if "checkbuild" was one of the build goals, which means that the
// user is interested in additional checks at the expense of build time.
func (c *configImpl) Checkbuild() bool {
return c.checkbuild
}
func (c *configImpl) Dist() bool {
return c.dist
}

78
ui/build/test_build.go Normal file
View file

@ -0,0 +1,78 @@
// 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 (
"bufio"
"path/filepath"
"strings"
)
// Checks for files in the out directory that have a rule that depends on them but no rule to
// create them. This catches a common set of build failures where a rule to generate a file is
// deleted (either by deleting a module in an Android.mk file, or by modifying the build system
// incorrectly). These failures are often not caught by a local incremental build because the
// previously built files are still present in the output directory.
func testForDanglingRules(ctx Context, config Config) {
ctx.BeginTrace("test for dangling rules")
defer ctx.EndTrace()
// Get a list of leaf nodes in the dependency graph from ninja
executable := config.PrebuiltBuildTool("ninja")
args := []string{}
args = append(args, config.NinjaArgs()...)
args = append(args, "-f", config.CombinedNinjaFile())
args = append(args, "-t", "targets", "rule")
cmd := Command(ctx, config, "ninja", executable, args...)
stdout, err := cmd.StdoutPipe()
if err != nil {
ctx.Fatal(err)
}
cmd.StartOrFatal()
outDir := config.OutDir()
bootstrapDir := filepath.Join(outDir, "soong", ".bootstrap")
miniBootstrapDir := filepath.Join(outDir, "soong", ".minibootstrap")
var danglingRules []string
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
line := scanner.Text()
if !strings.HasPrefix(line, outDir) {
// Leaf node is not in the out directory.
continue
}
if strings.HasPrefix(line, bootstrapDir) || strings.HasPrefix(line, miniBootstrapDir) {
// Leaf node is in one of Soong's bootstrap directories, which do not have
// full build rules in the primary build.ninja file.
continue
}
danglingRules = append(danglingRules, line)
}
cmd.WaitOrFatal()
if len(danglingRules) > 0 {
ctx.Println("Dependencies in out found with no rule to create them:")
for _, dep := range danglingRules {
ctx.Println(dep)
}
ctx.Fatal("")
}
}