Kaynağa Gözat

Move globbing to Blueprint

Move Soong's globbing-with-dependencies support into Blueprint so it can
be used for subdirs= lines in Android.bp files.

Blueprint has a slight change in behavior around subname= lines, it now
always uses the subname and doesn't fall back to Blueprints.  To support
the Blueprints files in build/blueprint, use them directly with build=.

Test: build, add source file that matches glob, rebuild
Change-Id: Ifd0b0d3bc061aae0a16d6c7ca9a1cd8672656b4d
Colin Cross 7 yıl önce
ebeveyn
işleme
7f19f37443
12 değiştirilmiş dosya ile 87 ekleme ve 405 silme
  1. 0 15
      Android.bp
  2. 0 120
      android/glob.go
  3. 7 8
      android/module.go
  4. 10 8
      android/paths.go
  5. 0 27
      android/util.go
  6. 59 21
      build.ninja.in
  7. 0 23
      cmd/soong_glob/Android.bp
  8. 0 77
      cmd/soong_glob/soong_glob.go
  9. 0 100
      glob/glob.go
  10. 2 2
      java/app.go
  11. 5 3
      java/resources.go
  12. 4 1
      root.bp

+ 0 - 15
Android.bp

@@ -24,19 +24,6 @@ bootstrap_go_package {
     ],
 }
 
