Merge "use symlink for bundled APEX"
diff --git a/Android.bp b/Android.bp
index 9403b26..0382ee2 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/config.go b/android/config.go
index 101f457..3c49c1a 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) {
@@ -901,8 +914,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..67d1f12 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
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_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/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/register.go b/android/register.go
index b5defec..b48d3d1 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() {
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/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 d5ab1f6..7449a3f 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -144,6 +144,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
@@ -155,6 +158,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 {
diff --git a/apex/apex.go b/apex/apex.go
index 0dbd280..fb61a58 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -465,6 +465,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 {
@@ -553,9 +555,9 @@
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
@@ -727,6 +729,12 @@
ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
javaLibTag, a.properties.Java_libs...)
+ // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
+ if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ javaLibTag, "jacocoagent")
+ }
+
if String(a.properties.Key) == "" {
ctx.ModuleErrorf("key is missing")
return
@@ -917,7 +925,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 {
@@ -930,6 +940,7 @@
android.Module
Privileged() bool
OutputFile() android.Path
+ JacocoReportClassesFile() android.Path
}, pkgName string) apexFile {
appDir := "app"
if aapp.Privileged() {
@@ -937,7 +948,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`.
@@ -1281,8 +1294,7 @@
a.buildUnflattenedApex(ctx)
}
- apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
- a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
+ a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
}
func newApexBundle() *apexBundle {
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/cc/androidmk.go b/cc/androidmk.go
index 988ebd4..ff88091 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -284,6 +284,9 @@
fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", benchmark.testConfig.String())
}
fmt.Fprintln(w, "LOCAL_NATIVE_BENCHMARK := true")
+ if !BoolDefault(benchmark.Properties.Auto_gen_config, true) {
+ fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ }
})
androidMkWriteTestData(benchmark.data, ctx, ret)
@@ -304,6 +307,9 @@
if test.testConfig != nil {
fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", test.testConfig.String())
}
+ if !BoolDefault(test.Properties.Auto_gen_config, true) {
+ fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ }
})
androidMkWriteTestData(test.data, ctx, ret)
diff --git a/cc/cc.go b/cc/cc.go
index 0c32225..04f0351 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2460,7 +2460,25 @@
}
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) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
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/vndk.go b/cc/config/vndk.go
index c3cda49..9feb5a3 100644
--- a/cc/config/vndk.go
+++ b/cc/config/vndk.go
@@ -84,6 +84,7 @@
"android.hardware.thermal@1.0",
"android.hardware.tv.cec@1.0",
"android.hardware.tv.input@1.0",
+ "android.hardware.vibrator-ndk_platform",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
@@ -165,5 +166,4 @@
"libxml2",
"libyuv",
"libziparchive",
- "vintf-vibrator-ndk_platform",
}
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 4618f4e..0072355 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -210,11 +210,6 @@
ctx.ModuleErrorf("PGO specification is missing properties: " + missingProps)
}
- // Sampling not supported yet
- if isSampling {
- ctx.PropertyErrorf("pgo.sampling", "\"sampling\" is not supported yet)")
- }
-
if isSampling && isInstrumentation {
ctx.PropertyErrorf("pgo", "Exactly one of \"instrumentation\" and \"sampling\" properties must be set")
}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 83e3673..2a929c5 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -16,13 +16,14 @@
import (
"encoding/json"
- "io/ioutil"
"strings"
"android/soong/android"
)
-// GlobalConfig stores the configuration for dex preopting set by the product
+// GlobalConfig stores the configuration for dex preopting. The fields are set
+// from product variables via dex_preopt_config.mk, except for SoongConfig
+// which come from CreateGlobalSoongConfig.
type GlobalConfig struct {
DisablePreopt bool // disable preopt for all modules
DisablePreoptModules []string // modules with preopt disabled by product-specific config
@@ -82,19 +83,19 @@
Dex2oatImageXmx string // max heap size for dex2oat for the boot image
Dex2oatImageXms string // initial heap size for dex2oat for the boot image
- Tools Tools // paths to tools possibly used by the generated commands
+ SoongConfig GlobalSoongConfig // settings read from dexpreopt_soong.config
}
-// Tools contains paths to tools possibly used by the generated commands. If you add a new tool here you MUST add it
-// to the order-only dependency list in DEXPREOPT_GEN_DEPS.
-type Tools struct {
- Profman android.Path
- Dex2oat android.Path
- Aapt android.Path
- SoongZip android.Path
- Zip2zip android.Path
- ManifestCheck android.Path
-
+// GlobalSoongConfig contains the global config that is generated from Soong,
+// stored in dexpreopt_soong.config.
+type GlobalSoongConfig struct {
+ // Paths to tools possibly used by the generated commands.
+ Profman android.Path
+ Dex2oat android.Path
+ Aapt android.Path
+ SoongZip android.Path
+ Zip2zip android.Path
+ ManifestCheck android.Path
ConstructContext android.Path
}
@@ -133,6 +134,17 @@
PresignedPrebuilt bool
}
+type globalSoongConfigSingleton struct{}
+
+var pctx = android.NewPackageContext("android/soong/dexpreopt")
+
+func init() {
+ pctx.Import("android/soong/android")
+ android.RegisterSingletonType("dexpreopt-soong-config", func() android.Singleton {
+ return &globalSoongConfigSingleton{}
+ })
+}
+
func constructPath(ctx android.PathContext, path string) android.Path {
buildDirPrefix := ctx.Config().BuildDir() + "/"
if path == "" {
@@ -167,9 +179,12 @@
return constructPath(ctx, path).(android.WritablePath)
}
-// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig struct. It 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) (GlobalConfig, []byte, error) {
+// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig
+// struct, except the SoongConfig field which is set from the provided
+// 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, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) {
type GlobalJSONConfig struct {
GlobalConfig
@@ -177,44 +192,29 @@
// used to construct the real value manually below.
DirtyImageObjects string
BootImageProfiles []string
-
- Tools struct {
- Profman string
- Dex2oat string
- Aapt string
- SoongZip string
- Zip2zip string
- ManifestCheck string
-
- ConstructContext string
- }
}
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.
config.GlobalConfig.DirtyImageObjects = android.OptionalPathForPath(constructPath(ctx, config.DirtyImageObjects))
config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles)
- config.GlobalConfig.Tools.Profman = constructPath(ctx, config.Tools.Profman)
- config.GlobalConfig.Tools.Dex2oat = constructPath(ctx, config.Tools.Dex2oat)
- config.GlobalConfig.Tools.Aapt = constructPath(ctx, config.Tools.Aapt)
- config.GlobalConfig.Tools.SoongZip = constructPath(ctx, config.Tools.SoongZip)
- config.GlobalConfig.Tools.Zip2zip = constructPath(ctx, config.Tools.Zip2zip)
- config.GlobalConfig.Tools.ManifestCheck = constructPath(ctx, config.Tools.ManifestCheck)
- config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext)
+ // Set this here to force the caller to provide a value for this struct (from
+ // 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
@@ -232,7 +232,7 @@
config := ModuleJSONConfig{}
- _, err := loadConfig(ctx, path, &config)
+ err := json.Unmarshal(data, &config)
if err != nil {
return config.ModuleConfig, err
}
@@ -253,24 +253,102 @@
return config.ModuleConfig, nil
}
-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
+// CreateGlobalSoongConfig creates a GlobalSoongConfig from the current context.
+// Should not be used in dexpreopt_gen.
+func CreateGlobalSoongConfig(ctx android.PathContext) GlobalSoongConfig {
+ // Default to debug version to help find bugs.
+ // Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
+ var dex2oatBinary string
+ if ctx.Config().Getenv("USE_DEX2OAT_DEBUG") == "false" {
+ dex2oatBinary = "dex2oat"
+ } else {
+ dex2oatBinary = "dex2oatd"
}
- err = json.Unmarshal(data, config)
+ return GlobalSoongConfig{
+ Profman: ctx.Config().HostToolPath(ctx, "profman"),
+ Dex2oat: ctx.Config().HostToolPath(ctx, dex2oatBinary),
+ Aapt: ctx.Config().HostToolPath(ctx, "aapt"),
+ SoongZip: ctx.Config().HostToolPath(ctx, "soong_zip"),
+ Zip2zip: ctx.Config().HostToolPath(ctx, "zip2zip"),
+ ManifestCheck: ctx.Config().HostToolPath(ctx, "manifest_check"),
+ ConstructContext: android.PathForSource(ctx, "build/make/core/construct_context.sh"),
+ }
+}
+
+type globalJsonSoongConfig struct {
+ Profman string
+ Dex2oat string
+ Aapt string
+ SoongZip string
+ Zip2zip string
+ ManifestCheck string
+ ConstructContext string
+}
+
+// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
+// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
+func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
+ var jc globalJsonSoongConfig
+
+ err := json.Unmarshal(data, &jc)
if err != nil {
- return nil, err
+ return GlobalSoongConfig{}, err
}
- return data, nil
+ config := GlobalSoongConfig{
+ Profman: constructPath(ctx, jc.Profman),
+ Dex2oat: constructPath(ctx, jc.Dex2oat),
+ Aapt: constructPath(ctx, jc.Aapt),
+ SoongZip: constructPath(ctx, jc.SoongZip),
+ Zip2zip: constructPath(ctx, jc.Zip2zip),
+ ManifestCheck: constructPath(ctx, jc.ManifestCheck),
+ ConstructContext: constructPath(ctx, jc.ConstructContext),
+ }
+
+ return config, nil
+}
+
+func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ config := CreateGlobalSoongConfig(ctx)
+ jc := globalJsonSoongConfig{
+ Profman: config.Profman.String(),
+ Dex2oat: config.Dex2oat.String(),
+ Aapt: config.Aapt.String(),
+ SoongZip: config.SoongZip.String(),
+ Zip2zip: config.Zip2zip.String(),
+ ManifestCheck: config.ManifestCheck.String(),
+ ConstructContext: config.ConstructContext.String(),
+ }
+
+ data, err := json.Marshal(jc)
+ if err != nil {
+ ctx.Errorf("failed to JSON marshal GlobalSoongConfig: %v", err)
+ return
+ }
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: android.PathForOutput(ctx, "dexpreopt_soong.config"),
+ Args: map[string]string{
+ "content": string(data),
+ },
+ })
+}
+
+func (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
+ config := CreateGlobalSoongConfig(ctx)
+
+ ctx.Strict("DEX2OAT", config.Dex2oat.String())
+ ctx.Strict("DEXPREOPT_GEN_DEPS", strings.Join([]string{
+ config.Profman.String(),
+ config.Dex2oat.String(),
+ config.Aapt.String(),
+ config.SoongZip.String(),
+ config.Zip2zip.String(),
+ config.ManifestCheck.String(),
+ config.ConstructContext.String(),
+ }, " "))
}
func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
@@ -312,7 +390,7 @@
BootFlags: "",
Dex2oatImageXmx: "",
Dex2oatImageXms: "",
- Tools: Tools{
+ SoongConfig: GlobalSoongConfig{
Profman: android.PathForTesting("profman"),
Dex2oat: android.PathForTesting("dex2oat"),
Aapt: android.PathForTesting("aapt"),
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index fc1bae1..ac5b691 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -131,7 +131,7 @@
cmd := rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
- Tool(global.Tools.Profman)
+ Tool(global.SoongConfig.Profman)
if module.ProfileIsTextListing {
// The profile is a test listing of classes (used for framework jars).
@@ -170,7 +170,7 @@
cmd := rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
- Tool(global.Tools.Profman)
+ Tool(global.SoongConfig.Profman)
// The profile is a test listing of methods.
// We need to generate the actual binary profile.
@@ -222,14 +222,6 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- // TODO(skvadrik): fix this to use boot image location in the module config (currently it is broken
- // in JIT-zygote builds, because "default" boot image is hard-coded in parts of the module config).
- bootImage := module.DexPreoptImages[archIdx]
- var bootImageLocation string
- if bootImage != nil {
- bootImageLocation = PathToLocation(bootImage, arch)
- }
-
// The class loader context using paths in the build
var classLoaderContextHost android.Paths
@@ -307,14 +299,14 @@
if module.EnforceUsesLibraries {
if module.ManifestPath != nil {
rule.Command().Text(`target_sdk_version="$(`).
- Tool(global.Tools.ManifestCheck).
+ Tool(global.SoongConfig.ManifestCheck).
Flag("--extract-target-sdk-version").
Input(module.ManifestPath).
Text(`)"`)
} else {
// No manifest to extract targetSdkVersion from, hope that DexJar is an APK
rule.Command().Text(`target_sdk_version="$(`).
- Tool(global.Tools.Aapt).
+ Tool(global.SoongConfig.Aapt).
Flag("dump badging").
Input(module.DexPath).
Text(`| grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p"`).
@@ -335,7 +327,7 @@
Implicits(conditionalClassLoaderContextHost29)
rule.Command().Textf(`conditional_target_libs_29="%s"`,
strings.Join(conditionalClassLoaderContextTarget29, " "))
- rule.Command().Text("source").Tool(global.Tools.ConstructContext).Input(module.DexPath)
+ rule.Command().Text("source").Tool(global.SoongConfig.ConstructContext).Input(module.DexPath)
}
// Devices that do not have a product partition use a symlink from /product to /system/product.
@@ -348,7 +340,7 @@
cmd := rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
- Tool(global.Tools.Dex2oat).
+ Tool(global.SoongConfig.Dex2oat).
Flag("--avoid-storing-invocation").
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatXms).
@@ -357,7 +349,7 @@
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
Flag("${class_loader_context_arg}").
Flag("${stored_class_loader_context_arg}").
- FlagWithArg("--boot-image=", bootImageLocation).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
+ FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
FlagWithInput("--dex-file=", module.DexPath).
FlagWithArg("--dex-location=", dexLocationArg).
FlagWithOutput("--oat-file=", odexPath).ImplicitOutput(vdexPath).
@@ -417,7 +409,7 @@
dmInstalledPath := pathtools.ReplaceExtension(module.DexLocation, "dm")
tmpPath := module.BuildPath.InSameDir(ctx, "primary.vdex")
rule.Command().Text("cp -f").Input(vdexPath).Output(tmpPath)
- rule.Command().Tool(global.Tools.SoongZip).
+ rule.Command().Tool(global.SoongConfig.SoongZip).
FlagWithArg("-L", "9").
FlagWithOutput("-o", dmPath).
Flag("-j").
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 6f51080..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"
@@ -30,17 +31,17 @@
)
var (
- dexpreoptScriptPath = flag.String("dexpreopt_script", "", "path to output dexpreopt script")
- globalConfigPath = flag.String("global", "", "path to global configuration file")
- moduleConfigPath = flag.String("module", "", "path to module configuration file")
- outDir = flag.String("out_dir", "", "path to output directory")
+ dexpreoptScriptPath = flag.String("dexpreopt_script", "", "path to output dexpreopt script")
+ globalSoongConfigPath = flag.String("global_soong", "", "path to global configuration file for settings originating from Soong")
+ globalConfigPath = flag.String("global", "", "path to global configuration file")
+ moduleConfigPath = flag.String("module", "", "path to module configuration file")
+ outDir = flag.String("out_dir", "", "path to output directory")
)
type pathContext struct {
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) {}
@@ -63,23 +64,51 @@
usage("path to output dexpreopt script is required")
}
+ if *globalSoongConfigPath == "" {
+ usage("--global_soong configuration file is required")
+ }
+
if *globalConfigPath == "" {
- usage("path to global configuration file is required")
+ usage("--global configuration file is required")
}
if *moduleConfigPath == "" {
- usage("path to module configuration file is required")
+ usage("--module configuration file is required")
}
- ctx := &pathContext{android.TestConfig(*outDir, nil, "", nil)}
+ ctx := &pathContext{android.NullConfig(*outDir)}
- globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
+ globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
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", *globalSoongConfigPath, err)
os.Exit(2)
}
- moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, *moduleConfigPath)
+ 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)
+ }
+
+ globalConfigData, err := ioutil.ReadFile(*globalConfigPath)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalConfigPath, err)
+ os.Exit(2)
+ }
+
+ 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)
@@ -121,7 +150,7 @@
dexpreoptRule.Command().Text("mkdir -p").Flag(filepath.Dir(installPath.String()))
dexpreoptRule.Command().Text("cp -f").Input(install.From).Output(installPath)
}
- dexpreoptRule.Command().Tool(global.Tools.SoongZip).
+ dexpreoptRule.Command().Tool(global.SoongConfig.SoongZip).
FlagWithArg("-o ", "$2").
FlagWithArg("-C ", installDir.String()).
FlagWithArg("-D ", installDir.String())
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/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/androidmk.go b/java/androidmk.go
index 7b74293..04bf15c 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -141,6 +141,9 @@
entries.SetPath("LOCAL_FULL_TEST_CONFIG", j.testConfig)
}
androidMkWriteTestData(j.data, entries)
+ if !BoolDefault(j.testProperties.Auto_gen_config, true) {
+ entries.SetString("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", "true")
+ }
})
return entriesList
diff --git a/java/app.go b/java/app.go
index 2933ccb..05fa505 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1062,6 +1062,10 @@
return a.outputFile
}
+func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
var dpiVariantGroupType reflect.Type
var archVariantGroupType reflect.Type
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 1d363c9..66840b5 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -178,12 +178,6 @@
return false
}
-func skipDexpreoptArtBootJars(ctx android.BuilderContext) bool {
- // with EMMA_INSTRUMENT_FRAMEWORK=true ART boot class path libraries have dependencies on framework,
- // therefore dexpreopt ART libraries cannot be dexpreopted in isolation => no ART boot image
- return ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK")
-}
-
type dexpreoptBootJars struct {
defaultBootImage *bootImage
otherImages []*bootImage
@@ -193,7 +187,7 @@
// Accessor function for the apex package. Returns nil if dexpreopt is disabled.
func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths {
- if skipDexpreoptBootJars(ctx) || skipDexpreoptArtBootJars(ctx) {
+ if skipDexpreoptBootJars(ctx) {
return nil
}
return artBootImageConfig(ctx).imagesDeps
@@ -222,13 +216,12 @@
// Always create the default boot image first, to get a unique profile rule for all images.
d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx))
- if !skipDexpreoptArtBootJars(ctx) {
- // Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
- d.otherImages = append(d.otherImages, buildBootImage(ctx, artBootImageConfig(ctx)))
- }
+ // Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
+ 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)
@@ -335,7 +328,7 @@
invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
- cmd.Tool(global.Tools.Dex2oat).
+ cmd.Tool(global.SoongConfig.Dex2oat).
Flag("--avoid-storing-invocation").
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms).
@@ -444,7 +437,6 @@
return nil
}
profile := ctx.Config().Once(bootImageProfileRuleKey, func() interface{} {
- tools := global.Tools
defaultProfile := "frameworks/base/config/boot-image-profile.txt"
rule := android.NewRuleBuilder()
@@ -470,7 +462,7 @@
rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
- Tool(tools.Profman).
+ Tool(global.SoongConfig.Profman).
FlagWithInput("--create-profile-from=", bootImageProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
FlagForEachArg("--dex-location=", image.dexLocationsDeps).
@@ -499,8 +491,6 @@
return nil
}
return ctx.Config().Once(bootFrameworkProfileRuleKey, func() interface{} {
- tools := global.Tools
-
rule := android.NewRuleBuilder()
rule.MissingDeps(missingDeps)
@@ -521,7 +511,7 @@
rule.Command().
Text(`ANDROID_LOG_TAGS="*:e"`).
- Tool(tools.Profman).
+ Tool(global.SoongConfig.Profman).
Flag("--generate-boot-profile").
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
@@ -598,6 +588,7 @@
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
if d.dexpreoptConfigForMake != nil {
ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String())
+ ctx.Strict("DEX_PREOPT_SOONG_CONFIG_FOR_MAKE", android.PathForOutput(ctx, "dexpreopt_soong.config").String())
}
image := d.defaultBootImage
@@ -605,7 +596,6 @@
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
- ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS", strings.Join(image.imageLocations, ":"))
var imageNames []string
for _, current := range append(d.otherImages, image) {
@@ -618,15 +608,15 @@
sort.Slice(arches, func(i, j int) bool { return arches[i].String() < arches[j].String() })
for _, arch := range arches {
- ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.vdexInstalls[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_"+current.name+"_"+arch.String(), current.images[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+current.name+"_"+arch.String(), strings.Join(current.imagesDeps[arch].Strings(), " "))
- ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.installs[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+current.name+"_"+arch.String(), current.unstrippedInstalls[arch].String())
- if current.zip != nil {
- }
+ sfx := current.name + "_" + arch.String()
+ ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps[arch].Strings(), " "))
+ ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls[arch].String())
}
+ ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(current.imageLocations, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
}
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
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 91e0dfb..31bec93 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -36,9 +36,11 @@
func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
- if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
- ctx.AddNinjaFileDeps(f)
- globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f)
+ if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
+ panic(err)
+ } else if data != nil {
+ soongConfig := dexpreopt.CreateGlobalSoongConfig(ctx)
+ globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, data, soongConfig)
if err != nil {
panic(err)
}
@@ -120,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.
@@ -135,6 +138,10 @@
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
artModules := global.ArtApexJars
+ // With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ artModules = append(artModules, "jacocoagent")
+ }
frameworkModules := android.RemoveListFromList(global.BootJars,
concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars)))
@@ -162,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
@@ -226,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)
}
@@ -238,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..a546cd5 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 {
@@ -651,7 +652,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 +1462,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 +1721,10 @@
return proptools.StringDefault(j.deviceProperties.Stem, j.Name())
}
+func (j *Module) JacocoReportClassesFile() android.Path {
+ return j.jacocoReportClassesFile
+}
+
//
// Java libraries (.jar file)
//
@@ -2295,6 +2301,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/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/sdk.go b/java/sdk.go
index c048805..66eb284 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -127,12 +127,12 @@
}
if !jarPath.Valid() {
- ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdk, jar)
return sdkDep{}
}
if !aidlPath.Valid() {
- ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
+ ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", sdk, aidl)
return sdkDep{}
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 5518d5d..9b30e2c 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -667,7 +667,11 @@
jar := filepath.Join(dir, module.BaseModuleName()+".jar")
jarPath := android.ExistentPathForSource(ctx, jar)
if !jarPath.Valid() {
- ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", v, jar)
+ if ctx.Config().AllowMissingDependencies() {
+ return android.Paths{android.PathForSource(ctx, jar)}
+ } else {
+ ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", sdkVersion, jar)
+ }
return nil
}
return android.Paths{jarPath.Path()}
diff --git a/python/androidmk.go b/python/androidmk.go
index aae7ced..8e8e8ef 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -76,6 +76,10 @@
p.testConfig.String())
}
}
+
+ if !BoolDefault(p.binaryProperties.Auto_gen_config, true) {
+ fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ }
})
base.subAndroidMk(ret, p.binaryDecorator.pythonInstaller)
}
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 2636d97..0fba739 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -99,6 +99,9 @@
if test.testConfig != nil {
fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", test.testConfig.String())
}
+ if !BoolDefault(test.Properties.Auto_gen_config, true) {
+ fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ }
})
// TODO(chh): add test data with androidMkWriteTestData(test.data, ctx, ret)
}
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/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/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()
}