Merge "build: Link the unwinder dynamically into platform and vendor binaries."
diff --git a/Android.bp b/Android.bp
index 45180c3..ab03a36 100644
--- a/Android.bp
+++ b/Android.bp
@@ -69,6 +69,7 @@
"android/proto.go",
"android/register.go",
"android/rule_builder.go",
+ "android/sandbox.go",
"android/sdk.go",
"android/sh_binary.go",
"android/singleton.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index f3c15e4..dbf3aa8 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -323,7 +323,7 @@
return
}
- err := translateAndroidMk(ctx, transMk.String(), androidMkModulesList)
+ err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
if err != nil {
ctx.Errorf(err.Error())
}
@@ -364,8 +364,8 @@
}
// Don't write to the file if it hasn't changed
- if _, err := os.Stat(mkFile); !os.IsNotExist(err) {
- if data, err := ioutil.ReadFile(mkFile); err == nil {
+ if _, err := os.Stat(absolutePath(mkFile)); !os.IsNotExist(err) {
+ if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil {
matches := buf.Len() == len(data)
if matches {
@@ -383,7 +383,7 @@
}
}
- return ioutil.WriteFile(mkFile, buf.Bytes(), 0666)
+ return ioutil.WriteFile(absolutePath(mkFile), buf.Bytes(), 0666)
}
func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
diff --git a/android/apex.go b/android/apex.go
index 8482dc2..a4b6956 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -82,7 +82,10 @@
}
type ApexProperties struct {
- // Availability of this module in APEXes. Only the listed APEXes can include this module.
+ // Availability of this module in APEXes. Only the listed APEXes can contain
+ // this module. If the module has stubs then other APEXes and the platform may
+ // access it through them (subject to visibility).
+ //
// "//apex_available:anyapex" is a pseudo APEX name that matches to any APEX.
// "//apex_available:platform" refers to non-APEX partitions like "system.img".
// Default is ["//apex_available:platform", "//apex_available:anyapex"].
@@ -144,9 +147,9 @@
func CheckAvailableForApex(what string, apex_available []string) bool {
if len(apex_available) == 0 {
- // apex_available defaults to ["//apex_available:platform", "//apex_available:anyapex"],
- // which means 'available to everybody'.
- return true
+ // apex_available defaults to ["//apex_available:platform"],
+ // which means 'available to the platform but no apexes'.
+ return what == AvailableToPlatform
}
return InList(what, apex_available) ||
(what != AvailableToPlatform && InList(availableToAnyApex, apex_available))
diff --git a/android/config.go b/android/config.go
index 101f457..1cb543d 100644
--- a/android/config.go
+++ b/android/config.go
@@ -135,12 +135,12 @@
}
func loadConfig(config *config) error {
- err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName)
+ err := loadFromConfigFile(&config.FileConfigurableOptions, absolutePath(config.ConfigFileName))
if err != nil {
return err
}
- return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName)
+ return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName))
}
// loads configuration options from a JSON file in the cwd.
@@ -204,6 +204,17 @@
return nil
}
+// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that
+// use the android package.
+func NullConfig(buildDir string) Config {
+ return Config{
+ config: &config{
+ buildDir: buildDir,
+ fs: pathtools.OsFs,
+ },
+ }
+}
+
// TestConfig returns a Config object suitable for using for tests
func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config {
envCopy := make(map[string]string)
@@ -320,7 +331,7 @@
buildDir: buildDir,
multilibConflicts: make(map[ArchType]bool),
- fs: pathtools.OsFs,
+ fs: pathtools.NewOsFs(absSrcDir),
}
config.deviceConfig = &deviceConfig{
@@ -350,7 +361,7 @@
}
inMakeFile := filepath.Join(buildDir, ".soong.in_make")
- if _, err := os.Stat(inMakeFile); err == nil {
+ if _, err := os.Stat(absolutePath(inMakeFile)); err == nil {
config.inMake = true
}
@@ -398,6 +409,8 @@
return Config{config}, nil
}
+var TestConfigOsFs = map[string][]byte{}
+
// mockFileSystem replaces all reads with accesses to the provided map of
// filenames to contents stored as a byte slice.
func (c *config) mockFileSystem(bp string, fs map[string][]byte) {
@@ -822,6 +835,14 @@
return c.Getenv("XREF_CORPUS")
}
+// Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'.
+func (c *config) XrefCuEncoding() string {
+ if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" {
+ return enc
+ }
+ return "json"
+}
+
func (c *config) EmitXrefRules() bool {
return c.XrefCorpusName() != ""
}
@@ -901,8 +922,13 @@
return c.productVariables.BootJars
}
-func (c *config) DexpreoptGlobalConfig() string {
- return String(c.productVariables.DexpreoptGlobalConfig)
+func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) {
+ if c.productVariables.DexpreoptGlobalConfig == nil {
+ return nil, nil
+ }
+ path := absolutePath(*c.productVariables.DexpreoptGlobalConfig)
+ ctx.AddNinjaFileDeps(path)
+ return ioutil.ReadFile(path)
}
func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
diff --git a/android/env.go b/android/env.go
index d9f2db2..46bd3d6 100644
--- a/android/env.go
+++ b/android/env.go
@@ -52,6 +52,17 @@
os.Clearenv()
}
+// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
+// function above. It doesn't add any dependencies on the environment variable, so it should
+// only be used for values that won't change. For values that might change use ctx.Config().Getenv.
+func getenv(key string) string {
+ if originalEnv == nil {
+ return os.Getenv(key)
+ } else {
+ return originalEnv[key]
+ }
+}
+
func EnvSingleton() Singleton {
return &envSingleton{}
}
@@ -66,7 +77,12 @@
return
}
- err := env.WriteEnvFile(envFile.String(), envDeps)
+ data, err := env.EnvFileContents(envDeps)
+ if err != nil {
+ ctx.Errorf(err.Error())
+ }
+
+ err = WriteFileToOutputDir(envFile, data, 0666)
if err != nil {
ctx.Errorf(err.Error())
}
diff --git a/android/makevars.go b/android/makevars.go
index 38a028c..aba4cce 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -23,7 +23,6 @@
"strings"
"github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -41,7 +40,6 @@
Config() Config
DeviceConfig() DeviceConfig
AddNinjaFileDeps(deps ...string)
- Fs() pathtools.FileSystem
ModuleName(module blueprint.Module) string
ModuleDir(module blueprint.Module) string
@@ -151,7 +149,8 @@
return
}
- outFile := PathForOutput(ctx, "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String()
+ outFile := absolutePath(PathForOutput(ctx,
+ "make_vars"+proptools.String(ctx.Config().productVariables.Make_suffix)+".mk").String())
if ctx.Failed() {
return
@@ -175,15 +174,15 @@
outBytes := s.writeVars(vars)
- if _, err := os.Stat(outFile); err == nil {
- if data, err := ioutil.ReadFile(outFile); err == nil {
+ if _, err := os.Stat(absolutePath(outFile)); err == nil {
+ if data, err := ioutil.ReadFile(absolutePath(outFile)); err == nil {
if bytes.Equal(data, outBytes) {
return
}
}
}
- if err := ioutil.WriteFile(outFile, outBytes, 0666); err != nil {
+ if err := ioutil.WriteFile(absolutePath(outFile), outBytes, 0666); err != nil {
ctx.Errorf(err.Error())
}
}
diff --git a/android/module.go b/android/module.go
index c998007..05115d6 100644
--- a/android/module.go
+++ b/android/module.go
@@ -16,13 +16,13 @@
import (
"fmt"
+ "os"
"path"
"path/filepath"
"strings"
"text/scanner"
"github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -91,7 +91,8 @@
Glob(globPattern string, excludes []string) Paths
GlobFiles(globPattern string, excludes []string) Paths
- Fs() pathtools.FileSystem
+ IsSymlink(path Path) bool
+ Readlink(path Path) string
}
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
@@ -1172,6 +1173,22 @@
return pathsForModuleSrcFromFullPath(e, ret, false)
}
+func (b *earlyModuleContext) IsSymlink(path Path) bool {
+ fileInfo, err := b.config.fs.Lstat(path.String())
+ if err != nil {
+ b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
+ }
+ return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
+}
+
+func (b *earlyModuleContext) Readlink(path Path) string {
+ dest, err := b.config.fs.Readlink(path.String())
+ if err != nil {
+ b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
+ }
+ return dest
+}
+
func (e *earlyModuleContext) Module() Module {
module, _ := e.EarlyModuleContext.Module().(Module)
return module
@@ -1729,7 +1746,7 @@
Rule: Symlink,
Description: "install symlink " + fullInstallPath.Base(),
Output: fullInstallPath,
- OrderOnly: Paths{srcPath},
+ Input: srcPath,
Default: !m.Config().EmbeddedInMake(),
Args: map[string]string{
"fromPath": relPath,
diff --git a/android/mutator.go b/android/mutator.go
index f2f9663..3d1bb4f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -27,6 +27,7 @@
// run Pre-deps mutators
// run depsMutator
// run PostDeps mutators
+// run FinalDeps mutators (CreateVariations disallowed in this phase)
// continue on to GenerateAndroidBuildActions
func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) {
@@ -43,7 +44,7 @@
}
}
-func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) {
+func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc) {
mctx := ®isterMutatorsContext{}
register := func(funcs []RegisterMutatorFunc) {
@@ -60,11 +61,15 @@
register(postDeps)
+ mctx.finalPhase = true
+ register(finalDeps)
+
registerMutatorsToContext(ctx, mctx.mutators)
}
type registerMutatorsContext struct {
- mutators []*mutator
+ mutators []*mutator
+ finalPhase bool
}
type RegisterMutatorsContext interface {
@@ -102,6 +107,8 @@
RegisterOverridePostDepsMutators,
}
+var finalDeps = []RegisterMutatorFunc{}
+
func PreArchMutators(f RegisterMutatorFunc) {
preArch = append(preArch, f)
}
@@ -114,6 +121,10 @@
postDeps = append(postDeps, f)
}
+func FinalDepsMutators(f RegisterMutatorFunc) {
+ finalDeps = append(finalDeps, f)
+}
+
type TopDownMutator func(TopDownMutatorContext)
type TopDownMutatorContext interface {
@@ -156,14 +167,17 @@
type bottomUpMutatorContext struct {
bp blueprint.BottomUpMutatorContext
baseModuleContext
+ finalPhase bool
}
func (x *registerMutatorsContext) BottomUp(name string, m BottomUpMutator) MutatorHandle {
+ finalPhase := x.finalPhase
f := func(ctx blueprint.BottomUpMutatorContext) {
if a, ok := ctx.Module().(Module); ok {
actx := &bottomUpMutatorContext{
bp: ctx,
baseModuleContext: a.base().baseModuleContextFactory(ctx),
+ finalPhase: finalPhase,
}
m(actx)
}
@@ -285,6 +299,10 @@
}
func (b *bottomUpMutatorContext) CreateVariations(variations ...string) []Module {
+ if b.finalPhase {
+ panic("CreateVariations not allowed in FinalDepsMutators")
+ }
+
modules := b.bp.CreateVariations(variations...)
aModules := make([]Module, len(modules))
@@ -299,6 +317,10 @@
}
func (b *bottomUpMutatorContext) CreateLocalVariations(variations ...string) []Module {
+ if b.finalPhase {
+ panic("CreateLocalVariations not allowed in FinalDepsMutators")
+ }
+
modules := b.bp.CreateLocalVariations(variations...)
aModules := make([]Module, len(modules))
diff --git a/android/mutator_test.go b/android/mutator_test.go
index d179f9d..191b535 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -15,9 +15,12 @@
package android
import (
+ "fmt"
"reflect"
+ "strings"
"testing"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -185,3 +188,110 @@
t.Errorf("want module String() values:\n%q\ngot:\n%q", want, moduleStrings)
}
}
+
+func TestFinalDepsPhase(t *testing.T) {
+ ctx := NewTestContext()
+
+ finalGot := map[string]int{}
+
+ dep1Tag := struct {
+ blueprint.BaseDependencyTag
+ }{}
+ dep2Tag := struct {
+ blueprint.BaseDependencyTag
+ }{}
+
+ ctx.PostDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("far_deps_1", func(ctx BottomUpMutatorContext) {
+ if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep1Tag, "common_dep_1")
+ }
+ })
+ ctx.BottomUp("variant", func(ctx BottomUpMutatorContext) {
+ ctx.CreateLocalVariations("a", "b")
+ })
+ })
+
+ ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("far_deps_2", func(ctx BottomUpMutatorContext) {
+ if !strings.HasPrefix(ctx.ModuleName(), "common_dep") {
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, dep2Tag, "common_dep_2")
+ }
+ })
+ ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
+ finalGot[ctx.Module().String()] += 1
+ ctx.VisitDirectDeps(func(mod Module) {
+ finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
+ })
+ })
+ })
+
+ ctx.RegisterModuleType("test", mutatorTestModuleFactory)
+
+ bp := `
+ test {
+ name: "common_dep_1",
+ }
+ test {
+ name: "common_dep_2",
+ }
+ test {
+ name: "foo",
+ }
+ `
+
+ config := TestConfig(buildDir, nil, bp, nil)
+ ctx.Register(config)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+
+ finalWant := map[string]int{
+ "common_dep_1{variant:a}": 1,
+ "common_dep_1{variant:b}": 1,
+ "common_dep_2{variant:a}": 1,
+ "common_dep_2{variant:b}": 1,
+ "foo{variant:a}": 1,
+ "foo{variant:a} -> common_dep_1{variant:a}": 1,
+ "foo{variant:a} -> common_dep_2{variant:a}": 1,
+ "foo{variant:b}": 1,
+ "foo{variant:b} -> common_dep_1{variant:b}": 1,
+ "foo{variant:b} -> common_dep_2{variant:a}": 1,
+ }
+
+ if !reflect.DeepEqual(finalWant, finalGot) {
+ t.Errorf("want:\n%q\ngot:\n%q", finalWant, finalGot)
+ }
+}
+
+func TestNoCreateVariationsInFinalDeps(t *testing.T) {
+ ctx := NewTestContext()
+
+ checkErr := func() {
+ if err := recover(); err == nil || !strings.Contains(fmt.Sprintf("%s", err), "not allowed in FinalDepsMutators") {
+ panic("Expected FinalDepsMutators consistency check to fail")
+ }
+ }
+
+ ctx.FinalDepsMutators(func(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("vars", func(ctx BottomUpMutatorContext) {
+ defer checkErr()
+ ctx.CreateVariations("a", "b")
+ })
+ ctx.BottomUp("local_vars", func(ctx BottomUpMutatorContext) {
+ defer checkErr()
+ ctx.CreateLocalVariations("a", "b")
+ })
+ })
+
+ ctx.RegisterModuleType("test", mutatorTestModuleFactory)
+ config := TestConfig(buildDir, nil, `test {name: "foo"}`, nil)
+ ctx.Register(config)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ FailIfErrored(t, errs)
+}
diff --git a/android/override_module.go b/android/override_module.go
index 5bc787b..9f5127d 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -121,13 +121,13 @@
// override information is propagated and aggregated correctly.
overridesProperty *[]string
- properties overridableModuleProperties
+ overridableModuleProperties overridableModuleProperties
}
func InitOverridableModule(m OverridableModule, overridesProperty *[]string) {
m.setOverridableProperties(m.(Module).GetProperties())
m.setOverridesProperty(overridesProperty)
- m.AddProperties(&m.moduleBase().properties)
+ m.AddProperties(&m.moduleBase().overridableModuleProperties)
}
func (o *OverridableModuleBase) moduleBase() *OverridableModuleBase {
@@ -174,7 +174,7 @@
if b.overridesProperty != nil {
*b.overridesProperty = append(*b.overridesProperty, ctx.ModuleName())
}
- b.properties.OverriddenBy = o.Name()
+ b.overridableModuleProperties.OverriddenBy = o.Name()
}
// GetOverriddenBy returns the name of the override module that has overridden this module.
@@ -182,7 +182,7 @@
// of bar is created and its properties are overriden by foo. This method returns bar when called from
// the new local variant. It returns "" when called from the original variant of bar.
func (b *OverridableModuleBase) GetOverriddenBy() string {
- return b.properties.OverriddenBy
+ return b.overridableModuleProperties.OverriddenBy
}
func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMutatorContext) {
diff --git a/android/package.go b/android/package.go
index ed604c6..077c4a4 100644
--- a/android/package.go
+++ b/android/package.go
@@ -22,7 +22,19 @@
)
func init() {
- RegisterModuleType("package", PackageFactory)
+ RegisterPackageBuildComponents(InitRegistrationContext)
+}
+
+// Register the package module type and supporting mutators.
+//
+// This must be called in the correct order (relative to other methods that also
+// register mutators) to match the order of mutator registration in mutator.go.
+// Failing to do so will result in an unrealistic test environment.
+func RegisterPackageBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("package", PackageFactory)
+
+ // Register mutators that are hard coded in to mutator.go.
+ ctx.HardCodedPreArchMutators(RegisterPackageRenamer)
}
// The information maintained about each package.
diff --git a/android/package_ctx.go b/android/package_ctx.go
index d3527fa..a228910 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -19,7 +19,6 @@
"strings"
"github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
)
// PackageContext is a wrapper for blueprint.PackageContext that adds
@@ -60,10 +59,6 @@
e.pctx.AddNinjaFileDeps(deps...)
}
-func (e *configErrorWrapper) Fs() pathtools.FileSystem {
- return nil
-}
-
type PackageVarContext interface {
PathContext
errorfContext
diff --git a/android/package_test.go b/android/package_test.go
index bc66928..4710e39 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -87,8 +87,7 @@
config := TestArchConfig(buildDir, nil, "", fs)
ctx := NewTestArchContext()
- ctx.RegisterModuleType("package", PackageFactory)
- ctx.PreArchMutators(RegisterPackageRenamer)
+ RegisterPackageBuildComponents(ctx)
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles(".")
diff --git a/android/paths.go b/android/paths.go
index a03fe17..02f56d0 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -16,6 +16,8 @@
import (
"fmt"
+ "io/ioutil"
+ "os"
"path/filepath"
"reflect"
"sort"
@@ -25,10 +27,11 @@
"github.com/google/blueprint/pathtools"
)
+var absSrcDir string
+
// PathContext is the subset of a (Module|Singleton)Context required by the
// Path methods.
type PathContext interface {
- Fs() pathtools.FileSystem
Config() Config
AddNinjaFileDeps(deps ...string)
}
@@ -390,7 +393,7 @@
return PathsWithModuleSrcSubDir(ctx, paths, ""), nil
} else {
p := pathForModuleSrc(ctx, s)
- if exists, _, err := ctx.Fs().Exists(p.String()); err != nil {
+ if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
reportPathErrorf(ctx, "%s: %s", p, err.Error())
} else if !exists {
reportPathErrorf(ctx, "module source path %q does not exist", p)
@@ -720,7 +723,7 @@
var deps []string
// We cannot add build statements in this context, so we fall back to
// AddNinjaFileDeps
- files, deps, err = pathtools.Glob(path.String(), nil, pathtools.FollowSymlinks)
+ files, deps, err = ctx.Config().fs.Glob(path.String(), nil, pathtools.FollowSymlinks)
ctx.AddNinjaFileDeps(deps...)
}
@@ -752,7 +755,7 @@
if !exists {
modCtx.AddMissingDependencies([]string{path.String()})
}
- } else if exists, _, err := ctx.Fs().Exists(path.String()); err != nil {
+ } else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
reportPathErrorf(ctx, "%s: %s", path, err.Error())
} else if !exists {
reportPathErrorf(ctx, "source path %q does not exist", path)
@@ -1356,7 +1359,6 @@
config Config
}
-func (x *testPathContext) Fs() pathtools.FileSystem { return x.config.fs }
func (x *testPathContext) Config() Config { return x.config }
func (x *testPathContext) AddNinjaFileDeps(...string) {}
@@ -1402,3 +1404,16 @@
}
return rel, true, nil
}
+
+// Writes a file to the output directory. Attempting to write directly to the output directory
+// will fail due to the sandbox of the soong_build process.
+func WriteFileToOutputDir(path WritablePath, data []byte, perm os.FileMode) error {
+ return ioutil.WriteFile(absolutePath(path.String()), data, perm)
+}
+
+func absolutePath(path string) string {
+ if filepath.IsAbs(path) {
+ return path
+ }
+ return filepath.Join(absSrcDir, path)
+}
diff --git a/android/paths_test.go b/android/paths_test.go
index ec5e598..46e3e1f 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -21,7 +21,6 @@
"strings"
"testing"
- "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -207,10 +206,6 @@
inRoot bool
}
-func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem {
- return pathtools.MockFs(nil)
-}
-
func (m moduleInstallPathContextImpl) Config() Config {
return m.baseModuleContext.config
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 2c99f1f..c780cb2 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -36,6 +36,9 @@
var PrebuiltDepTag prebuiltDependencyTag
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
+
type PrebuiltProperties struct {
// When prefer is set to true the prebuilt will be used instead of any source module with
// a matching name.
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 8648b93..8ff5c40 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -141,10 +141,8 @@
config := TestConfig(buildDir, nil, bp, fs)
ctx := NewTestContext()
- RegisterPrebuiltMutators(ctx)
+ registerTestPrebuiltBuildComponents(ctx)
ctx.RegisterModuleType("filegroup", FileGroupFactory)
- ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
- ctx.RegisterModuleType("source", newSourceModule)
ctx.Register(config)
_, errs := ctx.ParseBlueprintsFiles("Android.bp")
@@ -212,6 +210,13 @@
}
}
+func registerTestPrebuiltBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
+ ctx.RegisterModuleType("source", newSourceModule)
+
+ RegisterPrebuiltMutators(ctx)
+}
+
type prebuiltModule struct {
ModuleBase
prebuilt Prebuilt
diff --git a/android/register.go b/android/register.go
index b5defec..ccfe01e 100644
--- a/android/register.go
+++ b/android/register.go
@@ -84,7 +84,9 @@
}
func NewContext() *Context {
- return &Context{blueprint.NewContext()}
+ ctx := &Context{blueprint.NewContext()}
+ ctx.SetSrcDir(absSrcDir)
+ return ctx
}
func (ctx *Context) Register() {
@@ -100,7 +102,7 @@
ctx.RegisterSingletonType(t.name, t.factory)
}
- registerMutators(ctx.Context, preArch, preDeps, postDeps)
+ registerMutators(ctx.Context, preArch, preDeps, postDeps, finalDeps)
// Register makevars after other singletons so they can export values through makevars
ctx.RegisterSingletonType("makevars", SingletonFactoryAdaptor(makeVarsSingletonFunc))
@@ -125,8 +127,15 @@
RegisterModuleType(name string, factory ModuleFactory)
RegisterSingletonType(name string, factory SingletonFactory)
PreArchMutators(f RegisterMutatorFunc)
+
+ // Register pre arch mutators that are hard coded into mutator.go.
+ //
+ // Only registers mutators for testing, is a noop on the InitRegistrationContext.
+ HardCodedPreArchMutators(f RegisterMutatorFunc)
+
PreDepsMutators(f RegisterMutatorFunc)
PostDepsMutators(f RegisterMutatorFunc)
+ FinalDepsMutators(f RegisterMutatorFunc)
}
// Used to register build components from an init() method, e.g.
@@ -178,6 +187,10 @@
PreArchMutators(f)
}
+func (ctx *initRegistrationContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+ // Nothing to do as the mutators are hard code in preArch in mutator.go
+}
+
func (ctx *initRegistrationContext) PreDepsMutators(f RegisterMutatorFunc) {
PreDepsMutators(f)
}
@@ -185,3 +198,7 @@
func (ctx *initRegistrationContext) PostDepsMutators(f RegisterMutatorFunc) {
PostDepsMutators(f)
}
+
+func (ctx *initRegistrationContext) FinalDepsMutators(f RegisterMutatorFunc) {
+ FinalDepsMutators(f)
+}
diff --git a/android/sandbox.go b/android/sandbox.go
new file mode 100644
index 0000000..ed022fb
--- /dev/null
+++ b/android/sandbox.go
@@ -0,0 +1,47 @@
+// Copyright 2020 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"
+ "os"
+)
+
+func init() {
+ // Stash the working directory in a private variable and then change the working directory
+ // to "/", which will prevent untracked accesses to files by Go Soong plugins. The
+ // SOONG_SANDBOX_SOONG_BUILD environment variable is set by soong_ui, and is not
+ // overrideable on the command line.
+
+ orig, err := os.Getwd()
+ if err != nil {
+ panic(fmt.Errorf("failed to get working directory: %s", err))
+ }
+ absSrcDir = orig
+
+ if getenv("SOONG_SANDBOX_SOONG_BUILD") == "true" {
+ err = os.Chdir("/")
+ if err != nil {
+ panic(fmt.Errorf("failed to change working directory to '/': %s", err))
+ }
+ }
+}
+
+// DO NOT USE THIS FUNCTION IN NEW CODE.
+// Deprecated: This function will be removed as soon as the existing use cases that use it have been
+// replaced.
+func AbsSrcDirForExistingUseCases() string {
+ return absSrcDir
+}
diff --git a/android/singleton.go b/android/singleton.go
index 5519ca0..91268ad 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -16,7 +16,6 @@
import (
"github.com/google/blueprint"
- "github.com/google/blueprint/pathtools"
)
// SingletonContext
@@ -74,8 +73,6 @@
// builder whenever a file matching the pattern as added or removed, without rerunning if a
// file that does not match the pattern is added to a searched directory.
GlobWithDeps(pattern string, excludes []string) ([]string, error)
-
- Fs() pathtools.FileSystem
}
type singletonAdaptor struct {
diff --git a/android/testing.go b/android/testing.go
index 6663728..9aff039 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -50,15 +50,20 @@
type TestContext struct {
*Context
- preArch, preDeps, postDeps []RegisterMutatorFunc
- NameResolver *NameResolver
- config Config
+ preArch, preDeps, postDeps, finalDeps []RegisterMutatorFunc
+ NameResolver *NameResolver
+ config Config
}
func (ctx *TestContext) PreArchMutators(f RegisterMutatorFunc) {
ctx.preArch = append(ctx.preArch, f)
}
+func (ctx *TestContext) HardCodedPreArchMutators(f RegisterMutatorFunc) {
+ // Register mutator function as normal for testing.
+ ctx.PreArchMutators(f)
+}
+
func (ctx *TestContext) PreDepsMutators(f RegisterMutatorFunc) {
ctx.preDeps = append(ctx.preDeps, f)
}
@@ -67,12 +72,16 @@
ctx.postDeps = append(ctx.postDeps, f)
}
+func (ctx *TestContext) FinalDepsMutators(f RegisterMutatorFunc) {
+ ctx.finalDeps = append(ctx.finalDeps, f)
+}
+
func (ctx *TestContext) Register(config Config) {
ctx.SetFs(config.fs)
if config.mockBpList != "" {
ctx.SetModuleListFile(config.mockBpList)
}
- registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps)
+ registerMutators(ctx.Context.Context, ctx.preArch, ctx.preDeps, ctx.postDeps, ctx.finalDeps)
ctx.RegisterSingletonType("env", EnvSingleton)
diff --git a/android/visibility.go b/android/visibility.go
index c28ec93..a597687 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -19,6 +19,8 @@
"regexp"
"strings"
"sync"
+
+ "github.com/google/blueprint"
)
// Enforces visibility rules between modules.
@@ -190,6 +192,15 @@
}).(*sync.Map)
}
+// Marker interface that identifies dependencies that are excluded from visibility
+// enforcement.
+type ExcludeFromVisibilityEnforcementTag interface {
+ blueprint.DependencyTag
+
+ // Method that differentiates this interface from others.
+ ExcludeFromVisibilityEnforcement()
+}
+
// The rule checker needs to be registered before defaults expansion to correctly check that
// //visibility:xxx isn't combined with other packages in the same list in any one module.
func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
@@ -389,6 +400,12 @@
// Visit all the dependencies making sure that this module has access to them all.
ctx.VisitDirectDeps(func(dep Module) {
+ // Ignore dependencies that have an ExcludeFromVisibilityEnforcementTag
+ tag := ctx.OtherModuleDependencyTag(dep)
+ if _, ok := tag.(ExcludeFromVisibilityEnforcementTag); ok {
+ return
+ }
+
depName := ctx.OtherModuleName(dep)
depDir := ctx.OtherModuleDir(dep)
depQualified := qualifiedModuleName{depDir, depName}
diff --git a/android/visibility_test.go b/android/visibility_test.go
index fbf2fb7..6006072 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -853,6 +853,51 @@
` not visible to this module`,
},
},
+ {
+ name: "verify that prebuilt dependencies are ignored for visibility reasons (not preferred)",
+ fs: map[string][]byte{
+ "prebuilts/Blueprints": []byte(`
+ prebuilt {
+ name: "module",
+ visibility: ["//top/other"],
+ }`),
+ "top/sources/source_file": nil,
+ "top/sources/Blueprints": []byte(`
+ source {
+ name: "module",
+ visibility: ["//top/other"],
+ }`),
+ "top/other/source_file": nil,
+ "top/other/Blueprints": []byte(`
+ source {
+ name: "other",
+ deps: [":module"],
+ }`),
+ },
+ },
+ {
+ name: "verify that prebuilt dependencies are ignored for visibility reasons (preferred)",
+ fs: map[string][]byte{
+ "prebuilts/Blueprints": []byte(`
+ prebuilt {
+ name: "module",
+ visibility: ["//top/other"],
+ prefer: true,
+ }`),
+ "top/sources/source_file": nil,
+ "top/sources/Blueprints": []byte(`
+ source {
+ name: "module",
+ visibility: ["//top/other"],
+ }`),
+ "top/other/source_file": nil,
+ "top/other/Blueprints": []byte(`
+ source {
+ name: "other",
+ deps: [":module"],
+ }`),
+ },
+ },
}
func TestVisibility(t *testing.T) {
@@ -871,10 +916,12 @@
config := TestArchConfig(buildDir, nil, "", fs)
ctx := NewTestArchContext()
- ctx.RegisterModuleType("package", PackageFactory)
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
- ctx.PreArchMutators(RegisterPackageRenamer)
+
+ // Order of the following method calls is significant.
+ RegisterPackageBuildComponents(ctx)
+ registerTestPrebuiltBuildComponents(ctx)
ctx.PreArchMutators(RegisterVisibilityRuleChecker)
ctx.PreArchMutators(RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(RegisterVisibilityRuleGatherer)
diff --git a/androidmk/Android.bp b/androidmk/Android.bp
index 4110073..70fc1f7 100644
--- a/androidmk/Android.bp
+++ b/androidmk/Android.bp
@@ -41,7 +41,6 @@
"androidmk-parser",
"blueprint-parser",
"bpfix-lib",
- "soong-android",
],
}
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 0082d8b..8860984 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -15,9 +15,9 @@
package androidmk
import (
- "android/soong/android"
mkparser "android/soong/androidmk/parser"
"fmt"
+ "sort"
"strings"
bpparser "github.com/google/blueprint/parser"
@@ -350,7 +350,13 @@
return err
}
- for _, nameClassification := range android.SortedStringKeys(namesByClassification) {
+ var classifications []string
+ for classification := range namesByClassification {
+ classifications = append(classifications, classification)
+ }
+ sort.Strings(classifications)
+
+ for _, nameClassification := range classifications {
name := namesByClassification[nameClassification]
if component, ok := lists[nameClassification]; ok && !emptyList(component) {
err = setVariable(ctx.file, ctx.append, ctx.prefix, name, component, true)
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 9aa0894..ad7d2f1 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -117,6 +117,9 @@
fmt.Fprintln(w, "LOCAL_IS_HOST_MODULE := true")
}
}
+ if fi.jacocoReportClassesFile != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", fi.jacocoReportClassesFile.String())
+ }
if fi.class == javaSharedLib {
javaModule := fi.module.(javaLibrary)
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
@@ -128,6 +131,12 @@
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
+ } else if fi.class == app {
+ // soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk Therefore
+ // we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
+ // we will have foo.apk.apk
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".apk"))
+ fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
} else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
if cc, ok := fi.module.(*cc.Module); ok {
@@ -142,9 +151,19 @@
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
} else {
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
- // For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
- if a.primaryApexType && fi.builtFile == a.manifestPbOut && len(a.compatSymlinks) > 0 {
- fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+ if a.primaryApexType && fi.builtFile == a.manifestPbOut {
+ // Make apex_manifest.pb module for this APEX to override all other
+ // modules in the APEXes being overridden by this APEX
+ var patterns []string
+ for _, o := range a.overridableProperties.Overrides {
+ patterns = append(patterns, "%."+o+a.suffix)
+ }
+ fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES :=", strings.Join(patterns, " "))
+
+ if len(a.compatSymlinks) > 0 {
+ // For flattened apexes, compat symlinks are attached to apex_manifest.json which is guaranteed for every apex
+ fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD :=", strings.Join(a.compatSymlinks, " && "))
+ }
}
fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
}
@@ -207,8 +226,8 @@
if len(moduleNames) > 0 {
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
}
- if len(a.externalDeps) > 0 {
- fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.externalDeps, " "))
+ if len(a.requiredDeps) > 0 {
+ fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.requiredDeps, " "))
}
a.writeRequiredModules(w)
var postInstallCommands []string
@@ -226,6 +245,14 @@
if apexType == imageApex {
fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
}
+
+ if a.installedFilesFile != nil {
+ goal := "droidcore"
+ distFile := name + "-installed-files.txt"
+ fmt.Fprintln(w, ".PHONY:", goal)
+ fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n",
+ goal, a.installedFilesFile.String(), distFile)
+ }
}
}}
}
diff --git a/apex/apex.go b/apex/apex.go
index eb96142..33b1be3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -57,8 +57,249 @@
certificateTag = dependencyTag{name: "certificate"}
usesTag = dependencyTag{name: "uses"}
androidAppTag = dependencyTag{name: "androidApp"}
+ apexAvailWl = makeApexAvailableWhitelist()
)
+// This is a map from apex to modules, which overrides the
+// apex_available setting for that particular module to make
+// it available for the apex regardless of its setting.
+// TODO(b/147364041): remove this
+func makeApexAvailableWhitelist() map[string][]string {
+ // The "Module separator"s below are employed to minimize merge conflicts.
+ m := make(map[string][]string)
+ //
+ // Module separator
+ //
+ m["com.android.adbd"] = []string{"adbd", "libcrypto"}
+ //
+ // Module separator
+ //
+ m["com.android.art"] = []string{
+ "jacocoagent",
+ "libadbconnection_server",
+ "libartd-disassembler",
+ "libbacktrace",
+ "libbase",
+ "libc++",
+ "libcrypto",
+ "libdexfile_support",
+ "libexpat",
+ "libicuuc",
+ "liblzma",
+ "libmeminfo",
+ "libprocinfo",
+ "libunwindstack",
+ "libvixl",
+ "libvixld",
+ "libz",
+ "libziparchive",
+ "prebuilt_libclang_rt",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.bluetooth.updatable"] = []string{
+ "android.hardware.audio.common@5.0",
+ "android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
+ "android.hardware.bluetooth.a2dp@1.0",
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hidl.safe_union@1.0",
+ "libbase",
+ "libbinderthreadstate",
+ "libbluetooth",
+ "libbluetooth_jni",
+ "libc++",
+ "libchrome",
+ "libcrypto",
+ "libcutils",
+ "libevent",
+ "libfmq",
+ "libhidlbase",
+ "libprocessgroup",
+ "libprotobuf-cpp-lite",
+ "libstatslog",
+ "libtinyxml2",
+ "libutils",
+ "libz",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.conscrypt"] = []string{"boringssl_self_test", "libc++", "libcrypto", "libssl"}
+ //
+ // Module separator
+ //
+ m["com.android.cronet"] = []string{"org.chromium.net.cronet", "prebuilt_libcronet.80.0.3986.0"}
+ //
+ // Module separator
+ //
+ m["com.android.media"] = []string{
+ "android.hardware.cas@1.0",
+ "android.hardware.cas.native@1.0",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "android.hidl.memory.token@1.0",
+ "android.hidl.token@1.0",
+ "android.hidl.token@1.0-utils",
+ "libaacextractor",
+ "libamrextractor",
+ "libbase",
+ "libbinderthreadstate",
+ "libc++",
+ "libcrypto",
+ "libcutils",
+ "libflacextractor",
+ "libhidlbase",
+ "libhidlmemory",
+ "libmidiextractor",
+ "libmkvextractor",
+ "libmp3extractor",
+ "libmp4extractor",
+ "libmpeg2extractor",
+ "liboggextractor",
+ "libprocessgroup",
+ "libutils",
+ "libwavextractor",
+ "updatable-media",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.media.swcodec"] = []string{
+ "android.frameworks.bufferhub@1.0",
+ "android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
+ "android.hardware.configstore-utils",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.media@1.0",
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.omx@1.0",
+ "android.hidl.memory@1.0",
+ "android.hidl.memory.token@1.0",
+ "android.hidl.safe_union@1.0",
+ "android.hidl.token@1.0",
+ "android.hidl.token@1.0-utils",
+ "libavservices_minijail",
+ "libbacktrace",
+ "libbase",
+ "libbinderthreadstate",
+ "libc++",
+ "libcap",
+ "libcodec2",
+ "libcodec2_hidl@1.0",
+ "libcodec2_soft_aacdec",
+ "libcodec2_soft_aacenc",
+ "libcodec2_soft_amrnbdec",
+ "libcodec2_soft_amrnbenc",
+ "libcodec2_soft_amrwbdec",
+ "libcodec2_soft_amrwbenc",
+ "libcodec2_soft_av1dec_gav1",
+ "libcodec2_soft_avcdec",
+ "libcodec2_soft_avcenc",
+ "libcodec2_soft_common",
+ "libcodec2_soft_flacdec",
+ "libcodec2_soft_flacenc",
+ "libcodec2_soft_g711alawdec",
+ "libcodec2_soft_g711mlawdec",
+ "libcodec2_soft_gsmdec",
+ "libcodec2_soft_h263dec",
+ "libcodec2_soft_h263enc",
+ "libcodec2_soft_hevcdec",
+ "libcodec2_soft_hevcenc",
+ "libcodec2_soft_mp3dec",
+ "libcodec2_soft_mpeg2dec",
+ "libcodec2_soft_mpeg4dec",
+ "libcodec2_soft_mpeg4enc",
+ "libcodec2_soft_opusdec",
+ "libcodec2_soft_opusenc",
+ "libcodec2_soft_rawdec",
+ "libcodec2_soft_vorbisdec",
+ "libcodec2_soft_vp8dec",
+ "libcodec2_soft_vp8enc",
+ "libcodec2_soft_vp9dec",
+ "libcodec2_soft_vp9enc",
+ "libcodec2_vndk",
+ "libc_scudo",
+ "libcutils",
+ "libdexfile_support",
+ "libEGL",
+ "libfmq",
+ "libgraphicsenv",
+ "libhardware",
+ "libhidlbase",
+ "libhidlmemory",
+ "libion",
+ "liblzma",
+ "libmedia_codecserviceregistrant",
+ "libminijail",
+ "libnativebridge_lazy",
+ "libnativeloader_lazy",
+ "libopus",
+ "libprocessgroup",
+ "libscudo_wrapper",
+ "libsfplugin_ccodec_utils",
+ "libstagefright_amrnb_common",
+ "libstagefright_bufferpool@2.0.1",
+ "libstagefright_bufferqueue_helper",
+ "libstagefright_enc_common",
+ "libstagefright_flacdec",
+ "libstagefright_foundation",
+ "libsync",
+ "libui",
+ "libunwindstack",
+ "libutils",
+ "libvorbisidec",
+ "libvpx",
+ "mediaswcodec",
+ "prebuilt_libclang_rt",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.runtime"] = []string{
+ "libbase",
+ "libc++",
+ "libdexfile_support",
+ "liblzma",
+ "libunwindstack",
+ "prebuilt_libclang_rt",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.resolv"] = []string{"libcrypto", "libnetd_resolv", "libssl"}
+ //
+ // Module separator
+ //
+ m["com.android.tethering"] = []string{"libbase", "libc++", "libnativehelper_compat_libc++"}
+ //
+ // Module separator
+ //
+ m["com.android.vndk"] = []string{
+ "libbacktrace",
+ "libbinderthreadstate",
+ "libblas",
+ "libcompiler_rt",
+ "libgui",
+ "libunwind",
+ }
+ //
+ // Module separator
+ //
+ return m
+}
+
func init() {
android.RegisterModuleType("apex", BundleFactory)
android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -341,6 +582,8 @@
// Whether this APEX should support Android10. Default is false. If this is set true, then apex_manifest.json is bundled as well
// because Android10 requires legacy apex_manifest.json instead of apex_manifest.pb
Legacy_android10_support *bool
+
+ IsCoverageVariant bool `blueprint:"mutated"`
}
type apexTargetBundleProperties struct {
@@ -465,6 +708,8 @@
requiredModuleNames []string
targetRequiredModuleNames []string
hostRequiredModuleNames []string
+
+ jacocoReportClassesFile android.Path // only for javalibs and apps
}
func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
@@ -518,8 +763,13 @@
// list of files to be included in this apex
filesInfo []apexFile
- // list of module names that this APEX is depending on
+ // list of module names that should be installed along with this APEX
+ requiredDeps []string
+
+ // list of module names that this APEX is depending on (to be shown via *-deps-info target)
externalDeps []string
+ // list of module names that this APEX is including (to be shown via *-deps-info target)
+ internalDeps []string
testApex bool
vndkApex bool
@@ -529,15 +779,17 @@
manifestJsonOut android.WritablePath
manifestPbOut android.WritablePath
- // list of commands to create symlinks for backward compatibility
+ // list of commands to create symlinks for backward compatibility.
// these commands will be attached as LOCAL_POST_INSTALL_CMD to
- // apex package itself(for unflattened build) or apex_manifest.json(for flattened build)
+ // apex package itself(for unflattened build) or apex_manifest(for flattened build)
// so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
compatSymlinks []string
// Suffix of module name in Android.mk
// ".flattened", ".apex", ".zipapex", or ""
suffix string
+
+ installedFilesFile android.WritablePath
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -815,6 +1067,10 @@
a.properties.HideFromMake = true
}
+func (a *apexBundle) MarkAsCoverageVariant(coverage bool) {
+ a.properties.IsCoverageVariant = coverage
+}
+
// TODO(jiyong) move apexFileFor* close to the apexFile type definition
func apexFileForNativeLibrary(ctx android.BaseModuleContext, ccMod *cc.Module, handleSpecialLibs bool) apexFile {
// Decide the APEX-local directory by the multilib of the library
@@ -895,7 +1151,9 @@
func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaLibrary) apexFile {
dirInApex := "javalib"
fileToCopy := lib.DexJar()
- return newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
+ af := newApexFile(ctx, fileToCopy, lib.Name(), dirInApex, javaSharedLib, lib)
+ af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
+ return af
}
func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt android.PrebuiltEtcModule, depName string) apexFile {
@@ -908,6 +1166,7 @@
android.Module
Privileged() bool
OutputFile() android.Path
+ JacocoReportClassesFile() android.Path
}, pkgName string) apexFile {
appDir := "app"
if aapp.Privileged() {
@@ -915,7 +1174,9 @@
}
dirInApex := filepath.Join(appDir, pkgName)
fileToCopy := aapp.OutputFile()
- return newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+ af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
+ af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
+ return af
}
// Context "decorator", overriding the InstallBypassMake method to always reply `true`.
@@ -938,7 +1199,7 @@
a.primaryApexType = true
if ctx.Config().InstallExtraFlattenedApexes() {
- a.externalDeps = append(a.externalDeps, a.Name()+flattenedSuffix)
+ a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
}
}
case zipApex:
@@ -997,6 +1258,9 @@
depTag := ctx.OtherModuleDependencyTag(child)
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
+ if depTag != keyTag && depTag != certificateTag {
+ a.internalDeps = append(a.internalDeps, depName)
+ }
switch depTag {
case sharedLibTag:
if cc, ok := child.(*cc.Module); ok {
@@ -1127,9 +1391,10 @@
//
// Always include if we are a host-apex however since those won't have any
// system libraries.
- if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
- a.externalDeps = append(a.externalDeps, cc.Name())
+ if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.requiredDeps) {
+ a.requiredDeps = append(a.requiredDeps, cc.Name())
}
+ a.externalDeps = append(a.externalDeps, depName)
requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
// Don't track further
return false
@@ -1137,6 +1402,8 @@
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true
filesInfo = append(filesInfo, af)
+ a.internalDeps = append(a.internalDeps, depName)
+ a.internalDeps = append(a.internalDeps, cc.AllStaticDeps()...)
return true // track transitive dependencies
}
} else if cc.IsTestPerSrcDepTag(depTag) {
@@ -1152,8 +1419,10 @@
return true // track transitive dependencies
}
} else if java.IsJniDepTag(depTag) {
- // Do nothing for JNI dep. JNI libraries are always embedded in APK-in-APEX.
+ a.externalDeps = append(a.externalDeps, depName)
return true
+ } else if java.IsStaticLibDepTag(depTag) {
+ a.internalDeps = append(a.internalDeps, depName)
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
}
@@ -1205,7 +1474,12 @@
if !ctx.Host() && !a.testApex {
for _, fi := range filesInfo {
if am, ok := fi.module.(android.ApexModule); ok {
- if !am.AvailableFor(ctx.ModuleName()) {
+ // vndk {enabled:true} implies visibility to the vndk apex
+ if ccm, ok := fi.module.(*cc.Module); ok && ccm.IsVndk() && a.vndkApex {
+ continue
+ }
+
+ if !am.AvailableFor(ctx.ModuleName()) && !whitelistedApexAvailable(ctx.ModuleName(), a.vndkApex, fi.module) {
ctx.ModuleErrorf("requires %q that is not available for the APEX", fi.module.Name())
// don't stop so that we can report other violations in the same run
}
@@ -1249,8 +1523,28 @@
a.buildUnflattenedApex(ctx)
}
- apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
- a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
+ a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
+
+ a.buildApexDependencyInfo(ctx)
+}
+
+func whitelistedApexAvailable(apex string, is_vndk bool, module android.Module) bool {
+ key := apex
+ key = strings.Replace(key, "test_", "", 1)
+ key = strings.Replace(key, "com.android.art.debug", "com.android.art", 1)
+ key = strings.Replace(key, "com.android.art.release", "com.android.art", 1)
+
+ moduleName := module.Name()
+ if strings.Contains(moduleName, "prebuilt_libclang_rt") {
+ // This module has variants that depend on the product being built.
+ moduleName = "prebuilt_libclang_rt"
+ }
+
+ if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) {
+ return true
+ }
+
+ return false
}
func newApexBundle() *apexBundle {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index cc346e9..2103b6e 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -219,6 +219,7 @@
"apex_manifest.json": nil,
"AndroidManifest.xml": nil,
"system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/myapex2-file_contexts": nil,
"system/sepolicy/apex/otherapex-file_contexts": nil,
"system/sepolicy/apex/commonapex-file_contexts": nil,
"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
@@ -287,7 +288,6 @@
ctx.RegisterModuleType("override_apex", overrideApexFactory)
cc.RegisterRequiredBuildComponentsForTest(ctx)
- ctx.RegisterModuleType("cc_binary", cc.BinaryFactory)
ctx.RegisterModuleType("cc_test", cc.TestFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory)
ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory)
@@ -402,6 +402,11 @@
shared_libs: ["mylib2"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
cc_binary {
@@ -421,6 +426,7 @@
system_shared_libs: [],
static_executable: true,
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -429,6 +435,11 @@
system_shared_libs: [],
stl: "none",
notice: "custom_notice",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
java_library {
@@ -439,6 +450,11 @@
compile_dex: true,
static_libs: ["myotherjar"],
libs: ["mysharedjar"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
java_library {
@@ -520,6 +536,12 @@
}
ensureListContains(t, noticeInputs, "NOTICE")
ensureListContains(t, noticeInputs, "custom_notice")
+
+ depsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("myapex-deps-info.txt").Args["content"], "\\n")
+ ensureListContains(t, depsInfo, "internal myjar")
+ ensureListContains(t, depsInfo, "internal mylib")
+ ensureListContains(t, depsInfo, "internal mylib2")
+ ensureListContains(t, depsInfo, "internal myotherjar")
}
func TestDefaults(t *testing.T) {
@@ -553,6 +575,7 @@
name: "mylib",
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
java_library {
@@ -561,6 +584,7 @@
sdk_version: "none",
system_modules: "none",
compile_dex: true,
+ apex_available: [ "myapex" ],
}
android_app {
@@ -568,6 +592,7 @@
srcs: ["foo/bar/MyClass.java"],
sdk_version: "none",
system_modules: "none",
+ apex_available: [ "myapex" ],
}
`)
ensureExactContents(t, ctx, "myapex", []string{
@@ -620,6 +645,7 @@
shared_libs: ["mylib2"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -627,6 +653,7 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`)
@@ -667,6 +694,7 @@
shared_libs: ["mylib2", "mylib3"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -689,6 +717,7 @@
stubs: {
versions: ["10", "11", "12"],
},
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -696,6 +725,7 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`)
@@ -740,13 +770,13 @@
func TestApexWithExplicitStubsDependency(t *testing.T) {
ctx, _ := testApex(t, `
apex {
- name: "myapex",
- key: "myapex.key",
+ name: "myapex2",
+ key: "myapex2.key",
native_shared_libs: ["mylib"],
}
apex_key {
- name: "myapex.key",
+ name: "myapex2.key",
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}
@@ -757,6 +787,7 @@
shared_libs: ["libfoo#10"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex2" ],
}
cc_library {
@@ -779,7 +810,7 @@
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
// Ensure that direct non-stubs dep is always included
@@ -791,7 +822,7 @@
// Ensure that dependency of stubs is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex2").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with version 10 of libfoo
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
@@ -802,6 +833,12 @@
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
+
+ depsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("myapex2-deps-info.txt").Args["content"], "\\n")
+ ensureListContains(t, depsInfo, "internal mylib")
+ ensureListContains(t, depsInfo, "external libfoo")
+ ensureListNotContains(t, depsInfo, "internal libfoo")
+ ensureListNotContains(t, depsInfo, "external mylib")
}
func TestApexWithRuntimeLibsDependency(t *testing.T) {
@@ -832,6 +869,7 @@
runtime_libs: ["libfoo", "libbar"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -849,6 +887,7 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`)
@@ -893,6 +932,7 @@
shared_libs: ["libbar"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -943,6 +983,7 @@
srcs: ["mylib.cpp"],
shared_libs: ["libdl#27"],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library_shared {
@@ -950,6 +991,7 @@
srcs: ["mylib.cpp"],
shared_libs: ["libdl#27"],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -972,6 +1014,10 @@
stubs: {
versions: ["27", "28", "29"],
},
+ apex_available: [
+ "//apex_available:platform",
+ "myapex"
+ ],
}
cc_library {
@@ -983,6 +1029,10 @@
stubs: {
versions: ["27", "28", "29"],
},
+ apex_available: [
+ "//apex_available:platform",
+ "myapex"
+ ],
}
cc_library {
@@ -1074,6 +1124,7 @@
relative_install_path: "foo/bar",
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_binary {
@@ -1083,6 +1134,7 @@
system_shared_libs: [],
static_executable: true,
stl: "none",
+ apex_available: [ "myapex" ],
}
`)
@@ -1127,6 +1179,7 @@
system_shared_libs: [],
vendor_available: true,
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -1135,6 +1188,7 @@
system_shared_libs: [],
vendor_available: true,
stl: "none",
+ apex_available: [ "myapex" ],
}
`, func(fs map[string][]byte, config android.Config) {
setUseVendorWhitelistForTest(config, []string{"myapex"})
@@ -1235,6 +1289,10 @@
stubs: {
versions: ["1", "2", "3"],
},
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
cc_binary {
@@ -1268,6 +1326,7 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex_keytest" ],
}
apex_key {
@@ -1461,6 +1520,12 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ "otherapex",
+ ],
}
`)
@@ -1514,6 +1579,7 @@
stubs: {
versions: ["1", "2", "3"],
},
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -1616,6 +1682,7 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -1628,6 +1695,7 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`+vndkLibrariesTxtFiles("current"))
@@ -1665,6 +1733,7 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_prebuilt_library_shared {
@@ -1682,6 +1751,7 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`+vndkLibrariesTxtFiles("current"),
withFiles(map[string][]byte{
@@ -1752,6 +1822,7 @@
srcs: ["libvndk27_arm64.so"],
},
},
+ apex_available: [ "myapex_v27" ],
}
vndk_prebuilt_shared {
@@ -1888,6 +1959,7 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
`+vndkLibrariesTxtFiles("current"),
withTargets(map[android.OsType][]android.Target{
@@ -1980,6 +2052,7 @@
srcs: ["libvndk27binder32.so"],
}
},
+ apex_available: [ "myapex_v27" ],
}
`+vndkLibrariesTxtFiles("27"),
withFiles(map[string][]byte{
@@ -2045,6 +2118,7 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex_nodep" ],
}
cc_library {
@@ -2053,6 +2127,11 @@
shared_libs: ["libfoo"],
system_shared_libs: [],
stl: "none",
+ apex_available: [
+ "myapex_dep",
+ "myapex_provider",
+ "myapex_selfcontained",
+ ],
}
cc_library {
@@ -2063,6 +2142,10 @@
},
system_shared_libs: [],
stl: "none",
+ apex_available: [
+ "myapex_provider",
+ "myapex_selfcontained",
+ ],
}
`)
@@ -2135,6 +2218,10 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
`)
@@ -2186,6 +2273,11 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
`)
@@ -2254,6 +2346,11 @@
srcs: ["mylib.cpp"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
cc_library {
@@ -2262,6 +2359,11 @@
system_shared_libs: [],
stl: "none",
compile_multilib: "first",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
cc_library {
@@ -2652,7 +2754,7 @@
config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
})
ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- ensureListContains(t, ab.externalDeps, "myapex.flattened")
+ ensureListContains(t, ab.requiredDeps, "myapex.flattened")
mk := android.AndroidMkDataForTest(t, config, "", ab)
var builder strings.Builder
mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
@@ -2688,6 +2790,7 @@
shared_libs: ["libcommon"],
system_shared_libs: [],
stl: "none",
+ apex_available: [ "myapex" ],
}
cc_library {
@@ -2695,6 +2798,12 @@
srcs: ["mylib_common.cpp"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "commonapex",
+ "myapex",
+ ],
}
`)
@@ -2846,6 +2955,7 @@
sdk_version: "none",
system_modules: "none",
jni_libs: ["libjni"],
+ apex_available: [ "myapex" ],
}
android_app {
@@ -2854,6 +2964,7 @@
sdk_version: "none",
system_modules: "none",
privileged: true,
+ apex_available: [ "myapex" ],
}
cc_library_shared {
@@ -2947,6 +3058,7 @@
android_test_helper_app {
name: "TesterHelpAppFoo",
srcs: ["foo/bar/MyClass.java"],
+ apex_available: [ "myapex" ],
}
`)
@@ -3202,6 +3314,7 @@
package_name: "foo",
sdk_version: "none",
system_modules: "none",
+ apex_available: [ "myapex" ],
}
override_android_app {
@@ -3265,6 +3378,7 @@
module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
args := module.Rule("apexRule").Args
ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
+ ensureNotContains(t, args["opt_flags"], "--no_hashtree")
}
func TestJavaSDKLibrary(t *testing.T) {
@@ -3285,6 +3399,7 @@
name: "foo",
srcs: ["a.java"],
api_packages: ["foo"],
+ apex_available: [ "myapex" ],
}
`, withFiles(map[string][]byte{
"api/current.txt": nil,
@@ -3350,6 +3465,7 @@
required: ["a", "b"],
host_required: ["c", "d"],
target_required: ["e", "f"],
+ apex_available: [ "myapex" ],
}
`)
diff --git a/apex/builder.go b/apex/builder.go
index 4a760b9..9122188 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -233,6 +233,19 @@
return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles)).HtmlGzOutput
}
+func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
+ output := android.PathForModuleOut(ctx, "installed-files.txt")
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ Implicit(builtApex).
+ Text("(cd " + imageDir.String() + " ; ").
+ Text("find . -type f -printf \"%s %p\\n\") ").
+ Text(" | sort -nr > ").
+ Output(output)
+ rule.Build(pctx, ctx, "installed-files."+a.Name(), "Installed files")
+ return output.OutputPath
+}
+
func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
var abis []string
for _, target := range ctx.MultiTargets() {
@@ -307,6 +320,7 @@
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
+ imageDir := android.PathForModuleOut(ctx, "image"+suffix)
if apexType == imageApex {
// files and dirs that will be created in APEX
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
@@ -383,7 +397,7 @@
ctx.PropertyErrorf("test_only_no_hashtree", "not available")
return
}
- if (!ctx.Config().UnbundledBuild() && a.installable()) || a.testOnlyShouldSkipHashtreeGeneration() {
+ if !proptools.Bool(a.properties.Legacy_android10_support) || a.testOnlyShouldSkipHashtreeGeneration() {
// Apexes which are supposed to be installed in builtin dirs(/system, etc)
// don't need hashtree for activation. Therefore, by removing hashtree from
// apex bundle (filesystem image in it, to be specific), we can save storage.
@@ -408,7 +422,7 @@
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
+ "image_dir": imageDir.String(),
"copy_commands": strings.Join(copyCommands, " && "),
"manifest": a.manifestPbOut.String(),
"file_contexts": a.fileContexts.String(),
@@ -446,7 +460,7 @@
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
+ "image_dir": imageDir.String(),
"copy_commands": strings.Join(copyCommands, " && "),
"manifest": a.manifestPbOut.String(),
},
@@ -474,6 +488,9 @@
ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
}
a.buildFilesInfo(ctx)
+
+ // installed-files.txt is dist'ed
+ a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
}
func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
@@ -554,3 +571,51 @@
}
return ""
}
+
+func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
+ if !a.primaryApexType {
+ return
+ }
+
+ if a.properties.IsCoverageVariant {
+ // Otherwise, we will have duplicated rules for coverage and
+ // non-coverage variants of the same APEX
+ return
+ }
+
+ if ctx.Host() {
+ // No need to generate dependency info for host variant
+ return
+ }
+
+ internalDeps := a.internalDeps
+ externalDeps := a.externalDeps
+
+ internalDeps = android.SortedUniqueStrings(internalDeps)
+ externalDeps = android.SortedUniqueStrings(externalDeps)
+ externalDeps = android.RemoveListFromList(externalDeps, internalDeps)
+
+ var content strings.Builder
+ for _, name := range internalDeps {
+ fmt.Fprintf(&content, "internal %s\\n", name)
+ }
+ for _, name := range externalDeps {
+ fmt.Fprintf(&content, "external %s\\n", name)
+ }
+
+ depsInfoFile := android.PathForOutput(ctx, a.Name()+"-deps-info.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Description: "Dependency Info",
+ Output: depsInfoFile,
+ Args: map[string]string{
+ "content": content.String(),
+ },
+ })
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Phony,
+ Output: android.PathForPhony(ctx, a.Name()+"-deps-info"),
+ Inputs: []android.Path{depsInfoFile},
+ })
+}
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index ba5a466..d089c28 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -33,6 +33,10 @@
installDir android.InstallPath
installFilename string
outputApex android.WritablePath
+
+ // list of commands to create symlinks for backward compatibility.
+ // these commands will be attached as LOCAL_POST_INSTALL_CMD
+ compatSymlinks []string
}
type PrebuiltProperties struct {
@@ -178,7 +182,12 @@
ctx.InstallFile(p.installDir, p.installFilename, p.inputApex)
}
- // TODO(b/143192278): Add compat symlinks for prebuilt_apex
+ // in case that prebuilt_apex replaces source apex (using prefer: prop)
+ p.compatSymlinks = makeCompatSymlinks(p.BaseModuleName(), ctx)
+ // or that prebuilt_apex overrides other apexes (using overrides: prop)
+ for _, overridden := range p.properties.Overrides {
+ p.compatSymlinks = append(p.compatSymlinks, makeCompatSymlinks(overridden, ctx)...)
+ }
}
func (p *Prebuilt) AndroidMkEntries() []android.AndroidMkEntries {
@@ -192,6 +201,9 @@
entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.properties.Overrides...)
+ if len(p.compatSymlinks) > 0 {
+ entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(p.compatSymlinks, " && "))
+ }
},
},
}}
diff --git a/apex/vndk.go b/apex/vndk.go
index 1f52d11..f2e913e 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -105,7 +105,8 @@
}
}
-func makeCompatSymlinks(apexName string, ctx android.ModuleContext) (symlinks []string) {
+// name is module.BaseModuleName() which is used as LOCAL_MODULE_NAME and also LOCAL_OVERRIDES_*
+func makeCompatSymlinks(name string, ctx android.ModuleContext) (symlinks []string) {
// small helper to add symlink commands
addSymlink := func(target, dir, linkName string) {
link := filepath.Join(dir, linkName)
@@ -116,9 +117,13 @@
// When all hard-coded references are fixed, remove symbolic links
// Note that we should keep following symlinks for older VNDKs (<=29)
// Since prebuilt vndk libs still depend on system/lib/vndk path
- if strings.HasPrefix(apexName, vndkApexNamePrefix) {
+ if strings.HasPrefix(name, vndkApexName) {
+ vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
+ if strings.HasPrefix(name, vndkApexNamePrefix) {
+ vndkVersion = strings.TrimPrefix(name, vndkApexNamePrefix)
+ }
// the name of vndk apex is formatted "com.android.vndk.v" + version
- vndkVersion := strings.TrimPrefix(apexName, vndkApexNamePrefix)
+ apexName := vndkApexNamePrefix + vndkVersion
if ctx.Config().Android64() {
addSymlink("/apex/"+apexName+"/lib64", "$(TARGET_OUT)/lib64", "vndk-sp-"+vndkVersion)
addSymlink("/apex/"+apexName+"/lib64", "$(TARGET_OUT)/lib64", "vndk-"+vndkVersion)
@@ -127,22 +132,25 @@
addSymlink("/apex/"+apexName+"/lib", "$(TARGET_OUT)/lib", "vndk-sp-"+vndkVersion)
addSymlink("/apex/"+apexName+"/lib", "$(TARGET_OUT)/lib", "vndk-"+vndkVersion)
}
+ return
}
// http://b/121248172 - create a link from /system/usr/icu to
// /apex/com.android.i18n/etc/icu so that apps can find the ICU .dat file.
// A symlink can't overwrite a directory and the /system/usr/icu directory once
// existed so the required structure must be created whatever we find.
- if apexName == "com.android.i18n" {
- addSymlink("/apex/"+apexName+"/etc/icu", "$(TARGET_OUT)/usr", "icu")
+ if name == "com.android.i18n" {
+ addSymlink("/apex/com.android.i18n/etc/icu", "$(TARGET_OUT)/usr", "icu")
+ return
}
// TODO(b/124106384): Clean up compat symlinks for ART binaries.
- if strings.HasPrefix(apexName, "com.android.art.") {
+ if strings.HasPrefix(name, "com.android.art.") {
artBinaries := []string{"dalvikvm", "dex2oat"}
for _, b := range artBinaries {
addSymlink("/apex/com.android.art/bin/"+b, "$(TARGET_OUT)/bin", b)
}
+ return
}
return
}
diff --git a/build_kzip.bash b/build_kzip.bash
index 02b346d..329825a 100755
--- a/build_kzip.bash
+++ b/build_kzip.bash
@@ -6,12 +6,14 @@
# The following environment variables affect the result:
# BUILD_NUMBER build number, used to generate unique ID (will use UUID if not set)
# DIST_DIR where the resulting all.kzip will be placed
+# KYTHE_KZIP_ENCODING proto or json (proto is default)
# OUT_DIR output directory (out if not specified})
# TARGET_BUILD_VARIANT variant, e.g., `userdebug`
# TARGET_PRODUCT target device name, e.g., 'aosp_blueline'
# XREF_CORPUS source code repository URI, e.g., 'android.googlesource.com/platform/superproject'
: ${BUILD_NUMBER:=$(uuidgen)}
+: ${KYTHE_KZIP_ENCODING:=proto}
# The extraction might fail for some source files, so run with -k and then check that
# sufficiently many files were generated.
@@ -20,13 +22,14 @@
build/soong/soong_ui.bash --build-mode --all-modules --dir=$PWD -k merge_zips xref_cxx xref_java
#Build extraction file for Go files in build/soong directory.
declare -r abspath_out=$(realpath "${out}")
-(cd build/soong;
- ../../prebuilts/build-tools/linux-x86/bin/go_extractor \
- --goroot="${PWD}/../../prebuilts/go/linux-x86" \
- --rules=vnames.go.json \
- --canonicalize_package_corpus \
- --output "${abspath_out}/soong/all.go.kzip" \
- ./... )
+declare -r go_extractor=$(realpath prebuilts/build-tools/linux-x86/bin/go_extractor)
+declare -r go_root=$(realpath prebuilts/go/linux-x86)
+for dir in blueprint soong; do
+ (cd "build/$dir";
+ "$go_extractor" --goroot="$go_root" --rules=vnames.go.json --canonicalize_package_corpus \
+ --output "${abspath_out}/soong/build_${dir}.go.kzip" ./...
+ )
+done
declare -r kzip_count=$(find "$out" -name '*.kzip' | wc -l)
(($kzip_count>100000)) || { printf "Too few kzip files were generated: %d\n" $kzip_count; exit 1; }
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ff88091..c9cd01c 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -217,6 +217,9 @@
fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
fmt.Fprintln(w, "LOCAL_VNDK_DEPEND_ON_CORE_VARIANT := true")
}
+ if library.checkSameCoreVariant {
+ fmt.Fprintln(w, "LOCAL_CHECK_SAME_VNDK_VARIANTS := true")
+ }
})
if library.shared() && !library.buildStubs() {
diff --git a/cc/binary.go b/cc/binary.go
index 617d4dd..ba6ed5f 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -56,8 +56,12 @@
}
func init() {
- android.RegisterModuleType("cc_binary", BinaryFactory)
- android.RegisterModuleType("cc_binary_host", binaryHostFactory)
+ RegisterBinaryBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_binary", BinaryFactory)
+ ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
}
// cc_binary produces a binary that is runnable on a device.
diff --git a/cc/builder.go b/cc/builder.go
index 1ec323f..5f0da5f 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -238,9 +238,13 @@
_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
_ = pctx.VariableFunc("kytheCorpus",
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+ _ = pctx.VariableFunc("kytheCuEncoding",
+ func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
kytheExtract = pctx.StaticRule("kythe",
blueprint.RuleParams{
- Command: "rm -f $out && KYTHE_CORPUS=${kytheCorpus} KYTHE_OUTPUT_FILE=$out KYTHE_VNAMES=$kytheVnames $cxxExtractor $cFlags $in ",
+ Command: `rm -f $out && ` +
+ `KYTHE_CORPUS=${kytheCorpus} KYTHE_OUTPUT_FILE=$out KYTHE_VNAMES=$kytheVnames KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
+ `$cxxExtractor $cFlags $in `,
CommandDeps: []string{"$cxxExtractor", "$kytheVnames"},
},
"cFlags")
diff --git a/cc/cc.go b/cc/cc.go
index 0c32225..022e350 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -398,6 +398,13 @@
return ok && ccDepTag.Shared
}
+func IsStaticDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(DependencyTag)
+ return ok && (ccDepTag == staticExportDepTag ||
+ ccDepTag == lateStaticDepTag ||
+ ccDepTag == wholeStaticDepTag)
+}
+
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == runtimeDepTag
@@ -463,6 +470,9 @@
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
kytheFiles android.Paths
+
+ // name of the modules that are direct or indirect static deps of this module
+ allStaticDeps []string
}
func (c *Module) Toc() android.OptionalPath {
@@ -1103,7 +1113,7 @@
// Host modules do not need ABI dumps.
return false
}
- if ctx.isStubs() {
+ if ctx.isStubs() || ctx.isNDKStubLibrary() {
// Stubs do not need ABI dumps.
return false
}
@@ -1258,6 +1268,15 @@
return results
}
+func gatherTransitiveStaticDeps(staticDeps []LinkableInterface) []string {
+ var ret []string
+ for _, dep := range staticDeps {
+ ret = append(ret, dep.Module().Name())
+ ret = append(ret, dep.AllStaticDeps()...)
+ }
+ return android.FirstUniqueStrings(ret)
+}
+
func (c *Module) IsTestPerSrcAllTestsVariation() bool {
test, ok := c.linker.(testPerSrc)
return ok && test.isAllTestsVariation()
@@ -2328,6 +2347,8 @@
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
}
+ c.allStaticDeps = gatherTransitiveStaticDeps(directStaticDeps)
+
return depPaths
}
@@ -2460,7 +2481,29 @@
}
func (c *Module) installable() bool {
- return c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid()
+ ret := c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid()
+
+ // The platform variant doesn't need further condition. Apex variants however might not
+ // be installable because it will likely to be included in the APEX and won't appear
+ // in the system partition.
+ if c.IsForPlatform() {
+ return ret
+ }
+
+ // Special case for modules that are configured to be installed to /data, which includes
+ // test modules. For these modules, both APEX and non-APEX variants are considered as
+ // installable. This is because even the APEX variants won't be included in the APEX, but
+ // will anyway be installed to /data/*.
+ // See b/146995717
+ if c.InstallInData() {
+ return ret
+ }
+
+ return false
+}
+
+func (c *Module) AllStaticDeps() []string {
+ return c.allStaticDeps
}
func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
diff --git a/cc/ccdeps.go b/cc/ccdeps.go
index 9b89110..4e23a7b 100644
--- a/cc/ccdeps.go
+++ b/cc/ccdeps.go
@@ -142,7 +142,7 @@
compilerParams.HeaderSearchPath =
append(compilerParams.HeaderSearchPath, strings.TrimPrefix(param, "-I"))
case systemHeaderSearchPath:
- if i < len(params)-1 {
+ if i < len(cparams)-1 {
compilerParams.SystemHeaderSearchPath = append(compilerParams.SystemHeaderSearchPath, cparams[i+1])
}
i = i + 1
diff --git a/cc/cmakelists.go b/cc/cmakelists.go
index 97d21f4..f7d9081 100644
--- a/cc/cmakelists.go
+++ b/cc/cmakelists.go
@@ -76,7 +76,7 @@
// Link all handmade CMakeLists.txt aggregate from
// BASE/development/ide/clion to
// BASE/out/development/ide/clion.
- dir := filepath.Join(getAndroidSrcRootDirectory(ctx), cLionAggregateProjectsDirectory)
+ dir := filepath.Join(android.AbsSrcDirForExistingUseCases(), cLionAggregateProjectsDirectory)
filepath.Walk(dir, linkAggregateCMakeListsFiles)
return
@@ -147,7 +147,7 @@
f.WriteString("# Tools > CMake > Change Project Root \n\n")
f.WriteString(fmt.Sprintf("cmake_minimum_required(VERSION %s)\n", minimumCMakeVersionSupported))
f.WriteString(fmt.Sprintf("project(%s)\n", ccModule.ModuleBase.Name()))
- f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", getAndroidSrcRootDirectory(ctx)))
+ f.WriteString(fmt.Sprintf("set(ANDROID_ROOT %s)\n\n", android.AbsSrcDirForExistingUseCases()))
pathToCC, _ := evalVariable(ctx, "${config.ClangBin}/")
f.WriteString(fmt.Sprintf("set(CMAKE_C_COMPILER \"%s%s\")\n", buildCMakePath(pathToCC), "clang"))
@@ -465,7 +465,7 @@
}
func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string {
- return filepath.Join(getAndroidSrcRootDirectory(ctx),
+ return filepath.Join(android.AbsSrcDirForExistingUseCases(),
cLionOutputProjectsDirectory,
path.Dir(ctx.BlueprintFile(module)),
module.ModuleBase.Name()+"-"+
@@ -473,8 +473,3 @@
module.ModuleBase.Os().Name,
cMakeListsFilename)
}
-
-func getAndroidSrcRootDirectory(ctx android.SingletonContext) string {
- srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
- return srcPath
-}
diff --git a/cc/compdb.go b/cc/compdb.go
index dff14db..ea12443 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -79,9 +79,9 @@
// Create the output file.
dir := android.PathForOutput(ctx, compdbOutputProjectsDirectory)
- os.MkdirAll(dir.String(), 0777)
+ os.MkdirAll(filepath.Join(android.AbsSrcDirForExistingUseCases(), dir.String()), 0777)
compDBFile := dir.Join(ctx, compdbFilename)
- f, err := os.Create(compDBFile.String())
+ f, err := os.Create(filepath.Join(android.AbsSrcDirForExistingUseCases(), compDBFile.String()))
if err != nil {
log.Fatalf("Could not create file %s: %s", compDBFile, err)
}
@@ -103,8 +103,8 @@
}
f.Write(dat)
- finalLinkPath := filepath.Join(ctx.Config().Getenv(envVariableCompdbLink), compdbFilename)
- if finalLinkPath != "" {
+ if finalLinkDir := ctx.Config().Getenv(envVariableCompdbLink); finalLinkDir != "" {
+ finalLinkPath := filepath.Join(finalLinkDir, compdbFilename)
os.Remove(finalLinkPath)
if err := os.Symlink(compDBFile.String(), finalLinkPath); err != nil {
log.Fatalf("Unable to symlink %s to %s: %s", compDBFile, finalLinkPath, err)
@@ -174,18 +174,17 @@
return
}
- rootDir := getCompdbAndroidSrcRootDirectory(ctx)
- pathToCC, err := ctx.Eval(pctx, rootDir+"/${config.ClangBin}/")
+ pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}")
ccPath := "/bin/false"
cxxPath := "/bin/false"
if err == nil {
- ccPath = pathToCC + "clang"
- cxxPath = pathToCC + "clang++"
+ ccPath = filepath.Join(pathToCC, "clang")
+ cxxPath = filepath.Join(pathToCC, "clang++")
}
for _, src := range srcs {
if _, ok := builds[src.String()]; !ok {
builds[src.String()] = compDbEntry{
- Directory: rootDir,
+ Directory: android.AbsSrcDirForExistingUseCases(),
Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
File: src.String(),
}
@@ -200,8 +199,3 @@
}
return []string{""}, err
}
-
-func getCompdbAndroidSrcRootDirectory(ctx android.SingletonContext) string {
- srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
- return srcPath
-}
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
new file mode 100644
index 0000000..b2f54e5
--- /dev/null
+++ b/cc/config/OWNERS
@@ -0,0 +1 @@
+per-file vndk.go = smoreland@google.com, victoryang@google.com
diff --git a/cc/config/global.go b/cc/config/global.go
index 87314dc..1ce29b9 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -166,6 +166,9 @@
flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
} else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") {
flags = append(flags, "-ftrivial-auto-var-init=pattern")
+ } else {
+ // Default to pattern initialization.
+ flags = append(flags, "-ftrivial-auto-var-init=pattern")
}
return strings.Join(flags, " ")
diff --git a/cc/config/vndk.go b/cc/config/vndk.go
index 9feb5a3..3b16c78 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -71,6 +71,7 @@
"android.hardware.nfc@1.2",
"android.hardware.oemlock@1.0",
"android.hardware.power.stats@1.0",
+ "android.hardware.power-ndk_platform",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
"android.hardware.radio@1.4",
@@ -131,6 +132,7 @@
"libsqlite",
"libssl",
"libstagefright_amrnb_common",
+ "libstagefright_bufferpool@2.0",
"libstagefright_bufferqueue_helper",
"libstagefright_enc_common",
"libstagefright_flacdec",
diff --git a/cc/coverage.go b/cc/coverage.go
index c03a568..b6451ee 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -163,6 +163,7 @@
IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
PreventInstall()
HideFromMake()
+ MarkAsCoverageVariant(bool)
}
func coverageMutator(mctx android.BottomUpMutatorContext) {
@@ -191,6 +192,7 @@
// module which are split into "" and "cov" variants. e.g. when cc_test refers
// to an APEX via 'data' property.
m := mctx.CreateVariations("", "cov")
+ m[0].(Coverage).MarkAsCoverageVariant(true)
m[0].(Coverage).PreventInstall()
m[0].(Coverage).HideFromMake()
}
diff --git a/cc/library.go b/cc/library.go
index ae95bc5..f29c4d0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -385,7 +385,8 @@
// If useCoreVariant is true, the vendor variant of a VNDK library is
// not installed.
- useCoreVariant bool
+ useCoreVariant bool
+ checkSameCoreVariant bool
// Decorated interafaces
*baseCompiler
@@ -1096,8 +1097,11 @@
if ctx.isVndkSp() {
library.baseInstaller.subDir = "vndk-sp"
} else if ctx.isVndk() {
- if ctx.DeviceConfig().VndkUseCoreVariant() && !ctx.mustUseVendorVariant() {
- library.useCoreVariant = true
+ if !ctx.mustUseVendorVariant() {
+ library.checkSameCoreVariant = true
+ if ctx.DeviceConfig().VndkUseCoreVariant() {
+ library.useCoreVariant = true
+ }
}
library.baseInstaller.subDir = "vndk"
}
diff --git a/cc/linkable.go b/cc/linkable.go
index 815d405..106092b 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -51,6 +51,8 @@
ToolchainLibrary() bool
NdkPrebuiltStl() bool
StubDecorator() bool
+
+ AllStaticDeps() []string
}
type DependencyTag struct {
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index b8423be..5744bb2 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "os"
"path/filepath"
"strings"
@@ -255,16 +254,8 @@
depsPath := android.PathForSource(ctx, "bionic/libc/versioner-dependencies")
depsGlob := ctx.Glob(filepath.Join(depsPath.String(), "**/*"), nil)
for i, path := range depsGlob {
- fileInfo, err := os.Lstat(path.String())
- if err != nil {
- ctx.ModuleErrorf("os.Lstat(%q) failed: %s", path.String, err)
- }
- if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
- dest, err := os.Readlink(path.String())
- if err != nil {
- ctx.ModuleErrorf("os.Readlink(%q) failed: %s",
- path.String, err)
- }
+ if ctx.IsSymlink(path) {
+ dest := ctx.Readlink(path)
// Additional .. to account for the symlink itself.
depsGlob[i] = android.PathForSource(
ctx, filepath.Clean(filepath.Join(path.String(), "..", dest)))
diff --git a/cc/pgo.go b/cc/pgo.go
index 0072355..e341d03 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -177,6 +177,10 @@
// if profileFile gets updated
flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
+
+ if props.isSampling() {
+ flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true")
+ }
}
return flags
}
diff --git a/cc/testing.go b/cc/testing.go
index d6f2391..ba8ed95 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -23,6 +23,7 @@
android.RegisterPrebuiltMutators(ctx)
RegisterCCBuildComponents(ctx)
+ RegisterBinaryBuildComponents(ctx)
RegisterLibraryBuildComponents(ctx)
ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
@@ -308,8 +309,6 @@
func CreateTestContext() *android.TestContext {
ctx := android.NewTestArchContext()
- ctx.RegisterModuleType("cc_binary", BinaryFactory)
- ctx.RegisterModuleType("cc_binary_host", binaryHostFactory)
ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
ctx.RegisterModuleType("cc_test", TestFactory)
ctx.RegisterModuleType("llndk_headers", llndkHeadersFactory)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 0c79ccc..2a929c5 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -16,7 +16,6 @@
import (
"encoding/json"
- "io/ioutil"
"strings"
"android/soong/android"
@@ -185,7 +184,7 @@
// soongConfig argument. LoadGlobalConfig is used directly in Soong and in
// dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by
// Make.
-func LoadGlobalConfig(ctx android.PathContext, path string, soongConfig GlobalSoongConfig) (GlobalConfig, []byte, error) {
+func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) {
type GlobalJSONConfig struct {
GlobalConfig
@@ -196,9 +195,9 @@
}
config := GlobalJSONConfig{}
- data, err := loadConfig(ctx, path, &config)
+ err := json.Unmarshal(data, &config)
if err != nil {
- return config.GlobalConfig, nil, err
+ return config.GlobalConfig, err
}
// Construct paths that require a PathContext.
@@ -209,13 +208,13 @@
// either CreateGlobalSoongConfig or LoadGlobalSoongConfig).
config.GlobalConfig.SoongConfig = soongConfig
- return config.GlobalConfig, data, nil
+ return config.GlobalConfig, nil
}
// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct. It is not used in Soong, which
// receives a ModuleConfig struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called from oMake to
// read the module dexpreopt.config written by Make.
-func LoadModuleConfig(ctx android.PathContext, path string) (ModuleConfig, error) {
+func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
type ModuleJSONConfig struct {
ModuleConfig
@@ -233,7 +232,7 @@
config := ModuleJSONConfig{}
- _, err := loadConfig(ctx, path, &config)
+ err := json.Unmarshal(data, &config)
if err != nil {
return config.ModuleConfig, err
}
@@ -289,10 +288,10 @@
// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
-func LoadGlobalSoongConfig(ctx android.PathContext, path string) (GlobalSoongConfig, error) {
+func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
var jc globalJsonSoongConfig
- _, err := loadConfig(ctx, path, &jc)
+ err := json.Unmarshal(data, &jc)
if err != nil {
return GlobalSoongConfig{}, err
}
@@ -352,26 +351,6 @@
}, " "))
}
-func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
- r, err := ctx.Fs().Open(path)
- if err != nil {
- return nil, err
- }
- defer r.Close()
-
- data, err := ioutil.ReadAll(r)
- if err != nil {
- return nil, err
- }
-
- err = json.Unmarshal(data, config)
- if err != nil {
- return nil, err
- }
-
- return data, nil
-}
-
func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
return GlobalConfig{
DisablePreopt: false,
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index d2faa00..e2818bb 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -18,6 +18,7 @@
"bytes"
"flag"
"fmt"
+ "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -41,7 +42,6 @@
config android.Config
}
-func (x *pathContext) Fs() pathtools.FileSystem { return pathtools.OsFs }
func (x *pathContext) Config() android.Config { return x.config }
func (x *pathContext) AddNinjaFileDeps(...string) {}
@@ -76,21 +76,39 @@
usage("--module configuration file is required")
}
- ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)}
+ ctx := &pathContext{android.NullConfig(*outDir)}
- globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, *globalSoongConfigPath)
+ globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalSoongConfigPath, err)
+ os.Exit(2)
+ }
+
+ globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err)
os.Exit(2)
}
- globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath, globalSoongConfig)
+ globalConfigData, err := ioutil.ReadFile(*globalConfigPath)
if err != nil {
- fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
+ fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalConfigPath, err)
os.Exit(2)
}
- moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, *moduleConfigPath)
+ globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData, globalSoongConfig)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error parse global config %q: %s\n", *globalConfigPath, err)
+ os.Exit(2)
+ }
+
+ moduleConfigData, err := ioutil.ReadFile(*moduleConfigPath)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error reading module config %q: %s\n", *moduleConfigPath, err)
+ os.Exit(2)
+ }
+
+ moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err)
os.Exit(2)
diff --git a/env/env.go b/env/env.go
index bf58a99..a98e1f6 100644
--- a/env/env.go
+++ b/env/env.go
@@ -27,7 +27,7 @@
type envFileEntry struct{ Key, Value string }
type envFileData []envFileEntry
-func WriteEnvFile(filename string, envDeps map[string]string) error {
+func EnvFileContents(envDeps map[string]string) ([]byte, error) {
contents := make(envFileData, 0, len(envDeps))
for key, value := range envDeps {
contents = append(contents, envFileEntry{key, value})
@@ -37,17 +37,12 @@
data, err := json.MarshalIndent(contents, "", " ")
if err != nil {
- return err
+ return nil, err
}
data = append(data, '\n')
- err = ioutil.WriteFile(filename, data, 0664)
- if err != nil {
- return err
- }
-
- return nil
+ return data, nil
}
func StaleEnvFile(filename string) (bool, error) {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 57ca9bc..c5aaed2 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -30,10 +30,18 @@
)
func init() {
- android.RegisterModuleType("genrule_defaults", defaultsFactory)
+ registerGenruleBuildComponents(android.InitRegistrationContext)
+}
- android.RegisterModuleType("gensrcs", GenSrcsFactory)
- android.RegisterModuleType("genrule", GenRuleFactory)
+func registerGenruleBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("genrule_defaults", defaultsFactory)
+
+ ctx.RegisterModuleType("gensrcs", GenSrcsFactory)
+ ctx.RegisterModuleType("genrule", GenRuleFactory)
+
+ ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel()
+ })
}
var (
@@ -166,7 +174,7 @@
return g.outputDeps
}
-func (g *Module) DepsMutator(ctx android.BottomUpMutatorContext) {
+func toolDepsMutator(ctx android.BottomUpMutatorContext) {
if g, ok := ctx.Module().(*Module); ok {
for _, tool := range g.properties.Tools {
tag := hostToolDependencyTag{label: tool}
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index ea49e08..7eb43ac 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -55,10 +55,10 @@
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
- ctx.RegisterModuleType("genrule", GenRuleFactory)
- ctx.RegisterModuleType("gensrcs", GenSrcsFactory)
- ctx.RegisterModuleType("genrule_defaults", defaultsFactory)
ctx.RegisterModuleType("tool", toolFactory)
+
+ registerGenruleBuildComponents(ctx)
+
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.Register(config)
diff --git a/java/aar.go b/java/aar.go
index 201e590..ae064e5 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -576,6 +576,10 @@
return a.prebuilt.Name(a.ModuleBase.Name())
}
+func (a *AARImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
if !ctx.Config().UnbundledBuildUsePrebuiltSdks() {
sdkDep := decodeSdkDep(ctx, sdkContext(a))
diff --git a/java/app.go b/java/app.go
index 2933ccb..e9941f2 100755
--- a/java/app.go
+++ b/java/app.go
@@ -644,22 +644,40 @@
}
a.generateAndroidBuildActions(ctx)
- a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
+ testConfig := tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config,
a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites, a.testProperties.Auto_gen_config)
- if a.overridableAppProperties.Package_name != nil {
- fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
- rule := android.NewRuleBuilder()
- rule.Command().BuiltTool(ctx, "test_config_fixer").
- FlagWithInput("--manifest ", a.manifestPath).
- FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name).
- Input(a.testConfig).
- Output(fixedConfig)
- rule.Build(pctx, ctx, "fix_test_config", "fix test config")
- a.testConfig = fixedConfig
- }
+ a.testConfig = a.FixTestConfig(ctx, testConfig)
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
+func (a *AndroidTest) FixTestConfig(ctx android.ModuleContext, testConfig android.Path) android.Path {
+ if testConfig == nil {
+ return nil
+ }
+
+ fixedConfig := android.PathForModuleOut(ctx, "test_config_fixer", "AndroidTest.xml")
+ rule := android.NewRuleBuilder()
+ command := rule.Command().BuiltTool(ctx, "test_config_fixer").Input(testConfig).Output(fixedConfig)
+ fixNeeded := false
+
+ if ctx.ModuleName() != a.installApkName {
+ fixNeeded = true
+ command.FlagWithArg("--test-file-name ", a.installApkName+".apk")
+ }
+
+ if a.overridableAppProperties.Package_name != nil {
+ fixNeeded = true
+ command.FlagWithInput("--manifest ", a.manifestPath).
+ FlagWithArg("--package-name ", *a.overridableAppProperties.Package_name)
+ }
+
+ if fixNeeded {
+ rule.Build(pctx, ctx, "fix_test_config", "fix test config")
+ return fixedConfig
+ }
+ return testConfig
+}
+
func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
a.AndroidApp.DepsMutator(ctx)
}
@@ -752,6 +770,7 @@
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
+ android.InitApexModule(module)
return module
}
@@ -925,6 +944,16 @@
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
+ // Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
+ // with them may invalidate pre-existing signature data.
+ if ctx.InstallInTestcases() && Bool(a.properties.Presigned) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Output: outputPath,
+ Input: inputPath,
+ })
+ return
+ }
rule := android.NewRuleBuilder()
rule.Command().
Textf(`if (zipinfo %s 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
@@ -1002,6 +1031,8 @@
var installDir android.InstallPath
if Bool(a.properties.Privileged) {
installDir = android.PathForModuleInstall(ctx, "priv-app", a.BaseModuleName())
+ } else if ctx.InstallInTestcases() {
+ installDir = android.PathForModuleInstall(ctx, a.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
} else {
installDir = android.PathForModuleInstall(ctx, "app", a.BaseModuleName())
}
@@ -1062,6 +1093,10 @@
return a.outputFile
}
+func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
var dpiVariantGroupType reflect.Type
var archVariantGroupType reflect.Type
@@ -1154,6 +1189,10 @@
a.data = android.PathsForModuleSrc(ctx, a.testProperties.Data)
}
+func (a *AndroidTestImport) InstallInTestcases() bool {
+ return true
+}
+
// android_test_import imports a prebuilt test apk with additional processing specified in the
// module. DPI or arch variant configurations can be made as with android_app_import.
func AndroidTestImportFactory() android.Module {
diff --git a/java/app_test.go b/java/app_test.go
index 9bdef4e..6f89da4 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1305,6 +1305,87 @@
}
}
+func TestAndroidTest_FixTestConfig(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ package_name: "com.android.foo",
+ sdk_version: "current",
+ }
+
+ android_test {
+ name: "foo_test",
+ srcs: ["b.java"],
+ instrumentation_for: "foo",
+ }
+
+ android_test {
+ name: "bar_test",
+ srcs: ["b.java"],
+ package_name: "com.android.bar.test",
+ instrumentation_for: "foo",
+ }
+
+ override_android_test {
+ name: "baz_test",
+ base: "foo_test",
+ package_name: "com.android.baz.test",
+ }
+ `)
+
+ testCases := []struct {
+ moduleName string
+ variantName string
+ expectedFlags []string
+ }{
+ {
+ moduleName: "foo_test",
+ variantName: "android_common",
+ },
+ {
+ moduleName: "bar_test",
+ variantName: "android_common",
+ expectedFlags: []string{
+ "--manifest " + buildDir + "/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
+ "--package-name com.android.bar.test",
+ },
+ },
+ {
+ moduleName: "foo_test",
+ variantName: "android_common_baz_test",
+ expectedFlags: []string{
+ "--manifest " + buildDir +
+ "/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
+ "--package-name com.android.baz.test",
+ "--test-file-name baz_test.apk",
+ },
+ },
+ }
+
+ for _, test := range testCases {
+ variant := ctx.ModuleForTests(test.moduleName, test.variantName)
+ params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
+
+ if len(test.expectedFlags) > 0 {
+ if params.Rule == nil {
+ t.Errorf("test_config_fixer was expected to run, but didn't")
+ } else {
+ for _, flag := range test.expectedFlags {
+ if !strings.Contains(params.RuleParams.Command, flag) {
+ t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
+ }
+ }
+ }
+ } else {
+ if params.Rule != nil {
+ t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
+ }
+ }
+
+ }
+}
+
func TestAndroidAppImport(t *testing.T) {
ctx, _ := testJava(t, `
android_app_import {
@@ -1628,6 +1709,40 @@
}
}
+func TestAndroidTestImport_NoJinUncompressForPresigned(t *testing.T) {
+ ctx, _ := testJava(t, `
+ android_test_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ certificate: "cert/new_cert",
+ data: [
+ "testdata/data",
+ ],
+ }
+
+ android_test_import {
+ name: "foo_presigned",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ data: [
+ "testdata/data",
+ ],
+ }
+ `)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+ jniRule := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
+ if !strings.HasPrefix(jniRule, "if (zipinfo") {
+ t.Errorf("Unexpected JNI uncompress rule command: " + jniRule)
+ }
+
+ variant = ctx.ModuleForTests("foo_presigned", "android_common")
+ jniRule = variant.Output("jnis-uncompressed/foo_presigned.apk").BuildParams.Rule.String()
+ if jniRule != android.Cp.String() {
+ t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+ }
+}
+
func TestStl(t *testing.T) {
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
diff --git a/java/builder.go b/java/builder.go
index 417a7fa..26a49ea 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -64,6 +64,8 @@
_ = pctx.VariableFunc("kytheCorpus",
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+ _ = pctx.VariableFunc("kytheCuEncoding",
+ func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
// Run it with -add-opens=java.base/java.nio=ALL-UNNAMED to avoid JDK9's warning about
// "Illegal reflective access by com.google.protobuf.Utf8$UnsafeProcessor ...
@@ -76,6 +78,7 @@
`KYTHE_ROOT_DIRECTORY=. KYTHE_OUTPUT_FILE=$out ` +
`KYTHE_CORPUS=${kytheCorpus} ` +
`KYTHE_VNAMES=${kytheVnames} ` +
+ `KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
`${config.SoongJavacWrapper} ${config.JavaCmd} ` +
`--add-opens=java.base/java.nio=ALL-UNNAMED ` +
`-jar ${config.JavaKytheExtractorJar} ` +
diff --git a/java/config/config.go b/java/config/config.go
index 9738454..6da7279 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -45,7 +45,9 @@
"core-icu4j",
"core-oj",
"core-libart",
+ // TODO: Could this be all updatable bootclasspath jars?
"updatable-media",
+ "framework-sdkextensions",
"ike",
}
)
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 1524418..b40ab93 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -170,6 +170,10 @@
return d.srcJarArgs, d.srcJarDeps
}
+func (d *DeviceHostConverter) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (d *DeviceHostConverter) AndroidMk() android.AndroidMkData {
return android.AndroidMkData{
Class: "JAVA_LIBRARIES",
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 479dec6..da68660 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -85,6 +85,11 @@
return true
}
+ // Don't preopt APEX variant module
+ if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
+ return true
+ }
+
// TODO: contains no java code
return false
@@ -101,9 +106,8 @@
global := dexpreoptGlobalConfig(ctx)
bootImage := defaultBootImageConfig(ctx)
- defaultBootImage := bootImage
if global.UseApexImage {
- bootImage = apexBootImageConfig(ctx)
+ bootImage = frameworkJZBootImageConfig(ctx)
}
var archs []android.ArchType
@@ -174,11 +178,8 @@
DexPreoptImagesDeps: imagesDeps,
DexPreoptImageLocations: bootImage.imageLocations,
- // We use the dex paths and dex locations of the default boot image, as it
- // contains the full dexpreopt boot classpath. Other images may just contain a subset of
- // the dexpreopt boot classpath.
- PreoptBootClassPathDexFiles: defaultBootImage.dexPathsDeps.Paths(),
- PreoptBootClassPathDexLocations: defaultBootImage.dexLocationsDeps,
+ PreoptBootClassPathDexFiles: bootImage.dexPathsDeps.Paths(),
+ PreoptBootClassPathDexLocations: bootImage.dexLocationsDeps,
PreoptExtractedApk: false,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index fe5bed5..66840b5 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -220,7 +220,8 @@
d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx)))
if global.GenerateApexImage {
// Create boot images for the JIT-zygote experiment.
- d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
+ d.otherImages = append(d.otherImages, buildBootImage(ctx, artJZBootImageConfig(ctx)))
+ d.otherImages = append(d.otherImages, buildBootImage(ctx, frameworkJZBootImageConfig(ctx)))
}
dumpOatRules(ctx, d.defaultBootImage)
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 8f29e9e..4ce30f6 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -48,7 +48,7 @@
pathCtx := android.PathContextForTesting(config)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- dexpreoptConfig.ArtApexJars = []string{"foo", "bar", "baz"}
+ dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext()
@@ -59,9 +59,10 @@
dexpreoptBootJars := ctx.SingletonForTests("dex_bootjars")
- bootArt := dexpreoptBootJars.Output("boot.art")
+ bootArt := dexpreoptBootJars.Output("boot-foo.art")
expectedInputs := []string{
+ "dex_artjars/apex/com.android.art/javalib/arm64/boot.art",
"dex_bootjars_input/foo.jar",
"dex_bootjars_input/bar.jar",
"dex_bootjars_input/baz.jar",
@@ -82,19 +83,19 @@
expectedOutputs := []string{
"dex_bootjars/system/framework/arm64/boot.invocation",
- "dex_bootjars/system/framework/arm64/boot.art",
+ "dex_bootjars/system/framework/arm64/boot-foo.art",
"dex_bootjars/system/framework/arm64/boot-bar.art",
"dex_bootjars/system/framework/arm64/boot-baz.art",
- "dex_bootjars/system/framework/arm64/boot.oat",
+ "dex_bootjars/system/framework/arm64/boot-foo.oat",
"dex_bootjars/system/framework/arm64/boot-bar.oat",
"dex_bootjars/system/framework/arm64/boot-baz.oat",
- "dex_bootjars/system/framework/arm64/boot.vdex",
+ "dex_bootjars/system/framework/arm64/boot-foo.vdex",
"dex_bootjars/system/framework/arm64/boot-bar.vdex",
"dex_bootjars/system/framework/arm64/boot-baz.vdex",
- "dex_bootjars_unstripped/system/framework/arm64/boot.oat",
+ "dex_bootjars_unstripped/system/framework/arm64/boot-foo.oat",
"dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
"dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 35748b8..31bec93 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -36,10 +36,11 @@
func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
- if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
+ if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
+ panic(err)
+ } else if data != nil {
soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx)
- ctx.AddNinjaFileDeps(f)
- globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f, soongConfig)
+ globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig)
if err != nil {
panic(err)
}
@@ -121,10 +122,11 @@
}
var (
- bootImageConfigKey = android.NewOnceKey("bootImageConfig")
- artBootImageName = "art"
- frameworkBootImageName = "boot"
- apexBootImageName = "apex"
+ bootImageConfigKey = android.NewOnceKey("bootImageConfig")
+ artBootImageName = "art"
+ frameworkBootImageName = "boot"
+ artJZBootImageName = "jitzygote-art"
+ frameworkJZBootImageName = "jitzygote-boot"
)
// Construct the global boot image configs.
@@ -167,33 +169,44 @@
}
// Framework config for the boot image extension.
- // It includes both the Core libraries and framework.
+ // It includes framework libraries and depends on the ART config.
frameworkCfg := bootImageConfig{
- extension: false,
+ extension: true,
name: frameworkBootImageName,
stem: "boot",
installSubdir: frameworkSubdir,
- modules: concat(artModules, frameworkModules),
- dexLocations: concat(artLocations, frameworkLocations),
- dexLocationsDeps: concat(artLocations, frameworkLocations),
+ modules: frameworkModules,
+ dexLocations: frameworkLocations,
+ dexLocationsDeps: append(artLocations, frameworkLocations...),
}
- // Apex config for the boot image used in the JIT-zygote experiment.
- // It includes both the Core libraries and framework.
- apexCfg := bootImageConfig{
+ // ART config for JIT-zygote boot image.
+ artJZCfg := bootImageConfig{
extension: false,
- name: apexBootImageName,
+ name: artJZBootImageName,
+ stem: "apex",
+ installSubdir: artSubdir,
+ modules: artModules,
+ dexLocations: artLocations,
+ dexLocationsDeps: artLocations,
+ }
+
+ // Framework config for JIT-zygote boot image extension.
+ frameworkJZCfg := bootImageConfig{
+ extension: true,
+ name: frameworkJZBootImageName,
stem: "apex",
installSubdir: frameworkSubdir,
- modules: concat(artModules, frameworkModules),
- dexLocations: concat(artLocations, frameworkLocations),
- dexLocationsDeps: concat(artLocations, frameworkLocations),
+ modules: frameworkModules,
+ dexLocations: frameworkLocations,
+ dexLocationsDeps: append(artLocations, frameworkLocations...),
}
configs := map[string]*bootImageConfig{
- artBootImageName: &artCfg,
- frameworkBootImageName: &frameworkCfg,
- apexBootImageName: &apexCfg,
+ artBootImageName: &artCfg,
+ frameworkBootImageName: &frameworkCfg,
+ artJZBootImageName: &artJZCfg,
+ frameworkJZBootImageName: &frameworkJZCfg,
}
// common to all configs
@@ -231,6 +244,14 @@
c.zip = c.dir.Join(ctx, c.name+".zip")
}
+ // specific to the framework config
+ frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
+ frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
+
+ // specific to the jitzygote-framework config
+ frameworkJZCfg.dexPathsDeps = append(artJZCfg.dexPathsDeps, frameworkJZCfg.dexPathsDeps...)
+ frameworkJZCfg.imageLocations = append(artJZCfg.imageLocations, frameworkJZCfg.imageLocations...)
+
return configs
}).(map[string]*bootImageConfig)
}
@@ -243,8 +264,12 @@
return *genBootImageConfigs(ctx)[frameworkBootImageName]
}
-func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
- return *genBootImageConfigs(ctx)[apexBootImageName]
+func artJZBootImageConfig(ctx android.PathContext) bootImageConfig {
+ return *genBootImageConfigs(ctx)[artJZBootImageName]
+}
+
+func frameworkJZBootImageConfig(ctx android.PathContext) bootImageConfig {
+ return *genBootImageConfigs(ctx)[frameworkJZBootImageName]
}
func defaultBootclasspath(ctx android.PathContext) []string {
diff --git a/java/java.go b/java/java.go
index a48b5a3..4c6a5a5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -447,6 +447,7 @@
ExportedPlugins() (android.Paths, []string)
SrcJarArgs() ([]string, android.Paths)
BaseModuleName() string
+ JacocoReportClassesFile() android.Path
}
type SdkLibraryDependency interface {
@@ -499,6 +500,14 @@
usesLibTag = dependencyTag{name: "uses-library"}
)
+func IsLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == libTag
+}
+
+func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
+ return depTag == staticLibTag
+}
+
type sdkDep struct {
useModule, useFiles, useDefaultLibs, invalidVersion bool
@@ -618,12 +627,9 @@
}
linkType, _ := j.getLinkType(ctx.ModuleName())
- if linkType == javaSystem {
+ // only platform modules can use internal props
+ if linkType != javaPlatform {
ret[idx] = stub
- } else if linkType != javaPlatform {
- ctx.PropertyErrorf("sdk_version",
- "can't link against sysprop_library %q from a module using public or core API",
- lib)
}
}
@@ -651,7 +657,14 @@
}
}
- if j.shouldInstrumentStatic(ctx) {
+ // Framework libraries need special handling in static coverage builds: they should not have
+ // static dependency on jacoco, otherwise there would be multiple conflicting definitions of
+ // the same jacoco classes coming from different bootclasspath jars.
+ if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ j.properties.Instrument = true
+ }
+ } else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
}
@@ -1454,12 +1467,6 @@
j.headerJarFile = j.implementationJarFile
}
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) {
- j.properties.Instrument = true
- }
- }
-
if j.shouldInstrument(ctx) {
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
@@ -1719,6 +1726,10 @@
return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
}
+func (j *Module) JacocoReportClassesFile() android.Path {
+ return j.jacocoReportClassesFile
+}
+
//
// Java libraries (.jar file)
//
@@ -2295,6 +2306,10 @@
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (a *Import) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
}
diff --git a/java/java_test.go b/java/java_test.go
index 30a8ca6..a2788cb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1227,3 +1227,67 @@
checkPatchModuleFlag(t, ctx, "baz", expected)
})
}
+
+func TestJavaSystemModules(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_system_modules {
+ name: "system-modules",
+ libs: ["system-module1", "system-module2"],
+ }
+ java_library {
+ name: "system-module1",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ java_library {
+ name: "system-module2",
+ srcs: ["b.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ `)
+
+ // check the existence of the module
+ systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+ cmd := systemModules.Rule("jarsTosystemModules")
+
+ // make sure the command compiles against the supplied modules.
+ for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+ if !strings.Contains(cmd.Args["classpath"], module) {
+ t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+ module)
+ }
+ }
+}
+
+func TestJavaSystemModulesImport(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_system_modules_import {
+ name: "system-modules",
+ libs: ["system-module1", "system-module2"],
+ }
+ java_import {
+ name: "system-module1",
+ jars: ["a.jar"],
+ }
+ java_import {
+ name: "system-module2",
+ jars: ["b.jar"],
+ }
+ `)
+
+ // check the existence of the module
+ systemModules := ctx.ModuleForTests("system-modules", "android_common")
+
+ cmd := systemModules.Rule("jarsTosystemModules")
+
+ // make sure the command compiles against the supplied modules.
+ for _, module := range []string{"system-module1.jar", "system-module2.jar"} {
+ if !strings.Contains(cmd.Args["classpath"], module) {
+ t.Errorf("system modules classpath %v does not contain %q", cmd.Args["classpath"],
+ module)
+ }
+ }
+}
diff --git a/java/jdeps.go b/java/jdeps.go
index fccc40f..49e3de3 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -17,7 +17,6 @@
import (
"encoding/json"
"fmt"
- "os"
"android/soong/android"
)
@@ -92,23 +91,21 @@
moduleInfos[name] = dpInfo
})
- jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String()
+ jfpath := android.PathForOutput(ctx, jdepsJsonFileName)
err := createJsonFile(moduleInfos, jfpath)
if err != nil {
ctx.Errorf(err.Error())
}
}
-func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath string) error {
- file, err := os.Create(jfpath)
- if err != nil {
- return fmt.Errorf("Failed to create file: %s, relative: %v", jdepsJsonFileName, err)
- }
- defer file.Close()
+func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath android.WritablePath) error {
buf, err := json.MarshalIndent(moduleInfos, "", "\t")
if err != nil {
- return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err)
+ return fmt.Errorf("JSON marshal of java deps failed: %s", err)
}
- fmt.Fprintf(file, string(buf))
+ err = android.WriteFileToOutputDir(jfpath, buf, 0666)
+ if err != nil {
+ return fmt.Errorf("Writing java deps to %s failed: %s", jfpath.String(), err)
+ }
return nil
}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 715485f..d5c7579 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -80,6 +80,12 @@
p.metadata = outputPath
}
+func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
+ if p.metadata != nil {
+ ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String())
+ }
+}
+
func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule := android.NewRuleBuilder()
diff --git a/java/system_modules.go b/java/system_modules.go
index ed2fc18..92297c4 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -35,6 +35,7 @@
func RegisterSystemModulesBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_system_modules", SystemModulesFactory)
+ ctx.RegisterModuleType("java_system_modules_import", systemModulesImportFactory)
}
var (
@@ -92,6 +93,9 @@
return outDir, outputs.Paths()
}
+// java_system_modules creates a system module from a set of java libraries that can
+// be referenced from the system_modules property. It must contain at a minimum the
+// java.base module which must include classes from java.lang amongst other java packages.
func SystemModulesFactory() android.Module {
module := &SystemModules{}
module.AddProperties(&module.properties)
@@ -157,3 +161,30 @@
},
}
}
+
+// A prebuilt version of java_system_modules. It does not import the
+// generated system module, it generates the system module from imported
+// java libraries in the same way that java_system_modules does. It just
+// acts as a prebuilt, i.e. can have the same base name as another module
+// type and the one to use is selected at runtime.
+func systemModulesImportFactory() android.Module {
+ module := &systemModulesImport{}
+ module.AddProperties(&module.properties)
+ android.InitPrebuiltModule(module, &module.properties.Libs)
+ android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
+ return module
+}
+
+type systemModulesImport struct {
+ SystemModules
+ prebuilt android.Prebuilt
+}
+
+func (system *systemModulesImport) Name() string {
+ return system.prebuilt.Name(system.ModuleBase.Name())
+}
+
+func (system *systemModulesImport) Prebuilt() *android.Prebuilt {
+ return &system.prebuilt
+}
diff --git a/python/python.go b/python/python.go
index c67c577..8b912be 100644
--- a/python/python.go
+++ b/python/python.go
@@ -340,6 +340,11 @@
// dependencies later.
ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, "libsqlite")
+ if ctx.Device() {
+ ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag,
+ "liblog")
+ }
+
if ctx.Target().Os.Bionic() {
ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag,
"libc", "libdl", "libm")
diff --git a/rust/config/global.go b/rust/config/global.go
index ad8eb3a..fb9b14b 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -29,7 +29,6 @@
DefaultEdition = "2018"
Stdlibs = []string{
"libstd",
- "libterm",
"libtest",
}
diff --git a/rust/library.go b/rust/library.go
index 43819ce..0cf2dd0 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -323,6 +323,7 @@
return deps
}
func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.baseModuleName())
flags = library.baseCompiler.compilerFlags(ctx, flags)
if library.shared() || library.static() {
library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...)
@@ -337,7 +338,7 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
- if library.dylib() || library.shared() {
+ if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
// https://github.com/rust-lang/rust/issues/19680
// https://github.com/rust-lang/rust/issues/34909
diff --git a/rust/rust.go b/rust/rust.go
index 0eab8d2..14513fb 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -346,6 +346,11 @@
return nil
}
+func (mod *Module) AllStaticDeps() []string {
+ // TODO(jiyong): do this for rust?
+ return nil
+}
+
func (mod *Module) Module() android.Module {
return mod
}
diff --git a/scripts/test_config_fixer.py b/scripts/test_config_fixer.py
index 7bb4b52..32d5b17 100644
--- a/scripts/test_config_fixer.py
+++ b/scripts/test_config_fixer.py
@@ -37,6 +37,8 @@
help=('AndroidManifest.xml that contains the original package name'))
parser.add_argument('--package-name', default='', dest='package_name',
help=('overwrite package fields in the test config'))
+ parser.add_argument('--test-file-name', default='', dest='test_file_name',
+ help=('overwrite test file name in the test config'))
parser.add_argument('input', help='input test config file')
parser.add_argument('output', help='output test config file')
return parser.parse_args()
@@ -46,7 +48,6 @@
manifest = parse_manifest(manifest_doc)
original_package = manifest.getAttribute('package')
- print('package: ' + original_package)
test_config = parse_test_config(test_config_doc)
tests = get_children_with_tag(test_config, 'test')
@@ -57,6 +58,18 @@
if option.getAttribute('name') == "package" and option.getAttribute('value') == original_package:
option.setAttribute('value', package_name)
+def overwrite_test_file_name(test_config_doc, test_file_name):
+
+ test_config = parse_test_config(test_config_doc)
+ tests = get_children_with_tag(test_config, 'target_preparer')
+
+ for test in tests:
+ if test.getAttribute('class') == "com.android.tradefed.targetprep.TestAppInstallSetup":
+ options = get_children_with_tag(test, 'option')
+ for option in options:
+ if option.getAttribute('name') == "test-file-name":
+ option.setAttribute('value', test_file_name)
+
def main():
"""Program entry point."""
try:
@@ -70,6 +83,9 @@
manifest_doc = minidom.parse(args.manifest)
overwrite_package_name(doc, manifest_doc, args.package_name)
+ if args.test_file_name:
+ overwrite_test_file_name(doc, args.test_file_name)
+
with open(args.output, 'wb') as f:
write_xml(f, doc)
diff --git a/scripts/test_config_fixer_test.py b/scripts/test_config_fixer_test.py
index b90582e..1272c6b 100644
--- a/scripts/test_config_fixer_test.py
+++ b/scripts/test_config_fixer_test.py
@@ -67,5 +67,32 @@
self.assertEqual(expected, output.getvalue())
+class OverwriteTestFileNameTest(unittest.TestCase):
+ """ Unit tests for overwrite_test_file_name function """
+
+ test_config = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<configuration description="Runs some tests.">\n'
+ ' <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">\n'
+ ' <option name="test-file-name" value="%s"/>\n'
+ ' </target_preparer>\n'
+ ' <test class="com.android.tradefed.testtype.AndroidJUnitTest">\n'
+ ' <option name="package" value="com.android.foo"/>\n'
+ ' <option name="runtime-hint" value="20s"/>\n'
+ ' </test>\n'
+ '</configuration>\n')
+
+ def test_all(self):
+ doc = minidom.parseString(self.test_config % ("foo.apk"))
+
+ test_config_fixer.overwrite_test_file_name(doc, "bar.apk")
+ output = StringIO.StringIO()
+ test_config_fixer.write_xml(output, doc)
+
+ # Only the matching package name in a test node should be updated.
+ expected = self.test_config % ("bar.apk")
+ self.assertEqual(expected, output.getvalue())
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/sdk/bp.go b/sdk/bp.go
index 19fb70d..ae06a09 100644
--- a/sdk/bp.go
+++ b/sdk/bp.go
@@ -51,13 +51,23 @@
return s.properties[name]
}
-func (s *bpPropertySet) copy() bpPropertySet {
+func (s *bpPropertySet) deepCopy() *bpPropertySet {
propertiesCopy := make(map[string]interface{})
for p, v := range s.properties {
- propertiesCopy[p] = v
+ var valueCopy interface{}
+ if ps, ok := v.(*bpPropertySet); ok {
+ valueCopy = ps.deepCopy()
+ } else if values, ok := v.([]string); ok {
+ valuesCopy := make([]string, len(values))
+ copy(valuesCopy, values)
+ valueCopy = valuesCopy
+ } else {
+ valueCopy = v
+ }
+ propertiesCopy[p] = valueCopy
}
- return bpPropertySet{
+ return &bpPropertySet{
properties: propertiesCopy,
order: append([]string(nil), s.order...),
}
@@ -95,15 +105,15 @@
}
type bpModule struct {
- bpPropertySet
+ *bpPropertySet
moduleType string
}
var _ android.BpModule = (*bpModule)(nil)
-func (m *bpModule) copy() *bpModule {
+func (m *bpModule) deepCopy() *bpModule {
return &bpModule{
- bpPropertySet: m.bpPropertySet.copy(),
+ bpPropertySet: m.bpPropertySet.deepCopy(),
moduleType: m.moduleType,
}
}
@@ -134,8 +144,9 @@
func (f *bpFile) newModule(moduleType string) *bpModule {
module := &bpModule{
- moduleType: moduleType,
+ moduleType: moduleType,
+ bpPropertySet: &bpPropertySet{},
}
- (&module.bpPropertySet).init()
+ module.bpPropertySet.init()
return module
}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 255ac08..9a75610 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -101,6 +101,11 @@
srcs: ["libfoo.so"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
}
cc_prebuilt_library_shared {
@@ -109,6 +114,11 @@
srcs: ["libfoo.so"],
system_shared_libs: [],
stl: "none",
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex2",
+ ],
}
cc_library_shared {
@@ -117,6 +127,10 @@
shared_libs: ["sdkmember"],
system_shared_libs: [],
stl: "none",
+ apex_available: [
+ "myapex",
+ "myapex2",
+ ],
}
apex {
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 218a16a..692c205 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -73,6 +73,10 @@
sdk_version: "none",
compile_dex: true,
host_supported: true,
+ apex_available: [
+ "myapex",
+ "myapex2",
+ ],
}
apex {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 44e5cbb..3b0752f 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -285,12 +285,15 @@
// For dependencies from an in-development version of an SDK member to frozen versions of the same member
// e.g. libfoo -> libfoo.mysdk.11 and libfoo.mysdk.12
-type sdkMemberVesionedDepTag struct {
+type sdkMemberVersionedDepTag struct {
dependencyTag
member string
version string
}
+// Mark this tag so dependencies that use it are excluded from visibility enforcement.
+func (t sdkMemberVersionedDepTag) ExcludeFromVisibilityEnforcement() {}
+
// Step 1: create dependencies from an SDK module to its members.
func memberMutator(mctx android.BottomUpMutatorContext) {
if s, ok := mctx.Module().(*sdk); ok {
@@ -337,7 +340,7 @@
if m, ok := mctx.Module().(android.SdkAware); ok && m.IsInAnySdk() {
if !m.ContainingSdk().Unversioned() {
memberName := m.MemberName()
- tag := sdkMemberVesionedDepTag{member: memberName, version: m.ContainingSdk().Version}
+ tag := sdkMemberVersionedDepTag{member: memberName, version: m.ContainingSdk().Version}
mctx.AddReverseDependency(mctx.Module(), tag, memberName)
}
}
diff --git a/sdk/testing.go b/sdk/testing.go
index 8097889..c9cc30f 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -62,14 +62,12 @@
ctx := android.NewTestArchContext()
// from android package
- ctx.PreArchMutators(android.RegisterPackageRenamer)
+ android.RegisterPackageBuildComponents(ctx)
ctx.PreArchMutators(android.RegisterVisibilityRuleChecker)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(android.RegisterVisibilityRuleGatherer)
ctx.PostDepsMutators(android.RegisterVisibilityRuleEnforcer)
- ctx.RegisterModuleType("package", android.PackageFactory)
-
// from java package
java.RegisterJavaBuildComponents(ctx)
java.RegisterAppBuildComponents(ctx)
diff --git a/sdk/update.go b/sdk/update.go
index 5bc3b83..2731d50 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -196,7 +196,7 @@
for _, unversioned := range builder.prebuiltOrder {
// Copy the unversioned module so it can be modified to make it versioned.
- versioned := unversioned.copy()
+ versioned := unversioned.deepCopy()
name := versioned.properties["name"].(string)
versioned.setProperty("name", builder.versionedSdkMemberName(name))
versioned.insertAfter("name", "sdk_member_name", name)
@@ -286,7 +286,7 @@
for _, bpModule := range bpFile.order {
contents.Printfln("")
contents.Printfln("%s {", bpModule.moduleType)
- outputPropertySet(contents, &bpModule.bpPropertySet)
+ outputPropertySet(contents, bpModule.bpPropertySet)
contents.Printfln("}")
}
}
diff --git a/ui/build/build.go b/ui/build/build.go
index 1c2d864..69ef003 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -19,6 +19,8 @@
"os"
"path/filepath"
"text/template"
+
+ "android/soong/ui/metrics"
)
// Ensures the out directory exists, and has the proper files to prevent kati
@@ -139,6 +141,9 @@
ctx.Verboseln("Environment:", config.Environment().Environ())
ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024)
+ ctx.BeginTrace(metrics.Total, "total")
+ defer ctx.EndTrace()
+
if config.SkipMake() {
ctx.Verboseln("Skipping Make/Kati as requested")
what = what & (BuildSoong | BuildNinja)
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 8c6ebb8..0b56b67 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -127,6 +127,7 @@
"GOMA_USE_LOCAL",
// RBE client
+ "FLAG_compare",
"FLAG_exec_root",
"FLAG_exec_strategy",
"FLAG_invocation_id",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 711a9c7..bfe662d 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -82,14 +82,11 @@
"fuser": Allowed,
"getopt": Allowed,
"git": Allowed,
- "gzcat": Allowed,
- "gzip": Allowed,
"hexdump": Allowed,
"jar": Allowed,
"java": Allowed,
"javap": Allowed,
"lsof": Allowed,
- "m4": Log,
"openssl": Allowed,
"patch": Allowed,
"pstree": Allowed,
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 3388417..afbc073 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -119,6 +119,7 @@
"-j", strconv.Itoa(config.Parallel()),
"--frontend_file", fifo,
"-f", filepath.Join(config.SoongOutDir(), file))
+ cmd.Environment.Set("SOONG_SANDBOX_SOONG_BUILD", "true")
cmd.Sandbox = soongSandbox
cmd.RunAndStreamOrFatal()
}
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index 64bbbf3..8254e4a 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -30,6 +30,7 @@
RunSoong = "soong"
PrimaryNinja = "ninja"
TestRun = "test"
+ Total = "total"
)
type Metrics struct {
@@ -56,6 +57,8 @@
case PrimaryNinja:
m.metrics.NinjaRuns = append(m.metrics.NinjaRuns, &perf)
break
+ case Total:
+ m.metrics.Total = &perf
default:
// ignored
}
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 0fe5a0d..3986d0e 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -195,10 +195,12 @@
// The metrics for calling Soong.
SoongRuns []*PerfInfo `protobuf:"bytes,19,rep,name=soong_runs,json=soongRuns" json:"soong_runs,omitempty"`
// The metrics for calling Ninja.
- NinjaRuns []*PerfInfo `protobuf:"bytes,20,rep,name=ninja_runs,json=ninjaRuns" json:"ninja_runs,omitempty"`
- XXX_NoUnkeyedLiteral struct{} `json:"-"`
- XXX_unrecognized []byte `json:"-"`
- XXX_sizecache int32 `json:"-"`
+ NinjaRuns []*PerfInfo `protobuf:"bytes,20,rep,name=ninja_runs,json=ninjaRuns" json:"ninja_runs,omitempty"`
+ // The metrics for the whole build
+ Total *PerfInfo `protobuf:"bytes,21,opt,name=total" json:"total,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
}
func (m *MetricsBase) Reset() { *m = MetricsBase{} }
@@ -371,6 +373,13 @@
return nil
}
+func (m *MetricsBase) GetTotal() *PerfInfo {
+ if m != nil {
+ return m.Total
+ }
+ return nil
+}
+
type PerfInfo struct {
// The description for the phase/action/part while the tool running.
Desc *string `protobuf:"bytes,1,opt,name=desc" json:"desc,omitempty"`
@@ -612,58 +621,58 @@
func init() { proto.RegisterFile("metrics.proto", fileDescriptor_6039342a2ba47b72) }
var fileDescriptor_6039342a2ba47b72 = []byte{
- // 834 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x6f, 0x6b, 0xdb, 0x46,
- 0x18, 0xaf, 0x62, 0x25, 0xb6, 0x1e, 0xc5, 0xae, 0x7a, 0xc9, 0xa8, 0xba, 0x12, 0x66, 0xc4, 0x3a,
- 0xf2, 0x62, 0x75, 0x8b, 0x29, 0xa1, 0x98, 0x32, 0x48, 0x1c, 0x53, 0xba, 0x60, 0xbb, 0x28, 0x71,
- 0x57, 0xb6, 0x17, 0x87, 0x22, 0x9d, 0x1b, 0x75, 0x96, 0x4e, 0xdc, 0x9d, 0xca, 0xfc, 0x21, 0xf6,
- 0x4d, 0xf6, 0xb5, 0xf6, 0x3d, 0xc6, 0x3d, 0x27, 0x39, 0x0a, 0x78, 0x34, 0xf4, 0xdd, 0xe9, 0xf9,
- 0xfd, 0xb9, 0xdf, 0x73, 0xd2, 0x3d, 0x82, 0x6e, 0xc6, 0x94, 0x48, 0x63, 0x39, 0x28, 0x04, 0x57,
- 0x9c, 0x1c, 0x48, 0xce, 0xf3, 0x4f, 0xf4, 0xba, 0x4c, 0x57, 0x09, 0xad, 0xa0, 0xe0, 0x1f, 0x07,
- 0xdc, 0xa9, 0x59, 0x9f, 0x45, 0x92, 0x91, 0x97, 0x70, 0x68, 0x08, 0x49, 0xa4, 0x18, 0x55, 0x69,
- 0xc6, 0xa4, 0x8a, 0xb2, 0xc2, 0xb7, 0xfa, 0xd6, 0x71, 0x2b, 0x24, 0x88, 0x9d, 0x47, 0x8a, 0x5d,
- 0xd5, 0x08, 0x79, 0x02, 0x1d, 0xa3, 0x48, 0x13, 0x7f, 0xa7, 0x6f, 0x1d, 0x3b, 0x61, 0x1b, 0x9f,
- 0xdf, 0x25, 0x64, 0x04, 0x4f, 0x8a, 0x55, 0xa4, 0x96, 0x5c, 0x64, 0xf4, 0x0b, 0x13, 0x32, 0xe5,
- 0x39, 0x8d, 0x79, 0xc2, 0xf2, 0x28, 0x63, 0x7e, 0x0b, 0xb9, 0x8f, 0x6b, 0xc2, 0x07, 0x83, 0x8f,
- 0x2b, 0x98, 0x3c, 0x83, 0x9e, 0x8a, 0xc4, 0x27, 0xa6, 0x68, 0x21, 0x78, 0x52, 0xc6, 0xca, 0xb7,
- 0x51, 0xd0, 0x35, 0xd5, 0xf7, 0xa6, 0x48, 0x12, 0x38, 0xac, 0x68, 0x26, 0xc4, 0x97, 0x48, 0xa4,
- 0x51, 0xae, 0xfc, 0xdd, 0xbe, 0x75, 0xdc, 0x1b, 0x3e, 0x1f, 0x6c, 0xe9, 0x79, 0xd0, 0xe8, 0x77,
- 0x70, 0xa6, 0x91, 0x0f, 0x46, 0x34, 0x6a, 0x4d, 0x66, 0x6f, 0x43, 0x62, 0xfc, 0x9a, 0x00, 0x99,
- 0x83, 0x5b, 0xed, 0x12, 0x89, 0xf8, 0xc6, 0xdf, 0x43, 0xf3, 0x67, 0x5f, 0x35, 0x3f, 0x15, 0xf1,
- 0xcd, 0xa8, 0xbd, 0x98, 0x5d, 0xcc, 0xe6, 0xbf, 0xcd, 0x42, 0x30, 0x16, 0xba, 0x48, 0x06, 0x70,
- 0xd0, 0x30, 0xdc, 0xa4, 0x6e, 0x63, 0x8b, 0x8f, 0x6e, 0x89, 0x75, 0x80, 0x9f, 0xa1, 0x8a, 0x45,
- 0xe3, 0xa2, 0xdc, 0xd0, 0x3b, 0x48, 0xf7, 0x0c, 0x32, 0x2e, 0xca, 0x9a, 0x7d, 0x01, 0xce, 0x0d,
- 0x97, 0x55, 0x58, 0xe7, 0x9b, 0xc2, 0x76, 0xb4, 0x01, 0x46, 0x0d, 0xa1, 0x8b, 0x66, 0xc3, 0x3c,
- 0x31, 0x86, 0xf0, 0x4d, 0x86, 0xae, 0x36, 0x19, 0xe6, 0x09, 0x7a, 0x3e, 0x86, 0x36, 0x7a, 0x72,
- 0xe9, 0xbb, 0xd8, 0xc3, 0x9e, 0x7e, 0x9c, 0x4b, 0x12, 0x54, 0x9b, 0x71, 0x49, 0xd9, 0x5f, 0x4a,
- 0x44, 0xfe, 0x3e, 0xc2, 0xae, 0x81, 0x27, 0xba, 0xb4, 0xe1, 0xc4, 0x82, 0x4b, 0xa9, 0x2d, 0xba,
- 0xb7, 0x9c, 0xb1, 0xae, 0xcd, 0x25, 0xf9, 0x09, 0x1e, 0x36, 0x38, 0x18, 0xbb, 0x67, 0x3e, 0x9f,
- 0x0d, 0x0b, 0x83, 0x3c, 0x87, 0x83, 0x06, 0x6f, 0xd3, 0xe2, 0x43, 0x73, 0xb0, 0x1b, 0x6e, 0x23,
- 0x37, 0x2f, 0x15, 0x4d, 0x52, 0xe1, 0x7b, 0x26, 0x37, 0x2f, 0xd5, 0x79, 0x2a, 0xc8, 0x2f, 0xe0,
- 0x4a, 0xa6, 0xca, 0x82, 0x2a, 0xce, 0x57, 0xd2, 0x7f, 0xd4, 0x6f, 0x1d, 0xbb, 0xc3, 0xa3, 0xad,
- 0x47, 0xf4, 0x9e, 0x89, 0xe5, 0xbb, 0x7c, 0xc9, 0x43, 0x40, 0xc5, 0x95, 0x16, 0x90, 0x11, 0x38,
- 0x7f, 0x46, 0x2a, 0xa5, 0xa2, 0xcc, 0xa5, 0x4f, 0xee, 0xa3, 0xee, 0x68, 0x7e, 0x58, 0xe6, 0x92,
- 0xbc, 0x01, 0x30, 0x4c, 0x14, 0x1f, 0xdc, 0x47, 0xec, 0x20, 0x5a, 0xab, 0xf3, 0x34, 0xff, 0x1c,
- 0x19, 0xf5, 0xe1, 0xbd, 0xd4, 0x28, 0xd0, 0xea, 0xe0, 0x25, 0xec, 0xdf, 0xb9, 0x28, 0x1d, 0xb0,
- 0x17, 0x97, 0x93, 0xd0, 0x7b, 0x40, 0xba, 0xe0, 0xe8, 0xd5, 0xf9, 0xe4, 0x6c, 0xf1, 0xd6, 0xb3,
- 0x48, 0x1b, 0xf4, 0xe5, 0xf2, 0x76, 0x82, 0x37, 0x60, 0xe3, 0x51, 0xba, 0x50, 0x7f, 0x1a, 0xde,
- 0x03, 0x8d, 0x9e, 0x86, 0x53, 0xcf, 0x22, 0x0e, 0xec, 0x9e, 0x86, 0xd3, 0x93, 0x57, 0xde, 0x8e,
- 0xae, 0x7d, 0x7c, 0x7d, 0xe2, 0xb5, 0x08, 0xc0, 0xde, 0xc7, 0xd7, 0x27, 0xf4, 0xe4, 0x95, 0x67,
- 0x07, 0x7f, 0x5b, 0xd0, 0xa9, 0x73, 0x10, 0x02, 0x76, 0xc2, 0x64, 0x8c, 0xb3, 0xc9, 0x09, 0x71,
- 0xad, 0x6b, 0x38, 0x5d, 0xcc, 0x24, 0xc2, 0x35, 0x39, 0x02, 0x90, 0x2a, 0x12, 0x0a, 0xc7, 0x19,
- 0xce, 0x1d, 0x3b, 0x74, 0xb0, 0xa2, 0xa7, 0x18, 0x79, 0x0a, 0x8e, 0x60, 0xd1, 0xca, 0xa0, 0x36,
- 0xa2, 0x1d, 0x5d, 0x40, 0xf0, 0x08, 0x20, 0x63, 0x19, 0x17, 0x6b, 0x5a, 0x4a, 0x86, 0x53, 0xc5,
- 0x0e, 0x1d, 0x53, 0x59, 0x48, 0x16, 0xfc, 0x6b, 0x41, 0x6f, 0xca, 0x93, 0x72, 0xc5, 0xae, 0xd6,
- 0x05, 0xc3, 0x54, 0x7f, 0xc0, 0xbe, 0x39, 0x37, 0xb9, 0x96, 0x8a, 0x65, 0x98, 0xae, 0x37, 0x7c,
- 0xb1, 0xfd, 0xba, 0xdc, 0x91, 0x9a, 0x61, 0x74, 0x89, 0xb2, 0xc6, 0xc5, 0xb9, 0xbe, 0xad, 0x92,
- 0x1f, 0xc0, 0xcd, 0x50, 0x43, 0xd5, 0xba, 0xa8, 0xbb, 0x84, 0x6c, 0x63, 0x43, 0x7e, 0x84, 0x5e,
- 0x5e, 0x66, 0x94, 0x2f, 0xa9, 0x29, 0x4a, 0xec, 0xb7, 0x1b, 0xee, 0xe7, 0x65, 0x36, 0x5f, 0x9a,
- 0xfd, 0x64, 0xf0, 0x02, 0xdc, 0xc6, 0x5e, 0x77, 0xdf, 0x85, 0x03, 0xbb, 0x97, 0xf3, 0xf9, 0x4c,
- 0xbf, 0xb4, 0x0e, 0xd8, 0xd3, 0xd3, 0x8b, 0x89, 0xb7, 0x13, 0xac, 0xe0, 0xfb, 0xb1, 0x48, 0x55,
- 0x1a, 0x47, 0xab, 0x85, 0x64, 0xe2, 0x57, 0x5e, 0x8a, 0x9c, 0xad, 0xab, 0xdb, 0xbe, 0x39, 0x74,
- 0xab, 0x71, 0xe8, 0x23, 0x68, 0x57, 0x5d, 0x62, 0x4a, 0x77, 0xd8, 0xff, 0xda, 0xc0, 0x08, 0x6b,
- 0x41, 0x70, 0x0d, 0x4f, 0xb7, 0xec, 0x26, 0xeb, 0xed, 0xc6, 0x60, 0xc7, 0xe5, 0x67, 0xe9, 0x5b,
- 0xf8, 0xb1, 0x6e, 0x3f, 0xd9, 0xff, 0x4f, 0x1b, 0xa2, 0xf8, 0xec, 0xbb, 0xdf, 0xab, 0xff, 0x61,
- 0xa5, 0xa0, 0xf8, 0x93, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x20, 0x07, 0xbc, 0xf0, 0x34, 0x07,
- 0x00, 0x00,
+ // 847 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x6e, 0xdb, 0x36,
+ 0x14, 0xae, 0x12, 0x25, 0xb6, 0x8e, 0x62, 0x57, 0x65, 0x52, 0x54, 0x5d, 0x11, 0xcc, 0x10, 0xd6,
+ 0x21, 0x17, 0xab, 0x5b, 0x78, 0x45, 0x50, 0x18, 0xc5, 0x80, 0xc4, 0x31, 0x8a, 0x2e, 0xb0, 0x5d,
+ 0x28, 0x71, 0x57, 0x6c, 0x17, 0x02, 0x23, 0xd1, 0x8d, 0x3a, 0x4b, 0x14, 0x48, 0xaa, 0x98, 0x1f,
+ 0x62, 0x0f, 0xb9, 0x8b, 0xbd, 0xc7, 0xc0, 0x43, 0xc9, 0x51, 0x00, 0x0f, 0x09, 0x7a, 0x47, 0x9d,
+ 0xef, 0x87, 0xdf, 0xa1, 0xc4, 0x23, 0xe8, 0x64, 0x4c, 0x89, 0x34, 0x96, 0xfd, 0x42, 0x70, 0xc5,
+ 0xc9, 0xbe, 0xe4, 0x3c, 0xff, 0x1c, 0x5d, 0x95, 0xe9, 0x32, 0x89, 0x2a, 0x28, 0xf8, 0xc7, 0x01,
+ 0x77, 0x62, 0xd6, 0xa7, 0x54, 0x32, 0xf2, 0x0a, 0x0e, 0x0c, 0x21, 0xa1, 0x8a, 0x45, 0x2a, 0xcd,
+ 0x98, 0x54, 0x34, 0x2b, 0x7c, 0xab, 0x67, 0x1d, 0x6d, 0x87, 0x04, 0xb1, 0x33, 0xaa, 0xd8, 0x65,
+ 0x8d, 0x90, 0xa7, 0xd0, 0x36, 0x8a, 0x34, 0xf1, 0xb7, 0x7a, 0xd6, 0x91, 0x13, 0xb6, 0xf0, 0xf9,
+ 0x7d, 0x42, 0x86, 0xf0, 0xb4, 0x58, 0x52, 0xb5, 0xe0, 0x22, 0x8b, 0xbe, 0x32, 0x21, 0x53, 0x9e,
+ 0x47, 0x31, 0x4f, 0x58, 0x4e, 0x33, 0xe6, 0x6f, 0x23, 0xf7, 0x49, 0x4d, 0xf8, 0x68, 0xf0, 0x51,
+ 0x05, 0x93, 0xe7, 0xd0, 0x55, 0x54, 0x7c, 0x66, 0x2a, 0x2a, 0x04, 0x4f, 0xca, 0x58, 0xf9, 0x36,
+ 0x0a, 0x3a, 0xa6, 0xfa, 0xc1, 0x14, 0x49, 0x02, 0x07, 0x15, 0xcd, 0x84, 0xf8, 0x4a, 0x45, 0x4a,
+ 0x73, 0xe5, 0xef, 0xf4, 0xac, 0xa3, 0xee, 0xe0, 0x45, 0x7f, 0x43, 0xcf, 0xfd, 0x46, 0xbf, 0xfd,
+ 0x53, 0x8d, 0x7c, 0x34, 0xa2, 0xe1, 0xf6, 0x78, 0xfa, 0x2e, 0x24, 0xc6, 0xaf, 0x09, 0x90, 0x19,
+ 0xb8, 0xd5, 0x2e, 0x54, 0xc4, 0xd7, 0xfe, 0x2e, 0x9a, 0x3f, 0xbf, 0xd3, 0xfc, 0x44, 0xc4, 0xd7,
+ 0xc3, 0xd6, 0x7c, 0x7a, 0x3e, 0x9d, 0xfd, 0x36, 0x0d, 0xc1, 0x58, 0xe8, 0x22, 0xe9, 0xc3, 0x7e,
+ 0xc3, 0x70, 0x9d, 0xba, 0x85, 0x2d, 0x3e, 0xba, 0x21, 0xd6, 0x01, 0x7e, 0x82, 0x2a, 0x56, 0x14,
+ 0x17, 0xe5, 0x9a, 0xde, 0x46, 0xba, 0x67, 0x90, 0x51, 0x51, 0xd6, 0xec, 0x73, 0x70, 0xae, 0xb9,
+ 0xac, 0xc2, 0x3a, 0xdf, 0x14, 0xb6, 0xad, 0x0d, 0x30, 0x6a, 0x08, 0x1d, 0x34, 0x1b, 0xe4, 0x89,
+ 0x31, 0x84, 0x6f, 0x32, 0x74, 0xb5, 0xc9, 0x20, 0x4f, 0xd0, 0xf3, 0x09, 0xb4, 0xd0, 0x93, 0x4b,
+ 0xdf, 0xc5, 0x1e, 0x76, 0xf5, 0xe3, 0x4c, 0x92, 0xa0, 0xda, 0x8c, 0xcb, 0x88, 0xfd, 0xa5, 0x04,
+ 0xf5, 0xf7, 0x10, 0x76, 0x0d, 0x3c, 0xd6, 0xa5, 0x35, 0x27, 0x16, 0x5c, 0x4a, 0x6d, 0xd1, 0xb9,
+ 0xe1, 0x8c, 0x74, 0x6d, 0x26, 0xc9, 0x8f, 0xf0, 0xb0, 0xc1, 0xc1, 0xd8, 0x5d, 0xf3, 0xf9, 0xac,
+ 0x59, 0x18, 0xe4, 0x05, 0xec, 0x37, 0x78, 0xeb, 0x16, 0x1f, 0x9a, 0x83, 0x5d, 0x73, 0x1b, 0xb9,
+ 0x79, 0xa9, 0xa2, 0x24, 0x15, 0xbe, 0x67, 0x72, 0xf3, 0x52, 0x9d, 0xa5, 0x82, 0xfc, 0x02, 0xae,
+ 0x64, 0xaa, 0x2c, 0x22, 0xc5, 0xf9, 0x52, 0xfa, 0x8f, 0x7a, 0xdb, 0x47, 0xee, 0xe0, 0x70, 0xe3,
+ 0x11, 0x7d, 0x60, 0x62, 0xf1, 0x3e, 0x5f, 0xf0, 0x10, 0x50, 0x71, 0xa9, 0x05, 0x64, 0x08, 0xce,
+ 0x9f, 0x54, 0xa5, 0x91, 0x28, 0x73, 0xe9, 0x93, 0xfb, 0xa8, 0xdb, 0x9a, 0x1f, 0x96, 0xb9, 0x24,
+ 0x6f, 0x01, 0x0c, 0x13, 0xc5, 0xfb, 0xf7, 0x11, 0x3b, 0x88, 0xd6, 0xea, 0x3c, 0xcd, 0xbf, 0x50,
+ 0xa3, 0x3e, 0xb8, 0x97, 0x1a, 0x05, 0xa8, 0xfe, 0x19, 0x76, 0x14, 0x57, 0x74, 0xe9, 0x3f, 0xee,
+ 0x59, 0x77, 0x0b, 0x0d, 0x37, 0x78, 0x05, 0x7b, 0xb7, 0x6e, 0x57, 0x1b, 0xec, 0xf9, 0xc5, 0x38,
+ 0xf4, 0x1e, 0x90, 0x0e, 0x38, 0x7a, 0x75, 0x36, 0x3e, 0x9d, 0xbf, 0xf3, 0x2c, 0xd2, 0x02, 0x7d,
+ 0x23, 0xbd, 0xad, 0xe0, 0x2d, 0xd8, 0x78, 0xfe, 0x2e, 0xd4, 0xdf, 0x93, 0xf7, 0x40, 0xa3, 0x27,
+ 0xe1, 0xc4, 0xb3, 0x88, 0x03, 0x3b, 0x27, 0xe1, 0xe4, 0xf8, 0xb5, 0xb7, 0xa5, 0x6b, 0x9f, 0xde,
+ 0x1c, 0x7b, 0xdb, 0x04, 0x60, 0xf7, 0xd3, 0x9b, 0xe3, 0xe8, 0xf8, 0xb5, 0x67, 0x07, 0x7f, 0x5b,
+ 0xd0, 0xae, 0x33, 0x10, 0x02, 0x76, 0xc2, 0x64, 0x8c, 0x03, 0xcd, 0x09, 0x71, 0xad, 0x6b, 0x38,
+ 0x92, 0xcc, 0xf8, 0xc2, 0x35, 0x39, 0x04, 0x90, 0x8a, 0x0a, 0x85, 0x33, 0x10, 0x87, 0x95, 0x1d,
+ 0x3a, 0x58, 0xd1, 0xa3, 0x8f, 0x3c, 0x03, 0x47, 0x30, 0xba, 0x34, 0xa8, 0x8d, 0x68, 0x5b, 0x17,
+ 0x10, 0x3c, 0x04, 0xc8, 0x58, 0xc6, 0xc5, 0x2a, 0x2a, 0x25, 0xc3, 0x51, 0x64, 0x87, 0x8e, 0xa9,
+ 0xcc, 0x25, 0x0b, 0xfe, 0xb5, 0xa0, 0x3b, 0xe1, 0x49, 0xb9, 0x64, 0x97, 0xab, 0x82, 0x61, 0xaa,
+ 0x3f, 0x60, 0xcf, 0x9c, 0x99, 0x5c, 0x49, 0xc5, 0x32, 0x4c, 0xd7, 0x1d, 0xbc, 0xdc, 0x7c, 0xc7,
+ 0x6e, 0x49, 0xcd, 0x04, 0xbb, 0x40, 0x59, 0xe3, 0xb6, 0x5d, 0xdd, 0x54, 0xc9, 0xf7, 0xe0, 0x66,
+ 0xa8, 0x89, 0xd4, 0xaa, 0xa8, 0xbb, 0x84, 0x6c, 0x6d, 0x43, 0x7e, 0x80, 0x6e, 0x5e, 0x66, 0x11,
+ 0x5f, 0x44, 0xa6, 0x28, 0xb1, 0xdf, 0x4e, 0xb8, 0x97, 0x97, 0xd9, 0x6c, 0x61, 0xf6, 0x93, 0xc1,
+ 0x4b, 0x70, 0x1b, 0x7b, 0xdd, 0x7e, 0x17, 0x0e, 0xec, 0x5c, 0xcc, 0x66, 0x53, 0xfd, 0xd2, 0xda,
+ 0x60, 0x4f, 0x4e, 0xce, 0xc7, 0xde, 0x56, 0xb0, 0x84, 0xef, 0x46, 0x22, 0x55, 0x69, 0x4c, 0x97,
+ 0x73, 0xc9, 0xc4, 0xaf, 0xbc, 0x14, 0x39, 0x5b, 0x55, 0x23, 0x62, 0x7d, 0xe8, 0x56, 0xe3, 0xd0,
+ 0x87, 0xd0, 0xaa, 0xba, 0xc4, 0x94, 0xee, 0xa0, 0x77, 0xd7, 0x94, 0x09, 0x6b, 0x41, 0x70, 0x05,
+ 0xcf, 0x36, 0xec, 0x26, 0xeb, 0xed, 0x46, 0x60, 0xc7, 0xe5, 0x17, 0xe9, 0x5b, 0xf8, 0x85, 0x6f,
+ 0x3e, 0xd9, 0xff, 0x4f, 0x1b, 0xa2, 0xf8, 0xf4, 0xf1, 0xef, 0xd5, 0x4f, 0xb4, 0x52, 0x44, 0xf8,
+ 0x67, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xbd, 0xe2, 0xb1, 0x69, 0x07, 0x00, 0x00,
}
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 1ea24bf..194aa6b 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -89,6 +89,9 @@
// The metrics for calling Ninja.
repeated PerfInfo ninja_runs = 20;
+
+ // The metrics for the whole build
+ optional PerfInfo total = 21;
}
message PerfInfo {