Merge "Delete output files before copying to them."
diff --git a/Android.bp b/Android.bp
index 496dcd2..82be0fa 100644
--- a/Android.bp
+++ b/Android.bp
@@ -51,6 +51,7 @@
"android/paths.go",
"android/prebuilt.go",
"android/register.go",
+ "android/testing.go",
"android/util.go",
"android/variable.go",
@@ -123,6 +124,7 @@
"cc/strip.go",
"cc/tidy.go",
"cc/util.go",
+ "cc/vndk.go",
"cc/cmakelists.go",
"cc/compiler.go",
@@ -201,6 +203,9 @@
"java/java.go",
"java/resources.go",
],
+ testSrcs: [
+ "java/java_test.go",
+ ],
pluginFor: ["soong_build"],
}
diff --git a/android/androidmk.go b/android/androidmk.go
index b81cc2a..6197f59 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -61,8 +61,6 @@
return
}
- ctx.SetNinjaBuildDir(pctx, filepath.Join(config.buildDir, ".."))
-
var androidMkModulesList []Module
ctx.VisitAllModules(func(module blueprint.Module) {
@@ -246,8 +244,8 @@
if amod.commonProperties.Vendor {
fmt.Fprintln(w, "LOCAL_VENDOR_MODULE := true")
}
- if amod.commonProperties.Owner != "" {
- fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", amod.commonProperties.Owner)
+ if amod.commonProperties.Owner != nil {
+ fmt.Fprintln(w, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
}
}
diff --git a/android/arch.go b/android/arch.go
index 67ce30e..08421a1 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -879,10 +879,12 @@
{"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
{"arm", "armv7-a-neon", "kryo", []string{"armeabi-v7a"}},
+ {"arm", "armv7-a-neon", "exynos-m2", []string{"armeabi-v7a"}},
{"arm64", "armv8-a", "cortex-a53", []string{"arm64-v8a"}},
{"arm64", "armv8-a", "cortex-a73", []string{"arm64-v8a"}},
{"arm64", "armv8-a", "denver64", []string{"arm64-v8a"}},
{"arm64", "armv8-a", "kryo", []string{"arm64-v8a"}},
+ {"arm64", "armv8-a", "exynos-m2", []string{"arm64-v8a"}},
{"mips", "mips32-fp", "", []string{"mips"}},
{"mips", "mips32r2-fp", "", []string{"mips"}},
{"mips", "mips32r2-fp-xburst", "", []string{"mips"}},
diff --git a/android/config.go b/android/config.go
index 3de1ef1..5dcc59b 100644
--- a/android/config.go
+++ b/android/config.go
@@ -84,6 +84,8 @@
inMake bool
+ captureBuild bool // true for tests, saves build parameters for each module
+
OncePer
}
@@ -171,7 +173,8 @@
DeviceName: stringPtr("test_device"),
},
- buildDir: buildDir,
+ buildDir: buildDir,
+ captureBuild: true,
}
config.deviceConfig = &deviceConfig{
config: config,
@@ -527,20 +530,21 @@
func (c *deviceConfig) CoverageEnabledForPath(path string) bool {
coverage := false
if c.config.ProductVariables.CoveragePaths != nil {
- for _, prefix := range *c.config.ProductVariables.CoveragePaths {
- if strings.HasPrefix(path, prefix) {
- coverage = true
- break
- }
+ if prefixInList(path, *c.config.ProductVariables.CoveragePaths) {
+ coverage = true
}
}
if coverage && c.config.ProductVariables.CoverageExcludePaths != nil {
- for _, prefix := range *c.config.ProductVariables.CoverageExcludePaths {
- if strings.HasPrefix(path, prefix) {
- coverage = false
- break
- }
+ if prefixInList(path, *c.config.ProductVariables.CoverageExcludePaths) {
+ coverage = false
}
}
return coverage
}
+
+func (c *config) IntegerOverflowDisabledForPath(path string) bool {
+ if c.ProductVariables.IntegerOverflowExcludePaths == nil {
+ return false
+ }
+ return prefixInList(path, *c.ProductVariables.IntegerOverflowExcludePaths)
+}
diff --git a/android/defaults.go b/android/defaults.go
index 0776405..4bf872e 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -29,16 +29,16 @@
Defaults []string
}
-type DefaultableModule struct {
+type DefaultableModuleBase struct {
defaultsProperties defaultsProperties
defaultableProperties []interface{}
}
-func (d *DefaultableModule) defaults() *defaultsProperties {
+func (d *DefaultableModuleBase) defaults() *defaultsProperties {
return &d.defaultsProperties
}
-func (d *DefaultableModule) setProperties(props []interface{}) {
+func (d *DefaultableModuleBase) setProperties(props []interface{}) {
d.defaultableProperties = props
}
@@ -48,17 +48,21 @@
applyDefaults(TopDownMutatorContext, []Defaults)
}
-var _ Defaultable = (*DefaultableModule)(nil)
-
-func InitDefaultableModule(module Module, d Defaultable) {
-
- d.setProperties(module.GetProperties())
-
- module.AddProperties(d.defaults())
+type DefaultableModule interface {
+ Module
+ Defaultable
}
-type DefaultsModule struct {
- DefaultableModule
+var _ Defaultable = (*DefaultableModuleBase)(nil)
+
+func InitDefaultableModule(module DefaultableModule) {
+ module.(Defaultable).setProperties(module.(Module).GetProperties())
+
+ module.AddProperties(module.defaults())
+}
+
+type DefaultsModuleBase struct {
+ DefaultableModuleBase
defaultProperties []interface{}
}
@@ -68,31 +72,31 @@
properties() []interface{}
}
-func (d *DefaultsModule) isDefaults() bool {
+func (d *DefaultsModuleBase) isDefaults() bool {
return true
}
-func (d *DefaultsModule) properties() []interface{} {
+func (d *DefaultsModuleBase) properties() []interface{} {
return d.defaultableProperties
}
-func InitDefaultsModule(module Module, d Defaults) {
+func InitDefaultsModule(module DefaultableModule) {
module.AddProperties(
&hostAndDeviceProperties{},
&commonProperties{},
&variableProperties{})
InitArchModule(module)
- InitDefaultableModule(module, d)
+ InitDefaultableModule(module)
module.AddProperties(&module.base().nameProperties)
module.base().module = module
}
-var _ Defaults = (*DefaultsModule)(nil)
+var _ Defaults = (*DefaultsModuleBase)(nil)
-func (defaultable *DefaultableModule) applyDefaults(ctx TopDownMutatorContext,
+func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
defaultsList []Defaults) {
for _, defaults := range defaultsList {
@@ -113,6 +117,11 @@
}
}
+func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
+ ctx.TopDown("defaults", defaultsMutator).Parallel()
+}
+
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
if defaultable, ok := ctx.Module().(Defaultable); ok {
ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
diff --git a/android/module.go b/android/module.go
index 7f541be..3a3d173 100644
--- a/android/module.go
+++ b/android/module.go
@@ -111,6 +111,8 @@
AddProperties(props ...interface{})
GetProperties() []interface{}
+
+ BuildParamsForTests() []ModuleBuildParams
}
type nameProperties struct {
@@ -145,7 +147,7 @@
Proprietary bool
// vendor who owns this module
- Owner string
+ Owner *string
// whether this module is device specific and should be installed into /vendor
Vendor bool
@@ -291,6 +293,9 @@
hooks hooks
registerProps []interface{}
+
+ // For tests
+ buildParams []ModuleBuildParams
}
func (a *ModuleBase) AddProperties(props ...interface{}) {
@@ -301,6 +306,10 @@
return a.registerProps
}
+func (a *ModuleBase) BuildParamsForTests() []ModuleBuildParams {
+ return a.buildParams
+}
+
// Name returns the name of the module. It may be overridden by individual module types, for
// example prebuilts will prepend prebuilt_ to the name.
func (a *ModuleBase) Name() string {
@@ -520,6 +529,8 @@
return
}
}
+
+ a.buildParams = androidCtx.buildParams
}
type androidBaseContextImpl struct {
@@ -538,6 +549,9 @@
checkbuildFiles Paths
missingDeps []string
module Module
+
+ // For tests
+ buildParams []ModuleBuildParams
}
func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
@@ -566,6 +580,10 @@
}
func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) {
+ if a.config.captureBuild {
+ a.buildParams = append(a.buildParams, params)
+ }
+
bparams := blueprint.BuildParams{
Rule: params.Rule,
Deps: params.Deps,
diff --git a/android/mutator.go b/android/mutator.go
index bb49487..c8f3e8f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,8 +15,6 @@
package android
import (
- "sync"
-
"github.com/google/blueprint"
)
@@ -27,9 +25,6 @@
// Deps
// PostDeps
-var registerMutatorsOnce sync.Once
-var registeredMutators []*mutator
-
func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
for _, t := range mutators {
var handle blueprint.MutatorHandle
@@ -44,56 +39,24 @@
}
}
-func registerMutators(ctx *blueprint.Context) {
-
- registerMutatorsOnce.Do(func() {
- ctx := ®isterMutatorsContext{}
-
- register := func(funcs []RegisterMutatorFunc) {
- for _, f := range funcs {
- f(ctx)
- }
- }
-
- ctx.TopDown("load_hooks", loadHookMutator).Parallel()
- ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
- ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
- ctx.TopDown("defaults", defaultsMutator).Parallel()
-
- register(preArch)
-
- ctx.BottomUp("arch", archMutator).Parallel()
- ctx.TopDown("arch_hooks", archHookMutator).Parallel()
-
- register(preDeps)
-
- ctx.BottomUp("deps", depsMutator).Parallel()
-
- ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
- ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
-
- register(postDeps)
-
- registeredMutators = ctx.mutators
- })
-
- registerMutatorsToContext(ctx, registeredMutators)
-}
-
-func RegisterTestMutators(ctx *blueprint.Context) {
- mutators := ®isterMutatorsContext{}
+func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) {
+ mctx := ®isterMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) {
for _, f := range funcs {
- f(mutators)
+ f(mctx)
}
}
- register(testPreDeps)
- mutators.BottomUp("deps", depsMutator).Parallel()
- register(testPostDeps)
+ register(preArch)
- registerMutatorsToContext(ctx, mutators.mutators)
+ register(preDeps)
+
+ mctx.BottomUp("deps", depsMutator).Parallel()
+
+ register(postDeps)
+
+ registerMutatorsToContext(ctx, mctx.mutators)
}
type registerMutatorsContext struct {
@@ -107,7 +70,24 @@
type RegisterMutatorFunc func(RegisterMutatorsContext)
-var preArch, preDeps, postDeps, testPreDeps, testPostDeps []RegisterMutatorFunc
+var preArch = []RegisterMutatorFunc{
+ func(ctx RegisterMutatorsContext) {
+ ctx.TopDown("load_hooks", loadHookMutator).Parallel()
+ },
+ registerPrebuiltsPreArchMutators,
+ RegisterDefaultsPreArchMutators,
+}
+
+var preDeps = []RegisterMutatorFunc{
+ func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("arch", archMutator).Parallel()
+ ctx.TopDown("arch_hooks", archHookMutator).Parallel()
+ },
+}
+
+var postDeps = []RegisterMutatorFunc{
+ registerPrebuiltsPostDepsMutators,
+}
func PreArchMutators(f RegisterMutatorFunc) {
preArch = append(preArch, f)
@@ -121,14 +101,6 @@
postDeps = append(postDeps, f)
}
-func TestPreDepsMutators(f RegisterMutatorFunc) {
- testPreDeps = append(testPreDeps, f)
-}
-
-func TeststPostDepsMutators(f RegisterMutatorFunc) {
- testPostDeps = append(testPostDeps, f)
-}
-
type AndroidTopDownMutator func(TopDownMutatorContext)
type TopDownMutatorContext interface {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 772df7a..080df91 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -61,6 +61,15 @@
Prebuilt() *Prebuilt
}
+func registerPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
+}
+
+func registerPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
+ ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
+ ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
+}
+
// prebuiltMutator ensures that there is always a module with an undecorated name, and marks
// prebuilt modules that have both a prebuilt and a source module.
func prebuiltMutator(ctx BottomUpMutatorContext) {
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 5fa2032..fe763ed 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -122,9 +122,12 @@
for _, test := range prebuiltsTests {
t.Run(test.name, func(t *testing.T) {
- ctx := NewContext()
+ ctx := NewTestContext()
+ ctx.PreArchMutators(registerPrebuiltsPreArchMutators)
+ ctx.PostDepsMutators(registerPrebuiltsPostDepsMutators)
ctx.RegisterModuleType("prebuilt", ModuleFactoryAdaptor(newPrebuiltModule))
ctx.RegisterModuleType("source", ModuleFactoryAdaptor(newSourceModule))
+ ctx.Register()
ctx.MockFileSystem(map[string][]byte{
"Blueprints": []byte(`
source {
@@ -139,13 +142,10 @@
_, errs = ctx.PrepareBuildActions(config)
fail(t, errs)
- foo := findModule(ctx, "foo")
- if foo == nil {
- t.Fatalf("failed to find module foo")
- }
+ foo := ctx.ModuleForTests("foo", "")
var dependsOnSourceModule, dependsOnPrebuiltModule bool
- ctx.VisitDirectDeps(foo, func(m blueprint.Module) {
+ ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
if _, ok := m.(*sourceModule); ok {
dependsOnSourceModule = true
}
@@ -228,16 +228,6 @@
func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
}
-func findModule(ctx *blueprint.Context, name string) blueprint.Module {
- var ret blueprint.Module
- ctx.VisitAllModules(func(m blueprint.Module) {
- if ctx.ModuleName(m) == name {
- ret = m
- }
- })
- return ret
-}
-
func fail(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
diff --git a/android/register.go b/android/register.go
index 76a1cc9..226e790 100644
--- a/android/register.go
+++ b/android/register.go
@@ -60,9 +60,15 @@
singletons = append(singletons, singleton{name, factory})
}
-func NewContext() *blueprint.Context {
- ctx := blueprint.NewContext()
+type Context struct {
+ *blueprint.Context
+}
+func NewContext() *Context {
+ return &Context{blueprint.NewContext()}
+}
+
+func (ctx *Context) Register() {
for _, t := range moduleTypes {
ctx.RegisterModuleType(t.name, t.factory)
}
@@ -71,9 +77,7 @@
ctx.RegisterSingletonType(t.name, t.factory)
}
- registerMutators(ctx)
+ registerMutators(ctx.Context, preArch, preDeps, postDeps)
ctx.RegisterSingletonType("env", EnvSingleton)
-
- return ctx
}
diff --git a/android/testing.go b/android/testing.go
new file mode 100644
index 0000000..4144775
--- /dev/null
+++ b/android/testing.go
@@ -0,0 +1,98 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint"
+)
+
+func NewTestContext() *TestContext {
+ return &TestContext{
+ Context: blueprint.NewContext(),
+ }
+}
+
+type TestContext struct {
+ *blueprint.Context
+ preArch, preDeps, postDeps []RegisterMutatorFunc
+}
+
+func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
+ ctx.preArch = append(ctx.preArch, f)
+}
+
+func (ctx *TestContext) PreDepsMutators(f RegisterMutatorFunc) {
+ ctx.preDeps = append(ctx.preDeps, f)
+}
+
+func (ctx *TestContext) PostDepsMutators(f RegisterMutatorFunc) {
+ ctx.postDeps = append(ctx.postDeps, f)
+}
+
+func (ctx *TestContext) Register() {
+ registerMutators(ctx.Context, ctx.preArch, ctx.preDeps, ctx.postDeps)
+
+ ctx.RegisterSingletonType("env", EnvSingleton)
+}
+
+func (ctx *TestContext) ModuleForTests(name, variant string) TestingModule {
+ var module Module
+ ctx.VisitAllModules(func(m blueprint.Module) {
+ if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant {
+ module = m.(Module)
+ }
+ })
+
+ if module == nil {
+ panic(fmt.Errorf("failed to find module %q variant %q", name, variant))
+ }
+
+ return TestingModule{module}
+}
+
+type TestingModule struct {
+ module Module
+}
+
+func (m TestingModule) Module() Module {
+ return m.module
+}
+
+func (m TestingModule) Rule(rule string) ModuleBuildParams {
+ for _, p := range m.module.BuildParamsForTests() {
+ if strings.Contains(p.Rule.String(), rule) {
+ return p
+ }
+ }
+ panic(fmt.Errorf("couldn't find rule %q", rule))
+}
+
+func (m TestingModule) Output(file string) ModuleBuildParams {
+ for _, p := range m.module.BuildParamsForTests() {
+ outputs := append(WritablePaths(nil), p.Outputs...)
+ if p.Output != nil {
+ outputs = append(outputs, p.Output)
+ }
+ for _, f := range outputs {
+ if f.Base() == file {
+ return p
+ }
+ }
+ }
+ panic(fmt.Errorf("couldn't find output %q", file))
+}
diff --git a/android/util.go b/android/util.go
index 8cee256..80c7870 100644
--- a/android/util.go
+++ b/android/util.go
@@ -68,6 +68,15 @@
return indexList(s, list) != -1
}
+func prefixInList(s string, list []string) bool {
+ for _, prefix := range list {
+ if strings.HasPrefix(s, prefix) {
+ return true
+ }
+ }
+ return false
+}
+
// checkCalledFromInit panics if a Go package's init function is not on the
// call stack.
func checkCalledFromInit() {
diff --git a/android/variable.go b/android/variable.go
index 7ca7a55..8462d0d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -140,6 +140,8 @@
Treble *bool `json:",omitempty"`
Pdk *bool `json:",omitempty"`
+ IntegerOverflowExcludePaths *[]string `json:",omitempty"`
+
VendorPath *string `json:",omitempty"`
ClangTidy *bool `json:",omitempty"`
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 78395c3..194b2c9 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -102,11 +102,11 @@
"LOCAL_RENDERSCRIPT_INCLUDES": "renderscript.include_dirs",
"LOCAL_RENDERSCRIPT_FLAGS": "renderscript.flags",
- "LOCAL_JAVA_RESOURCE_DIRS": "java_resource_dirs",
+ "LOCAL_JAVA_RESOURCE_DIRS": "resource_dirs",
"LOCAL_JAVACFLAGS": "javacflags",
"LOCAL_DX_FLAGS": "dxflags",
- "LOCAL_JAVA_LIBRARIES": "java_libs",
- "LOCAL_STATIC_JAVA_LIBRARIES": "java_static_libs",
+ "LOCAL_JAVA_LIBRARIES": "libs",
+ "LOCAL_STATIC_JAVA_LIBRARIES": "static_libs",
"LOCAL_AIDL_INCLUDES": "aidl.include_dirs",
"LOCAL_AAPT_FLAGS": "aaptflags",
"LOCAL_PACKAGE_SPLITS": "package_splits",
diff --git a/bootstrap.bash b/bootstrap.bash
index e48f480..dbc6eb2 100755
--- a/bootstrap.bash
+++ b/bootstrap.bash
@@ -17,25 +17,21 @@
fi
export SRCDIR="."
export BOOTSTRAP="${SRCDIR}/bootstrap.bash"
+export BLUEPRINTDIR="${SRCDIR}/build/blueprint"
export TOPNAME="Android.bp"
-export BOOTSTRAP_MANIFEST="${SRCDIR}/build/soong/build.ninja.in"
export RUN_TESTS="-t"
case $(uname) in
Linux)
- export GOOS="linux"
export PREBUILTOS="linux-x86"
;;
Darwin)
- export GOOS="darwin"
export PREBUILTOS="darwin-x86"
;;
*) echo "unknown OS:" $(uname) && exit 1;;
esac
-export GOROOT="${SRCDIR}/prebuilts/go/$PREBUILTOS/"
-export GOARCH="amd64"
-export GOCHAR="6"
+export GOROOT="${SRCDIR}/prebuilts/go/$PREBUILTOS"
if [[ $# -eq 0 ]]; then
mkdir -p $BUILDDIR
diff --git a/build.ninja.in b/build.ninja.in
deleted file mode 100644
index 9449d73..0000000
--- a/build.ninja.in
+++ /dev/null
@@ -1,567 +0,0 @@
-# ******************************************************************************
-# *** 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.goTestMainCmd = ${g.bootstrap.buildDir}/.bootstrap/bin/gotestmain
-
-g.bootstrap.goTestRunnerCmd = ${g.bootstrap.buildDir}/.bootstrap/bin/gotestrunner
-
-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.gotestmain
- command = ${g.bootstrap.goTestMainCmd} -o ${out} -pkg ${pkg} ${in}
- description = gotestmain ${out}
-
-rule g.bootstrap.link
- command = GOROOT='${g.bootstrap.goRoot}' ${g.bootstrap.linkCmd} -o ${out} ${libDirFlags} ${in}
- description = link ${out}
-
-rule g.bootstrap.test
- command = ${g.bootstrap.goTestRunnerCmd} -p ${pkgSrcDir} -f ${out} -- ${in} -test.short
- description = test ${pkg}
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Module: blueprint
-# Variant:
-# Type: bootstrap_go_package
-# Factory: github.com/google/blueprint/bootstrap.newGoPackageModuleFactory.func1
-# Defined: build/blueprint/Blueprints:1:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/github.com/google/blueprint.a $
- : g.bootstrap.compile ${g.bootstrap.srcDir}/build/blueprint/context.go $
- ${g.bootstrap.srcDir}/build/blueprint/glob.go $
- ${g.bootstrap.srcDir}/build/blueprint/live_tracker.go $
- ${g.bootstrap.srcDir}/build/blueprint/mangle.go $
- ${g.bootstrap.srcDir}/build/blueprint/module_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_defs.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_strings.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_writer.go $
- ${g.bootstrap.srcDir}/build/blueprint/package_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/scope.go $
- ${g.bootstrap.srcDir}/build/blueprint/singleton_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/unpack.go $
- ${g.bootstrap.srcDir}/build/blueprint/context_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_strings_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_writer_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/splice_modules_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/unpack_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/visit_test.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
- pkgPath = github.com/google/blueprint
-default $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/github.com/google/blueprint.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.go: $
- g.bootstrap.gotestmain $
- ${g.bootstrap.srcDir}/build/blueprint/context_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_strings_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_writer_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/splice_modules_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/unpack_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/visit_test.go | $
- ${g.bootstrap.goTestMainCmd}
- pkg = github.com/google/blueprint
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.go
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.a: $
- g.bootstrap.compile $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/github.com/google/blueprint.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint/test
- pkgPath = main
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test: g.bootstrap.link $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.a | $
- ${g.bootstrap.linkCmd}
- libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint/test -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.passed: $
- g.bootstrap.test $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test | $
- ${g.bootstrap.goTestRunnerCmd} || $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.passed $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.passed
- pkg = github.com/google/blueprint
- pkgSrcDir = ${g.bootstrap.srcDir}/build/blueprint
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.passed
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
- : g.bootstrap.compile ${g.bootstrap.srcDir}/build/blueprint/context.go $
- ${g.bootstrap.srcDir}/build/blueprint/glob.go $
- ${g.bootstrap.srcDir}/build/blueprint/live_tracker.go $
- ${g.bootstrap.srcDir}/build/blueprint/mangle.go $
- ${g.bootstrap.srcDir}/build/blueprint/module_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_defs.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_strings.go $
- ${g.bootstrap.srcDir}/build/blueprint/ninja_writer.go $
- ${g.bootstrap.srcDir}/build/blueprint/package_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/scope.go $
- ${g.bootstrap.srcDir}/build/blueprint/singleton_ctx.go $
- ${g.bootstrap.srcDir}/build/blueprint/unpack.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-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: build/blueprint/Blueprints:89:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/bootstrap.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/cleanup.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/command.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/config.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/doc.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/glob.go $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/writedocs.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-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: build/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}/build/blueprint/bootstrap/bpdoc/bpdoc.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-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: build/blueprint/Blueprints:49:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:33:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/github.com/google/blueprint/parser.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/parser/ast.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/modify.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/parser.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/printer.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/sort.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/parser_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/printer_test.go | $
- ${g.bootstrap.compileCmd}
- pkgPath = github.com/google/blueprint/parser
-default $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/github.com/google/blueprint/parser.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.go: $
- g.bootstrap.gotestmain $
- ${g.bootstrap.srcDir}/build/blueprint/parser/parser_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/printer_test.go | $
- ${g.bootstrap.goTestMainCmd}
- pkg = github.com/google/blueprint/parser
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.go
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.a: $
- g.bootstrap.compile $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/github.com/google/blueprint/parser.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test
- pkgPath = main
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test: $
- g.bootstrap.link $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.a | $
- ${g.bootstrap.linkCmd}
- libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.passed: $
- g.bootstrap.test $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test | $
- ${g.bootstrap.goTestRunnerCmd}
- pkg = github.com/google/blueprint/parser
- pkgSrcDir = ${g.bootstrap.srcDir}/build/blueprint/parser
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.passed
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/parser/ast.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/modify.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/parser.go $
- ${g.bootstrap.srcDir}/build/blueprint/parser/printer.go $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:55:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/github.com/google/blueprint/pathtools.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/lists.go $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/fs.go $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob.go $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob_test.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/test/github.com/google/blueprint/pathtools.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.go: $
- g.bootstrap.gotestmain $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/glob_test.go | $
- ${g.bootstrap.goTestMainCmd}
- pkg = github.com/google/blueprint/pathtools
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.go
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.a: $
- g.bootstrap.compile $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/github.com/google/blueprint/pathtools.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test
- pkgPath = main
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test: $
- g.bootstrap.link $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.a | $
- ${g.bootstrap.linkCmd}
- libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed: $
- g.bootstrap.test $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test | $
- ${g.bootstrap.goTestRunnerCmd}
- pkg = github.com/google/blueprint/pathtools
- pkgSrcDir = ${g.bootstrap.srcDir}/build/blueprint/pathtools
-default $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/lists.go $
- ${g.bootstrap.srcDir}/build/blueprint/pathtools/fs.go $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:71:1
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/github.com/google/blueprint/proptools.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/clone.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/escape.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/extend.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/proptools.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/typeequal.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/clone_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/escape_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/extend_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/typeequal_test.go | $
- ${g.bootstrap.compileCmd}
- pkgPath = github.com/google/blueprint/proptools
-default $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/github.com/google/blueprint/proptools.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.go: $
- g.bootstrap.gotestmain $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/clone_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/escape_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/extend_test.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/typeequal_test.go | $
- ${g.bootstrap.goTestMainCmd}
- pkg = github.com/google/blueprint/proptools
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.go
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.a: $
- g.bootstrap.compile $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/github.com/google/blueprint/proptools.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test
- pkgPath = main
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test: $
- g.bootstrap.link $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.a | $
- ${g.bootstrap.linkCmd}
- libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test
-default ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test
-
-build ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.passed: $
- g.bootstrap.test $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test | $
- ${g.bootstrap.goTestRunnerCmd}
- pkg = github.com/google/blueprint/proptools
- pkgSrcDir = ${g.bootstrap.srcDir}/build/blueprint/proptools
-default $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.passed
-
-build $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
- : g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/clone.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/escape.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/extend.go $
- ${g.bootstrap.srcDir}/build/blueprint/proptools/proptools.go $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:130:1
-
-build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a: $
- g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/bpglob/bpglob.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a
- incFlags = -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -I ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg
- pkgPath = bpglob
-default ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a
-
-build ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out: g.bootstrap.link $
- ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/bpglob.a | $
- ${g.bootstrap.linkCmd}
- libDirFlags = -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg -L ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg
-default ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out
-
-build ${g.bootstrap.BinDir}/bpglob: g.bootstrap.cp $
- ${g.bootstrap.buildDir}/.bootstrap/bpglob/obj/a.out || $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed
-default ${g.bootstrap.BinDir}/bpglob
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# Module: gotestmain
-# Variant:
-# Type: bootstrap_core_go_binary
-# Factory: github.com/google/blueprint/bootstrap.newGoBinaryModuleFactory.func1
-# Defined: build/blueprint/Blueprints:148:1
-
-build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $
- g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:153:1
-
-build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $
- g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/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: build/blueprint/Blueprints:121:1
-
-build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $
- g.bootstrap.compile $
- ${g.bootstrap.srcDir}/build/blueprint/bootstrap/minibp/main.go | $
- ${g.bootstrap.compileCmd} $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-deptools/pkg/github.com/google/blueprint/deptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/pkg/github.com/google/blueprint.a $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-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 || $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-parser/test/test.passed $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-pathtools/test/test.passed $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/test/test.passed $
- ${g.bootstrap.buildDir}/.bootstrap/blueprint/test/test.passed
-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}/Android.bp | ${builder}
- builder = ${g.bootstrap.BinDir}/minibp
- extra = --build-primary -t
-default ${g.bootstrap.buildDir}/.bootstrap/build.ninja
-
-build ${g.bootstrap.buildDir}/.minibootstrap/build.ninja.in: $
- g.bootstrap.build.ninja ${g.bootstrap.srcDir}/Android.bp | ${builder}
- builder = ${g.bootstrap.BinDir}/minibp
- extra = -t
-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
-
diff --git a/build_test.bash b/build_test.bash
index ab841cb..065d7f6 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -28,7 +28,7 @@
export TRACE_BEGIN_SOONG=$(date +%s%N)
export TOP=$(cd $(dirname ${BASH_SOURCE[0]})/../..; PWD= /bin/pwd)
-source "${TOP}/build/soong/cmd/microfactory/microfactory.bash"
+source "${TOP}/build/soong/scripts/microfactory.bash"
case $(uname) in
Linux)
@@ -36,5 +36,5 @@
;;
esac
-build_go multiproduct_kati android/soong/cmd/multiproduct_kati
+soong_build_go multiproduct_kati android/soong/cmd/multiproduct_kati
exec "$(getoutdir)/multiproduct_kati" "$@"
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 2a3b344..940e7c7 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -23,6 +23,10 @@
"android/soong/android"
)
+var (
+ vendorSuffix = ".vendor"
+)
+
type AndroidMkContext interface {
Target() android.Target
subAndroidMk(*android.AndroidMkData, interface{})
@@ -81,13 +85,34 @@
}
c.subAndroidMk(&ret, c.installer)
- if c.vndk() {
- ret.SubName += ".vendor"
+ if c.vndk() && Bool(c.Properties.Vendor_available) {
+ // .vendor suffix is added only when we will have two variants: core and vendor.
+ // The suffix is not added for vendor-only module.
+ ret.SubName += vendorSuffix
}
return ret, nil
}
+func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, ret *android.AndroidMkData) {
+ var testFiles []string
+ for _, d := range data {
+ rel := d.Rel()
+ path := d.String()
+ if !strings.HasSuffix(path, rel) {
+ panic(fmt.Errorf("path %q does not end with %q", path, rel))
+ }
+ path = strings.TrimSuffix(path, rel)
+ testFiles = append(testFiles, path+":"+rel)
+ }
+ if len(testFiles) > 0 {
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
+ fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
+ return nil
+ })
+ }
+}
+
func (library *libraryDecorator) androidMkWriteExportedFlags(w io.Writer) {
exportedFlags := library.exportedFlags()
if len(exportedFlags) > 0 {
@@ -212,6 +237,8 @@
}
return nil
})
+
+ androidMkWriteTestData(benchmark.data, ctx, ret)
}
func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
@@ -229,22 +256,7 @@
return nil
})
- var testFiles []string
- for _, d := range test.data {
- rel := d.Rel()
- path := d.String()
- if !strings.HasSuffix(path, rel) {
- panic(fmt.Errorf("path %q does not end with %q", path, rel))
- }
- path = strings.TrimSuffix(path, rel)
- testFiles = append(testFiles, path+":"+rel)
- }
- if len(testFiles) > 0 {
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
- fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
- return nil
- })
- }
+ androidMkWriteTestData(test.data, ctx, ret)
}
func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
diff --git a/cc/cc.go b/cc/cc.go
index c17b95e..0f754a6 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -183,6 +183,8 @@
sdk() bool
sdkVersion() string
vndk() bool
+ isVndk() bool
+ isVndkSp() bool
createVndkSourceAbiDump() bool
selectedStl() string
baseModuleName() string
@@ -273,7 +275,7 @@
// to construct the output file. Behavior can be customized with a Customizer interface
type Module struct {
android.ModuleBase
- android.DefaultableModule
+ android.DefaultableModuleBase
Properties BaseProperties
unused UnusedProperties
@@ -291,6 +293,7 @@
sanitize *sanitize
coverage *coverage
sabi *sabi
+ vndkdep *vndkdep
androidMkSharedLibDeps []string
@@ -327,13 +330,16 @@
if c.sabi != nil {
c.AddProperties(c.sabi.props()...)
}
+ if c.vndkdep != nil {
+ c.AddProperties(c.vndkdep.props()...)
+ }
for _, feature := range c.features {
c.AddProperties(feature.props()...)
}
android.InitAndroidArchModule(c, c.hod, c.multilib)
- android.InitDefaultableModule(c, c)
+ android.InitDefaultableModule(c)
return c
}
@@ -353,6 +359,13 @@
return c.Properties.UseVndk
}
+func (c *Module) isVndk() bool {
+ if c.vndkdep != nil {
+ return c.vndkdep.isVndk()
+ }
+ return false
+}
+
type baseModuleContext struct {
android.BaseContext
moduleContextImpl
@@ -368,10 +381,10 @@
moduleContextImpl
}
-// Vendor returns true for vendor modules so that they get installed onto the
-// correct partition
+// Vendor returns true for vendor modules excluding VNDK libraries so that
+// they get installed onto the correct partition
func (ctx *moduleContext) Vendor() bool {
- return ctx.ModuleContext.Vendor() || ctx.moduleContextImpl.mod.Properties.UseVndk
+ return ctx.ModuleContext.Vendor() || (ctx.mod.vndk() && !ctx.mod.isVndk())
}
type moduleContextImpl struct {
@@ -431,9 +444,20 @@
return ctx.mod.vndk()
}
+func (ctx *moduleContextImpl) isVndk() bool {
+ return ctx.mod.isVndk()
+}
+
+func (ctx *moduleContextImpl) isVndkSp() bool {
+ if vndk := ctx.mod.vndkdep; vndk != nil {
+ return vndk.isVndkSp()
+ }
+ return false
+}
+
// Create source abi dumps if the module belongs to the list of VndkLibraries.
func (ctx *moduleContextImpl) createVndkSourceAbiDump() bool {
- return ctx.ctx.Device() && ((Bool(ctx.mod.Properties.Vendor_available)) || (inList(ctx.baseModuleName(), config.LLndkLibraries())))
+ return ctx.ctx.Device() && (ctx.mod.isVndk() || inList(ctx.baseModuleName(), config.LLndkLibraries()))
}
func (ctx *moduleContextImpl) selectedStl() string {
@@ -463,6 +487,7 @@
module.sanitize = &sanitize{}
module.coverage = &coverage{}
module.sabi = &sabi{}
+ module.vndkdep = &vndkdep{}
return module
}
@@ -591,6 +616,9 @@
if c.sabi != nil {
c.sabi.begin(ctx)
}
+ if c.vndkdep != nil {
+ c.vndkdep.begin(ctx)
+ }
for _, feature := range c.features {
feature.begin(ctx)
}
@@ -624,6 +652,9 @@
if c.sabi != nil {
deps = c.sabi.deps(ctx, deps)
}
+ if c.vndkdep != nil {
+ deps = c.vndkdep.deps(ctx, deps)
+ }
for _, feature := range c.features {
deps = feature.deps(ctx, deps)
}
@@ -689,9 +720,6 @@
deps := c.deps(ctx)
- c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.SharedLibs...)
- c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, deps.LateSharedLibs...)
-
variantNdkLibs := []string{}
variantLateNdkLibs := []string{}
if ctx.Os() == android.Android {
@@ -828,7 +856,12 @@
return
}
if from.Properties.UseVndk {
- // Vendor code is already limited by the vendor mutator
+ // Though vendor code is limited by the vendor mutator,
+ // each vendor-available module needs to check
+ // link-type for VNDK.
+ if from.vndkdep != nil {
+ from.vndkdep.vndkCheckLinkType(ctx, to)
+ }
return
}
if from.Properties.Sdk_version == "" {
@@ -1065,6 +1098,26 @@
}
*depPtr = append(*depPtr, dep.Path())
}
+
+ // Export the shared libs to the make world. In doing so, .vendor suffix
+ // is added if the lib has both core and vendor variants and this module
+ // is building against vndk. This is because the vendor variant will be
+ // have .vendor suffix in its name in the make world. However, if the
+ // lib is a vendor-only lib or this lib is not building against vndk,
+ // then the suffix is not added.
+ switch tag {
+ case sharedDepTag, sharedExportDepTag, lateSharedDepTag:
+ libName := strings.TrimSuffix(name, llndkLibrarySuffix)
+ libName = strings.TrimPrefix(libName, "prebuilt_")
+ isLLndk := inList(libName, config.LLndkLibraries())
+ if c.vndk() && (Bool(cc.Properties.Vendor_available) || isLLndk) {
+ libName += vendorSuffix
+ }
+ // Note: the order of libs in this list is not important because
+ // they merely serve as dependencies in the make world and do not
+ // affect this lib itself.
+ c.Properties.AndroidMkSharedLibs = append(c.Properties.AndroidMkSharedLibs, libName)
+ }
})
// Dedup exported flags from dependencies
@@ -1102,7 +1155,7 @@
//
type Defaults struct {
android.ModuleBase
- android.DefaultsModule
+ android.DefaultsModuleBase
}
func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1136,9 +1189,10 @@
&TidyProperties{},
&CoverageProperties{},
&SAbiProperties{},
+ &VndkProperties{},
)
- android.InitDefaultsModule(module, module)
+ android.InitDefaultsModule(module)
return module
}
@@ -1169,6 +1223,18 @@
"doesn't make sense at the same time as `vendor: true` or `proprietary: true`")
return
}
+ if vndk := m.vndkdep; vndk != nil {
+ if vndk.isVndk() && !Bool(m.Properties.Vendor_available) {
+ mctx.PropertyErrorf("vndk",
+ "has to define `vendor_available: true` to enable vndk")
+ return
+ }
+ if !vndk.isVndk() && vndk.isVndkSp() {
+ mctx.PropertyErrorf("vndk",
+ "must set `enabled: true` to set `support_system_process: true`")
+ return
+ }
+ }
if !mctx.DeviceConfig().CompileVndk() {
// If the device isn't compiling against the VNDK, we always
@@ -1180,6 +1246,7 @@
mctx.CreateVariations(vendorMode)
} else if Bool(m.Properties.Vendor_available) {
// This will be available in both /system and /vendor
+ // or a /system directory that is available to vendor.
mod := mctx.CreateVariations(coreMode, vendorMode)
mod[1].(*Module).Properties.UseVndk = true
} else if mctx.Vendor() && m.Properties.Sdk_version == "" {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index a371cf6..139c901 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -81,6 +81,9 @@
// don't support a Kryo specific target yet.
"-mcpu=cortex-a57",
},
+ "exynos-m2": []string{
+ "-mcpu=exynos-m2",
+ },
}
arm64ClangCpuVariantCflags = copyVariantFlags(arm64CpuVariantCflags)
@@ -96,6 +99,7 @@
"cortex-a53",
"cortex-a73",
"kryo",
+ "exynos-m2",
"denver64")
// Clang supports specific Kryo targeting
@@ -124,6 +128,11 @@
strings.Join(arm64CpuVariantCflags["kryo"], " "))
pctx.StaticVariable("Arm64ClangKryoCflags",
strings.Join(arm64ClangCpuVariantCflags["kryo"], " "))
+
+ pctx.StaticVariable("Arm64ExynosM2Cflags",
+ strings.Join(arm64CpuVariantCflags["cortex-a53"], " "))
+ pctx.StaticVariable("Arm64ClangExynosM2Cflags",
+ strings.Join(arm64ClangCpuVariantCflags["exynos-m2"], " "))
}
var (
@@ -132,6 +141,7 @@
"cortex-a53": "${config.Arm64CortexA53Cflags}",
"cortex-a73": "${config.Arm64CortexA53Cflags}",
"kryo": "${config.Arm64KryoCflags}",
+ "exynos-m2": "${config.Arm64ExynosM2Cflags}",
}
arm64ClangCpuVariantCflagsVar = map[string]string{
@@ -139,6 +149,7 @@
"cortex-a53": "${config.Arm64ClangCortexA53Cflags}",
"cortex-a73": "${config.Arm64ClangCortexA53Cflags}",
"kryo": "${config.Arm64ClangKryoCflags}",
+ "exynos-m2": "${config.Arm64ClangExynosM2Cflags}",
}
)
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 6606100..e97e723 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -182,6 +182,7 @@
"cortex-a73",
"krait",
"kryo",
+ "exynos-m2",
"denver")
android.RegisterArchVariantFeatures(android.Arm, "armv7-a-neon", "neon")
@@ -274,6 +275,7 @@
"cortex-a73": "${config.ArmCortexA53Cflags}",
"krait": "${config.ArmKraitCflags}",
"kryo": "${config.ArmKryoCflags}",
+ "exynos-m2": "${config.ArmCortexA53Cflags}",
"denver": "${config.ArmCortexA15Cflags}",
}
@@ -293,6 +295,7 @@
"cortex-a73": "${config.ArmClangCortexA53Cflags}",
"krait": "${config.ArmClangKraitCflags}",
"kryo": "${config.ArmClangKryoCflags}",
+ "exynos-m2": "${config.ArmClangCortexA53Cflags}",
"denver": "${config.ArmClangCortexA15Cflags}",
}
)
diff --git a/cc/config/global.go b/cc/config/global.go
index 4ae22c9..f4a1230 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -124,7 +124,7 @@
// This is used by non-NDK modules to get jni.h. export_include_dirs doesn't help
// with this, since there is no associated library.
pctx.PrefixedExistentPathsForSourcesVariable("CommonNativehelperInclude", "-I",
- []string{"libnativehelper/include/nativehelper"})
+ []string{"libnativehelper/include_deprecated"})
pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
pctx.VariableFunc("ClangBase", func(config interface{}) (string, error) {
diff --git a/cc/installer.go b/cc/installer.go
index 112a7ea..7bedc56 100644
--- a/cc/installer.go
+++ b/cc/installer.go
@@ -48,6 +48,7 @@
dir string
dir64 string
+ subDir string
relative string
location installLocation
@@ -61,17 +62,17 @@
}
func (installer *baseInstaller) installDir(ctx ModuleContext) android.OutputPath {
- subDir := installer.dir
+ dir := installer.dir
if ctx.toolchain().Is64Bit() && installer.dir64 != "" {
- subDir = installer.dir64
+ dir = installer.dir64
}
if !ctx.Host() && !ctx.Arch().Native {
- subDir = filepath.Join(subDir, ctx.Arch().ArchType.String())
+ dir = filepath.Join(dir, ctx.Arch().ArchType.String())
}
if installer.location == InstallInData && ctx.vndk() {
- subDir = filepath.Join(subDir, "vendor")
+ dir = filepath.Join(dir, "vendor")
}
- return android.PathForModuleInstall(ctx, subDir, installer.Properties.Relative_install_path, installer.relative)
+ return android.PathForModuleInstall(ctx, dir, installer.subDir, installer.Properties.Relative_install_path, installer.relative)
}
func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) {
diff --git a/cc/kernel_headers.go b/cc/kernel_headers.go
index c66fca6..42dc770 100644
--- a/cc/kernel_headers.go
+++ b/cc/kernel_headers.go
@@ -40,12 +40,9 @@
libraryDecorator: library,
}
- module.compiler = nil
module.linker = stub
- module.installer = nil
- android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
- return module
+ return module.Init()
}
func init() {
diff --git a/cc/library.go b/cc/library.go
index c7c1142..3d463bd 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -156,7 +156,7 @@
}
func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
- if ctx.Vendor() && f.Properties.Target.Vendor.Export_include_dirs != nil {
+ if ctx.vndk() && f.Properties.Target.Vendor.Export_include_dirs != nil {
return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Export_include_dirs)
} else {
return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
@@ -351,7 +351,7 @@
}
return Objects{}
}
- if (ctx.createVndkSourceAbiDump() || (library.sabi.Properties.CreateSAbiDumps && ctx.Device())) && !ctx.Vendor() {
+ if ctx.createVndkSourceAbiDump() {
exportIncludeDirs := android.PathsForModuleSrc(ctx, library.flagExporter.Properties.Export_include_dirs)
var SourceAbiFlags []string
for _, dir := range exportIncludeDirs.Strings() {
@@ -596,7 +596,7 @@
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
//Also take into account object re-use.
- if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() && !ctx.Vendor() {
+ if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() {
refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, "current", fileName, vndkVsNdk(ctx), true)
versionScript := android.OptionalPathForModuleSrc(ctx, library.Properties.Version_script)
var symbolFile android.OptionalPath
@@ -699,6 +699,15 @@
func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
if library.shared() {
+ if ctx.Device() {
+ if ctx.vndk() {
+ if ctx.isVndkSp() {
+ library.baseInstaller.subDir = "vndk-sp"
+ } else if ctx.isVndk() {
+ library.baseInstaller.subDir = "vndk"
+ }
+ }
+ }
library.baseInstaller.install(ctx, file)
}
}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 66ffc9f..c3d3462 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -61,6 +61,11 @@
versionScriptPath android.ModuleGenPath
}
+func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags = stub.baseCompiler.compilerFlags(ctx, flags)
+ return addStubLibraryCompilerFlags(flags)
+}
+
func (stub *llndkStubDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
objs, versionScript := compileStubLibrary(ctx, flags, stub.Properties.Symbol_file, "current", "--vndk")
stub.versionScriptPath = versionScript
diff --git a/cc/makevars.go b/cc/makevars.go
index 11c3162..294f3e6 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -82,6 +82,16 @@
ctx.Strict("RS_GLOBAL_INCLUDES", "${config.RsGlobalIncludes}")
+ nativeHelperIncludeFlags, err := ctx.Eval("${config.CommonNativehelperInclude}")
+ if err != nil {
+ panic(err)
+ }
+ nativeHelperIncludes, nativeHelperSystemIncludes := splitSystemIncludes(ctx, nativeHelperIncludeFlags)
+ if len(nativeHelperSystemIncludes) > 0 {
+ panic("native helper may not have any system includes")
+ }
+ ctx.Strict("JNI_H_INCLUDE", strings.Join(nativeHelperIncludes, " "))
+
includeFlags, err := ctx.Eval("${config.CommonGlobalIncludes}")
if err != nil {
panic(err)
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 5765aa9..dbfc5be 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -242,6 +242,25 @@
ndkMigratedLibs = append(ndkMigratedLibs, name)
}
+func addStubLibraryCompilerFlags(flags Flags) Flags {
+ flags.CFlags = append(flags.CFlags,
+ // We're knowingly doing some otherwise unsightly things with builtin
+ // functions here. We're just generating stub libraries, so ignore it.
+ "-Wno-incompatible-library-redeclaration",
+ "-Wno-builtin-requires-header",
+ "-Wno-invalid-noreturn",
+ // These libraries aren't actually used. Don't worry about unwinding
+ // (avoids the need to link an unwinder into a fake library).
+ "-fno-unwind-tables",
+ )
+ return flags
+}
+
+func (stub *stubDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags = stub.baseCompiler.compilerFlags(ctx, flags)
+ return addStubLibraryCompilerFlags(flags)
+}
+
func compileStubLibrary(ctx ModuleContext, flags Flags, symbolFile, apiLevel, vndk string) (Objects, android.ModuleGenPath) {
arch := ctx.Arch().ArchType.String()
@@ -263,18 +282,6 @@
},
})
- flags.CFlags = append(flags.CFlags,
- // We're knowingly doing some otherwise unsightly things with builtin
- // functions here. We're just generating stub libraries, so ignore it.
- "-Wno-incompatible-library-redeclaration",
- "-Wno-builtin-requires-header",
- "-Wno-invalid-noreturn",
-
- // These libraries aren't actually used. Don't worry about unwinding
- // (avoids the need to link an unwinder into a fake library).
- "-fno-unwind-tables",
- )
-
subdir := ""
srcs := []android.Path{stubSrcPath}
return compileObjs(ctx, flagsToBuilderFlags(flags), subdir, srcs, nil), versionScriptPath
diff --git a/cc/sabi.go b/cc/sabi.go
index 9aff738..1a5361d 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -67,12 +67,19 @@
// Assuming that the cflags which clang LibTooling tools cannot
// understand have not been converted to ninja variables yet.
flags.ToolingCFlags = filterOutWithPrefix(flags.CFlags, config.ClangLibToolingUnknownCflags)
+
+ // RSClang does not support recent mcpu option likes exynos-m2.
+ // So we need overriding mcpu option when we want to use it.
+ if ctx.Arch().CpuVariant == "exynos-m2" {
+ flags.ToolingCFlags = append(flags.ToolingCFlags, "-mcpu=cortex-a53")
+ }
+
return flags
}
func sabiDepsMutator(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok &&
- (Bool(c.Properties.Vendor_available) || (inList(c.Name(), config.LLndkLibraries())) ||
+ (c.isVndk() || inList(c.Name(), config.LLndkLibraries()) ||
(c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
mctx.VisitDirectDeps(func(m blueprint.Module) {
tag := mctx.OtherModuleDependencyTag(m)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 49bd0f3..1fcb32c 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -116,7 +116,8 @@
type sanitize struct {
Properties SanitizeProperties
- runtimeLibrary string
+ runtimeLibrary string
+ androidMkRuntimeLibrary string
}
func (sanitize *sanitize) props() []interface{} {
@@ -188,7 +189,9 @@
}
if found, globalSanitizers = removeFromList("integer_overflow", globalSanitizers); found && s.Integer_overflow == nil {
- s.Integer_overflow = boolPtr(true)
+ if !ctx.AConfig().IntegerOverflowDisabledForPath(ctx.ModuleDir()) {
+ s.Integer_overflow = boolPtr(true)
+ }
}
if len(globalSanitizers) > 0 {
@@ -283,9 +286,6 @@
if Bool(sanitize.Properties.Sanitize.All_undefined) {
sanitizers = append(sanitizers, "undefined")
- if ctx.Device() {
- ctx.ModuleErrorf("ubsan is not yet supported on the device")
- }
} else {
if Bool(sanitize.Properties.Sanitize.Undefined) {
sanitizers = append(sanitizers,
@@ -420,12 +420,18 @@
runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain())
}
- // ASan runtime library must be the first in the link order.
if runtimeLibrary != "" {
+ // ASan runtime library must be the first in the link order.
flags.libFlags = append([]string{
"${config.ClangAsanLibDir}/" + runtimeLibrary + ctx.toolchain().ShlibSuffix(),
}, flags.libFlags...)
sanitize.runtimeLibrary = runtimeLibrary
+
+ // When linking against VNDK, use the vendor variant of the runtime lib
+ sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary
+ if ctx.vndk() {
+ sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary + vendorSuffix
+ }
}
blacklist := android.OptionalPathForModuleSrc(ctx, sanitize.Properties.Sanitize.Blacklist)
@@ -439,8 +445,8 @@
func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) error {
- if sanitize.runtimeLibrary != "" {
- fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.runtimeLibrary)
+ if sanitize.androidMkRuntimeLibrary != "" {
+ fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.androidMkRuntimeLibrary)
}
return nil
diff --git a/cc/stl.go b/cc/stl.go
index 9e67145..65d7e40 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -23,7 +23,7 @@
// select the STL library to use. Possible values are "libc++", "libc++_static",
// "stlport", "stlport_static", "ndk", "libstdc++", or "none". Leave blank to select the
// default
- Stl *string
+ Stl *string `android:"arch_variant"`
SelectedStl string `blueprint:"mutated"`
}
diff --git a/cc/test.go b/cc/test.go
index ea05ba5..a52e94a 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -298,6 +298,10 @@
}
type BenchmarkProperties struct {
+ // list of files or filegroup modules that provide data that should be installed alongside
+ // the test
+ Data []string
+
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string
@@ -306,6 +310,7 @@
type benchmarkDecorator struct {
*binaryDecorator
Properties BenchmarkProperties
+ data android.Paths
}
func (benchmark *benchmarkDecorator) linkerInit(ctx BaseModuleContext) {
@@ -324,12 +329,14 @@
}
func (benchmark *benchmarkDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
+ android.ExtractSourcesDeps(ctx, benchmark.Properties.Data)
deps = benchmark.binaryDecorator.linkerDeps(ctx, deps)
deps.StaticLibs = append(deps.StaticLibs, "libgoogle-benchmark")
return deps
}
func (benchmark *benchmarkDecorator) install(ctx ModuleContext, file android.Path) {
+ benchmark.data = ctx.ExpandSources(benchmark.Properties.Data, nil)
benchmark.binaryDecorator.baseInstaller.dir = filepath.Join("nativetest", ctx.ModuleName())
benchmark.binaryDecorator.baseInstaller.dir64 = filepath.Join("nativetest64", ctx.ModuleName())
benchmark.binaryDecorator.baseInstaller.install(ctx, file)
diff --git a/cc/test_data_test.go b/cc/test_data_test.go
index a798919..962bde5 100644
--- a/cc/test_data_test.go
+++ b/cc/test_data_test.go
@@ -23,8 +23,6 @@
"android/soong/android"
"android/soong/genrule"
-
- "github.com/google/blueprint"
)
type dataFile struct {
@@ -123,8 +121,7 @@
for _, test := range testDataTests {
t.Run(test.name, func(t *testing.T) {
- ctx := blueprint.NewContext()
- android.RegisterTestMutators(ctx)
+ ctx := android.NewTestContext()
ctx.MockFileSystem(map[string][]byte{
"Blueprints": []byte(`subdirs = ["dir"]`),
"dir/Blueprints": []byte(test.modules),
@@ -135,18 +132,16 @@
android.ModuleFactoryAdaptor(genrule.FileGroupFactory))
ctx.RegisterModuleType("test",
android.ModuleFactoryAdaptor(newTest))
+ ctx.Register()
_, errs := ctx.ParseBlueprintsFiles("Blueprints")
fail(t, errs)
_, errs = ctx.PrepareBuildActions(config)
fail(t, errs)
- foo := findModule(ctx, "foo")
- if foo == nil {
- t.Fatalf("failed to find module foo")
- }
+ foo := ctx.ModuleForTests("foo", "")
- got := foo.(*testDataTest).data
+ got := foo.Module().(*testDataTest).data
if len(got) != len(test.data) {
t.Errorf("expected %d data files, got %d",
len(test.data), len(got))
@@ -192,16 +187,6 @@
test.data = ctx.ExpandSources(test.Properties.Data, nil)
}
-func findModule(ctx *blueprint.Context, name string) blueprint.Module {
- var ret blueprint.Module
- ctx.VisitAllModules(func(m blueprint.Module) {
- if ctx.ModuleName(m) == name {
- ret = m
- }
- })
- return ret
-}
-
func fail(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
diff --git a/cc/vndk.go b/cc/vndk.go
new file mode 100644
index 0000000..fd1bdcb
--- /dev/null
+++ b/cc/vndk.go
@@ -0,0 +1,98 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+ "android/soong/android"
+)
+
+type VndkProperties struct {
+ Vndk struct {
+ // declared as a VNDK or VNDK-SP module. The vendor variant
+ // will be installed in /system instead of /vendor partition.
+ //
+ // `vendor_available: true` must set to together for VNDK
+ // modules.
+ Enabled *bool
+
+ // declared as a VNDK-SP module, which is a subset of VNDK.
+ //
+ // `vndk: { enabled: true }` must set together.
+ //
+ // All these modules are allowed to link to VNDK-SP or LL-NDK
+ // modules only. Other dependency will cause link-type errors.
+ //
+ // If `support_system_process` is not set or set to false,
+ // the module is VNDK-core and can link to other VNDK-core,
+ // VNDK-SP or LL-NDK modules only.
+ Support_system_process *bool
+ }
+}
+
+type vndkdep struct {
+ Properties VndkProperties
+}
+
+func (vndk *vndkdep) props() []interface{} {
+ return []interface{}{&vndk.Properties}
+}
+
+func (vndk *vndkdep) begin(ctx BaseModuleContext) {}
+
+func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps {
+ return deps
+}
+
+func (vndk *vndkdep) isVndk() bool {
+ return Bool(vndk.Properties.Vndk.Enabled)
+}
+
+func (vndk *vndkdep) isVndkSp() bool {
+ return Bool(vndk.Properties.Vndk.Support_system_process)
+}
+
+func (vndk *vndkdep) typeName() string {
+ if !vndk.isVndk() {
+ return "native:vendor"
+ }
+ if !vndk.isVndkSp() {
+ return "native:vendor:vndk"
+ }
+ return "native:vendor:vndksp"
+}
+
+func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module) {
+ if to.linker == nil {
+ return
+ }
+ if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
+ // Check only shared libraries.
+ // Other (static and LL-NDK) libraries are allowed to link.
+ return
+ }
+ if !to.Properties.UseVndk {
+ ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library",
+ vndk.typeName(), to.Name())
+ return
+ }
+ if to.vndkdep == nil {
+ return
+ }
+ if (vndk.isVndk() && !to.vndkdep.isVndk()) || (vndk.isVndkSp() && !to.vndkdep.isVndkSp()) {
+ ctx.ModuleErrorf("(%s) should not link to %q(%s)",
+ vndk.typeName(), to.Name(), to.vndkdep.typeName())
+ return
+ }
+}
diff --git a/cmd/microfactory/Android.bp b/cmd/microfactory/Android.bp
deleted file mode 100644
index a457f43..0000000
--- a/cmd/microfactory/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-blueprint_go_binary {
- name: "microfactory",
- srcs: [
- "microfactory.go",
- ],
- testSrcs: [
- "microfactory_test.go",
- ],
-}
diff --git a/cmd/microfactory/microfactory.bash b/cmd/microfactory/microfactory.bash
deleted file mode 100644
index 7489fe3..0000000
--- a/cmd/microfactory/microfactory.bash
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2017 Google Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set of utility functions to build and run go code with microfactory
-#
-# Inputs:
-# ${TOP}: The top of the android source tree
-# ${OUT_DIR}: The output directory location (defaults to ${TOP}/out)
-# ${OUT_DIR_COMMON_BASE}: Change the default out directory to
-# ${OUT_DIR_COMMON_BASE}/$(basename ${TOP})
-
-# Ensure GOROOT is set to the in-tree version.
-case $(uname) in
- Linux)
- export GOROOT="${TOP}/prebuilts/go/linux-x86/"
- ;;
- Darwin)
- export GOROOT="${TOP}/prebuilts/go/darwin-x86/"
- ;;
- *) echo "unknown OS:" $(uname) >&2 && exit 1;;
-esac
-
-# Find the output directory
-function getoutdir
-{
- local out_dir="${OUT_DIR-}"
- if [ -z "${out_dir}" ]; then
- if [ "${OUT_DIR_COMMON_BASE-}" ]; then
- out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${TOP})"
- else
- out_dir="${TOP}/out"
- fi
- fi
- echo "${out_dir}"
-}
-
-# Bootstrap microfactory from source if necessary and use it to build the
-# requested binary.
-#
-# Arguments:
-# $1: name of the requested binary
-# $2: package name
-function build_go
-{
- # Increment when microfactory changes enough that it cannot rebuild itself.
- # For example, if we use a new command line argument that doesn't work on older versions.
- local mf_version=2
-
- local mf_src="${TOP}/build/soong/cmd/microfactory"
-
- local out_dir=$(getoutdir)
- local mf_bin="${out_dir}/microfactory_$(uname)"
- local mf_version_file="${out_dir}/.microfactory_$(uname)_version"
- local built_bin="${out_dir}/$1"
- local from_src=1
-
- if [ -f "${mf_bin}" ] && [ -f "${mf_version_file}" ]; then
- if [ "${mf_version}" -eq "$(cat "${mf_version_file}")" ]; then
- from_src=0
- fi
- fi
-
- local mf_cmd
- if [ $from_src -eq 1 ]; then
- mf_cmd="${GOROOT}/bin/go run ${mf_src}/microfactory.go"
- else
- mf_cmd="${mf_bin}"
- fi
-
- ${mf_cmd} -s "${mf_src}" -b "${mf_bin}" \
- -pkg-path "android/soong=${TOP}/build/soong" -trimpath "${TOP}/build/soong" \
- -o "${built_bin}" $2
-
- if [ $from_src -eq 1 ]; then
- echo "${mf_version}" >"${mf_version_file}"
- fi
-}
diff --git a/cmd/microfactory/microfactory.go b/cmd/microfactory/microfactory.go
deleted file mode 100644
index 6c062e2..0000000
--- a/cmd/microfactory/microfactory.go
+++ /dev/null
@@ -1,572 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Microfactory is a tool to incrementally compile a go program. It's similar
-// to `go install`, but doesn't require a GOPATH. A package->path mapping can
-// be specified as command line options:
-//
-// -pkg-path android/soong=build/soong
-// -pkg-path github.com/google/blueprint=build/blueprint
-//
-// The paths can be relative to the current working directory, or an absolute
-// path. Both packages and paths are compared with full directory names, so the
-// android/soong-test package wouldn't be mapped in the above case.
-//
-// Microfactory will ignore *_test.go files, and limits *_darwin.go and
-// *_linux.go files to MacOS and Linux respectively. It does not support build
-// tags or any other suffixes.
-//
-// Builds are incremental by package. All input files are hashed, and if the
-// hash of an input or dependency changes, the package is rebuilt.
-//
-// It also exposes the -trimpath option from go's compiler so that embedded
-// path names (such as in log.Llongfile) are relative paths instead of absolute
-// paths.
-//
-// If you don't have a previously built version of Microfactory, when used with
-// -s <microfactory_src_dir> -b <microfactory_bin_file>, Microfactory can
-// rebuild itself as necessary. Combined with a shell script like soong_ui.bash
-// that uses `go run` to run Microfactory for the first time, go programs can be
-// quickly bootstrapped entirely from source (and a standard go distribution).
-package main
-
-import (
- "bytes"
- "crypto/sha1"
- "flag"
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
- "io"
- "io/ioutil"
- "os"
- "os/exec"
- "path/filepath"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "syscall"
-)
-
-var (
- race = false
- verbose = false
-
- goToolDir = filepath.Join(runtime.GOROOT(), "pkg", "tool", runtime.GOOS+"_"+runtime.GOARCH)
- goVersion = findGoVersion()
-)
-
-func findGoVersion() string {
- if version, err := ioutil.ReadFile(filepath.Join(runtime.GOROOT(), "VERSION")); err == nil {
- return string(version)
- }
-
- cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), "version")
- if version, err := cmd.Output(); err == nil {
- return string(version)
- } else {
- panic(fmt.Sprintf("Unable to discover go version: %v", err))
- }
-}
-
-type GoPackage struct {
- Name string
-
- // Inputs
- directDeps []*GoPackage // specified directly by the module
- allDeps []*GoPackage // direct dependencies and transitive dependencies
- files []string
-
- // Outputs
- pkgDir string
- output string
- hashResult []byte
-
- // Status
- mutex sync.Mutex
- compiled bool
- failed error
- rebuilt bool
-}
-
-// LinkedHashMap<string, GoPackage>
-type linkedDepSet struct {
- packageSet map[string](*GoPackage)
- packageList []*GoPackage
-}
-
-func newDepSet() *linkedDepSet {
- return &linkedDepSet{packageSet: make(map[string]*GoPackage)}
-}
-func (s *linkedDepSet) tryGetByName(name string) (*GoPackage, bool) {
- pkg, contained := s.packageSet[name]
- return pkg, contained
-}
-func (s *linkedDepSet) getByName(name string) *GoPackage {
- pkg, _ := s.tryGetByName(name)
- return pkg
-}
-func (s *linkedDepSet) add(name string, goPackage *GoPackage) {
- s.packageSet[name] = goPackage
- s.packageList = append(s.packageList, goPackage)
-}
-func (s *linkedDepSet) ignore(name string) {
- s.packageSet[name] = nil
-}
-
-// FindDeps searches all applicable go files in `path`, parses all of them
-// for import dependencies that exist in pkgMap, then recursively does the
-// same for all of those dependencies.
-func (p *GoPackage) FindDeps(path string, pkgMap *pkgPathMapping) error {
- depSet := newDepSet()
- err := p.findDeps(path, pkgMap, depSet)
- if err != nil {
- return err
- }
- p.allDeps = depSet.packageList
- return nil
-}
-
-// findDeps is the recursive version of FindDeps. allPackages is the map of
-// all locally defined packages so that the same dependency of two different
-// packages is only resolved once.
-func (p *GoPackage) findDeps(path string, pkgMap *pkgPathMapping, allPackages *linkedDepSet) error {
- // If this ever becomes too slow, we can look at reading the files once instead of twice
- // But that just complicates things today, and we're already really fast.
- foundPkgs, err := parser.ParseDir(token.NewFileSet(), path, func(fi os.FileInfo) bool {
- name := fi.Name()
- if fi.IsDir() || strings.HasSuffix(name, "_test.go") || name[0] == '.' || name[0] == '_' {
- return false
- }
- if runtime.GOOS != "darwin" && strings.HasSuffix(name, "_darwin.go") {
- return false
- }
- if runtime.GOOS != "linux" && strings.HasSuffix(name, "_linux.go") {
- return false
- }
- return true
- }, parser.ImportsOnly)
- if err != nil {
- return fmt.Errorf("Error parsing directory %q: %v", path, err)
- }
-
- var foundPkg *ast.Package
- // foundPkgs is a map[string]*ast.Package, but we only want one package
- if len(foundPkgs) != 1 {
- return fmt.Errorf("Expected one package in %q, got %d", path, len(foundPkgs))
- }
- // Extract the first (and only) entry from the map.
- for _, pkg := range foundPkgs {
- foundPkg = pkg
- }
-
- var deps []string
- localDeps := make(map[string]bool)
-
- for filename, astFile := range foundPkg.Files {
- p.files = append(p.files, filename)
-
- for _, importSpec := range astFile.Imports {
- name, err := strconv.Unquote(importSpec.Path.Value)
- if err != nil {
- return fmt.Errorf("%s: invalid quoted string: <%s> %v", filename, importSpec.Path.Value, err)
- }
-
- if pkg, ok := allPackages.tryGetByName(name); ok {
- if pkg != nil {
- if _, ok := localDeps[name]; !ok {
- deps = append(deps, name)
- localDeps[name] = true
- }
- }
- continue
- }
-
- var pkgPath string
- if path, ok, err := pkgMap.Path(name); err != nil {
- return err
- } else if !ok {
- // Probably in the stdlib, but if not, then the compiler will fail with a reasonable error message
- // Mark it as such so that we don't try to decode its path again.
- allPackages.ignore(name)
- continue
- } else {
- pkgPath = path
- }
-
- pkg := &GoPackage{
- Name: name,
- }
- deps = append(deps, name)
- allPackages.add(name, pkg)
- localDeps[name] = true
-
- if err := pkg.findDeps(pkgPath, pkgMap, allPackages); err != nil {
- return err
- }
- }
- }
-
- sort.Strings(p.files)
-
- if verbose {
- fmt.Fprintf(os.Stderr, "Package %q depends on %v\n", p.Name, deps)
- }
-
- for _, dep := range deps {
- p.directDeps = append(p.directDeps, allPackages.getByName(dep))
- }
-
- return nil
-}
-
-func (p *GoPackage) Compile(outDir, trimPath string) error {
- p.mutex.Lock()
- defer p.mutex.Unlock()
- if p.compiled {
- return p.failed
- }
- p.compiled = true
-
- // Build all dependencies in parallel, then fail if any of them failed.
- var wg sync.WaitGroup
- for _, dep := range p.directDeps {
- wg.Add(1)
- go func(dep *GoPackage) {
- defer wg.Done()
- dep.Compile(outDir, trimPath)
- }(dep)
- }
- wg.Wait()
- for _, dep := range p.directDeps {
- if dep.failed != nil {
- p.failed = dep.failed
- return p.failed
- }
- }
-
- p.pkgDir = filepath.Join(outDir, p.Name)
- p.output = filepath.Join(p.pkgDir, p.Name) + ".a"
- shaFile := p.output + ".hash"
-
- hash := sha1.New()
- fmt.Fprintln(hash, runtime.GOOS, runtime.GOARCH, goVersion)
-
- cmd := exec.Command(filepath.Join(goToolDir, "compile"),
- "-o", p.output,
- "-p", p.Name,
- "-complete", "-pack", "-nolocalimports")
- if race {
- cmd.Args = append(cmd.Args, "-race")
- fmt.Fprintln(hash, "-race")
- }
- if trimPath != "" {
- cmd.Args = append(cmd.Args, "-trimpath", trimPath)
- fmt.Fprintln(hash, trimPath)
- }
- for _, dep := range p.directDeps {
- cmd.Args = append(cmd.Args, "-I", dep.pkgDir)
- hash.Write(dep.hashResult)
- }
- for _, filename := range p.files {
- cmd.Args = append(cmd.Args, filename)
- fmt.Fprintln(hash, filename)
-
- // Hash the contents of the input files
- f, err := os.Open(filename)
- if err != nil {
- f.Close()
- err = fmt.Errorf("%s: %v", filename, err)
- p.failed = err
- return err
- }
- _, err = io.Copy(hash, f)
- if err != nil {
- f.Close()
- err = fmt.Errorf("%s: %v", filename, err)
- p.failed = err
- return err
- }
- f.Close()
- }
- p.hashResult = hash.Sum(nil)
-
- var rebuild bool
- if _, err := os.Stat(p.output); err != nil {
- rebuild = true
- }
- if !rebuild {
- if oldSha, err := ioutil.ReadFile(shaFile); err == nil {
- rebuild = !bytes.Equal(oldSha, p.hashResult)
- } else {
- rebuild = true
- }
- }
-
- if !rebuild {
- return nil
- }
-
- err := os.RemoveAll(p.pkgDir)
- if err != nil {
- err = fmt.Errorf("%s: %v", p.Name, err)
- p.failed = err
- return err
- }
-
- err = os.MkdirAll(filepath.Dir(p.output), 0777)
- if err != nil {
- err = fmt.Errorf("%s: %v", p.Name, err)
- p.failed = err
- return err
- }
-
- cmd.Stdin = nil
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if verbose {
- fmt.Fprintln(os.Stderr, cmd.Args)
- }
- err = cmd.Run()
- if err != nil {
- err = fmt.Errorf("%s: %v", p.Name, err)
- p.failed = err
- return err
- }
-
- err = ioutil.WriteFile(shaFile, p.hashResult, 0666)
- if err != nil {
- err = fmt.Errorf("%s: %v", p.Name, err)
- p.failed = err
- return err
- }
-
- p.rebuilt = true
-
- return nil
-}
-
-func (p *GoPackage) Link(out string) error {
- if p.Name != "main" {
- return fmt.Errorf("Can only link main package")
- }
-
- shaFile := filepath.Join(filepath.Dir(out), "."+filepath.Base(out)+"_hash")
-
- if !p.rebuilt {
- if _, err := os.Stat(out); err != nil {
- p.rebuilt = true
- } else if oldSha, err := ioutil.ReadFile(shaFile); err != nil {
- p.rebuilt = true
- } else {
- p.rebuilt = !bytes.Equal(oldSha, p.hashResult)
- }
- }
- if !p.rebuilt {
- return nil
- }
-
- err := os.Remove(shaFile)
- if err != nil && !os.IsNotExist(err) {
- return err
- }
- err = os.Remove(out)
- if err != nil && !os.IsNotExist(err) {
- return err
- }
-
- cmd := exec.Command(filepath.Join(goToolDir, "link"), "-o", out)
- if race {
- cmd.Args = append(cmd.Args, "-race")
- }
- for _, dep := range p.allDeps {
- cmd.Args = append(cmd.Args, "-L", dep.pkgDir)
- }
- cmd.Args = append(cmd.Args, p.output)
- cmd.Stdin = nil
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if verbose {
- fmt.Fprintln(os.Stderr, cmd.Args)
- }
- err = cmd.Run()
- if err != nil {
- return fmt.Errorf("command %s failed with error %v", cmd.Args, err)
- }
-
- return ioutil.WriteFile(shaFile, p.hashResult, 0666)
-}
-
-// rebuildMicrofactory checks to see if microfactory itself needs to be rebuilt,
-// and if does, it will launch a new copy instead of returning.
-func rebuildMicrofactory(mybin, mysrc string, pkgMap *pkgPathMapping) {
- intermediates := filepath.Join(filepath.Dir(mybin), "."+filepath.Base(mybin)+"_intermediates")
-
- err := os.MkdirAll(intermediates, 0777)
- if err != nil {
- fmt.Fprintln(os.Stderr, "Failed to create intermediates directory: %v", err)
- os.Exit(1)
- }
-
- pkg := &GoPackage{
- Name: "main",
- }
-
- if err := pkg.FindDeps(mysrc, pkgMap); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
-
- if err := pkg.Compile(intermediates, mysrc); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
-
- if err := pkg.Link(mybin); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
-
- if !pkg.rebuilt {
- return
- }
-
- cmd := exec.Command(mybin, os.Args[1:]...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- if err := cmd.Run(); err == nil {
- os.Exit(0)
- } else if e, ok := err.(*exec.ExitError); ok {
- os.Exit(e.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
- }
- os.Exit(1)
-}
-
-func main() {
- var output, mysrc, mybin, trimPath string
- var pkgMap pkgPathMapping
-
- flags := flag.NewFlagSet("", flag.ExitOnError)
- flags.BoolVar(&race, "race", false, "enable data race detection.")
- flags.BoolVar(&verbose, "v", false, "Verbose")
- flags.StringVar(&output, "o", "", "Output file")
- flags.StringVar(&mysrc, "s", "", "Microfactory source directory (for rebuilding microfactory if necessary)")
- flags.StringVar(&mybin, "b", "", "Microfactory binary location")
- flags.StringVar(&trimPath, "trimpath", "", "remove prefix from recorded source file paths")
- flags.Var(&pkgMap, "pkg-path", "Mapping of package prefixes to file paths")
- err := flags.Parse(os.Args[1:])
-
- if err == flag.ErrHelp || flags.NArg() != 1 || output == "" {
- fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "-o out/binary <main-package>")
- flags.PrintDefaults()
- os.Exit(1)
- }
-
- if mybin != "" && mysrc != "" {
- rebuildMicrofactory(mybin, mysrc, &pkgMap)
- }
-
- mainPackage := &GoPackage{
- Name: "main",
- }
-
- if path, ok, err := pkgMap.Path(flags.Arg(0)); err != nil {
- fmt.Fprintln(os.Stderr, "Error finding main path:", err)
- os.Exit(1)
- } else if !ok {
- fmt.Fprintln(os.Stderr, "Cannot find path for", flags.Arg(0))
- } else {
- if err := mainPackage.FindDeps(path, &pkgMap); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- }
-
- intermediates := filepath.Join(filepath.Dir(output), "."+filepath.Base(output)+"_intermediates")
-
- err = os.MkdirAll(intermediates, 0777)
- if err != nil {
- fmt.Fprintln(os.Stderr, "Failed to create intermediates directory: %ve", err)
- os.Exit(1)
- }
-
- err = mainPackage.Compile(intermediates, trimPath)
- if err != nil {
- fmt.Fprintln(os.Stderr, "Failed to compile:", err)
- os.Exit(1)
- }
-
- err = mainPackage.Link(output)
- if err != nil {
- fmt.Fprintln(os.Stderr, "microfactory.go failed to link:", err)
- os.Exit(1)
- }
-}
-
-// pkgPathMapping can be used with flag.Var to parse -pkg-path arguments of
-// <package-prefix>=<path-prefix> mappings.
-type pkgPathMapping struct {
- pkgs []string
-
- paths map[string]string
-}
-
-func (pkgPathMapping) String() string {
- return "<package-prefix>=<path-prefix>"
-}
-
-func (p *pkgPathMapping) Set(value string) error {
- equalPos := strings.Index(value, "=")
- if equalPos == -1 {
- return fmt.Errorf("Argument must be in the form of: %q", p.String())
- }
-
- pkgPrefix := strings.TrimSuffix(value[:equalPos], "/")
- pathPrefix := strings.TrimSuffix(value[equalPos+1:], "/")
-
- if p.paths == nil {
- p.paths = make(map[string]string)
- }
- if _, ok := p.paths[pkgPrefix]; ok {
- return fmt.Errorf("Duplicate package prefix: %q", pkgPrefix)
- }
-
- p.pkgs = append(p.pkgs, pkgPrefix)
- p.paths[pkgPrefix] = pathPrefix
-
- return nil
-}
-
-// Path takes a package name, applies the path mappings and returns the resulting path.
-//
-// If the package isn't mapped, we'll return false to prevent compilation attempts.
-func (p *pkgPathMapping) Path(pkg string) (string, bool, error) {
- if p.paths == nil {
- return "", false, fmt.Errorf("No package mappings")
- }
-
- for _, pkgPrefix := range p.pkgs {
- if pkg == pkgPrefix {
- return p.paths[pkgPrefix], true, nil
- } else if strings.HasPrefix(pkg, pkgPrefix+"/") {
- return filepath.Join(p.paths[pkgPrefix], strings.TrimPrefix(pkg, pkgPrefix+"/")), true, nil
- }
- }
-
- return "", false, nil
-}
diff --git a/cmd/microfactory/microfactory_test.go b/cmd/microfactory/microfactory_test.go
deleted file mode 100644
index 8c02bcf..0000000
--- a/cmd/microfactory/microfactory_test.go
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
- "flag"
- "io/ioutil"
- "os"
- "path/filepath"
- "reflect"
- "runtime"
- "testing"
- "time"
-)
-
-func TestSimplePackagePathMap(t *testing.T) {
- t.Parallel()
-
- var pkgMap pkgPathMapping
- flags := flag.NewFlagSet("", flag.ContinueOnError)
- flags.Var(&pkgMap, "m", "")
- err := flags.Parse([]string{
- "-m", "android/soong=build/soong/",
- "-m", "github.com/google/blueprint/=build/blueprint",
- })
- if err != nil {
- t.Fatal(err)
- }
-
- compare := func(got, want interface{}) {
- if !reflect.DeepEqual(got, want) {
- t.Errorf("Unexpected values in .pkgs:\nwant: %v\n got: %v",
- want, got)
- }
- }
-
- wantPkgs := []string{"android/soong", "github.com/google/blueprint"}
- compare(pkgMap.pkgs, wantPkgs)
- compare(pkgMap.paths[wantPkgs[0]], "build/soong")
- compare(pkgMap.paths[wantPkgs[1]], "build/blueprint")
-
- got, ok, err := pkgMap.Path("android/soong/ui/test")
- if err != nil {
- t.Error("Unexpected error in pkgMap.Path(soong):", err)
- } else if !ok {
- t.Error("Expected a result from pkgMap.Path(soong)")
- } else {
- compare(got, "build/soong/ui/test")
- }
-
- got, ok, err = pkgMap.Path("github.com/google/blueprint")
- if err != nil {
- t.Error("Unexpected error in pkgMap.Path(blueprint):", err)
- } else if !ok {
- t.Error("Expected a result from pkgMap.Path(blueprint)")
- } else {
- compare(got, "build/blueprint")
- }
-}
-
-func TestBadPackagePathMap(t *testing.T) {
- t.Parallel()
-
- var pkgMap pkgPathMapping
- if _, _, err := pkgMap.Path("testing"); err == nil {
- t.Error("Expected error if no maps are specified")
- }
- if err := pkgMap.Set(""); err == nil {
- t.Error("Expected error with blank argument, but none returned")
- }
- if err := pkgMap.Set("a=a"); err != nil {
- t.Error("Unexpected error: %v", err)
- }
- if err := pkgMap.Set("a=b"); err == nil {
- t.Error("Expected error with duplicate package prefix, but none returned")
- }
- if _, ok, err := pkgMap.Path("testing"); err != nil {
- t.Error("Unexpected error: %v", err)
- } else if ok {
- t.Error("Expected testing to be consider in the stdlib")
- }
-}
-
-// TestSingleBuild ensures that just a basic build works.
-func TestSingleBuild(t *testing.T) {
- t.Parallel()
-
- setupDir(t, func(dir string, loadPkg loadPkgFunc) {
- // The output binary
- out := filepath.Join(dir, "out", "test")
-
- pkg := loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- t.Fatalf("Got error when compiling:", err)
- }
-
- if err := pkg.Link(out); err != nil {
- t.Fatal("Got error when linking:", err)
- }
-
- if _, err := os.Stat(out); err != nil {
- t.Error("Cannot stat output:", err)
- }
- })
-}
-
-// testBuildAgain triggers two builds, running the modify function in between
-// each build. It verifies that the second build did or did not actually need
-// to rebuild anything based on the shouldRebuild argument.
-func testBuildAgain(t *testing.T,
- shouldRecompile, shouldRelink bool,
- modify func(dir string, loadPkg loadPkgFunc),
- after func(pkg *GoPackage)) {
-
- t.Parallel()
-
- setupDir(t, func(dir string, loadPkg loadPkgFunc) {
- // The output binary
- out := filepath.Join(dir, "out", "test")
-
- pkg := loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- t.Fatal("Got error when compiling:", err)
- }
-
- if err := pkg.Link(out); err != nil {
- t.Fatal("Got error when linking:", err)
- }
-
- var firstTime time.Time
- if stat, err := os.Stat(out); err == nil {
- firstTime = stat.ModTime()
- } else {
- t.Fatal("Failed to stat output file:", err)
- }
-
- // mtime on HFS+ (the filesystem on darwin) are stored with 1
- // second granularity, so the timestamp checks will fail unless
- // we wait at least a second. Sleeping 1.1s to be safe.
- if runtime.GOOS == "darwin" {
- time.Sleep(1100 * time.Millisecond)
- }
-
- modify(dir, loadPkg)
-
- pkg = loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- t.Fatal("Got error when compiling:", err)
- }
- if shouldRecompile {
- if !pkg.rebuilt {
- t.Fatal("Package should have recompiled, but was not recompiled.")
- }
- } else {
- if pkg.rebuilt {
- t.Fatal("Package should not have needed to be recompiled, but was recompiled.")
- }
- }
-
- if err := pkg.Link(out); err != nil {
- t.Fatal("Got error while linking:", err)
- }
- if shouldRelink {
- if !pkg.rebuilt {
- t.Error("Package should have relinked, but was not relinked.")
- }
- } else {
- if pkg.rebuilt {
- t.Error("Package should not have needed to be relinked, but was relinked.")
- }
- }
-
- if stat, err := os.Stat(out); err == nil {
- if shouldRelink {
- if stat.ModTime() == firstTime {
- t.Error("Output timestamp should be different, but both were", firstTime)
- }
- } else {
- if stat.ModTime() != firstTime {
- t.Error("Output timestamp should be the same.")
- t.Error(" first:", firstTime)
- t.Error("second:", stat.ModTime())
- }
- }
- } else {
- t.Fatal("Failed to stat output file:", err)
- }
-
- after(pkg)
- })
-}
-
-// TestRebuildAfterNoChanges ensures that we don't rebuild if nothing
-// changes
-func TestRebuildAfterNoChanges(t *testing.T) {
- testBuildAgain(t, false, false, func(dir string, loadPkg loadPkgFunc) {}, func(pkg *GoPackage) {})
-}
-
-// TestRebuildAfterTimestamp ensures that we don't rebuild because
-// timestamps of important files have changed. We should only rebuild if the
-// content hashes are different.
-func TestRebuildAfterTimestampChange(t *testing.T) {
- testBuildAgain(t, false, false, func(dir string, loadPkg loadPkgFunc) {
- // Ensure that we've spent some amount of time asleep
- time.Sleep(100 * time.Millisecond)
-
- newTime := time.Now().Local()
- os.Chtimes(filepath.Join(dir, "test.fact"), newTime, newTime)
- os.Chtimes(filepath.Join(dir, "main/main.go"), newTime, newTime)
- os.Chtimes(filepath.Join(dir, "a/a.go"), newTime, newTime)
- os.Chtimes(filepath.Join(dir, "a/b.go"), newTime, newTime)
- os.Chtimes(filepath.Join(dir, "b/a.go"), newTime, newTime)
- }, func(pkg *GoPackage) {})
-}
-
-// TestRebuildAfterGoChange ensures that we rebuild after a content change
-// to a package's go file.
-func TestRebuildAfterGoChange(t *testing.T) {
- testBuildAgain(t, true, true, func(dir string, loadPkg loadPkgFunc) {
- if err := ioutil.WriteFile(filepath.Join(dir, "a", "a.go"), []byte(go_a_a+"\n"), 0666); err != nil {
- t.Fatal("Error writing a/a.go:", err)
- }
- }, func(pkg *GoPackage) {
- if !pkg.directDeps[0].rebuilt {
- t.Fatal("android/soong/a should have rebuilt")
- }
- if !pkg.directDeps[1].rebuilt {
- t.Fatal("android/soong/b should have rebuilt")
- }
- })
-}
-
-// TestRebuildAfterMainChange ensures that we don't rebuild any dependencies
-// if only the main package's go files are touched.
-func TestRebuildAfterMainChange(t *testing.T) {
- testBuildAgain(t, true, true, func(dir string, loadPkg loadPkgFunc) {
- if err := ioutil.WriteFile(filepath.Join(dir, "main", "main.go"), []byte(go_main_main+"\n"), 0666); err != nil {
- t.Fatal("Error writing main/main.go:", err)
- }
- }, func(pkg *GoPackage) {
- if pkg.directDeps[0].rebuilt {
- t.Fatal("android/soong/a should not have rebuilt")
- }
- if pkg.directDeps[1].rebuilt {
- t.Fatal("android/soong/b should not have rebuilt")
- }
- })
-}
-
-// TestRebuildAfterRemoveOut ensures that we rebuild if the output file is
-// missing, even if everything else doesn't need rebuilding.
-func TestRebuildAfterRemoveOut(t *testing.T) {
- testBuildAgain(t, false, true, func(dir string, loadPkg loadPkgFunc) {
- if err := os.Remove(filepath.Join(dir, "out", "test")); err != nil {
- t.Fatal("Failed to remove output:", err)
- }
- }, func(pkg *GoPackage) {})
-}
-
-// TestRebuildAfterPartialBuild ensures that even if the build was interrupted
-// between the recompile and relink stages, we'll still relink when we run again.
-func TestRebuildAfterPartialBuild(t *testing.T) {
- testBuildAgain(t, false, true, func(dir string, loadPkg loadPkgFunc) {
- if err := ioutil.WriteFile(filepath.Join(dir, "main", "main.go"), []byte(go_main_main+"\n"), 0666); err != nil {
- t.Fatal("Error writing main/main.go:", err)
- }
-
- pkg := loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- t.Fatal("Got error when compiling:", err)
- }
- if !pkg.rebuilt {
- t.Fatal("Package should have recompiled, but was not recompiled.")
- }
- }, func(pkg *GoPackage) {})
-}
-
-// BenchmarkInitialBuild computes how long a clean build takes (for tiny test
-// inputs).
-func BenchmarkInitialBuild(b *testing.B) {
- for i := 0; i < b.N; i++ {
- setupDir(b, func(dir string, loadPkg loadPkgFunc) {
- pkg := loadPkg()
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- b.Fatal("Got error when compiling:", err)
- }
-
- if err := pkg.Link(filepath.Join(dir, "out", "test")); err != nil {
- b.Fatal("Got error when linking:", err)
- }
- })
- }
-}
-
-// BenchmarkMinIncrementalBuild computes how long an incremental build that
-// doesn't actually need to build anything takes.
-func BenchmarkMinIncrementalBuild(b *testing.B) {
- setupDir(b, func(dir string, loadPkg loadPkgFunc) {
- pkg := loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- b.Fatal("Got error when compiling:", err)
- }
-
- if err := pkg.Link(filepath.Join(dir, "out", "test")); err != nil {
- b.Fatal("Got error when linking:", err)
- }
-
- b.ResetTimer()
-
- for i := 0; i < b.N; i++ {
- pkg := loadPkg()
-
- if err := pkg.Compile(filepath.Join(dir, "out"), ""); err != nil {
- b.Fatal("Got error when compiling:", err)
- }
-
- if err := pkg.Link(filepath.Join(dir, "out", "test")); err != nil {
- b.Fatal("Got error when linking:", err)
- }
-
- if pkg.rebuilt {
- b.Fatal("Should not have rebuilt anything")
- }
- }
- })
-}
-
-///////////////////////////////////////////////////////
-// Templates used to create fake compilable packages //
-///////////////////////////////////////////////////////
-
-const go_main_main = `
-package main
-import (
- "fmt"
- "android/soong/a"
- "android/soong/b"
-)
-func main() {
- fmt.Println(a.Stdout, b.Stdout)
-}
-`
-
-const go_a_a = `
-package a
-import "os"
-var Stdout = os.Stdout
-`
-
-const go_a_b = `
-package a
-`
-
-const go_b_a = `
-package b
-import "android/soong/a"
-var Stdout = a.Stdout
-`
-
-type T interface {
- Fatal(args ...interface{})
- Fatalf(format string, args ...interface{})
-}
-
-type loadPkgFunc func() *GoPackage
-
-func setupDir(t T, test func(dir string, loadPkg loadPkgFunc)) {
- dir, err := ioutil.TempDir("", "test")
- if err != nil {
- t.Fatalf("Error creating temporary directory: %#v", err)
- }
- defer os.RemoveAll(dir)
-
- writeFile := func(name, contents string) {
- if err := ioutil.WriteFile(filepath.Join(dir, name), []byte(contents), 0666); err != nil {
- t.Fatalf("Error writing %q: %#v", name, err)
- }
- }
- mkdir := func(name string) {
- if err := os.Mkdir(filepath.Join(dir, name), 0777); err != nil {
- t.Fatalf("Error creating %q directory: %#v", name, err)
- }
- }
- mkdir("main")
- mkdir("a")
- mkdir("b")
- writeFile("main/main.go", go_main_main)
- writeFile("a/a.go", go_a_a)
- writeFile("a/b.go", go_a_b)
- writeFile("b/a.go", go_b_a)
-
- loadPkg := func() *GoPackage {
- pkg := &GoPackage{
- Name: "main",
- }
- pkgMap := &pkgPathMapping{}
- pkgMap.Set("android/soong=" + dir)
- if err := pkg.FindDeps(filepath.Join(dir, "main"), pkgMap); err != nil {
- t.Fatalf("Error finding deps: %v", err)
- }
- return pkg
- }
-
- test(dir, loadPkg)
-}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index ed8f2fd..e15a6bd 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -32,6 +32,7 @@
srcDir := filepath.Dir(flag.Arg(0))
ctx := android.NewContext()
+ ctx.Register()
configuration, err := android.NewConfig(srcDir, bootstrap.BuildDir)
if err != nil {
@@ -44,5 +45,5 @@
ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
- bootstrap.Main(ctx, configuration, configuration.ConfigFileName, configuration.ProductVariablesFileName)
+ bootstrap.Main(ctx.Context, configuration, configuration.ConfigFileName, configuration.ProductVariablesFileName)
}
diff --git a/cmd/soong_env/Android.bp b/cmd/soong_env/Android.bp
index b0d827c..4cdc396 100644
--- a/cmd/soong_env/Android.bp
+++ b/cmd/soong_env/Android.bp
@@ -20,5 +20,6 @@
srcs: [
"soong_env.go",
],
+ default: true,
}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 26887ae..94d6d5c 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -89,6 +89,10 @@
buildCtx.CompleteTrace("startup", start_time, uint64(time.Now().UnixNano()))
}
}
+
+ if executable, err := os.Executable(); err == nil {
+ trace.ImportMicrofactoryLog(filepath.Join(filepath.Dir(executable), "."+filepath.Base(executable)+".trace"))
+ }
}
build.Build(buildCtx, config, build.BuildAll)
diff --git a/java/androidmk.go b/java/androidmk.go
index 9ffd35f..086ba7a 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -20,14 +20,14 @@
"android/soong/android"
)
-func (*JavaLibrary) AndroidMk() (ret android.AndroidMkData, err error) {
+func (*Library) AndroidMk() (ret android.AndroidMkData, err error) {
ret.Class = "JAVA_LIBRARIES"
// TODO
err = fmt.Errorf("Not yet implemented")
return
}
-func (*JavaPrebuilt) AndroidMk() (ret android.AndroidMkData, err error) {
+func (*Prebuilt) AndroidMk() (ret android.AndroidMkData, err error) {
ret.Class = "JAVA_LIBRARIES"
// TODO
err = fmt.Errorf("Not yet implemented")
diff --git a/java/app.go b/java/app.go
index 2f2b899..8a221ef 100644
--- a/java/app.go
+++ b/java/app.go
@@ -68,17 +68,14 @@
func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) {
a.Module.deps(ctx)
- var deps []string
if !a.properties.No_standard_libraries {
switch a.deviceProperties.Sdk_version { // TODO: Res_sdk_version?
case "current", "system_current", "":
- deps = append(deps, "framework-res")
+ ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
default:
// We'll already have a dependency on an sdk prebuilt android.jar
}
}
-
- ctx.AddDependency(ctx.Module(), nil, deps...)
}
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -237,7 +234,7 @@
var depFile android.OptionalPath
if sdkDep, ok := module.(sdkDependency); ok {
depFile = android.OptionalPathForPath(sdkDep.ClasspathFile())
- } else if javaDep, ok := module.(JavaDependency); ok {
+ } else if javaDep, ok := module.(Dependency); ok {
if ctx.OtherModuleName(module) == "framework-res" {
depFile = android.OptionalPathForPath(javaDep.(*AndroidApp).exportPackage)
}
diff --git a/java/builder.go b/java/builder.go
index 041c303..ed9d82c 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -40,7 +40,7 @@
javac = pctx.AndroidGomaStaticRule("javac",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `${config.JavacWrapper}$javacCmd ` +
+ `${JavacWrapper}$javacCmd ` +
`-encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
`-extdirs "" -d $outDir @$out.rsp || ( rm -rf "$outDir"; exit 41 ) && ` +
`find $outDir -name "*.class" > $out`,
diff --git a/java/java.go b/java/java.go
index 3cc552f..1ef1c26 100644
--- a/java/java.go
+++ b/java/java.go
@@ -30,13 +30,15 @@
)
func init() {
- android.RegisterModuleType("java_library", JavaLibraryFactory)
- android.RegisterModuleType("java_library_static", JavaLibraryFactory)
- android.RegisterModuleType("java_library_host", JavaLibraryHostFactory)
- android.RegisterModuleType("java_binary", JavaBinaryFactory)
- android.RegisterModuleType("java_binary_host", JavaBinaryHostFactory)
- android.RegisterModuleType("prebuilt_java_library", JavaPrebuiltFactory)
- android.RegisterModuleType("prebuilt_sdk", SdkPrebuiltFactory)
+ android.RegisterModuleType("java_defaults", defaultsFactory)
+
+ android.RegisterModuleType("java_library", LibraryFactory)
+ android.RegisterModuleType("java_library_static", LibraryFactory)
+ android.RegisterModuleType("java_library_host", LibraryHostFactory)
+ android.RegisterModuleType("java_binary", BinaryFactory)
+ android.RegisterModuleType("java_binary_host", BinaryHostFactory)
+ android.RegisterModuleType("java_prebuilt_library", PrebuiltFactory)
+ android.RegisterModuleType("android_prebuilt_sdk", SdkPrebuiltFactory)
android.RegisterModuleType("android_app", AndroidAppFactory)
android.RegisterSingletonType("logtags", LogtagsSingleton)
@@ -55,7 +57,7 @@
// DroidDoc
// Findbugs
-type compilerProperties struct {
+type CompilerProperties struct {
// list of source files used to compile the Java module. May be .java, .logtags, .proto,
// or .aidl files.
Srcs []string `android:"arch_variant"`
@@ -65,10 +67,10 @@
Exclude_srcs []string `android:"arch_variant"`
// list of directories containing Java resources
- Java_resource_dirs []string `android:"arch_variant"`
+ Resource_dirs []string `android:"arch_variant"`
- // list of directories that should be excluded from java_resource_dirs
- Exclude_java_resource_dirs []string `android:"arch_variant"`
+ // list of directories that should be excluded from resource_dirs
+ Exclude_resource_dirs []string `android:"arch_variant"`
// don't build against the default libraries (legacy-test, core-junit,
// ext, and framework for device targets)
@@ -78,10 +80,10 @@
Javacflags []string `android:"arch_variant"`
// list of of java libraries that will be in the classpath
- Java_libs []string `android:"arch_variant"`
+ Libs []string `android:"arch_variant"`
// list of java libraries that will be compiled into the resulting jar
- Java_static_libs []string `android:"arch_variant"`
+ Static_libs []string `android:"arch_variant"`
// manifest file to be included in resulting jar
Manifest *string
@@ -90,7 +92,7 @@
Jarjar_rules *string
}
-type compilerDeviceProperties struct {
+type CompilerDeviceProperties struct {
// list of module-specific flags that will be used for dex compiles
Dxflags []string `android:"arch_variant"`
@@ -112,9 +114,10 @@
// Module contains the properties and members used by all java module types
type Module struct {
android.ModuleBase
+ android.DefaultableModuleBase
- properties compilerProperties
- deviceProperties compilerDeviceProperties
+ properties CompilerProperties
+ deviceProperties CompilerDeviceProperties
// output file suitable for inserting into the classpath of another compile
classpathFile android.Path
@@ -140,52 +143,58 @@
installFile android.Path
}
-type JavaDependency interface {
+type Dependency interface {
ClasspathFile() android.Path
ClassJarSpecs() []jarSpec
ResourceJarSpecs() []jarSpec
AidlIncludeDirs() android.Paths
}
-func (j *Module) BootClasspath(ctx android.BaseContext) string {
- if ctx.Device() {
- switch j.deviceProperties.Sdk_version {
- case "":
- return "core-libart"
- case "current":
- // TODO: !TARGET_BUILD_APPS
- // TODO: export preprocessed framework.aidl from android_stubs_current
- return "android_stubs_current"
- case "system_current":
- return "android_system_stubs_current"
- default:
- return "sdk_v" + j.deviceProperties.Sdk_version
- }
- } else {
- if j.deviceProperties.Dex {
- return "core-libart"
- } else {
- return ""
- }
- }
+func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
+ android.InitAndroidArchModule(module, hod, android.MultilibCommon)
+ android.InitDefaultableModule(module)
}
-func (j *Module) deps(ctx android.BottomUpMutatorContext) {
- var deps []string
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+var (
+ staticLibTag = dependencyTag{name: "staticlib"}
+ libTag = dependencyTag{name: "javalib"}
+ bootClasspathTag = dependencyTag{name: "bootclasspath"}
+ frameworkResTag = dependencyTag{name: "framework-res"}
+ sdkDependencyTag = dependencyTag{name: "sdk"}
+)
+
+func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if !j.properties.No_standard_libraries {
- bootClasspath := j.BootClasspath(ctx)
- if bootClasspath != "" {
- deps = append(deps, bootClasspath)
+ if ctx.Device() {
+ switch j.deviceProperties.Sdk_version {
+ case "":
+ ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart")
+ case "current":
+ // TODO: !TARGET_BUILD_APPS
+ // TODO: export preprocessed framework.aidl from android_stubs_current
+ ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_stubs_current")
+ case "system_current":
+ ctx.AddDependency(ctx.Module(), bootClasspathTag, "android_system_stubs_current")
+ default:
+ ctx.AddDependency(ctx.Module(), sdkDependencyTag, "sdk_v"+j.deviceProperties.Sdk_version)
+ }
+ } else {
+ if j.deviceProperties.Dex {
+ ctx.AddDependency(ctx.Module(), bootClasspathTag, "core-libart")
+ }
}
+
if ctx.Device() && j.deviceProperties.Sdk_version == "" {
- deps = append(deps, config.DefaultLibraries...)
+ ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
}
}
- deps = append(deps, j.properties.Java_libs...)
- deps = append(deps, j.properties.Java_static_libs...)
-
- ctx.AddDependency(ctx.Module(), nil, deps...)
+ ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
+ ctx.AddDependency(ctx.Module(), staticLibTag, j.properties.Static_libs...)
}
func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
@@ -203,7 +212,9 @@
flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I"))
flags = append(flags, android.JoinWithPrefix(localAidlIncludes.Strings(), "-I"))
flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
- flags = append(flags, "-I"+android.PathForModuleSrc(ctx, "src").String())
+ if src := android.ExistentPathForSource(ctx, "", "src"); src.Valid() {
+ flags = append(flags, "-I"+src.String())
+ }
return flags
}
@@ -214,38 +225,48 @@
ctx.VisitDirectDeps(func(module blueprint.Module) {
otherName := ctx.OtherModuleName(module)
- if javaDep, ok := module.(JavaDependency); ok {
- if otherName == j.BootClasspath(ctx) {
- bootClasspath = android.OptionalPathForPath(javaDep.ClasspathFile())
- } else if inList(otherName, config.DefaultLibraries) {
- classpath = append(classpath, javaDep.ClasspathFile())
- } else if inList(otherName, j.properties.Java_libs) {
- classpath = append(classpath, javaDep.ClasspathFile())
- } else if inList(otherName, j.properties.Java_static_libs) {
- classpath = append(classpath, javaDep.ClasspathFile())
- classJarSpecs = append(classJarSpecs, javaDep.ClassJarSpecs()...)
- resourceJarSpecs = append(resourceJarSpecs, javaDep.ResourceJarSpecs()...)
- } else if otherName == "framework-res" {
- if ctx.ModuleName() == "framework" {
- // framework.jar has a one-off dependency on the R.java and Manifest.java files
- // generated by framework-res.apk
- srcFileLists = append(srcFileLists, module.(*AndroidApp).aaptJavaFileList)
- }
- } else {
- panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
+ tag := ctx.OtherModuleDependencyTag(module)
+
+ dep, _ := module.(Dependency)
+ if dep == nil {
+ switch tag {
+ case android.DefaultsDepTag, android.SourceDepTag:
+ default:
+ ctx.ModuleErrorf("depends on non-java module %q", otherName)
}
- aidlIncludeDirs = append(aidlIncludeDirs, javaDep.AidlIncludeDirs()...)
- if sdkDep, ok := module.(sdkDependency); ok {
- if sdkDep.AidlPreprocessed().Valid() {
- if aidlPreprocess.Valid() {
- ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q",
- aidlPreprocess, sdkDep.AidlPreprocessed())
- } else {
- aidlPreprocess = sdkDep.AidlPreprocessed()
- }
- }
- }
+ return
}
+
+ switch tag {
+ case bootClasspathTag:
+ bootClasspath = android.OptionalPathForPath(dep.ClasspathFile())
+ case libTag:
+ classpath = append(classpath, dep.ClasspathFile())
+ case staticLibTag:
+ classpath = append(classpath, dep.ClasspathFile())
+ classJarSpecs = append(classJarSpecs, dep.ClassJarSpecs()...)
+ resourceJarSpecs = append(resourceJarSpecs, dep.ResourceJarSpecs()...)
+ case frameworkResTag:
+ if ctx.ModuleName() == "framework" {
+ // framework.jar has a one-off dependency on the R.java and Manifest.java files
+ // generated by framework-res.apk
+ srcFileLists = append(srcFileLists, module.(*AndroidApp).aaptJavaFileList)
+ }
+ case sdkDependencyTag:
+ sdkDep := module.(sdkDependency)
+ if sdkDep.AidlPreprocessed().Valid() {
+ if aidlPreprocess.Valid() {
+ ctx.ModuleErrorf("multiple dependencies with preprocessed aidls:\n %q\n %q",
+ aidlPreprocess, sdkDep.AidlPreprocessed())
+ } else {
+ aidlPreprocess = sdkDep.AidlPreprocessed()
+ }
+ }
+ default:
+ panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
+ }
+
+ aidlIncludeDirs = append(aidlIncludeDirs, dep.AidlIncludeDirs()...)
})
return classpath, bootClasspath, classJarSpecs, resourceJarSpecs, aidlPreprocess,
@@ -273,16 +294,16 @@
flags.aidlFlags = "$aidlFlags"
}
- var javacDeps android.Paths
+ var deps android.Paths
if bootClasspath.Valid() {
flags.bootClasspath = "-bootclasspath " + bootClasspath.String()
- javacDeps = append(javacDeps, bootClasspath.Path())
+ deps = append(deps, bootClasspath.Path())
}
if len(classpath) > 0 {
flags.classpath = "-classpath " + strings.Join(classpath.Strings(), ":")
- javacDeps = append(javacDeps, classpath...)
+ deps = append(deps, classpath...)
}
srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
@@ -299,7 +320,7 @@
if len(srcFiles) > 0 {
// Compile java sources into .class files
- classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, javacDeps)
+ classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, deps)
if ctx.Failed() {
return
}
@@ -307,7 +328,7 @@
classJarSpecs = append([]jarSpec{classes}, classJarSpecs...)
}
- resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Java_resource_dirs, j.properties.Exclude_java_resource_dirs),
+ resourceJarSpecs = append(ResourceDirsToJarSpecs(ctx, j.properties.Resource_dirs, j.properties.Exclude_resource_dirs),
resourceJarSpecs...)
manifest := android.OptionalPathForModuleSrc(ctx, j.properties.Manifest)
@@ -376,7 +397,7 @@
j.outputFile = outputFile
}
-var _ JavaDependency = (*JavaLibrary)(nil)
+var _ Dependency = (*Library)(nil)
func (j *Module) ClasspathFile() android.Path {
return j.classpathFile
@@ -404,22 +425,22 @@
// Java libraries (.jar file)
//
-type JavaLibrary struct {
+type Library struct {
Module
}
-func (j *JavaLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.compile(ctx)
j.installFile = ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.outputFile)
}
-func (j *JavaLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
}
-func JavaLibraryFactory() android.Module {
- module := &JavaLibrary{}
+func LibraryFactory() android.Module {
+ module := &Library{}
module.deviceProperties.Dex = true
@@ -427,16 +448,16 @@
&module.Module.properties,
&module.Module.deviceProperties)
- android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
-func JavaLibraryHostFactory() android.Module {
- module := &JavaLibrary{}
+func LibraryHostFactory() android.Module {
+ module := &Library{}
module.AddProperties(&module.Module.properties)
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostSupported)
return module
}
@@ -444,19 +465,19 @@
// Java Binaries (.jar file plus wrapper script)
//
-type javaBinaryProperties struct {
+type binaryProperties struct {
// installable script to execute the resulting jar
Wrapper string
}
-type JavaBinary struct {
- JavaLibrary
+type Binary struct {
+ Library
- binaryProperties javaBinaryProperties
+ binaryProperties binaryProperties
}
-func (j *JavaBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.JavaLibrary.GenerateAndroidBuildActions(ctx)
+func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ j.Library.GenerateAndroidBuildActions(ctx)
// Depend on the installed jar (j.installFile) so that the wrapper doesn't get executed by
// another build rule before the jar has been installed.
@@ -464,12 +485,12 @@
j.installFile)
}
-func (j *JavaBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) {
j.deps(ctx)
}
-func JavaBinaryFactory() android.Module {
- module := &JavaBinary{}
+func BinaryFactory() android.Module {
+ module := &Binary{}
module.deviceProperties.Dex = true
@@ -478,19 +499,19 @@
&module.Module.deviceProperties,
&module.binaryProperties)
- android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
-func JavaBinaryHostFactory() android.Module {
- module := &JavaBinary{}
+func BinaryHostFactory() android.Module {
+ module := &Binary{}
module.AddProperties(
&module.Module.properties,
&module.Module.deviceProperties,
&module.binaryProperties)
- android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ InitJavaModule(module, android.HostSupported)
return module
}
@@ -498,28 +519,23 @@
// Java prebuilts
//
-type javaPrebuiltProperties struct {
- Srcs []string
-}
-
-type JavaPrebuilt struct {
+type Prebuilt struct {
android.ModuleBase
-
- properties javaPrebuiltProperties
+ prebuilt android.Prebuilt
classpathFile android.Path
classJarSpecs, resourceJarSpecs []jarSpec
}
-func (j *JavaPrebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (j *Prebuilt) Prebuilt() *android.Prebuilt {
+ return &j.prebuilt
}
-func (j *JavaPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if len(j.properties.Srcs) != 1 {
- ctx.ModuleErrorf("expected exactly one jar in srcs")
- return
- }
- prebuilt := android.PathForModuleSrc(ctx, j.properties.Srcs[0])
+func (j *Prebuilt) DepsMutator(ctx android.BottomUpMutatorContext) {
+}
+
+func (j *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ prebuilt := j.prebuilt.Path(ctx)
classJarSpec, resourceJarSpec := TransformPrebuiltJarToClasses(ctx, prebuilt)
@@ -529,28 +545,28 @@
ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"), ctx.ModuleName()+".jar", j.classpathFile)
}
-var _ JavaDependency = (*JavaPrebuilt)(nil)
+var _ Dependency = (*Prebuilt)(nil)
-func (j *JavaPrebuilt) ClasspathFile() android.Path {
+func (j *Prebuilt) ClasspathFile() android.Path {
return j.classpathFile
}
-func (j *JavaPrebuilt) ClassJarSpecs() []jarSpec {
+func (j *Prebuilt) ClassJarSpecs() []jarSpec {
return j.classJarSpecs
}
-func (j *JavaPrebuilt) ResourceJarSpecs() []jarSpec {
+func (j *Prebuilt) ResourceJarSpecs() []jarSpec {
return j.resourceJarSpecs
}
-func (j *JavaPrebuilt) AidlIncludeDirs() android.Paths {
+func (j *Prebuilt) AidlIncludeDirs() android.Paths {
return nil
}
-func JavaPrebuiltFactory() android.Module {
- module := &JavaPrebuilt{}
+func PrebuiltFactory() android.Module {
+ module := &Prebuilt{}
- module.AddProperties(&module.properties)
+ module.AddProperties(&module.prebuilt.Properties)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
return module
@@ -561,7 +577,7 @@
//
type sdkDependency interface {
- JavaDependency
+ Dependency
AidlPreprocessed() android.OptionalPath
}
@@ -572,7 +588,7 @@
}
type sdkPrebuilt struct {
- JavaPrebuilt
+ Prebuilt
sdkProperties sdkPrebuiltProperties
@@ -580,7 +596,7 @@
}
func (j *sdkPrebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- j.JavaPrebuilt.GenerateAndroidBuildActions(ctx)
+ j.Prebuilt.GenerateAndroidBuildActions(ctx)
j.aidlPreprocessed = android.OptionalPathForModuleSrc(ctx, j.sdkProperties.Aidl_preprocessed)
}
@@ -593,7 +609,7 @@
module := &sdkPrebuilt{}
module.AddProperties(
- &module.properties,
+ &module.prebuilt.Properties,
&module.sdkProperties)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
@@ -608,3 +624,35 @@
}
return false
}
+
+//
+// Defaults
+//
+type Defaults struct {
+ android.ModuleBase
+ android.DefaultsModuleBase
+}
+
+func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+}
+
+func (d *Defaults) DepsMutator(ctx android.BottomUpMutatorContext) {
+}
+
+func defaultsFactory() android.Module {
+ return DefaultsFactory()
+}
+
+func DefaultsFactory(props ...interface{}) android.Module {
+ module := &Defaults{}
+
+ module.AddProperties(props...)
+ module.AddProperties(
+ &CompilerProperties{},
+ &CompilerDeviceProperties{},
+ )
+
+ android.InitDefaultsModule(module)
+
+ return module
+}
diff --git a/java/java_test.go b/java/java_test.go
new file mode 100644
index 0000000..3443610
--- /dev/null
+++ b/java/java_test.go
@@ -0,0 +1,285 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+var buildDir string
+
+func setUp() {
+ var err error
+ buildDir, err = ioutil.TempDir("", "soong_java_test")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func tearDown() {
+ os.RemoveAll(buildDir)
+}
+
+func TestMain(m *testing.M) {
+ run := func() int {
+ setUp()
+ defer tearDown()
+
+ return m.Run()
+ }
+
+ os.Exit(run())
+}
+
+func testJava(t *testing.T, bp string) *android.TestContext {
+ config := android.TestConfig(buildDir)
+
+ ctx := android.NewTestContext()
+ ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(AndroidAppFactory))
+ ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(LibraryFactory))
+ ctx.RegisterModuleType("java_prebuilt_library", android.ModuleFactoryAdaptor(PrebuiltFactory))
+ ctx.RegisterModuleType("java_defaults", android.ModuleFactoryAdaptor(defaultsFactory))
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ ctx.Register()
+
+ extraModules := []string{"core-libart", "frameworks", "sdk_v14"}
+
+ for _, extra := range extraModules {
+ bp += fmt.Sprintf(`
+ java_library {
+ name: "%s",
+ no_standard_libraries: true,
+ }
+ `, extra)
+ }
+
+ ctx.MockFileSystem(map[string][]byte{
+ "Android.bp": []byte(bp),
+ "a.java": nil,
+ "b.java": nil,
+ "c.java": nil,
+ "a.jar": nil,
+ "b.jar": nil,
+ })
+
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+ fail(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ fail(t, errs)
+
+ return ctx
+}
+
+func TestSimple(t *testing.T) {
+ ctx := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ libs: ["bar"],
+ static_libs: ["baz"],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ }
+
+ java_library {
+ name: "baz",
+ srcs: ["c.java"],
+ }
+ `)
+
+ javac := ctx.ModuleForTests("foo", "").Rule("javac")
+ jar := ctx.ModuleForTests("foo", "").Rule("jar")
+
+ if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
+ t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
+ }
+
+ bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar")
+ if !strings.Contains(javac.Args["classpath"], bar) {
+ t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
+ }
+
+ baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list")
+ if !strings.Contains(jar.Args["jarArgs"], baz) {
+ t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz)
+ }
+}
+
+func TestSdk(t *testing.T) {
+ ctx := testJava(t, `
+ java_library {
+ name: "foo1",
+ srcs: ["a.java"],
+ }
+
+ java_library {
+ name: "foo2",
+ srcs: ["a.java"],
+ sdk_version: "",
+ }
+
+ java_library {
+ name: "foo3",
+ srcs: ["a.java"],
+ sdk_version: "14",
+ }
+
+ java_library {
+ name: "foo4",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+
+ java_library {
+ name: "foo5",
+ srcs: ["a.java"],
+ sdk_version: "system_current",
+ }
+
+ java_library {
+ name: "foo6",
+ srcs: ["a.java"],
+ sdk_version: "test_current",
+ }
+ `)
+
+ type depType int
+ const (
+ staticLib = iota
+ classpathLib
+ bootclasspathLib
+ )
+
+ check := func(module, dep string, depType depType) {
+ if dep != "" {
+ dep = filepath.Join(buildDir, ".intermediates", dep, "classes-full-debug.jar")
+ }
+
+ javac := ctx.ModuleForTests(module, "").Rule("javac")
+
+ if depType == bootclasspathLib {
+ got := strings.TrimPrefix(javac.Args["bootClasspath"], "-bootclasspath ")
+ if got != dep {
+ t.Errorf("module %q bootclasspath %q != %q", module, got, dep)
+ }
+ } else if depType == classpathLib {
+ got := strings.TrimPrefix(javac.Args["classpath"], "-classpath ")
+ if got != dep {
+ t.Errorf("module %q classpath %q != %q", module, got, dep)
+ }
+ }
+
+ if len(javac.Implicits) != 1 || javac.Implicits[0].String() != dep {
+ t.Errorf("module %q implicits != [%q]", dep)
+ }
+ }
+
+ check("foo1", "core-libart", bootclasspathLib)
+}
+
+func TestPrebuilts(t *testing.T) {
+ ctx := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["a.java"],
+ libs: ["bar"],
+ static_libs: ["baz"],
+ }
+
+ java_prebuilt_library {
+ name: "bar",
+ srcs: ["a.jar"],
+ }
+
+ java_prebuilt_library {
+ name: "baz",
+ srcs: ["b.jar"],
+ }
+ `)
+
+ javac := ctx.ModuleForTests("foo", "").Rule("javac")
+ jar := ctx.ModuleForTests("foo", "").Rule("jar")
+
+ bar := "a.jar"
+ if !strings.Contains(javac.Args["classpath"], bar) {
+ t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
+ }
+
+ baz := filepath.Join(buildDir, ".intermediates", "baz", "extracted", "classes.list")
+ if !strings.Contains(jar.Args["jarArgs"], baz) {
+ t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz)
+ }
+}
+
+func TestDefaults(t *testing.T) {
+ ctx := testJava(t, `
+ java_defaults {
+ name: "defaults",
+ srcs: ["a.java"],
+ libs: ["bar"],
+ static_libs: ["baz"],
+ }
+
+ java_library {
+ name: "foo",
+ defaults: ["defaults"],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ }
+
+ java_library {
+ name: "baz",
+ srcs: ["c.java"],
+ }
+ `)
+
+ javac := ctx.ModuleForTests("foo", "").Rule("javac")
+ jar := ctx.ModuleForTests("foo", "").Rule("jar")
+
+ if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
+ t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
+ }
+
+ bar := filepath.Join(buildDir, ".intermediates", "bar", "classes-full-debug.jar")
+ if !strings.Contains(javac.Args["classpath"], bar) {
+ t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], bar)
+ }
+
+ baz := filepath.Join(buildDir, ".intermediates", "baz", "classes.list")
+ if !strings.Contains(jar.Args["jarArgs"], baz) {
+ t.Errorf("foo jarArgs %v does not contain %q", jar.Args["jarArgs"], baz)
+ }
+}
+
+func fail(t *testing.T, errs []error) {
+ if len(errs) > 0 {
+ for _, err := range errs {
+ t.Error(err)
+ }
+ t.FailNow()
+ }
+}
diff --git a/python/python_test.go b/python/python_test.go
index 57aaa34..4c30d95 100644
--- a/python/python_test.go
+++ b/python/python_test.go
@@ -26,8 +26,6 @@
"testing"
"android/soong/android"
-
- "github.com/google/blueprint"
)
type pyBinary struct {
@@ -306,17 +304,17 @@
func TestPythonModule(t *testing.T) {
config, buildDir := setupBuildEnv(t)
defer tearDownBuildEnv(buildDir)
- android.TestPreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
- })
for _, d := range data {
t.Run(d.desc, func(t *testing.T) {
- ctx := blueprint.NewContext()
- android.RegisterTestMutators(ctx)
+ ctx := android.NewTestContext()
+ ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("version_split", versionSplitMutator()).Parallel()
+ })
ctx.RegisterModuleType("python_library_host",
android.ModuleFactoryAdaptor(PythonLibraryHostFactory))
ctx.RegisterModuleType("python_binary_host",
android.ModuleFactoryAdaptor(PythonBinaryHostFactory))
+ ctx.Register()
ctx.MockFileSystem(d.mockFiles)
_, testErrs := ctx.ParseBlueprintsFiles(bpFile)
fail(t, testErrs)
@@ -360,15 +358,12 @@
return
}
-func expectModule(t *testing.T, ctx *blueprint.Context, buildDir, name, variant string,
+func expectModule(t *testing.T, ctx *android.TestContext, buildDir, name, variant string,
expPyRunfiles, expDepsPyRunfiles []string,
expParSpec string, expDepsParSpecs []string) (testErrs []error) {
- module := findModule(ctx, name, variant)
- if module == nil {
- t.Fatalf("failed to find module %s!", name)
- }
+ module := ctx.ModuleForTests(name, variant)
- base, baseOk := module.(*pythonBaseModule)
+ base, baseOk := module.Module().(*pythonBaseModule)
if !baseOk {
t.Fatalf("%s is not Python module!", name)
}
@@ -438,16 +433,6 @@
os.RemoveAll(buildDir)
}
-func findModule(ctx *blueprint.Context, name, variant string) blueprint.Module {
- var ret blueprint.Module
- ctx.VisitAllModules(func(m blueprint.Module) {
- if ctx.ModuleName(m) == name && ctx.ModuleSubDir(m) == variant {
- ret = m
- }
- })
- return ret
-}
-
func fail(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
diff --git a/scripts/microfactory.bash b/scripts/microfactory.bash
new file mode 100644
index 0000000..65ba55d
--- /dev/null
+++ b/scripts/microfactory.bash
@@ -0,0 +1,66 @@
+# Copyright 2017 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set of utility functions to build and run go code with microfactory
+#
+# Inputs:
+# ${TOP}: The top of the android source tree
+# ${OUT_DIR}: The output directory location (defaults to ${TOP}/out)
+# ${OUT_DIR_COMMON_BASE}: Change the default out directory to
+# ${OUT_DIR_COMMON_BASE}/$(basename ${TOP})
+
+# Ensure GOROOT is set to the in-tree version.
+case $(uname) in
+ Linux)
+ export GOROOT="${TOP}/prebuilts/go/linux-x86/"
+ ;;
+ Darwin)
+ export GOROOT="${TOP}/prebuilts/go/darwin-x86/"
+ ;;
+ *) echo "unknown OS:" $(uname) >&2 && exit 1;;
+esac
+
+# Find the output directory
+function getoutdir
+{
+ local out_dir="${OUT_DIR-}"
+ if [ -z "${out_dir}" ]; then
+ if [ "${OUT_DIR_COMMON_BASE-}" ]; then
+ out_dir="${OUT_DIR_COMMON_BASE}/$(basename ${TOP})"
+ else
+ out_dir="out"
+ fi
+ fi
+ if [[ "${out_dir}" != /* ]]; then
+ out_dir="${TOP}/${out_dir}"
+ fi
+ echo "${out_dir}"
+}
+
+# Bootstrap microfactory from source if necessary and use it to build the
+# requested binary.
+#
+# Arguments:
+# $1: name of the requested binary
+# $2: package name
+function soong_build_go
+{
+ BUILDDIR=$(getoutdir) \
+ SRCDIR=${TOP} \
+ BLUEPRINTDIR=${TOP}/build/blueprint \
+ EXTRA_ARGS="-pkg-path android/soong=${TOP}/build/soong" \
+ build_go $@
+}
+
+source ${TOP}/build/blueprint/microfactory/microfactory.bash
diff --git a/soong_ui.bash b/soong_ui.bash
index 105af9f..a39aa9c 100755
--- a/soong_ui.bash
+++ b/soong_ui.bash
@@ -47,8 +47,12 @@
fi
}
+# Save the current PWD for use in soong_ui
+export ORIGINAL_PWD=${PWD}
export TOP=$(gettop)
-source build/soong/cmd/microfactory/microfactory.bash
+source ${TOP}/build/soong/scripts/microfactory.bash
-build_go soong_ui android/soong/cmd/soong_ui
+soong_build_go soong_ui android/soong/cmd/soong_ui
+
+cd ${TOP}
exec "$(getoutdir)/soong_ui" "$@"
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index 489c06d..548baee 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -27,7 +27,6 @@
"context.go",
"environment.go",
"exec.go",
- "java.go",
"kati.go",
"make.go",
"ninja.go",
@@ -37,6 +36,7 @@
"util.go",
],
testSrcs: [
+ "config_test.go",
"environment_test.go",
"util_test.go",
"proc_sync_test.go",
diff --git a/ui/build/build.go b/ui/build/build.go
index 1400c48..32f4ba5 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -114,9 +114,6 @@
return
}
- // Start getting java version as early as possible
- getJavaVersions(ctx, config)
-
// Make sure that no other Soong process is running with the same output directory
buildLock := BecomeSingletonOrFail(ctx, config)
defer buildLock.Unlock()
@@ -148,9 +145,6 @@
runSoong(ctx, config)
}
- // Check the java versions we read earlier
- checkJavaVersion(ctx, config)
-
if what&BuildKati != 0 {
// Run ckati
runKati(ctx, config)
diff --git a/ui/build/config.go b/ui/build/config.go
index 16826f2..ef06157 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -53,6 +53,12 @@
environ: OsEnvironment(),
}
+ // Sane default matching ninja
+ ret.parallel = runtime.NumCPU() + 2
+ ret.keepGoing = 1
+
+ ret.parseArgs(ctx, args)
+
// Make sure OUT_DIR is set appropriately
if outDir, ok := ret.environ.Get("OUT_DIR"); ok {
ret.environ.Set("OUT_DIR", filepath.Clean(outDir))
@@ -92,15 +98,16 @@
// Variables that have caused problems in the past
"DISPLAY",
"GREP_OPTIONS",
+
+ // Drop make flags
+ "MAKEFLAGS",
+ "MAKELEVEL",
+ "MFLAGS",
)
// Tell python not to spam the source tree with .pyc files.
ret.environ.Set("PYTHONDONTWRITEBYTECODE", "1")
- // Sane default matching ninja
- ret.parallel = runtime.NumCPU() + 2
- ret.keepGoing = 1
-
// Precondition: the current directory is the top of the source tree
if _, err := os.Stat(srcDirFileCheck); err != nil {
if os.IsNotExist(err) {
@@ -135,38 +142,51 @@
log.Fatalln("Directory names containing spaces are not supported")
}
- for _, arg := range args {
- arg = strings.TrimSpace(arg)
+ return Config{ret}
+}
+
+func (c *configImpl) parseArgs(ctx Context, args []string) {
+ for i := 0; i < len(args); i++ {
+ arg := strings.TrimSpace(args[i])
if arg == "--make-mode" {
continue
} else if arg == "showcommands" {
- ret.verbose = true
+ c.verbose = true
continue
} else if arg == "dist" {
- ret.dist = true
+ c.dist = true
}
if arg[0] == '-' {
- var err error
+ parseArgNum := func(def int) int {
+ if len(arg) > 2 {
+ p, err := strconv.ParseUint(arg[2:], 10, 31)
+ if err != nil {
+ ctx.Fatalf("Failed to parse %q: %v", arg, err)
+ }
+ return int(p)
+ } else if i+1 < len(args) {
+ p, err := strconv.ParseUint(args[i+1], 10, 31)
+ if err == nil {
+ i++
+ return int(p)
+ }
+ }
+ return def
+ }
+
if arg[1] == 'j' {
- // TODO: handle space between j and number
- // Unnecessary if used with makeparallel
- ret.parallel, err = strconv.Atoi(arg[2:])
+ c.parallel = parseArgNum(c.parallel)
} else if arg[1] == 'k' {
- // TODO: handle space between k and number
- // Unnecessary if used with makeparallel
- ret.keepGoing, err = strconv.Atoi(arg[2:])
+ c.keepGoing = parseArgNum(0)
} else {
ctx.Fatalln("Unknown option:", arg)
}
- if err != nil {
- ctx.Fatalln("Argument error:", err, arg)
- }
+ } else if k, v, ok := decodeKeyValue(arg); ok && len(k) > 0 {
+ c.environ.Set(k, v)
} else {
- ret.arguments = append(ret.arguments, arg)
+ c.arguments = append(c.arguments, arg)
}
}
-
- return Config{ret}
}
// Lunch configures the environment for a specific product similarly to the
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
new file mode 100644
index 0000000..e4eab94
--- /dev/null
+++ b/ui/build/config_test.go
@@ -0,0 +1,174 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package build
+
+import (
+ "bytes"
+ "context"
+ "reflect"
+ "strings"
+ "testing"
+
+ "android/soong/ui/logger"
+)
+
+func testContext() Context {
+ return Context{&ContextImpl{
+ Context: context.Background(),
+ Logger: logger.New(&bytes.Buffer{}),
+ StdioInterface: NewCustomStdio(&bytes.Buffer{}, &bytes.Buffer{}, &bytes.Buffer{}),
+ }}
+}
+
+func TestConfigParseArgsJK(t *testing.T) {
+ ctx := testContext()
+
+ testCases := []struct {
+ args []string
+
+ parallel int
+ keepGoing int
+ remaining []string
+ }{
+ {nil, -1, -1, nil},
+
+ {[]string{"-j"}, -1, -1, nil},
+ {[]string{"-j1"}, 1, -1, nil},
+ {[]string{"-j1234"}, 1234, -1, nil},
+
+ {[]string{"-j", "1"}, 1, -1, nil},
+ {[]string{"-j", "1234"}, 1234, -1, nil},
+ {[]string{"-j", "1234", "abc"}, 1234, -1, []string{"abc"}},
+ {[]string{"-j", "abc"}, -1, -1, []string{"abc"}},
+ {[]string{"-j", "1abc"}, -1, -1, []string{"1abc"}},
+
+ {[]string{"-k"}, -1, 0, nil},
+ {[]string{"-k0"}, -1, 0, nil},
+ {[]string{"-k1"}, -1, 1, nil},
+ {[]string{"-k1234"}, -1, 1234, nil},
+
+ {[]string{"-k", "0"}, -1, 0, nil},
+ {[]string{"-k", "1"}, -1, 1, nil},
+ {[]string{"-k", "1234"}, -1, 1234, nil},
+ {[]string{"-k", "1234", "abc"}, -1, 1234, []string{"abc"}},
+ {[]string{"-k", "abc"}, -1, 0, []string{"abc"}},
+ {[]string{"-k", "1abc"}, -1, 0, []string{"1abc"}},
+
+ // TODO: These are supported in Make, should we support them?
+ //{[]string{"-kj"}, -1, 0},
+ //{[]string{"-kj8"}, 8, 0},
+
+ // -jk is not valid in Make
+ }
+
+ for _, tc := range testCases {
+ t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
+ defer logger.Recover(func(err error) {
+ t.Fatal(err)
+ })
+
+ c := &configImpl{
+ parallel: -1,
+ keepGoing: -1,
+ }
+ c.parseArgs(ctx, tc.args)
+
+ if c.parallel != tc.parallel {
+ t.Errorf("for %q, parallel:\nwant: %d\n got: %d\n",
+ strings.Join(tc.args, " "),
+ tc.parallel, c.parallel)
+ }
+ if c.keepGoing != tc.keepGoing {
+ t.Errorf("for %q, keep going:\nwant: %d\n got: %d\n",
+ strings.Join(tc.args, " "),
+ tc.keepGoing, c.keepGoing)
+ }
+ if !reflect.DeepEqual(c.arguments, tc.remaining) {
+ t.Errorf("for %q, remaining arguments:\nwant: %q\n got: %q\n",
+ strings.Join(tc.args, " "),
+ tc.remaining, c.arguments)
+ }
+ })
+ }
+}
+
+func TestConfigParseArgsVars(t *testing.T) {
+ ctx := testContext()
+
+ testCases := []struct {
+ env []string
+ args []string
+
+ expectedEnv []string
+ remaining []string
+ }{
+ {},
+ {
+ env: []string{"A=bc"},
+
+ expectedEnv: []string{"A=bc"},
+ },
+ {
+ args: []string{"abc"},
+
+ remaining: []string{"abc"},
+ },
+
+ {
+ args: []string{"A=bc"},
+
+ expectedEnv: []string{"A=bc"},
+ },
+ {
+ env: []string{"A=a"},
+ args: []string{"A=bc"},
+
+ expectedEnv: []string{"A=bc"},
+ },
+
+ {
+ env: []string{"A=a"},
+ args: []string{"A=", "=b"},
+
+ expectedEnv: []string{"A="},
+ remaining: []string{"=b"},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
+ defer logger.Recover(func(err error) {
+ t.Fatal(err)
+ })
+
+ e := Environment(tc.env)
+ c := &configImpl{
+ environ: &e,
+ }
+ c.parseArgs(ctx, tc.args)
+
+ if !reflect.DeepEqual([]string(*c.environ), tc.expectedEnv) {
+ t.Errorf("for env=%q args=%q, environment:\nwant: %q\n got: %q\n",
+ tc.env, tc.args,
+ tc.expectedEnv, []string(*c.environ))
+ }
+ if !reflect.DeepEqual(c.arguments, tc.remaining) {
+ t.Errorf("for env=%q args=%q, remaining arguments:\nwant: %q\n got: %q\n",
+ tc.env, tc.args,
+ tc.remaining, c.arguments)
+ }
+ })
+ }
+}
diff --git a/ui/build/java.go b/ui/build/java.go
deleted file mode 100644
index 473af01..0000000
--- a/ui/build/java.go
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2017 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package build
-
-import (
- "regexp"
- "runtime"
- "strings"
- "sync"
-)
-
-const incompatibleJavacStr = "google"
-
-var javaVersionInfo = struct {
- once sync.Once
- startOnce sync.Once
-
- java_version_output string
- javac_version_output string
-}{}
-
-func getJavaVersions(ctx Context, config Config) {
- javaVersionInfo.startOnce.Do(func() {
- go func() {
- if ctx.Tracer != nil {
- thread := ctx.Tracer.NewThread("java_version")
- ctx.Tracer.Begin("get version", thread)
- defer ctx.Tracer.End(thread)
- }
-
- getJavaVersionsImpl(ctx, config)
- }()
- })
-}
-
-func getJavaVersionsImpl(ctx Context, config Config) {
- javaVersionInfo.once.Do(func() {
- cmd := Command(ctx, config, "java", "java", "-version")
- cmd.Environment.Unset("_JAVA_OPTIONS")
- javaVersionInfo.java_version_output = string(cmd.CombinedOutputOrFatal())
-
- cmd = Command(ctx, config, "javac", "javac", "-version")
- cmd.Environment.Unset("_JAVA_OPTIONS")
- javaVersionInfo.javac_version_output = string(cmd.CombinedOutputOrFatal())
- })
-}
-
-func checkJavaVersion(ctx Context, config Config) {
- ctx.BeginTrace("java_version_check")
- defer ctx.EndTrace()
-
- getJavaVersionsImpl(ctx, config)
-
- var required_java_version string
- var java_version_regexp *regexp.Regexp
- var javac_version_regexp *regexp.Regexp
-
- oj9_env, _ := config.Environment().Get("EXPERIMENTAL_USE_OPENJDK9")
- experimental_use_openjdk9 := oj9_env != ""
-
- if experimental_use_openjdk9 {
- required_java_version = "9"
- java_version_regexp = regexp.MustCompile(`^java .* "9.*"`)
- javac_version_regexp = regexp.MustCompile(`^javac 9`)
- } else {
- required_java_version = "1.8"
- java_version_regexp = regexp.MustCompile(`[ "]1\.8[\. "$]`)
- javac_version_regexp = java_version_regexp
- }
-
- java_version := javaVersionInfo.java_version_output
- javac_version := javaVersionInfo.javac_version_output
-
- found := false
- for _, l := range strings.Split(java_version, "\n") {
- if java_version_regexp.MatchString(l) {
- java_version = l
- found = true
- break
- }
- }
- if !found {
- ctx.Println("***************************************************************")
- ctx.Println("You are attempting to build with the incorrect version of java.")
- ctx.Println()
- ctx.Println("Your version is:", java_version)
- ctx.Println("The required version is:", required_java_version+".x")
- ctx.Println()
- ctx.Println("Please follow the machine setup instructions at:")
- ctx.Println(" https://source.android.com/source/initializing.html")
- ctx.Println("***************************************************************")
- ctx.Fatalln("stop")
- }
-
- if runtime.GOOS == "linux" {
- // Early access builds of OpenJDK 9 do not contain the string "openjdk" in the
- // version name. TODO(tobiast): Reconsider once the OpenJDK 9 toolchain is stable.
- // http://b/62123342
- if !strings.Contains(java_version, "openjdk") && !experimental_use_openjdk9 {
- ctx.Println("*******************************************************")
- ctx.Println("You are attempting to build with an unsupported JDK.")
- ctx.Println()
- ctx.Println("Only an OpenJDK based JDK is supported.")
- ctx.Println()
- ctx.Println("Please follow the machine setup instructions at:")
- ctx.Println(" https://source.android.com/source/initializing.html")
- ctx.Println("*******************************************************")
- ctx.Fatalln("stop")
- }
- } else { // darwin
- if strings.Contains(java_version, "openjdk") {
- ctx.Println("*******************************************************")
- ctx.Println("You are attempting to build with an unsupported JDK.")
- ctx.Println()
- ctx.Println("You use OpenJDK, but only Sun/Oracle JDK is supported.")
- ctx.Println()
- ctx.Println("Please follow the machine setup instructions at:")
- ctx.Println(" https://source.android.com/source/initializing.html")
- ctx.Println("*******************************************************")
- ctx.Fatalln("stop")
- }
- }
-
- incompatible_javac := strings.Contains(javac_version, incompatibleJavacStr)
-
- found = false
- for _, l := range strings.Split(javac_version, "\n") {
- if javac_version_regexp.MatchString(l) {
- javac_version = l
- found = true
- break
- }
- }
- if !found || incompatible_javac {
- ctx.Println("****************************************************************")
- ctx.Println("You are attempting to build with the incorrect version of javac.")
- ctx.Println()
- ctx.Println("Your version is:", javac_version)
- if incompatible_javac {
- ctx.Println("The '" + incompatibleJavacStr + "' version is not supported for Android platform builds.")
- ctx.Println("Use a publically available JDK and make sure you have run envsetup.sh / lunch.")
- } else {
- ctx.Println("The required version is:", required_java_version)
- }
- ctx.Println()
- ctx.Println("Please follow the machine setup instructions at:")
- ctx.Println(" https://source.android.com/source/initializing.html")
- ctx.Println("****************************************************************")
- ctx.Fatalln("stop")
- }
-}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index ddfe666..d242805 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -24,6 +24,7 @@
cmd := Command(ctx, config, "soong bootstrap", "./bootstrap.bash")
cmd.Environment.Set("BUILDDIR", config.SoongOutDir())
+ cmd.Environment.Set("NINJA_BUILDDIR", config.OutDir())
cmd.Sandbox = soongSandbox
cmd.Stdout = ctx.Stdout()
cmd.Stderr = ctx.Stderr()
diff --git a/ui/tracer/Android.bp b/ui/tracer/Android.bp
index 89812a1..9729c7e 100644
--- a/ui/tracer/Android.bp
+++ b/ui/tracer/Android.bp
@@ -17,6 +17,7 @@
pkgPath: "android/soong/ui/tracer",
deps: ["soong-ui-logger"],
srcs: [
+ "microfactory.go",
"ninja.go",
"tracer.go",
],
diff --git a/ui/tracer/microfactory.go b/ui/tracer/microfactory.go
new file mode 100644
index 0000000..320d9d8
--- /dev/null
+++ b/ui/tracer/microfactory.go
@@ -0,0 +1,63 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tracer
+
+import (
+ "bufio"
+ "os"
+ "strconv"
+ "strings"
+)
+
+func (t *tracerImpl) ImportMicrofactoryLog(filename string) {
+ if _, err := os.Stat(filename); err != nil {
+ return
+ }
+
+ f, err := os.Open(filename)
+ if err != nil {
+ t.log.Println("Error opening microfactory trace:", err)
+ return
+ }
+ defer f.Close()
+
+ entries := []*eventEntry{}
+ begin := map[string][]uint64{}
+ s := bufio.NewScanner(f)
+ for s.Scan() {
+ fields := strings.SplitN(s.Text(), " ", 3)
+ if len(fields) != 3 {
+ t.log.Verboseln("Unknown line in microfactory trace:", s.Text())
+ continue
+ }
+ timestamp, err := strconv.ParseUint(fields[0], 10, 64)
+ if err != nil {
+ t.log.Verboseln("Failed to parse timestamp in microfactory trace:", err)
+ }
+
+ if fields[1] == "B" {
+ begin[fields[2]] = append(begin[fields[2]], timestamp)
+ } else if beginTimestamps, ok := begin[fields[2]]; ok {
+ entries = append(entries, &eventEntry{
+ Name: fields[2],
+ Begin: beginTimestamps[len(beginTimestamps)-1],
+ End: timestamp,
+ })
+ begin[fields[2]] = beginTimestamps[:len(beginTimestamps)-1]
+ }
+ }
+
+ t.importEvents(entries)
+}
diff --git a/ui/tracer/ninja.go b/ui/tracer/ninja.go
index da558f1..1980559 100644
--- a/ui/tracer/ninja.go
+++ b/ui/tracer/ninja.go
@@ -23,16 +23,42 @@
"time"
)
-type ninjaLogEntry struct {
+type eventEntry struct {
Name string
- Begin int
- End int
+ Begin uint64
+ End uint64
}
-type ninjaLogEntries []*ninjaLogEntry
-func (n ninjaLogEntries) Len() int { return len(n) }
-func (n ninjaLogEntries) Less(i, j int) bool { return n[i].Begin < n[j].Begin }
-func (n ninjaLogEntries) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
+func (t *tracerImpl) importEvents(entries []*eventEntry) {
+ sort.Slice(entries, func(i, j int) bool {
+ return entries[i].Begin < entries[j].Begin
+ })
+
+ cpus := []uint64{}
+ for _, entry := range entries {
+ tid := -1
+ for cpu, endTime := range cpus {
+ if endTime <= entry.Begin {
+ tid = cpu
+ cpus[cpu] = entry.End
+ break
+ }
+ }
+ if tid == -1 {
+ tid = len(cpus)
+ cpus = append(cpus, entry.End)
+ }
+
+ t.writeEvent(&viewerEvent{
+ Name: entry.Name,
+ Phase: "X",
+ Time: entry.Begin,
+ Dur: entry.End - entry.Begin,
+ Pid: 1,
+ Tid: uint64(tid),
+ })
+ }
+}
// ImportNinjaLog reads a .ninja_log file from ninja and writes the events out
// to the trace.
@@ -61,8 +87,9 @@
s := bufio.NewScanner(f)
header := true
- entries := ninjaLogEntries{}
+ entries := []*eventEntry{}
prevEnd := 0
+ offset := uint64(startOffset.UnixNano()) / 1000
for s.Scan() {
if header {
hdr := s.Text()
@@ -89,10 +116,10 @@
entries = nil
}
prevEnd = end
- entries = append(entries, &ninjaLogEntry{
+ entries = append(entries, &eventEntry{
Name: fields[3],
- Begin: begin,
- End: end,
+ Begin: offset + uint64(begin)*1000,
+ End: offset + uint64(end)*1000,
})
}
if err := s.Err(); err != nil {
@@ -100,31 +127,5 @@
return
}
- sort.Sort(entries)
-
- cpus := []int{}
- offset := uint64(startOffset.UnixNano()) / 1000
- for _, entry := range entries {
- tid := -1
- for cpu, endTime := range cpus {
- if endTime <= entry.Begin {
- tid = cpu
- cpus[cpu] = entry.End
- break
- }
- }
- if tid == -1 {
- tid = len(cpus)
- cpus = append(cpus, entry.End)
- }
-
- t.writeEvent(&viewerEvent{
- Name: entry.Name,
- Phase: "X",
- Time: offset + uint64(entry.Begin)*1000,
- Dur: uint64(entry.End-entry.Begin) * 1000,
- Pid: 1,
- Tid: uint64(tid),
- })
- }
+ t.importEvents(entries)
}
diff --git a/ui/tracer/tracer.go b/ui/tracer/tracer.go
index f19ac18..8705040 100644
--- a/ui/tracer/tracer.go
+++ b/ui/tracer/tracer.go
@@ -45,6 +45,7 @@
End(thread Thread)
Complete(name string, thread Thread, begin, end uint64)
+ ImportMicrofactoryLog(filename string)
ImportNinjaLog(thread Thread, filename string, startOffset time.Time)
NewThread(name string) Thread