Import globbing from Soong
Add globbing with dependency checking to blueprint. Calling ModuleContext.GlobWithDeps or SingletonContext.GlobWithDeps will return a list of files that match the globs, while also adding efficient dependencies to rerun the primary builder if a file that matches the glob is added or removed. Also use the globbing support for optional_subdirs=, subdirs= and build= lines in blueprints files. The globbing slightly changes the behavior of subname= lines, it no longer falls back to looking for a file called "Blueprints". Blueprint files that need to include a subdirectory with a different name can use build= instead of subdir= to directly include them. The Blueprints file is updated to reset subname="Blueprints" in case we want to include subdirectories inside blueprint and the primary builder has changed the subname. Also adds a new test directory that contains a simple primary builder tree to test regeneration for globbing, and runs the tests in travis. Change-Id: I83ce525fd11e11579cc58ba5308d01ca8eea7bc6
This commit is contained in:
parent
b589835c0d
commit
127d2eae8b
18 changed files with 1012 additions and 109 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
out.test
|
||||
src.test
|
||||
|
|
|
@ -23,3 +23,4 @@ script:
|
|||
- ./blueprint.bash
|
||||
- diff -us ../build.ninja.in .minibootstrap/build.ninja.in
|
||||
- ../tests/test.sh
|
||||
- ../tests/test_tree_tests.sh
|
||||
|
|
11
Blueprints
11
Blueprints
|
@ -9,6 +9,7 @@ bootstrap_go_package(
|
|||
srcs = [
|
||||
"context.go",
|
||||
"fs.go",
|
||||
"glob.go",
|
||||
"live_tracker.go",
|
||||
"mangle.go",
|
||||
"module_ctx.go",
|
||||
|
@ -55,6 +56,9 @@ bootstrap_go_package(
|
|||
bootstrap_go_package(
|
||||
name = "blueprint-pathtools",
|
||||
pkgPath = "github.com/google/blueprint/pathtools",
|
||||
deps = [
|
||||
"blueprint-deptools",
|
||||
],
|
||||
srcs = [
|
||||
"pathtools/lists.go",
|
||||
"pathtools/glob.go",
|
||||
|
@ -97,6 +101,7 @@ bootstrap_go_package(
|
|||
"bootstrap/command.go",
|
||||
"bootstrap/config.go",
|
||||
"bootstrap/doc.go",
|
||||
"bootstrap/glob.go",
|
||||
"bootstrap/writedocs.go",
|
||||
],
|
||||
)
|
||||
|
@ -122,6 +127,12 @@ bootstrap_core_go_binary(
|
|||
srcs = ["bootstrap/minibp/main.go"],
|
||||
)
|
||||
|
||||
bootstrap_core_go_binary(
|
||||
name = "bpglob",
|
||||
deps = ["blueprint-pathtools"],
|
||||
srcs = ["bootstrap/bpglob/bpglob.go"],
|
||||
)
|
||||
|
||||
blueprint_go_binary(
|
||||
name = "bpfmt",
|
||||
deps = ["blueprint-parser"],
|
||||
|
|
77
bootstrap/bpglob/bpglob.go
Normal file
77
bootstrap/bpglob/bpglob.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
// 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.
|
||||
|
||||
// bpglob 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
|
||||
// github.com/google/blueprint/bootstrap/glob.go for a longer description.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
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: bpglob -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 := pathtools.GlobWithDepFile(flag.Arg(0), *out, *out+".d", excludes)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
|
@ -117,6 +117,8 @@ func Main(ctx *blueprint.Context, config interface{}, extraNinjaFileDeps ...stri
|
|||
ctx.RegisterTopDownMutator("bootstrap_stage", propagateStageBootstrap)
|
||||
ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig))
|
||||
|
||||
ctx.RegisterSingletonType("glob", globSingletonFactory(ctx))
|
||||
|
||||
deps, errs := ctx.ParseBlueprintsFiles(bootstrapConfig.topLevelBlueprintsFile)
|
||||
if len(errs) > 0 {
|
||||
fatalErrors(errs)
|
||||
|
|
144
bootstrap/glob.go
Normal file
144
bootstrap/glob.go
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2016 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 bootstrap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/deptools"
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
// 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("$BinDir", "bpglob")
|
||||
|
||||
// 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.StaticRule("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")
|
||||
)
|
||||
|
||||
// GlobFileContext is the subset of ModuleContext and SingletonContext needed by GlobFile
|
||||
type GlobFileContext interface {
|
||||
Build(pctx blueprint.PackageContext, params blueprint.BuildParams)
|
||||
}
|
||||
|
||||
// GlobFile creates a rule to write to fileListFile a list of the files that match the specified
|
||||
// pattern but do not match any of the patterns specified in excludes. The file will include
|
||||
// appropriate dependencies written to depFile to regenerate the file if and only if the list of
|
||||
// matching files has changed.
|
||||
func GlobFile(ctx GlobFileContext, pattern string, excludes []string,
|
||||
fileListFile, depFile string) {
|
||||
|
||||
ctx.Build(pctx, blueprint.BuildParams{
|
||||
Rule: GlobRule,
|
||||
Outputs: []string{fileListFile},
|
||||
Args: map[string]string{
|
||||
"glob": pattern,
|
||||
"excludes": joinWithPrefixAndQuote(excludes, "-e "),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// globSingleton collects any glob patterns that were seen by Context and writes out rules to
|
||||
// re-evaluate them whenever the contents of the searched directories change, and retrigger the
|
||||
// primary builder if the results change.
|
||||
type globSingleton struct {
|
||||
globLister func() []blueprint.GlobPath
|
||||
}
|
||||
|
||||
func globSingletonFactory(ctx *blueprint.Context) func() blueprint.Singleton {
|
||||
return func() blueprint.Singleton {
|
||||
return &globSingleton{
|
||||
globLister: ctx.Globs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *globSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
|
||||
if config, ok := ctx.Config().(ConfigInterface); ok && config.GeneratingBootstrapper() {
|
||||
// Skip singleton for bootstrap.bash -r case to avoid putting unnecessary glob lines into
|
||||
// the bootstrap manifest
|
||||
return
|
||||
}
|
||||
|
||||
for _, g := range s.globLister() {
|
||||
fileListFile := filepath.Join(BuildDir, ".glob", g.Name)
|
||||
depFile := fileListFile + ".d"
|
||||
|
||||
fileList := strings.Join(g.Files, "\n") + "\n"
|
||||
pathtools.WriteFileIfChanged(fileListFile, []byte(fileList), 0666)
|
||||
deptools.WriteDepFile(depFile, fileListFile, g.Deps)
|
||||
|
||||
GlobFile(ctx, g.Pattern, g.Excludes, fileListFile, depFile)
|
||||
|
||||
// Make build.ninja depend on the fileListFile
|
||||
ctx.AddNinjaFileDeps(fileListFile)
|
||||
}
|
||||
}
|
|
@ -58,8 +58,9 @@ rule g.bootstrap.link
|
|||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
|
||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/context.go $
|
||||
${g.bootstrap.srcDir}/fs.go ${g.bootstrap.srcDir}/live_tracker.go $
|
||||
${g.bootstrap.srcDir}/mangle.go ${g.bootstrap.srcDir}/module_ctx.go $
|
||||
${g.bootstrap.srcDir}/fs.go ${g.bootstrap.srcDir}/glob.go $
|
||||
${g.bootstrap.srcDir}/live_tracker.go ${g.bootstrap.srcDir}/mangle.go $
|
||||
${g.bootstrap.srcDir}/module_ctx.go $
|
||||
${g.bootstrap.srcDir}/ninja_defs.go $
|
||||
${g.bootstrap.srcDir}/ninja_strings.go $
|
||||
${g.bootstrap.srcDir}/ninja_writer.go $
|
||||
|
@ -67,9 +68,10 @@ build $
|
|||
${g.bootstrap.srcDir}/singleton_ctx.go ${g.bootstrap.srcDir}/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
|
||||
|
@ -79,7 +81,7 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:85:1
|
||||
# Defined: Blueprints:89:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
|
||||
|
@ -88,15 +90,16 @@ build $
|
|||
${g.bootstrap.srcDir}/bootstrap/command.go $
|
||||
${g.bootstrap.srcDir}/bootstrap/config.go $
|
||||
${g.bootstrap.srcDir}/bootstrap/doc.go $
|
||||
${g.bootstrap.srcDir}/bootstrap/glob.go $
|
||||
${g.bootstrap.srcDir}/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
|
||||
|
@ -106,17 +109,18 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:104:1
|
||||
# Defined: Blueprints:109:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
|
||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/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
|
||||
|
@ -126,7 +130,7 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:49:1
|
||||
# Defined: Blueprints:50:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
|
||||
|
@ -141,7 +145,7 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:33:1
|
||||
# Defined: Blueprints:34:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
||||
|
@ -159,12 +163,14 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:55:1
|
||||
# Defined: Blueprints:56:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/pathtools/lists.go $
|
||||
${g.bootstrap.srcDir}/pathtools/glob.go | ${g.bootstrap.compileCmd}
|
||||
${g.bootstrap.srcDir}/pathtools/glob.go | ${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
|
||||
|
@ -174,7 +180,7 @@ default $
|
|||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: Blueprints:67:1
|
||||
# Defined: Blueprints:71:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||
|
@ -188,12 +194,38 @@ 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: Blueprints:130:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a: $
|
||||
g.bootstrap.compile ${g.bootstrap.srcDir}/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
|
||||
default ${g.bootstrap.BinDir}/bpglob
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: gotestmain
|
||||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: Blueprints:137:1
|
||||
# Defined: Blueprints:148:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
|
||||
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | $
|
||||
|
@ -216,7 +248,7 @@ default ${g.bootstrap.BinDir}/gotestmain
|
|||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: Blueprints:142:1
|
||||
# Defined: Blueprints:153:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $
|
||||
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestrunner/gotestrunner.go $
|
||||
|
@ -239,26 +271,26 @@ default ${g.bootstrap.BinDir}/gotestrunner
|
|||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: Blueprints:116:1
|
||||
# Defined: Blueprints:121:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $
|
||||
g.bootstrap.compile ${g.bootstrap.srcDir}/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 $
|
||||
|
|
147
context.go
147
context.go
|
@ -25,6 +25,7 @@ import (
|
|||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"text/scanner"
|
||||
"text/template"
|
||||
|
@ -105,6 +106,9 @@ type Context struct {
|
|||
renames []rename
|
||||
replacements []replace
|
||||
|
||||
globs map[string]GlobPath
|
||||
globLock sync.Mutex
|
||||
|
||||
fs fileSystem
|
||||
}
|
||||
|
||||
|
@ -270,6 +274,7 @@ func NewContext() *Context {
|
|||
moduleNames: make(map[string]*moduleGroup),
|
||||
moduleInfo: make(map[Module]*moduleInfo),
|
||||
moduleNinjaNames: make(map[string]*moduleGroup),
|
||||
globs: make(map[string]GlobPath),
|
||||
fs: fs,
|
||||
}
|
||||
|
||||
|
@ -524,12 +529,11 @@ func (c *Context) SetAllowMissingDependencies(allowMissingDependencies bool) {
|
|||
// filename specifies the path to the Blueprints file. These paths are used for
|
||||
// error reporting and for determining the module's directory.
|
||||
func (c *Context) parse(rootDir, filename string, r io.Reader,
|
||||
scope *parser.Scope) (file *parser.File, subBlueprints []stringAndScope, deps []string,
|
||||
errs []error) {
|
||||
scope *parser.Scope) (file *parser.File, subBlueprints []stringAndScope, errs []error) {
|
||||
|
||||
relBlueprintsFile, err := filepath.Rel(rootDir, filename)
|
||||
if err != nil {
|
||||
return nil, nil, nil, []error{err}
|
||||
return nil, nil, []error{err}
|
||||
}
|
||||
|
||||
scope = parser.NewScope(scope)
|
||||
|
@ -550,7 +554,7 @@ func (c *Context) parse(rootDir, filename string, r io.Reader,
|
|||
|
||||
// If there were any parse errors don't bother trying to interpret the
|
||||
// result.
|
||||
return nil, nil, nil, errs
|
||||
return nil, nil, errs
|
||||
}
|
||||
file.Name = relBlueprintsFile
|
||||
|
||||
|
@ -570,24 +574,28 @@ func (c *Context) parse(rootDir, filename string, r io.Reader,
|
|||
}
|
||||
|
||||
subBlueprintsName, _, err := getStringFromScope(scope, "subname")
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if subBlueprintsName == "" {
|
||||
subBlueprintsName = "Blueprints"
|
||||
}
|
||||
|
||||
var blueprints []string
|
||||
|
||||
newBlueprints, newDeps, newErrs := c.findBuildBlueprints(filepath.Dir(filename), build, buildPos)
|
||||
newBlueprints, newErrs := c.findBuildBlueprints(filepath.Dir(filename), build, buildPos)
|
||||
blueprints = append(blueprints, newBlueprints...)
|
||||
deps = append(deps, newDeps...)
|
||||
errs = append(errs, newErrs...)
|
||||
|
||||
newBlueprints, newDeps, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), subdirs, subdirsPos,
|
||||
newBlueprints, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), subdirs, subdirsPos,
|
||||
subBlueprintsName, false)
|
||||
blueprints = append(blueprints, newBlueprints...)
|
||||
deps = append(deps, newDeps...)
|
||||
errs = append(errs, newErrs...)
|
||||
|
||||
newBlueprints, newDeps, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), optionalSubdirs,
|
||||
newBlueprints, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), optionalSubdirs,
|
||||
optionalSubdirsPos, subBlueprintsName, true)
|
||||
blueprints = append(blueprints, newBlueprints...)
|
||||
deps = append(deps, newDeps...)
|
||||
errs = append(errs, newErrs...)
|
||||
|
||||
subBlueprintsAndScope := make([]stringAndScope, len(blueprints))
|
||||
|
@ -595,7 +603,7 @@ func (c *Context) parse(rootDir, filename string, r io.Reader,
|
|||
subBlueprintsAndScope[i] = stringAndScope{b, scope}
|
||||
}
|
||||
|
||||
return file, subBlueprintsAndScope, deps, errs
|
||||
return file, subBlueprintsAndScope, errs
|
||||
}
|
||||
|
||||
type stringAndScope struct {
|
||||
|
@ -790,7 +798,7 @@ func (c *Context) parseBlueprintsFile(filename string, scope *parser.Scope, root
|
|||
}
|
||||
}()
|
||||
|
||||
file, subBlueprints, deps, errs := c.parse(rootDir, filename, f, scope)
|
||||
file, subBlueprints, errs := c.parse(rootDir, filename, f, scope)
|
||||
if len(errs) > 0 {
|
||||
errsCh <- errs
|
||||
} else {
|
||||
|
@ -799,22 +807,31 @@ func (c *Context) parseBlueprintsFile(filename string, scope *parser.Scope, root
|
|||
|
||||
for _, b := range subBlueprints {
|
||||
blueprintsCh <- b
|
||||
}
|
||||
|
||||
for _, d := range deps {
|
||||
depsCh <- d
|
||||
depsCh <- b.string
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) findBuildBlueprints(dir string, build []string,
|
||||
buildPos scanner.Position) (blueprints, deps []string, errs []error) {
|
||||
buildPos scanner.Position) ([]string, []error) {
|
||||
|
||||
var blueprints []string
|
||||
var errs []error
|
||||
|
||||
for _, file := range build {
|
||||
globPattern := filepath.Join(dir, file)
|
||||
matches, matchedDirs, err := pathtools.Glob(globPattern)
|
||||
pattern := filepath.Join(dir, file)
|
||||
var matches []string
|
||||
var err error
|
||||
|
||||
if pathtools.IsGlob(pattern) {
|
||||
matches, err = c.glob(pattern, nil)
|
||||
} else {
|
||||
// Not a glob, but use filepath.Glob to check if it exists
|
||||
matches, err = filepath.Glob(pattern)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q: %s", globPattern, err.Error()),
|
||||
Err: fmt.Errorf("%q: %s", pattern, err.Error()),
|
||||
Pos: buildPos,
|
||||
})
|
||||
continue
|
||||
|
@ -822,47 +839,40 @@ func (c *Context) findBuildBlueprints(dir string, build []string,
|
|||
|
||||
if len(matches) == 0 {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q: not found", globPattern),
|
||||
Err: fmt.Errorf("%q: not found", pattern),
|
||||
Pos: buildPos,
|
||||
})
|
||||
}
|
||||
|
||||
// Depend on all searched directories so we pick up future changes.
|
||||
deps = append(deps, matchedDirs...)
|
||||
|
||||
for _, foundBlueprints := range matches {
|
||||
exists, dir, err := c.fs.Exists(foundBlueprints)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
} else if !exists {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q not found", foundBlueprints),
|
||||
})
|
||||
continue
|
||||
} else if dir {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q is a directory", foundBlueprints),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
blueprints = append(blueprints, foundBlueprints)
|
||||
deps = append(deps, foundBlueprints)
|
||||
}
|
||||
}
|
||||
|
||||
return blueprints, deps, errs
|
||||
return blueprints, errs
|
||||
}
|
||||
|
||||
func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos scanner.Position,
|
||||
subBlueprintsName string, optional bool) (blueprints, deps []string, errs []error) {
|
||||
subBlueprintsName string, optional bool) ([]string, []error) {
|
||||
|
||||
var blueprints []string
|
||||
var errs []error
|
||||
|
||||
for _, subdir := range subdirs {
|
||||
globPattern := filepath.Join(dir, subdir)
|
||||
matches, matchedDirs, err := pathtools.Glob(globPattern)
|
||||
pattern := filepath.Join(dir, subdir, subBlueprintsName)
|
||||
var matches []string
|
||||
var err error
|
||||
|
||||
if pathtools.IsGlob(pattern) {
|
||||
matches, err = c.glob(pattern, nil)
|
||||
} else {
|
||||
// Not a glob, but use filepath.Glob to check if it exists
|
||||
matches, err = filepath.Glob(pattern)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q: %s", globPattern, err.Error()),
|
||||
Err: fmt.Errorf("%q: %s", pattern, err.Error()),
|
||||
Pos: subdirsPos,
|
||||
})
|
||||
continue
|
||||
|
@ -870,56 +880,17 @@ func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos
|
|||
|
||||
if len(matches) == 0 && !optional {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("%q: not found", globPattern),
|
||||
Err: fmt.Errorf("%q: not found", pattern),
|
||||
Pos: subdirsPos,
|
||||
})
|
||||
}
|
||||
|
||||
// Depend on all searched directories so we pick up future changes.
|
||||
deps = append(deps, matchedDirs...)
|
||||
|
||||
for _, foundSubdir := range matches {
|
||||
exists, dir, subdirStatErr := c.fs.Exists(foundSubdir)
|
||||
if subdirStatErr != nil {
|
||||
errs = append(errs, subdirStatErr)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip files
|
||||
if !dir {
|
||||
continue
|
||||
}
|
||||
|
||||
var subBlueprints string
|
||||
if subBlueprintsName != "" {
|
||||
subBlueprints = filepath.Join(foundSubdir, subBlueprintsName)
|
||||
exists, _, err = c.fs.Exists(subBlueprints)
|
||||
}
|
||||
|
||||
if err == nil && (!exists || subBlueprints == "") {
|
||||
subBlueprints = filepath.Join(foundSubdir, "Blueprints")
|
||||
exists, _, err = c.fs.Exists(subBlueprints)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !exists {
|
||||
// There is no Blueprints file in this subdirectory. We
|
||||
// need to add the directory to the list of dependencies
|
||||
// so that if someone adds a Blueprints file in the
|
||||
// future we'll pick it up.
|
||||
deps = append(deps, foundSubdir)
|
||||
} else {
|
||||
deps = append(deps, subBlueprints)
|
||||
blueprints = append(blueprints, subBlueprints)
|
||||
}
|
||||
for _, subBlueprints := range matches {
|
||||
blueprints = append(blueprints, subBlueprints)
|
||||
}
|
||||
}
|
||||
|
||||
return blueprints, deps, errs
|
||||
return blueprints, errs
|
||||
}
|
||||
|
||||
func getLocalStringListFromScope(scope *parser.Scope, v string) ([]string, scanner.Position, error) {
|
||||
|
|
|
@ -95,7 +95,7 @@ func TestContextParse(t *testing.T) {
|
|||
}
|
||||
`)
|
||||
|
||||
_, _, _, errs := ctx.parse(".", "Blueprint", r, nil)
|
||||
_, _, errs := ctx.parse(".", "Blueprint", r, nil)
|
||||
if len(errs) > 0 {
|
||||
t.Errorf("unexpected parse errors:")
|
||||
for _, err := range errs {
|
||||
|
|
116
glob.go
Normal file
116
glob.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
// 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 blueprint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/google/blueprint/pathtools"
|
||||
)
|
||||
|
||||
type GlobPath struct {
|
||||
Pattern string
|
||||
Excludes []string
|
||||
Files []string
|
||||
Deps []string
|
||||
Name string
|
||||
}
|
||||
|
||||
func verifyGlob(fileName, pattern string, excludes []string, g GlobPath) {
|
||||
if pattern != g.Pattern {
|
||||
panic(fmt.Errorf("Mismatched patterns %q and %q for glob file %q", pattern, g.Pattern, fileName))
|
||||
}
|
||||
if !reflect.DeepEqual(g.Excludes, excludes) {
|
||||
panic(fmt.Errorf("Mismatched excludes %v and %v for glob file %q", excludes, g.Excludes, fileName))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) glob(pattern string, excludes []string) ([]string, error) {
|
||||
fileName := globToFileName(pattern, excludes)
|
||||
|
||||
// Try to get existing glob from the stored results
|
||||
c.globLock.Lock()
|
||||
g, exists := c.globs[fileName]
|
||||
c.globLock.Unlock()
|
||||
|
||||
if exists {
|
||||
// Glob has already been done, double check it is identical
|
||||
verifyGlob(fileName, pattern, excludes, g)
|
||||
return g.Files, nil
|
||||
}
|
||||
|
||||
// Get a globbed file list
|
||||
files, deps, err := pathtools.GlobWithExcludes(pattern, excludes)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store the results
|
||||
c.globLock.Lock()
|
||||
if g, exists = c.globs[fileName]; !exists {
|
||||
c.globs[fileName] = GlobPath{pattern, excludes, files, deps, fileName}
|
||||
}
|
||||
c.globLock.Unlock()
|
||||
|
||||
// Getting the list raced with another goroutine, throw away the results and use theirs
|
||||
if exists {
|
||||
verifyGlob(fileName, pattern, excludes, g)
|
||||
return g.Files, nil
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (c *Context) Globs() []GlobPath {
|
||||
fileNames := make([]string, 0, len(c.globs))
|
||||
for k := range c.globs {
|
||||
fileNames = append(fileNames, k)
|
||||
}
|
||||
sort.Strings(fileNames)
|
||||
|
||||
globs := make([]GlobPath, len(fileNames))
|
||||
for i, fileName := range fileNames {
|
||||
globs[i] = c.globs[fileName]
|
||||
}
|
||||
|
||||
return globs
|
||||
}
|
||||
|
||||
func globToString(pattern string) string {
|
||||
ret := ""
|
||||
for _, c := range pattern {
|
||||
switch {
|
||||
case c >= 'a' && c <= 'z',
|
||||
c >= 'A' && c <= 'Z',
|
||||
c >= '0' && c <= '9',
|
||||
c == '_', c == '-', c == '/':
|
||||
ret += string(c)
|
||||
default:
|
||||
ret += "_"
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func globToFileName(pattern string, excludes []string) string {
|
||||
ret := globToString(pattern)
|
||||
for _, e := range excludes {
|
||||
ret += "__" + globToString(e)
|
||||
}
|
||||
return ret + ".glob"
|
||||
}
|
|
@ -128,6 +128,12 @@ type BaseModuleContext interface {
|
|||
PropertyErrorf(property, fmt string, args ...interface{})
|
||||
Failed() bool
|
||||
|
||||
// GlobWithDeps returns a list of files that match the specified pattern but do not match any
|
||||
// of the patterns in excludes. It also adds efficient dependencies to rerun the primary
|
||||
// builder whenever a file matching the pattern as added or removed, without rerunning if a
|
||||
// file that does not match the pattern is added to a searched directory.
|
||||
GlobWithDeps(pattern string, excludes []string) ([]string, error)
|
||||
|
||||
moduleInfo() *moduleInfo
|
||||
error(err error)
|
||||
}
|
||||
|
@ -246,6 +252,11 @@ func (d *baseModuleContext) Failed() bool {
|
|||
return len(d.errs) > 0
|
||||
}
|
||||
|
||||
func (d *baseModuleContext) GlobWithDeps(pattern string,
|
||||
excludes []string) ([]string, error) {
|
||||
return d.context.glob(pattern, excludes)
|
||||
}
|
||||
|
||||
var _ ModuleContext = (*moduleContext)(nil)
|
||||
|
||||
type moduleContext struct {
|
||||
|
|
|
@ -16,9 +16,12 @@ package pathtools
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint/deptools"
|
||||
)
|
||||
|
||||
var GlobMultipleRecursiveErr = errors.New("pattern contains multiple **")
|
||||
|
@ -28,7 +31,12 @@ var GlobLastRecursiveErr = errors.New("pattern ** as last path element")
|
|||
// list of directories that were searched to construct the file list.
|
||||
// The supported glob patterns are equivalent to filepath.Glob, with an
|
||||
// extension that recursive glob (** matching zero or more complete path
|
||||
// entries) is supported.
|
||||
// entries) is supported. Glob also returns a list of directories that were
|
||||
// searched.
|
||||
//
|
||||
// In general ModuleContext.GlobWithDeps or SingletonContext.GlobWithDeps
|
||||
// should be used instead, as they will automatically set up dependencies
|
||||
// to rerun the primary builder when the list of matching files changes.
|
||||
func Glob(pattern string) (matches, dirs []string, err error) {
|
||||
return GlobWithExcludes(pattern, nil)
|
||||
}
|
||||
|
@ -38,6 +46,11 @@ func Glob(pattern string) (matches, dirs []string, err error) {
|
|||
// that were searched to construct the file list. The supported glob and
|
||||
// exclude patterns are equivalent to filepath.Glob, with an extension that
|
||||
// recursive glob (** matching zero or more complete path entries) is supported.
|
||||
// GlobWIthExcludes also returns a list of directories that were searched.
|
||||
//
|
||||
// In general ModuleContext.GlobWithDeps or SingletonContext.GlobWithDeps
|
||||
// should be used instead, as they will automatically set up dependencies
|
||||
// to rerun the primary builder when the list of matching files changes.
|
||||
func GlobWithExcludes(pattern string, excludes []string) (matches, dirs []string, err error) {
|
||||
if filepath.Base(pattern) == "**" {
|
||||
return nil, nil, GlobLastRecursiveErr
|
||||
|
@ -287,3 +300,98 @@ func GlobPatternList(patterns []string, prefix string) (globedList []string, dep
|
|||
}
|
||||
return globedList, depDirs, nil
|
||||
}
|
||||
|
||||
// IsGlob returns true if the pattern contains any glob characters (*, ?, or [).
|
||||
func IsGlob(pattern string) bool {
|
||||
return strings.IndexAny(pattern, "*?[") >= 0
|
||||
}
|
||||
|
||||
// HasGlob returns true if any string in the list contains any glob characters (*, ?, or [).
|
||||
func HasGlob(in []string) bool {
|
||||
for _, s := range in {
|
||||
if IsGlob(s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// In general ModuleContext.GlobWithDeps or SingletonContext.GlobWithDeps
|
||||
// should be used instead, as they will automatically set up dependencies
|
||||
// to rerun the primary builder when the list of matching files changes.
|
||||
func GlobWithDepFile(glob, fileListFile, depFile string, excludes []string) (files []string, err error) {
|
||||
files, dirs, err := 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
|
||||
}
|
||||
|
||||
// WriteFileIfChanged wraps ioutil.WriteFile, but only writes the file if
|
||||
// the files does not already exist with identical contents. This can be used
|
||||
// along with ninja restat rules to skip rebuilding downstream rules if no
|
||||
// changes were made by a rule.
|
||||
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
|
||||
}
|
||||
|
|
|
@ -62,6 +62,12 @@ type SingletonContext interface {
|
|||
FinalModule(module Module) Module
|
||||
|
||||
AddNinjaFileDeps(deps ...string)
|
||||
|
||||
// GlobWithDeps returns a list of files that match the specified pattern but do not match any
|
||||
// of the patterns in excludes. It also adds efficient dependencies to rerun the primary
|
||||
// builder whenever a file matching the pattern as added or removed, without rerunning if a
|
||||
// file that does not match the pattern is added to a searched directory.
|
||||
GlobWithDeps(pattern string, excludes []string) ([]string, error)
|
||||
}
|
||||
|
||||
var _ SingletonContext = (*singletonContext)(nil)
|
||||
|
@ -228,3 +234,8 @@ func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Modu
|
|||
func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
|
||||
s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
|
||||
}
|
||||
|
||||
func (s *singletonContext) GlobWithDeps(pattern string,
|
||||
excludes []string) ([]string, error) {
|
||||
return s.context.glob(pattern, excludes)
|
||||
}
|
||||
|
|
3
tests/test_tree/Blueprints
Normal file
3
tests/test_tree/Blueprints
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Root Blueprints file for test_tree
|
||||
|
||||
subdirs=["*"]
|
1
tests/test_tree/a/Blueprints
Normal file
1
tests/test_tree/a/Blueprints
Normal file
|
@ -0,0 +1 @@
|
|||
// a/Blueprints
|
1
tests/test_tree/blueprint
Symbolic link
1
tests/test_tree/blueprint
Symbolic link
|
@ -0,0 +1 @@
|
|||
../..
|
335
tests/test_tree/build.ninja.in
Normal file
335
tests/test_tree/build.ninja.in
Normal file
|
@ -0,0 +1,335 @@
|
|||
# ******************************************************************************
|
||||
# *** This file is generated and should not be edited ***
|
||||
# ******************************************************************************
|
||||
#
|
||||
# This file contains variables, rules, and pools with name prefixes indicating
|
||||
# they were generated by the following Go packages:
|
||||
#
|
||||
# bootstrap [from Go package github.com/google/blueprint/bootstrap]
|
||||
#
|
||||
ninja_required_version = 1.7.0
|
||||
|
||||
g.bootstrap.buildDir = @@BuildDir@@
|
||||
|
||||
g.bootstrap.BinDir = ${g.bootstrap.buildDir}/.bootstrap/bin
|
||||
|
||||
g.bootstrap.bootstrapCmd = @@Bootstrap@@
|
||||
|
||||
g.bootstrap.compileCmd = @@GoCompile@@
|
||||
|
||||
g.bootstrap.goRoot = @@GoRoot@@
|
||||
|
||||
g.bootstrap.linkCmd = @@GoLink@@
|
||||
|
||||
g.bootstrap.srcDir = @@SrcDir@@
|
||||
|
||||
builddir = ${g.bootstrap.buildDir}/.minibootstrap
|
||||
|
||||
rule g.bootstrap.bootstrap
|
||||
command = BUILDDIR=${g.bootstrap.buildDir} ${g.bootstrap.bootstrapCmd} -i ${in}
|
||||
description = bootstrap ${in}
|
||||
generator = true
|
||||
|
||||
rule g.bootstrap.build.ninja
|
||||
command = ${builder} ${extra} -b ${g.bootstrap.buildDir} -d ${out}.d -o ${out} ${in}
|
||||
depfile = ${out}.d
|
||||
description = ${builder} ${out}
|
||||
restat = true
|
||||
|
||||
rule g.bootstrap.compile
|
||||
command = GOROOT='${g.bootstrap.goRoot}' ${g.bootstrap.compileCmd} -o ${out} -p ${pkgPath} -complete ${incFlags} -pack ${in}
|
||||
description = compile ${out}
|
||||
|
||||
rule g.bootstrap.cp
|
||||
command = cp ${in} ${out}
|
||||
description = cp ${out}
|
||||
|
||||
rule g.bootstrap.link
|
||||
command = GOROOT='${g.bootstrap.goRoot}' ${g.bootstrap.linkCmd} -o ${out} ${libDirFlags} ${in}
|
||||
description = link ${out}
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:1:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
|
||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/blueprint/context.go $
|
||||
${g.bootstrap.srcDir}/blueprint/fs.go $
|
||||
${g.bootstrap.srcDir}/blueprint/glob.go $
|
||||
${g.bootstrap.srcDir}/blueprint/live_tracker.go $
|
||||
${g.bootstrap.srcDir}/blueprint/mangle.go $
|
||||
${g.bootstrap.srcDir}/blueprint/module_ctx.go $
|
||||
${g.bootstrap.srcDir}/blueprint/ninja_defs.go $
|
||||
${g.bootstrap.srcDir}/blueprint/ninja_strings.go $
|
||||
${g.bootstrap.srcDir}/blueprint/ninja_writer.go $
|
||||
${g.bootstrap.srcDir}/blueprint/package_ctx.go $
|
||||
${g.bootstrap.srcDir}/blueprint/scope.go $
|
||||
${g.bootstrap.srcDir}/blueprint/singleton_ctx.go $
|
||||
${g.bootstrap.srcDir}/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-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
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-bootstrap
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:89:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
|
||||
: g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/bootstrap.go $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/cleanup.go $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/command.go $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/config.go $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/doc.go $
|
||||
${g.bootstrap.srcDir}/blueprint/bootstrap/glob.go $
|
||||
${g.bootstrap.srcDir}/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-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-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
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-bootstrap-bpdoc
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:109:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
|
||||
: g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/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-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
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-deptools
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:50:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
|
||||
: g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/deptools/depfile.go | $
|
||||
${g.bootstrap.compileCmd}
|
||||
pkgPath = github.com/google/blueprint/deptools
|
||||
default $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-parser
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:34:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/blueprint/parser/ast.go $
|
||||
${g.bootstrap.srcDir}/blueprint/parser/modify.go $
|
||||
${g.bootstrap.srcDir}/blueprint/parser/parser.go $
|
||||
${g.bootstrap.srcDir}/blueprint/parser/printer.go $
|
||||
${g.bootstrap.srcDir}/blueprint/parser/sort.go | $
|
||||
${g.bootstrap.compileCmd}
|
||||
pkgPath = github.com/google/blueprint/parser
|
||||
default $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-pathtools
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:56:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
||||
: g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/pathtools/lists.go $
|
||||
${g.bootstrap.srcDir}/blueprint/pathtools/glob.go | $
|
||||
${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
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: blueprint-proptools
|
||||
# Variant:
|
||||
# Type: bootstrap_go_package
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:71:1
|
||||
|
||||
build $
|
||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||
: g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/proptools/clone.go $
|
||||
${g.bootstrap.srcDir}/blueprint/proptools/escape.go $
|
||||
${g.bootstrap.srcDir}/blueprint/proptools/extend.go $
|
||||
${g.bootstrap.srcDir}/blueprint/proptools/proptools.go $
|
||||
${g.bootstrap.srcDir}/blueprint/proptools/typeequal.go | $
|
||||
${g.bootstrap.compileCmd}
|
||||
pkgPath = github.com/google/blueprint/proptools
|
||||
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: blueprint/Blueprints:130:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a: $
|
||||
g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/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
|
||||
default ${g.bootstrap.BinDir}/bpglob
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: gotestmain
|
||||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:148:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
|
||||
g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/gotestmain/gotestmain.go | $
|
||||
${g.bootstrap.compileCmd}
|
||||
pkgPath = gotestmain
|
||||
default ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out: $
|
||||
g.bootstrap.link $
|
||||
${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a | $
|
||||
${g.bootstrap.linkCmd}
|
||||
default ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out
|
||||
|
||||
build ${g.bootstrap.BinDir}/gotestmain: g.bootstrap.cp $
|
||||
${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/a.out
|
||||
default ${g.bootstrap.BinDir}/gotestmain
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: gotestrunner
|
||||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:153:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $
|
||||
g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/blueprint/gotestrunner/gotestrunner.go | $
|
||||
${g.bootstrap.compileCmd}
|
||||
pkgPath = gotestrunner
|
||||
default ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/a.out: $
|
||||
g.bootstrap.link $
|
||||
${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a | $
|
||||
${g.bootstrap.linkCmd}
|
||||
default ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/a.out
|
||||
|
||||
build ${g.bootstrap.BinDir}/gotestrunner: g.bootstrap.cp $
|
||||
${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/a.out
|
||||
default ${g.bootstrap.BinDir}/gotestrunner
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Module: minibp
|
||||
# Variant:
|
||||
# Type: bootstrap_core_go_binary
|
||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
||||
# Defined: blueprint/Blueprints:121:1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $
|
||||
g.bootstrap.compile $
|
||||
${g.bootstrap.srcDir}/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-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-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-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 $
|
||||
${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out
|
||||
default ${g.bootstrap.BinDir}/minibp
|
||||
|
||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
|
||||
# Singleton: bootstrap
|
||||
# Factory: github.com/google/blueprint/bootstrap.newSingletonFactory.func1
|
||||
|
||||
build ${g.bootstrap.buildDir}/.bootstrap/build.ninja: g.bootstrap.build.ninja $
|
||||
${g.bootstrap.srcDir}/Blueprints | ${builder}
|
||||
builder = ${g.bootstrap.BinDir}/minibp
|
||||
extra = --build-primary
|
||||
default ${g.bootstrap.buildDir}/.bootstrap/build.ninja
|
||||
|
||||
build ${g.bootstrap.buildDir}/.minibootstrap/build.ninja.in: $
|
||||
g.bootstrap.build.ninja ${g.bootstrap.srcDir}/Blueprints | ${builder}
|
||||
builder = ${g.bootstrap.BinDir}/minibp
|
||||
extra =
|
||||
default ${g.bootstrap.buildDir}/.minibootstrap/build.ninja.in
|
||||
|
||||
build ${g.bootstrap.buildDir}/.minibootstrap/build.ninja: $
|
||||
g.bootstrap.bootstrap $
|
||||
${g.bootstrap.buildDir}/.minibootstrap/build.ninja.in | $
|
||||
${g.bootstrap.bootstrapCmd}
|
||||
default ${g.bootstrap.buildDir}/.minibootstrap/build.ninja
|
||||
|
78
tests/test_tree_tests.sh
Executable file
78
tests/test_tree_tests.sh
Executable file
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
function mtime() {
|
||||
stat -c %Y $1
|
||||
}
|
||||
|
||||
# Go to top of blueprint tree
|
||||
TOP=$(dirname ${BASH_SOURCE[0]})/..
|
||||
cd ${TOP}
|
||||
|
||||
rm -rf out.test
|
||||
mkdir out.test
|
||||
|
||||
rm -rf src.test
|
||||
mkdir src.test
|
||||
cp -r tests/test_tree src.test/test_tree
|
||||
|
||||
cd out.test
|
||||
export SRCDIR=../src.test/test_tree
|
||||
${SRCDIR}/blueprint/bootstrap.bash
|
||||
./blueprint.bash
|
||||
|
||||
if ! cmp -s ${SRCDIR}/build.ninja.in .minibootstrap/build.ninja.in; then
|
||||
echo "tests/test_tree/build.ninja.in and .minibootstrap/build.ninja.in should be the same" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OLDTIME=$(mtime build.ninja)
|
||||
|
||||
sleep 2
|
||||
./blueprint.bash
|
||||
|
||||
if [ ${OLDTIME} != $(mtime build.ninja) ]; then
|
||||
echo "unnecessary build.ninja regeneration for null build" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir ${SRCDIR}/newglob
|
||||
|
||||
sleep 2
|
||||
./blueprint.bash
|
||||
|
||||
if [ ${OLDTIME} != $(mtime build.ninja) ]; then
|
||||
echo "unnecessary build.ninja regeneration for glob addition" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch ${SRCDIR}/newglob/Blueprints
|
||||
|
||||
sleep 2
|
||||
./blueprint.bash
|
||||
|
||||
if [ ${OLDTIME} = $(mtime build.ninja) ]; then
|
||||
echo "Failed to rebuild for glob addition" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OLDTIME=$(mtime build.ninja)
|
||||
rm ${SRCDIR}/newglob/Blueprints
|
||||
|
||||
sleep 2
|
||||
./blueprint.bash
|
||||
|
||||
if [ ${OLDTIME} = $(mtime build.ninja) ]; then
|
||||
echo "Failed to rebuild for glob removal" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OLDTIME=$(mtime build.ninja)
|
||||
rmdir ${SRCDIR}/newglob
|
||||
|
||||
sleep 2
|
||||
./blueprint.bash
|
||||
|
||||
if [ ${OLDTIME} != $(mtime build.ninja) ]; then
|
||||
echo "unnecessary build.ninja regeneration for glob removal" >&2
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in a new issue