-
-bootstrap_go_package {
-    name: "soong-glob",
-    pkgPath: "android/soong/glob",
-    deps: [
-        "blueprint-deptools",
-        "blueprint-pathtools",
-    ],
-    srcs: [
-        "glob/glob.go",
-    ],
-}
-
 bootstrap_go_package {
     name: "soong",
     pkgPath: "android/soong",
@@ -56,7 +43,6 @@ bootstrap_go_package {
         "blueprint-bootstrap",
         "soong",
         "soong-env",
-        "soong-glob",
     ],
     srcs: [
         "android/androidmk.go",
@@ -64,7 +50,6 @@ bootstrap_go_package {
         "android/config.go",
         "android/defaults.go",
         "android/defs.go",
-        "android/glob.go",
         "android/hooks.go",
         "android/makevars.go",
         "android/module.go",

+ 0 - 120
android/glob.go

@@ -1,120 +0,0 @@
-// Copyright 2015 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 android
-
-import (
-	"fmt"
-	"path/filepath"
-
-	"github.com/google/blueprint"
-
-	"android/soong/glob"
-)
-
-// This file supports globbing source files in Blueprints files.
-//
-// The build.ninja file needs to be regenerated any time a file matching the glob is added
-// or removed.  The naive solution is to have the build.ninja file depend on all the
-// traversed directories, but this will cause the regeneration step to run every time a
-// non-matching file is added to a traversed directory, including backup files created by
-// editors.
-//
-// The solution implemented here optimizes out regenerations when the directory modifications
-// don't match the glob by having the build.ninja file depend on an intermedate file that
-// is only updated when a file matching the glob is added or removed.  The intermediate file
-// depends on the traversed directories via a depfile.  The depfile is used to avoid build
-// errors if a directory is deleted - a direct dependency on the deleted directory would result
-// in a build failure with a "missing and no known rule to make it" error.
-
-var (
-	globCmd = filepath.Join("${bootstrap.ToolDir}", "soong_glob")
-
-	// globRule rule traverses directories to produce a list of files that match $glob
-	// and writes it to $out if it has changed, and writes the directories to $out.d
-	globRule = pctx.AndroidStaticRule("globRule",
-		blueprint.RuleParams{
-			Command:     fmt.Sprintf(`%s -o $out $excludes "$glob"`, globCmd),
-			CommandDeps: []string{globCmd},
-			Description: "glob $glob",
-
-			Restat:  true,
-			Deps:    blueprint.DepsGCC,
-			Depfile: "$out.d",
-		},
-		"glob", "excludes")
-)
-
-func hasGlob(in []string) bool {
-	for _, s := range in {
-		if glob.IsGlob(s) {
-			return true
-		}
-	}
-
-	return false
-}
-
-// The subset of ModuleContext and SingletonContext needed by Glob
-type globContext interface {
-	Build(pctx blueprint.PackageContext, params blueprint.BuildParams)
-	AddNinjaFileDeps(deps ...string)
-}
-
-func Glob(ctx globContext, outDir string, globPattern string, excludes []string) ([]string, error) {
-	fileListFile := filepath.Join(outDir, "glob", globToString(globPattern)+".glob")
-	depFile := fileListFile + ".d"
-
-	// Get a globbed file list, and write out fileListFile and depFile
-	files, err := glob.GlobWithDepFile(globPattern, fileListFile, depFile, excludes)
-	if err != nil {
-		return nil, err
-	}
-
-	GlobRule(ctx, globPattern, excludes, fileListFile, depFile)
-
-	// Make build.ninja depend on the fileListFile
-	ctx.AddNinjaFileDeps(fileListFile)
-
-	return files, nil
-}
-
-func GlobRule(ctx globContext, globPattern string, excludes []string,
-	fileListFile, depFile string) {
-
-	// Create a rule to rebuild fileListFile if a directory in depFile changes.  fileListFile
-	// will only be rewritten if it has changed, preventing unnecesary build.ninja regenerations.
-	ctx.Build(pctx, blueprint.BuildParams{
-		Rule:    globRule,
-		Outputs: []string{fileListFile},
-		Args: map[string]string{
-			"glob":     globPattern,
-			"excludes": JoinWithPrefixAndQuote(excludes, "-e "),
-		},
-	})
-}
-
-func globToString(glob string) string {
-	ret := ""
-	for _, c := range glob {
-		if c >= 'a' && c <= 'z' ||
-			c >= 'A' && c <= 'Z' ||
-			c >= '0' && c <= '9' ||
-			c == '_' || c == '-' || c == '/' {
-			ret += string(c)
-		}
-	}
-
-	return ret
-}

+ 7 - 8
android/module.go

@@ -19,9 +19,8 @@ import (
 	"path/filepath"
 	"strings"
 
-	"android/soong/glob"
-
 	"github.com/google/blueprint"
+	"github.com/google/blueprint/pathtools"
 )
 
 var (
@@ -76,7 +75,7 @@ type ModuleContext interface {
 	ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams)
 
 	ExpandSources(srcFiles, excludes []string) Paths
-	Glob(outDir, globPattern string, excludes []string) Paths
+	Glob(globPattern string, excludes []string) Paths
 
 	InstallFile(installPath OutputPath, srcPath Path, deps ...Path) OutputPath
 	InstallFileName(installPath OutputPath, name string, srcPath Path, deps ...Path) OutputPath
@@ -509,7 +508,7 @@ func (a *androidModuleContext) ninjaError(outputs []string, err error) {
 }
 
 func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params blueprint.BuildParams) {
-	if a.missingDeps != nil && params.Rule != globRule {
+	if a.missingDeps != nil {
 		a.ninjaError(params.Outputs, fmt.Errorf("module %s missing dependencies: %s\n",
 			a.ModuleName(), strings.Join(a.missingDeps, ", ")))
 		return
@@ -718,8 +717,8 @@ func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Path
 
 	globbedSrcFiles := make(Paths, 0, len(srcFiles))
 	for _, s := range srcFiles {
-		if glob.IsGlob(s) {
-			globbedSrcFiles = append(globbedSrcFiles, ctx.Glob("src_glob", filepath.Join(prefix, s), excludes)...)
+		if pathtools.IsGlob(s) {
+			globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
 		} else {
 			globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))
 		}
@@ -728,8 +727,8 @@ func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Path
 	return globbedSrcFiles
 }
 
-func (ctx *androidModuleContext) Glob(outDir, globPattern string, excludes []string) Paths {
-	ret, err := Glob(ctx, PathForModuleOut(ctx, outDir).String(), globPattern, excludes)
+func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) Paths {
+	ret, err := ctx.GlobWithDeps(globPattern, excludes)
 	if err != nil {
 		ctx.ModuleErrorf("glob: %s", err.Error())
 	}

+ 10 - 8
android/paths.go

@@ -21,8 +21,6 @@ import (
 	"reflect"
 	"strings"
 
-	"android/soong/glob"
-
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/pathtools"
 )
@@ -34,6 +32,10 @@ type PathContext interface {
 	AddNinjaFileDeps(deps ...string)
 }
 
+type PathGlobContext interface {
+	GlobWithDeps(globPattern string, excludes []string) ([]string, error)
+}
+
 var _ PathContext = blueprint.SingletonContext(nil)
 var _ PathContext = blueprint.ModuleContext(nil)
 
@@ -248,7 +250,7 @@ func PathsWithOptionalDefaultForModuleSrc(ctx ModuleContext, input []string, def
 	// Use Glob so that if the default doesn't exist, a dependency is added so that when it
 	// is created, we're run again.
 	path := filepath.Join(ctx.AConfig().srcDir, ctx.ModuleDir(), def)
-	return ctx.Glob("default", path, []string{})
+	return ctx.Glob(path, []string{})
 }
 
 // Strings returns the Paths in string form
@@ -382,15 +384,15 @@ func OptionalPathForSource(ctx PathContext, intermediates string, paths ...strin
 		return OptionalPath{}
 	}
 
-	if glob.IsGlob(path.String()) {
+	if pathtools.IsGlob(path.String()) {
 		reportPathError(ctx, "path may not contain a glob: %s", path.String())
 		return OptionalPath{}
 	}
 
-	if gctx, ok := ctx.(globContext); ok {
+	if gctx, ok := ctx.(PathGlobContext); ok {
 		// Use glob to produce proper dependencies, even though we only want
 		// a single file.
-		files, err := Glob(gctx, PathForIntermediates(ctx, intermediates).String(), path.String(), nil)
+		files, err := gctx.GlobWithDeps(path.String(), nil)
 		if err != nil {
 			reportPathError(ctx, "glob: %s", err.Error())
 			return OptionalPath{}
@@ -444,10 +446,10 @@ func (p SourcePath) OverlayPath(ctx ModuleContext, path Path) OptionalPath {
 	}
 	dir := filepath.Join(p.config.srcDir, p.path, relDir)
 	// Use Glob so that we are run again if the directory is added.
-	if glob.IsGlob(dir) {
+	if pathtools.IsGlob(dir) {
 		reportPathError(ctx, "Path may not contain a glob: %s", dir)
 	}
-	paths, err := Glob(ctx, PathForModuleOut(ctx, "overlay").String(), dir, []string{})
+	paths, err := ctx.GlobWithDeps(dir, []string{})
 	if err != nil {
 		reportPathError(ctx, "glob: %s", err.Error())
 		return OptionalPath{}

+ 0 - 27
android/util.go

@@ -45,33 +45,6 @@ func JoinWithPrefix(strs []string, prefix string) string {
 	return string(ret)
 }
 
-func JoinWithPrefixAndQuote(strs []string, prefix string) string {
-	if len(strs) == 0 {
-		return ""
-	}
-
-	if len(strs) == 1 {
-		return prefix + `"` + strs[0] + `"`
-	}
-
-	n := len(" ") * (len(strs) - 1)
-	for _, s := range strs {
-		n += len(prefix) + len(s) + len(`""`)
-	}
-
-	ret := make([]byte, 0, n)
-	for i, s := range strs {
-		if i != 0 {
-			ret = append(ret, ' ')
-		}
-		ret = append(ret, prefix...)
-		ret = append(ret, '"')
-		ret = append(ret, s...)
-		ret = append(ret, '"')
-	}
-	return string(ret)
-}
-
 func sortedKeys(m map[string][]string) []string {
 	s := make([]string, 0, len(m))
 	for k := range m {

+ 59 - 21
build.ninja.in

@@ -71,6 +71,7 @@ build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/github.com/google/blueprint.a $
         : g.bootstrap.compile ${g.bootstrap.srcDir}/build/blueprint/context.go $
         ${g.bootstrap.srcDir}/build/blueprint/fs.go $
+        ${g.bootstrap.srcDir}/build/blueprint/glob.go $
         ${g.bootstrap.srcDir}/build/blueprint/live_tracker.go $
         ${g.bootstrap.srcDir}/build/blueprint/mangle.go $
         ${g.bootstrap.srcDir}/build/blueprint/module_ctx.go $
@@ -89,9 +90,10 @@ build $
         ${g.bootstrap.srcDir}/build/blueprint/visit_test.go | $
         ${g.bootstrap.compileCmd} $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
-    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
     pkgPath = github.com/google/blueprint
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/github.com/google/blueprint.a
@@ -120,7 +122,7 @@ default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.a
 build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test: g.bootstrap.link $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.a | $
         ${g.bootstrap.linkCmd}
-    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/test -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
+    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/test -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
 default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test
 
 build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.passed: $
@@ -138,6 +140,7 @@ build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
         : g.bootstrap.compile ${g.bootstrap.srcDir}/build/blueprint/context.go $
         ${g.bootstrap.srcDir}/build/blueprint/fs.go $
+        ${g.bootstrap.srcDir}/build/blueprint/glob.go $
         ${g.bootstrap.srcDir}/build/blueprint/live_tracker.go $
         ${g.bootstrap.srcDir}/build/blueprint/mangle.go $
         ${g.bootstrap.srcDir}/build/blueprint/module_ctx.go $
@@ -150,9 +153,10 @@ build $
         ${g.bootstrap.srcDir}/build/blueprint/unpack.go | $
         ${g.bootstrap.compileCmd} $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
-    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
     pkgPath = github.com/google/blueprint
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
@@ -162,7 +166,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:85:1
+# Defined: build/blueprint/Blueprints:89:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
@@ -172,15 +176,16 @@ build $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/command.go $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/config.go $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/doc.go $
+        ${g.bootstrap.srcDir}/build/blueprint/bootstrap/glob.go $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/writedocs.go | $
         ${g.bootstrap.compileCmd} $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
-        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
-    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg
     pkgPath = github.com/google/blueprint/bootstrap
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
@@ -190,7 +195,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:104:1
+# Defined: build/blueprint/Blueprints:109:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
@@ -198,10 +203,11 @@ build $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/bpdoc/bpdoc.go | $
         ${g.bootstrap.compileCmd} $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
-    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg
     pkgPath = github.com/google/blueprint/bootstrap/bpdoc
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
@@ -211,7 +217,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:49:1
+# Defined: build/blueprint/Blueprints:50:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
@@ -227,7 +233,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:33:1
+# Defined: build/blueprint/Blueprints:34:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/github.com/google/blueprint/parser.a $
@@ -294,7 +300,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:55:1
+# Defined: build/blueprint/Blueprints:56:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/github.com/google/blueprint/pathtools.a $
@@ -302,7 +308,9 @@ build $
         ${g.bootstrap.srcDir}/build/blueprint/pathtools/lists.go $
         ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob.go $
         ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob_test.go | $
-        ${g.bootstrap.compileCmd}
+        ${g.bootstrap.compileCmd} $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg
     pkgPath = github.com/google/blueprint/pathtools
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/github.com/google/blueprint/pathtools.a
@@ -327,7 +335,7 @@ build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test: $
         g.bootstrap.link $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.a | $
         ${g.bootstrap.linkCmd}
-    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test
+    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg
 default ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test
 
 build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed: $
@@ -344,7 +352,9 @@ build $
         : g.bootstrap.compile $
         ${g.bootstrap.srcDir}/build/blueprint/pathtools/lists.go $
         ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob.go | $
-        ${g.bootstrap.compileCmd}
+        ${g.bootstrap.compileCmd} $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg
     pkgPath = github.com/google/blueprint/pathtools
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
@@ -354,7 +364,7 @@ default $
 # Variant:
 # Type:    bootstrap_go_package
 # Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:67:1
+# Defined: build/blueprint/Blueprints:71:1
 
 build $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/github.com/google/blueprint/proptools.a $
@@ -421,12 +431,40 @@ build $
 default $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
 
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+# Module:  bpglob
+# Variant:
+# Type:    bootstrap_core_go_binary
+# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
+# Defined: build/blueprint/Blueprints:130:1
+
+build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a: $
+        g.bootstrap.compile $
+        ${g.bootstrap.srcDir}/build/blueprint/bootstrap/bpglob/bpglob.go | $
+        ${g.bootstrap.compileCmd} $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg
+    pkgPath = bpglob
+default ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a
+
+build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out: g.bootstrap.link $
+        ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a | $
+        ${g.bootstrap.linkCmd}
+    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg
+default ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out
+
+build ${g.bootstrap.BinDir}/bpglob: g.bootstrap.cp $
+        ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out || $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed
+default ${g.bootstrap.BinDir}/bpglob
+
 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 # Module:  gotestmain
 # Variant:
 # Type:    bootstrap_core_go_binary
 # Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
-# Defined: build/blueprint/Blueprints:137:1
+# Defined: build/blueprint/Blueprints:148:1
 
 build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
         g.bootstrap.compile $
@@ -450,7 +488,7 @@ default ${g.bootstrap.BinDir}/gotestmain
 # Variant:
 # Type:    bootstrap_core_go_binary
 # Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
-# Defined: build/blueprint/Blueprints:142:1
+# Defined: build/blueprint/Blueprints:153:1
 
 build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $
         g.bootstrap.compile $
@@ -474,27 +512,27 @@ default ${g.bootstrap.BinDir}/gotestrunner
 # Variant:
 # Type:    bootstrap_core_go_binary
 # Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
-# Defined: build/blueprint/Blueprints:116:1
+# Defined: build/blueprint/Blueprints:121:1
 
 build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $
         g.bootstrap.compile $
         ${g.bootstrap.srcDir}/build/blueprint/bootstrap/minibp/main.go | $
         ${g.bootstrap.compileCmd} $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
+        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
-        ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
         ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
-    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
+    incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
     pkgPath = minibp
 default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a
 
 build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out: g.bootstrap.link $
         ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a | $
         ${g.bootstrap.linkCmd}
-    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
+    libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg
 default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out
 
 build ${g.bootstrap.BinDir}/minibp: g.bootstrap.cp $

+ 0 - 23
cmd/soong_glob/Android.bp

@@ -1,23 +0,0 @@
-// Copyright 2015 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.
-
-blueprint_go_binary {
-    name: "soong_glob",
-    deps: [
-        "soong-glob",
-    ],
-    srcs: [
-        "soong_glob.go",
-    ],
-}

+ 0 - 77
cmd/soong_glob/soong_glob.go

@@ -1,77 +0,0 @@
-// Copyright 2015 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.
-
-// soong_glob is the command line tool that checks if the list of files matching a glob has
-// changed, and only updates the output file list if it has changed.  It is used to optimize
-// out build.ninja regenerations when non-matching files are added.  See
-// android/soong/common/glob.go for a longer description.
-package main
-
-import (
-	"flag"
-	"fmt"
-	"os"
-
-	"android/soong/glob"
-)
-
-var (
-	out = flag.String("o", "", "file to write list of files that match glob")
-
-	excludes multiArg
-)
-
-func init() {
-	flag.Var(&excludes, "e", "pattern to exclude from results")
-}
-
-type multiArg []string
-
-func (m *multiArg) String() string {
-	return `""`
-}
-
-func (m *multiArg) Set(s string) error {
-	*m = append(*m, s)
-	return nil
-}
-
-func (m *multiArg) Get() interface{} {
-	return m
-}
-
-func usage() {
-	fmt.Fprintf(os.Stderr, "usage: soong_glob -o out glob\n")
-	flag.PrintDefaults()
-	os.Exit(2)
-}
-
-func main() {
-	flag.Parse()
-
-	if *out == "" {
-		fmt.Fprintf(os.Stderr, "error: -o is required\n")
-		usage()
-	}
-
-	if flag.NArg() != 1 {
-		usage()
-	}
-
-	_, err := glob.GlobWithDepFile(flag.Arg(0), *out, *out+".d", excludes)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
-		os.Exit(1)
-	}
-}

+ 0 - 100
glob/glob.go

@@ -1,100 +0,0 @@
-// Copyright 2015 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 glob
-
-import (
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/google/blueprint/deptools"
-	"github.com/google/blueprint/pathtools"
-)
-
-func IsGlob(glob string) bool {
-	return strings.IndexAny(glob, "*?[") >= 0
-}
-
-// GlobWithDepFile finds all files that match glob.  It compares the list of files
-// against the contents of fileListFile, and rewrites fileListFile if it has changed.  It also
-// writes all of the the directories it traversed as a depenencies on fileListFile to depFile.
-//
-// The format of glob is either path/*.ext for a single directory glob, or path/**/*.ext
-// for a recursive glob.
-//
-// Returns a list of file paths, and an error.
-func GlobWithDepFile(glob, fileListFile, depFile string, excludes []string) (files []string, err error) {
-	files, dirs, err := pathtools.GlobWithExcludes(glob, excludes)
-	if err != nil {
-		return nil, err
-	}
-
-	fileList := strings.Join(files, "\n") + "\n"
-
-	writeFileIfChanged(fileListFile, []byte(fileList), 0666)
-	deptools.WriteDepFile(depFile, fileListFile, dirs)
-
-	return
-}
-
-func writeFileIfChanged(filename string, data []byte, perm os.FileMode) error {
-	var isChanged bool
-
-	dir := filepath.Dir(filename)
-	err := os.MkdirAll(dir, 0777)
-	if err != nil {
-		return err
-	}
-
-	info, err := os.Stat(filename)
-	if err != nil {
-		if os.IsNotExist(err) {
-			// The file does not exist yet.
-			isChanged = true
-		} else {
-			return err
-		}
-	} else {
-		if info.Size() != int64(len(data)) {
-			isChanged = true
-		} else {
-			oldData, err := ioutil.ReadFile(filename)
-			if err != nil {
-				return err
-			}
-
-			if len(oldData) != len(data) {
-				isChanged = true
-			} else {
-				for i := range data {
-					if oldData[i] != data[i] {
-						isChanged = true
-						break
-					}
-				}
-			}
-		}
-	}
-
-	if isChanged {
-		err = ioutil.WriteFile(filename, data, perm)
-		if err != nil {
-			return err
-		}
-	}
-
-	return nil
-}

+ 2 - 2
java/app.go

@@ -207,14 +207,14 @@ func (a *AndroidApp) aaptFlags(ctx android.ModuleContext) ([]string, android.Pat
 	var aaptDeps android.Paths
 	var hasResources bool
 	for _, d := range resourceDirs {
-		newDeps := ctx.Glob("app_resources", filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
+		newDeps := ctx.Glob(filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
 		aaptDeps = append(aaptDeps, newDeps...)
 		if len(newDeps) > 0 {
 			hasResources = true
 		}
 	}
 	for _, d := range assetDirs {
-		newDeps := ctx.Glob("app_assets", filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
+		newDeps := ctx.Glob(filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames)
 		aaptDeps = append(aaptDeps, newDeps...)
 	}
 

+ 5 - 3
java/resources.go

@@ -17,6 +17,8 @@ package java
 import (
 	"path/filepath"
 
+	"github.com/google/blueprint/bootstrap"
+
 	"android/soong/android"
 )
 
@@ -54,13 +56,13 @@ func ResourceDirsToJarSpecs(ctx android.ModuleContext, resourceDirs, excludeDirs
 			continue
 		}
 		resourceDir := android.PathForModuleSrc(ctx, resourceDir)
-		dirs := ctx.Glob("java_resources", resourceDir.String(), nil)
+		dirs := ctx.Glob(resourceDir.String(), nil)
 		for _, dir := range dirs {
 			fileListFile := android.ResPathWithName(ctx, dir, "resources.list")
 			depFile := fileListFile.String() + ".d"
 
-			glob := filepath.Join(dir.String(), "**/*")
-			android.GlobRule(ctx, glob, excludes, fileListFile.String(), depFile)
+			pattern := filepath.Join(dir.String(), "**/*")
+			bootstrap.GlobFile(ctx, pattern, excludes, fileListFile.String(), depFile)
 			jarSpecs = append(jarSpecs, jarSpec{fileListFile, dir})
 		}
 	}

+ 4 - 1
root.bp

@@ -1,7 +1,10 @@
 subname = "Android.bp"
 
+build = [
+    "build/blueprint/Blueprints",
+]
+
 subdirs = [
-    "build/blueprint",
     "build/soong",
 ]