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
|
out.test
|
||||||
|
src.test
|
||||||
|
|
|
@ -23,3 +23,4 @@ script:
|
||||||
- ./blueprint.bash
|
- ./blueprint.bash
|
||||||
- diff -us ../build.ninja.in .minibootstrap/build.ninja.in
|
- diff -us ../build.ninja.in .minibootstrap/build.ninja.in
|
||||||
- ../tests/test.sh
|
- ../tests/test.sh
|
||||||
|
- ../tests/test_tree_tests.sh
|
||||||
|
|
11
Blueprints
11
Blueprints
|
@ -9,6 +9,7 @@ bootstrap_go_package(
|
||||||
srcs = [
|
srcs = [
|
||||||
"context.go",
|
"context.go",
|
||||||
"fs.go",
|
"fs.go",
|
||||||
|
"glob.go",
|
||||||
"live_tracker.go",
|
"live_tracker.go",
|
||||||
"mangle.go",
|
"mangle.go",
|
||||||
"module_ctx.go",
|
"module_ctx.go",
|
||||||
|
@ -55,6 +56,9 @@ bootstrap_go_package(
|
||||||
bootstrap_go_package(
|
bootstrap_go_package(
|
||||||
name = "blueprint-pathtools",
|
name = "blueprint-pathtools",
|
||||||
pkgPath = "github.com/google/blueprint/pathtools",
|
pkgPath = "github.com/google/blueprint/pathtools",
|
||||||
|
deps = [
|
||||||
|
"blueprint-deptools",
|
||||||
|
],
|
||||||
srcs = [
|
srcs = [
|
||||||
"pathtools/lists.go",
|
"pathtools/lists.go",
|
||||||
"pathtools/glob.go",
|
"pathtools/glob.go",
|
||||||
|
@ -97,6 +101,7 @@ bootstrap_go_package(
|
||||||
"bootstrap/command.go",
|
"bootstrap/command.go",
|
||||||
"bootstrap/config.go",
|
"bootstrap/config.go",
|
||||||
"bootstrap/doc.go",
|
"bootstrap/doc.go",
|
||||||
|
"bootstrap/glob.go",
|
||||||
"bootstrap/writedocs.go",
|
"bootstrap/writedocs.go",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -122,6 +127,12 @@ bootstrap_core_go_binary(
|
||||||
srcs = ["bootstrap/minibp/main.go"],
|
srcs = ["bootstrap/minibp/main.go"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
bootstrap_core_go_binary(
|
||||||
|
name = "bpglob",
|
||||||
|
deps = ["blueprint-pathtools"],
|
||||||
|
srcs = ["bootstrap/bpglob/bpglob.go"],
|
||||||
|
)
|
||||||
|
|
||||||
blueprint_go_binary(
|
blueprint_go_binary(
|
||||||
name = "bpfmt",
|
name = "bpfmt",
|
||||||
deps = ["blueprint-parser"],
|
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.RegisterTopDownMutator("bootstrap_stage", propagateStageBootstrap)
|
||||||
ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig))
|
ctx.RegisterSingletonType("bootstrap", newSingletonFactory(bootstrapConfig))
|
||||||
|
|
||||||
|
ctx.RegisterSingletonType("glob", globSingletonFactory(ctx))
|
||||||
|
|
||||||
deps, errs := ctx.ParseBlueprintsFiles(bootstrapConfig.topLevelBlueprintsFile)
|
deps, errs := ctx.ParseBlueprintsFiles(bootstrapConfig.topLevelBlueprintsFile)
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
fatalErrors(errs)
|
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 $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
|
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
|
||||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/context.go $
|
: g.bootstrap.compile ${g.bootstrap.srcDir}/context.go $
|
||||||
${g.bootstrap.srcDir}/fs.go ${g.bootstrap.srcDir}/live_tracker.go $
|
${g.bootstrap.srcDir}/fs.go ${g.bootstrap.srcDir}/glob.go $
|
||||||
${g.bootstrap.srcDir}/mangle.go ${g.bootstrap.srcDir}/module_ctx.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_defs.go $
|
||||||
${g.bootstrap.srcDir}/ninja_strings.go $
|
${g.bootstrap.srcDir}/ninja_strings.go $
|
||||||
${g.bootstrap.srcDir}/ninja_writer.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.srcDir}/singleton_ctx.go ${g.bootstrap.srcDir}/unpack.go $
|
||||||
| ${g.bootstrap.compileCmd} $
|
| ${g.bootstrap.compileCmd} $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
${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-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-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
|
pkgPath = github.com/google/blueprint
|
||||||
default $
|
default $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
|
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
|
||||||
|
@ -79,7 +81,7 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:85:1
|
# Defined: Blueprints:89:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
|
${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/command.go $
|
||||||
${g.bootstrap.srcDir}/bootstrap/config.go $
|
${g.bootstrap.srcDir}/bootstrap/config.go $
|
||||||
${g.bootstrap.srcDir}/bootstrap/doc.go $
|
${g.bootstrap.srcDir}/bootstrap/doc.go $
|
||||||
|
${g.bootstrap.srcDir}/bootstrap/glob.go $
|
||||||
${g.bootstrap.srcDir}/bootstrap/writedocs.go | $
|
${g.bootstrap.srcDir}/bootstrap/writedocs.go | $
|
||||||
${g.bootstrap.compileCmd} $
|
${g.bootstrap.compileCmd} $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
${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-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-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.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-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
|
pkgPath = github.com/google/blueprint/bootstrap
|
||||||
default $
|
default $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a
|
||||||
|
@ -106,17 +109,18 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:104:1
|
# Defined: Blueprints:109:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
|
${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.compile ${g.bootstrap.srcDir}/bootstrap/bpdoc/bpdoc.go | $
|
||||||
${g.bootstrap.compileCmd} $
|
${g.bootstrap.compileCmd} $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
${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-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-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.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
|
pkgPath = github.com/google/blueprint/bootstrap/bpdoc
|
||||||
default $
|
default $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a
|
||||||
|
@ -126,7 +130,7 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:49:1
|
# Defined: Blueprints:50:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
|
||||||
|
@ -141,7 +145,7 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:33:1
|
# Defined: Blueprints:34:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
||||||
|
@ -159,12 +163,14 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:55:1
|
# Defined: Blueprints:56:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
||||||
: g.bootstrap.compile ${g.bootstrap.srcDir}/pathtools/lists.go $
|
: 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
|
pkgPath = github.com/google/blueprint/pathtools
|
||||||
default $
|
default $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
|
||||||
|
@ -174,7 +180,7 @@ default $
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_go_package
|
# Type: bootstrap_go_package
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
|
||||||
# Defined: Blueprints:67:1
|
# Defined: Blueprints:71:1
|
||||||
|
|
||||||
build $
|
build $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
|
${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||||
|
@ -188,12 +194,38 @@ build $
|
||||||
default $
|
default $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
|
${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
|
# Module: gotestmain
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_core_go_binary
|
# Type: bootstrap_core_go_binary
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
# 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: $
|
build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
|
||||||
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | $
|
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | $
|
||||||
|
@ -216,7 +248,7 @@ default ${g.bootstrap.BinDir}/gotestmain
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_core_go_binary
|
# Type: bootstrap_core_go_binary
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
# 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: $
|
build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $
|
||||||
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestrunner/gotestrunner.go $
|
g.bootstrap.compile ${g.bootstrap.srcDir}/gotestrunner/gotestrunner.go $
|
||||||
|
@ -239,26 +271,26 @@ default ${g.bootstrap.BinDir}/gotestrunner
|
||||||
# Variant:
|
# Variant:
|
||||||
# Type: bootstrap_core_go_binary
|
# Type: bootstrap_core_go_binary
|
||||||
# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
|
# 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: $
|
build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $
|
||||||
g.bootstrap.compile ${g.bootstrap.srcDir}/bootstrap/minibp/main.go | $
|
g.bootstrap.compile ${g.bootstrap.srcDir}/bootstrap/minibp/main.go | $
|
||||||
${g.bootstrap.compileCmd} $
|
${g.bootstrap.compileCmd} $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
${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-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-proptools/pkg/github.com/google/blueprint/proptools.a $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.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-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.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
|
pkgPath = minibp
|
||||||
default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a
|
default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a
|
||||||
|
|
||||||
build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out: g.bootstrap.link $
|
build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out: g.bootstrap.link $
|
||||||
${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a | $
|
${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a | $
|
||||||
${g.bootstrap.linkCmd}
|
${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
|
default ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/a.out
|
||||||
|
|
||||||
build ${g.bootstrap.BinDir}/minibp: g.bootstrap.cp $
|
build ${g.bootstrap.BinDir}/minibp: g.bootstrap.cp $
|
||||||
|
|
147
context.go
147
context.go
|
@ -25,6 +25,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"text/scanner"
|
"text/scanner"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -105,6 +106,9 @@ type Context struct {
|
||||||
renames []rename
|
renames []rename
|
||||||
replacements []replace
|
replacements []replace
|
||||||
|
|
||||||
|
globs map[string]GlobPath
|
||||||
|
globLock sync.Mutex
|
||||||
|
|
||||||
fs fileSystem
|
fs fileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +274,7 @@ func NewContext() *Context {
|
||||||
moduleNames: make(map[string]*moduleGroup),
|
moduleNames: make(map[string]*moduleGroup),
|
||||||
moduleInfo: make(map[Module]*moduleInfo),
|
moduleInfo: make(map[Module]*moduleInfo),
|
||||||
moduleNinjaNames: make(map[string]*moduleGroup),
|
moduleNinjaNames: make(map[string]*moduleGroup),
|
||||||
|
globs: make(map[string]GlobPath),
|
||||||
fs: fs,
|
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
|
// filename specifies the path to the Blueprints file. These paths are used for
|
||||||
// error reporting and for determining the module's directory.
|
// error reporting and for determining the module's directory.
|
||||||
func (c *Context) parse(rootDir, filename string, r io.Reader,
|
func (c *Context) parse(rootDir, filename string, r io.Reader,
|
||||||
scope *parser.Scope) (file *parser.File, subBlueprints []stringAndScope, deps []string,
|
scope *parser.Scope) (file *parser.File, subBlueprints []stringAndScope, errs []error) {
|
||||||
errs []error) {
|
|
||||||
|
|
||||||
relBlueprintsFile, err := filepath.Rel(rootDir, filename)
|
relBlueprintsFile, err := filepath.Rel(rootDir, filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, []error{err}
|
return nil, nil, []error{err}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope = parser.NewScope(scope)
|
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
|
// If there were any parse errors don't bother trying to interpret the
|
||||||
// result.
|
// result.
|
||||||
return nil, nil, nil, errs
|
return nil, nil, errs
|
||||||
}
|
}
|
||||||
file.Name = relBlueprintsFile
|
file.Name = relBlueprintsFile
|
||||||
|
|
||||||
|
@ -570,24 +574,28 @@ func (c *Context) parse(rootDir, filename string, r io.Reader,
|
||||||
}
|
}
|
||||||
|
|
||||||
subBlueprintsName, _, err := getStringFromScope(scope, "subname")
|
subBlueprintsName, _, err := getStringFromScope(scope, "subname")
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subBlueprintsName == "" {
|
||||||
|
subBlueprintsName = "Blueprints"
|
||||||
|
}
|
||||||
|
|
||||||
var blueprints []string
|
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...)
|
blueprints = append(blueprints, newBlueprints...)
|
||||||
deps = append(deps, newDeps...)
|
|
||||||
errs = append(errs, newErrs...)
|
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)
|
subBlueprintsName, false)
|
||||||
blueprints = append(blueprints, newBlueprints...)
|
blueprints = append(blueprints, newBlueprints...)
|
||||||
deps = append(deps, newDeps...)
|
|
||||||
errs = append(errs, newErrs...)
|
errs = append(errs, newErrs...)
|
||||||
|
|
||||||
newBlueprints, newDeps, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), optionalSubdirs,
|
newBlueprints, newErrs = c.findSubdirBlueprints(filepath.Dir(filename), optionalSubdirs,
|
||||||
optionalSubdirsPos, subBlueprintsName, true)
|
optionalSubdirsPos, subBlueprintsName, true)
|
||||||
blueprints = append(blueprints, newBlueprints...)
|
blueprints = append(blueprints, newBlueprints...)
|
||||||
deps = append(deps, newDeps...)
|
|
||||||
errs = append(errs, newErrs...)
|
errs = append(errs, newErrs...)
|
||||||
|
|
||||||
subBlueprintsAndScope := make([]stringAndScope, len(blueprints))
|
subBlueprintsAndScope := make([]stringAndScope, len(blueprints))
|
||||||
|
@ -595,7 +603,7 @@ func (c *Context) parse(rootDir, filename string, r io.Reader,
|
||||||
subBlueprintsAndScope[i] = stringAndScope{b, scope}
|
subBlueprintsAndScope[i] = stringAndScope{b, scope}
|
||||||
}
|
}
|
||||||
|
|
||||||
return file, subBlueprintsAndScope, deps, errs
|
return file, subBlueprintsAndScope, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
type stringAndScope struct {
|
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 {
|
if len(errs) > 0 {
|
||||||
errsCh <- errs
|
errsCh <- errs
|
||||||
} else {
|
} else {
|
||||||
|
@ -799,22 +807,31 @@ func (c *Context) parseBlueprintsFile(filename string, scope *parser.Scope, root
|
||||||
|
|
||||||
for _, b := range subBlueprints {
|
for _, b := range subBlueprints {
|
||||||
blueprintsCh <- b
|
blueprintsCh <- b
|
||||||
}
|
depsCh <- b.string
|
||||||
|
|
||||||
for _, d := range deps {
|
|
||||||
depsCh <- d
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) findBuildBlueprints(dir string, build []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 {
|
for _, file := range build {
|
||||||
globPattern := filepath.Join(dir, file)
|
pattern := filepath.Join(dir, file)
|
||||||
matches, matchedDirs, err := pathtools.Glob(globPattern)
|
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 {
|
if err != nil {
|
||||||
errs = append(errs, &BlueprintError{
|
errs = append(errs, &BlueprintError{
|
||||||
Err: fmt.Errorf("%q: %s", globPattern, err.Error()),
|
Err: fmt.Errorf("%q: %s", pattern, err.Error()),
|
||||||
Pos: buildPos,
|
Pos: buildPos,
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
|
@ -822,47 +839,40 @@ func (c *Context) findBuildBlueprints(dir string, build []string,
|
||||||
|
|
||||||
if len(matches) == 0 {
|
if len(matches) == 0 {
|
||||||
errs = append(errs, &BlueprintError{
|
errs = append(errs, &BlueprintError{
|
||||||
Err: fmt.Errorf("%q: not found", globPattern),
|
Err: fmt.Errorf("%q: not found", pattern),
|
||||||
Pos: buildPos,
|
Pos: buildPos,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depend on all searched directories so we pick up future changes.
|
|
||||||
deps = append(deps, matchedDirs...)
|
|
||||||
|
|
||||||
for _, foundBlueprints := range matches {
|
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)
|
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,
|
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 {
|
for _, subdir := range subdirs {
|
||||||
globPattern := filepath.Join(dir, subdir)
|
pattern := filepath.Join(dir, subdir, subBlueprintsName)
|
||||||
matches, matchedDirs, err := pathtools.Glob(globPattern)
|
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 {
|
if err != nil {
|
||||||
errs = append(errs, &BlueprintError{
|
errs = append(errs, &BlueprintError{
|
||||||
Err: fmt.Errorf("%q: %s", globPattern, err.Error()),
|
Err: fmt.Errorf("%q: %s", pattern, err.Error()),
|
||||||
Pos: subdirsPos,
|
Pos: subdirsPos,
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
|
@ -870,56 +880,17 @@ func (c *Context) findSubdirBlueprints(dir string, subdirs []string, subdirsPos
|
||||||
|
|
||||||
if len(matches) == 0 && !optional {
|
if len(matches) == 0 && !optional {
|
||||||
errs = append(errs, &BlueprintError{
|
errs = append(errs, &BlueprintError{
|
||||||
Err: fmt.Errorf("%q: not found", globPattern),
|
Err: fmt.Errorf("%q: not found", pattern),
|
||||||
Pos: subdirsPos,
|
Pos: subdirsPos,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depend on all searched directories so we pick up future changes.
|
for _, subBlueprints := range matches {
|
||||||
deps = append(deps, matchedDirs...)
|
blueprints = append(blueprints, subBlueprints)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return blueprints, deps, errs
|
return blueprints, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLocalStringListFromScope(scope *parser.Scope, v string) ([]string, scanner.Position, error) {
|
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 {
|
if len(errs) > 0 {
|
||||||
t.Errorf("unexpected parse errors:")
|
t.Errorf("unexpected parse errors:")
|
||||||
for _, err := range errs {
|
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{})
|
PropertyErrorf(property, fmt string, args ...interface{})
|
||||||
Failed() bool
|
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
|
moduleInfo() *moduleInfo
|
||||||
error(err error)
|
error(err error)
|
||||||
}
|
}
|
||||||
|
@ -246,6 +252,11 @@ func (d *baseModuleContext) Failed() bool {
|
||||||
return len(d.errs) > 0
|
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)
|
var _ ModuleContext = (*moduleContext)(nil)
|
||||||
|
|
||||||
type moduleContext struct {
|
type moduleContext struct {
|
||||||
|
|
|
@ -16,9 +16,12 @@ package pathtools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/blueprint/deptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var GlobMultipleRecursiveErr = errors.New("pattern contains multiple **")
|
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.
|
// list of directories that were searched to construct the file list.
|
||||||
// The supported glob patterns are equivalent to filepath.Glob, with an
|
// The supported glob patterns are equivalent to filepath.Glob, with an
|
||||||
// extension that recursive glob (** matching zero or more complete path
|
// 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) {
|
func Glob(pattern string) (matches, dirs []string, err error) {
|
||||||
return GlobWithExcludes(pattern, nil)
|
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
|
// that were searched to construct the file list. The supported glob and
|
||||||
// exclude patterns are equivalent to filepath.Glob, with an extension that
|
// exclude patterns are equivalent to filepath.Glob, with an extension that
|
||||||
// recursive glob (** matching zero or more complete path entries) is supported.
|
// 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) {
|
func GlobWithExcludes(pattern string, excludes []string) (matches, dirs []string, err error) {
|
||||||
if filepath.Base(pattern) == "**" {
|
if filepath.Base(pattern) == "**" {
|
||||||
return nil, nil, GlobLastRecursiveErr
|
return nil, nil, GlobLastRecursiveErr
|
||||||
|
@ -287,3 +300,98 @@ func GlobPatternList(patterns []string, prefix string) (globedList []string, dep
|
||||||
}
|
}
|
||||||
return globedList, depDirs, nil
|
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
|
FinalModule(module Module) Module
|
||||||
|
|
||||||
AddNinjaFileDeps(deps ...string)
|
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)
|
var _ SingletonContext = (*singletonContext)(nil)
|
||||||
|
@ -228,3 +234,8 @@ func (s *singletonContext) VisitAllModuleVariants(module Module, visit func(Modu
|
||||||
func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
|
func (s *singletonContext) AddNinjaFileDeps(deps ...string) {
|
||||||
s.ninjaFileDeps = append(s.ninjaFileDeps, deps...)
|
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