Merge "Switch from clang-r370808b to clang-r377782"
diff --git a/android/arch.go b/android/arch.go
index 3657e6d..fb1accc 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -765,7 +765,7 @@
}
if len(moduleOSList) == 0 {
- base.commonProperties.Enabled = boolPtr(false)
+ base.Disable()
return
}
@@ -869,7 +869,7 @@
}
if len(targets) == 0 {
- base.commonProperties.Enabled = boolPtr(false)
+ base.Disable()
return
}
diff --git a/android/config.go b/android/config.go
index d0ac4c3..3c979f2 100644
--- a/android/config.go
+++ b/android/config.go
@@ -923,8 +923,23 @@
return c.productVariables.ModulesLoadedByPrivilegedModules
}
+// Expected format for apexJarValue = <apex name>:<jar name>
+func SplitApexJarPair(apexJarValue string) (string, string) {
+ var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2)
+ if apexJarPair == nil || len(apexJarPair) != 2 {
+ panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>",
+ apexJarValue))
+ }
+ return apexJarPair[0], apexJarPair[1]
+}
+
func (c *config) BootJars() []string {
- return c.productVariables.BootJars
+ jars := c.productVariables.BootJars
+ for _, p := range c.productVariables.UpdatableBootJars {
+ _, jar := SplitApexJarPair(p)
+ jars = append(jars, jar)
+ }
+ return jars
}
func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) {
diff --git a/android/module.go b/android/module.go
index da46dd7..5e56c4f 100644
--- a/android/module.go
+++ b/android/module.go
@@ -204,6 +204,7 @@
DepsMutator(BottomUpMutatorContext)
base() *ModuleBase
+ Disable()
Enabled() bool
Target() Target
InstallInData() bool
@@ -836,6 +837,10 @@
return *m.commonProperties.Enabled
}
+func (m *ModuleBase) Disable() {
+ m.commonProperties.Enabled = proptools.BoolPtr(false)
+}
+
func (m *ModuleBase) SkipInstall() {
m.commonProperties.SkipInstall = true
}
diff --git a/android/variable.go b/android/variable.go
index 58e5940..e4a3fa3 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -230,7 +230,8 @@
UncompressPrivAppDex *bool `json:",omitempty"`
ModulesLoadedByPrivilegedModules []string `json:",omitempty"`
- BootJars []string `json:",omitempty"`
+ BootJars []string `json:",omitempty"`
+ UpdatableBootJars []string `json:",omitempty"`
IntegerOverflowExcludePaths []string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index 4fbec60..e5f6424 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -285,7 +285,6 @@
"libsystem_headers",
"libtinyxml2",
"libudrv-uipc",
- "libutils",
"libutils_headers",
"libz",
"media_plugin_headers",
@@ -377,7 +376,6 @@
"libtextclassifier_hash_headers",
"libtextclassifier_hash_static",
"libtflite_kernel_utils",
- "libutils",
"libutils_headers",
"philox_random",
"philox_random_headers",
@@ -522,7 +520,6 @@
"libui",
"libui_headers",
"libunwindstack",
- "libutils",
"libutils_headers",
"libvibrator",
"libvorbisidec",
@@ -693,7 +690,6 @@
"libui",
"libui_headers",
"libunwindstack",
- "libutils",
"libutils_headers",
"libvorbisidec",
"libvpx",
@@ -840,7 +836,6 @@
"libstatssocket_headers",
"libsystem_headers",
"libsysutils",
- "libutils",
"libutils_headers",
"netd_event_listener_interface-ndk_platform",
"server_configurable_flags",
@@ -872,7 +867,6 @@
"libprocessgroup_headers",
"libsystem_headers",
"libtetherutilsjni",
- "libutils",
"libutils_headers",
"libvndksupport",
"tethering-aidl-interfaces-java",
@@ -919,7 +913,6 @@
"libprotobuf-java-lite",
"libprotobuf-java-nano",
"libsystem_headers",
- "libutils",
"libutils_headers",
"libwifi-jni",
"net-utils-services-common",
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 137cb63..d8210fc 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -413,9 +413,12 @@
}
func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ // Each vndk prebuilt is exported to androidMk only when BOARD_VNDK_VERSION != current
+ // and the version of the prebuilt is same as BOARD_VNDK_VERSION.
ret.Class = "SHARED_LIBRARIES"
- ret.SubName = c.NameSuffix()
+ // shouldn't add any suffixes due to mk modules
+ ret.SubName = ""
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
c.libraryDecorator.androidMkWriteExportedFlags(w)
@@ -426,6 +429,61 @@
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ if c.tocFile.Valid() {
+ fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String())
+ }
+ })
+}
+
+func (c *vendorSnapshotLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ // Each vendor snapshot is exported to androidMk only when BOARD_VNDK_VERSION != current
+ // and the version of the prebuilt is same as BOARD_VNDK_VERSION.
+ if c.shared() {
+ ret.Class = "SHARED_LIBRARIES"
+ } else if c.static() {
+ ret.Class = "STATIC_LIBRARIES"
+ } else if c.header() {
+ ret.Class = "HEADER_LIBRARIES"
+ }
+
+ if c.androidMkVendorSuffix {
+ ret.SubName = vendorSuffix
+ } else {
+ ret.SubName = ""
+ }
+
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ c.libraryDecorator.androidMkWriteExportedFlags(w)
+
+ if c.shared() {
+ path, file := filepath.Split(c.path.ToMakePath().String())
+ stem, suffix, ext := android.SplitFileExt(file)
+ fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
+ fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
+ if c.shared() {
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ }
+ if c.tocFile.Valid() {
+ fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String())
+ }
+ } else { // static or header
+ fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ }
+ })
+}
+
+func (c *vendorSnapshotBinaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+ ret.Class = "EXECUTABLES"
+
+ if c.androidMkVendorSuffix {
+ ret.SubName = vendorSuffix
+ } else {
+ ret.SubName = ""
+ }
+
+ ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(c.Properties.Symlinks, " "))
})
}
diff --git a/cc/cc.go b/cc/cc.go
index ce9d33a..e55c576 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -49,6 +49,8 @@
ctx.BottomUp("version", VersionMutator).Parallel()
ctx.BottomUp("begin", BeginMutator).Parallel()
ctx.BottomUp("sysprop_cc", SyspropMutator).Parallel()
+ ctx.BottomUp("vendor_snapshot", VendorSnapshotMutator).Parallel()
+ ctx.BottomUp("vendor_snapshot_source", VendorSnapshotSourceMutator).Parallel()
})
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -923,8 +925,16 @@
}
func (c *Module) isSnapshotPrebuilt() bool {
- _, ok := c.linker.(*vndkPrebuiltLibraryDecorator)
- return ok
+ if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
+ return true
+ }
+ if _, ok := c.linker.(*vendorSnapshotLibraryDecorator); ok {
+ return true
+ }
+ if _, ok := c.linker.(*vendorSnapshotBinaryDecorator); ok {
+ return true
+ }
+ return false
}
func (c *Module) ExportedIncludeDirs() android.Paths {
@@ -1612,6 +1622,10 @@
}
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
+ if !c.Enabled() {
+ return
+ }
+
ctx := &depsContext{
BottomUpMutatorContext: actx,
moduleContextImpl: moduleContextImpl{
@@ -1627,7 +1641,7 @@
if ctx.Os() == android.Android {
version := ctx.sdkVersion()
- // rewriteNdkLibs takes a list of names of shared libraries and scans it for three types
+ // rewriteLibs takes a list of names of shared libraries and scans it for three types
// of names:
//
// 1. Name of an NDK library that refers to a prebuilt module.
@@ -1643,7 +1657,26 @@
// nonvariantLibs
vendorPublicLibraries := vendorPublicLibraries(actx.Config())
- rewriteNdkLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
+ vendorSnapshotSharedLibs := vendorSnapshotSharedLibs(actx.Config())
+
+ rewriteVendorLibs := func(lib string) string {
+ if isLlndkLibrary(lib, ctx.Config()) {
+ return lib + llndkLibrarySuffix
+ }
+
+ // only modules with BOARD_VNDK_VERSION uses snapshot.
+ if c.VndkVersion() != actx.DeviceConfig().VndkVersion() {
+ return lib
+ }
+
+ if snapshot, ok := vendorSnapshotSharedLibs.get(lib, actx.Arch().ArchType); ok {
+ return snapshot
+ }
+
+ return lib
+ }
+
+ rewriteLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
variantLibs = []string{}
nonvariantLibs = []string{}
for _, entry := range list {
@@ -1655,8 +1688,8 @@
} else {
variantLibs = append(variantLibs, name+ndkLibrarySuffix)
}
- } else if ctx.useVndk() && isLlndkLibrary(name, ctx.Config()) {
- nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix)
+ } else if ctx.useVndk() {
+ nonvariantLibs = append(nonvariantLibs, rewriteVendorLibs(entry))
} else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) {
vendorPublicLib := name + vendorPublicLibrarySuffix
if actx.OtherModuleExists(vendorPublicLib) {
@@ -1675,9 +1708,14 @@
return nonvariantLibs, variantLibs
}
- deps.SharedLibs, variantNdkLibs = rewriteNdkLibs(deps.SharedLibs)
- deps.LateSharedLibs, variantLateNdkLibs = rewriteNdkLibs(deps.LateSharedLibs)
- deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders)
+ deps.SharedLibs, variantNdkLibs = rewriteLibs(deps.SharedLibs)
+ deps.LateSharedLibs, variantLateNdkLibs = rewriteLibs(deps.LateSharedLibs)
+ deps.ReexportSharedLibHeaders, _ = rewriteLibs(deps.ReexportSharedLibHeaders)
+ if ctx.useVndk() {
+ for idx, lib := range deps.RuntimeLibs {
+ deps.RuntimeLibs[idx] = rewriteVendorLibs(lib)
+ }
+ }
}
buildStubs := false
@@ -1689,11 +1727,28 @@
}
}
+ rewriteSnapshotLibs := func(lib string, snapshotMap *snapshotMap) string {
+ // only modules with BOARD_VNDK_VERSION uses snapshot.
+ if c.VndkVersion() != actx.DeviceConfig().VndkVersion() {
+ return lib
+ }
+
+ if snapshot, ok := snapshotMap.get(lib, actx.Arch().ArchType); ok {
+ return snapshot
+ }
+
+ return lib
+ }
+
+ vendorSnapshotHeaderLibs := vendorSnapshotHeaderLibs(actx.Config())
for _, lib := range deps.HeaderLibs {
depTag := headerDepTag
if inList(lib, deps.ReexportHeaderLibHeaders) {
depTag = headerExportDepTag
}
+
+ lib = rewriteSnapshotLibs(lib, vendorSnapshotHeaderLibs)
+
if buildStubs {
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
depTag, lib)
@@ -1709,12 +1764,16 @@
}
syspropImplLibraries := syspropImplLibraries(actx.Config())
+ vendorSnapshotStaticLibs := vendorSnapshotStaticLibs(actx.Config())
for _, lib := range deps.WholeStaticLibs {
depTag := wholeStaticDepTag
if impl, ok := syspropImplLibraries[lib]; ok {
lib = impl
}
+
+ lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs)
+
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
@@ -1730,14 +1789,18 @@
lib = impl
}
+ lib = rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs)
+
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
}
- actx.AddVariationDependencies([]blueprint.Variation{
- {Mutator: "link", Variation: "static"},
- }, lateStaticDepTag, deps.LateStaticLibs...)
+ for _, lib := range deps.LateStaticLibs {
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "link", Variation: "static"},
+ }, lateStaticDepTag, rewriteSnapshotLibs(lib, vendorSnapshotStaticLibs))
+ }
addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
var variations []blueprint.Variation
@@ -2284,14 +2347,33 @@
*depPtr = append(*depPtr, dep.Path())
}
- makeLibName := func(depName string) string {
+ vendorSuffixModules := vendorSuffixModules(ctx.Config())
+
+ baseLibName := func(depName string) string {
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
libName = strings.TrimPrefix(libName, "prebuilt_")
+ return libName
+ }
+
+ makeLibName := func(depName string) string {
+ libName := baseLibName(depName)
isLLndk := isLlndkLibrary(libName, ctx.Config())
isVendorPublicLib := inList(libName, *vendorPublicLibraries)
bothVendorAndCoreVariantsExist := ccDep.HasVendorVariant() || isLLndk
+ if c, ok := ccDep.(*Module); ok {
+ // Use base module name for snapshots when exporting to Makefile.
+ if c.isSnapshotPrebuilt() && !c.IsVndk() {
+ baseName := c.BaseModuleName()
+ if vendorSuffixModules[baseName] {
+ return baseName + ".vendor"
+ } else {
+ return baseName
+ }
+ }
+ }
+
if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.IsVndk() && !ccDep.MustUseVendorVariant() && !c.InRamdisk() && !c.InRecovery() {
// The vendor module is a no-vendor-variant VNDK library. Depend on the
// core module instead.
@@ -2331,8 +2413,8 @@
// they merely serve as Make dependencies and do not affect this lib itself.
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs, makeLibName(depName))
- // Record depName as-is for snapshots.
- c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, depName)
+ // Record baseLibName for snapshots.
+ c.Properties.SnapshotSharedLibs = append(c.Properties.SnapshotSharedLibs, baseLibName(depName))
case ndkStubDepTag, ndkLateStubDepTag:
c.Properties.AndroidMkSharedLibs = append(
c.Properties.AndroidMkSharedLibs,
@@ -2343,8 +2425,8 @@
case runtimeDepTag:
c.Properties.AndroidMkRuntimeLibs = append(
c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
- // Record depName as-is for snapshots.
- c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, depName)
+ // Record baseLibName for snapshots.
+ c.Properties.SnapshotRuntimeLibs = append(c.Properties.SnapshotRuntimeLibs, baseLibName(depName))
case wholeStaticDepTag:
c.Properties.AndroidMkWholeStaticLibs = append(
c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
@@ -2719,10 +2801,16 @@
platformVndkVersion,
productVndkVersion,
)
- } else if lib, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
+ } else if m.isSnapshotPrebuilt() {
// Make vendor variants only for the versions in BOARD_VNDK_VERSION and
// PRODUCT_EXTRA_VNDK_VERSIONS.
- vendorVariants = append(vendorVariants, lib.version())
+ if snapshot, ok := m.linker.(interface {
+ version() string
+ }); ok {
+ vendorVariants = append(vendorVariants, snapshot.version())
+ } else {
+ mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
+ }
} else if m.HasVendorVariant() && !vendorSpecific {
// This will be available in /system, /vendor and /product
// or a /system directory that is available to vendor and product.
@@ -2819,6 +2907,14 @@
m.Properties.ImageVariationPrefix = VendorVariationPrefix
m.Properties.VndkVersion = strings.TrimPrefix(variant, VendorVariationPrefix)
squashVendorSrcs(m)
+
+ // Makefile shouldn't know vendor modules other than BOARD_VNDK_VERSION.
+ // Hide other vendor variants to avoid collision.
+ vndkVersion := ctx.DeviceConfig().VndkVersion()
+ if vndkVersion != "current" && vndkVersion != "" && vndkVersion != m.Properties.VndkVersion {
+ m.Properties.HideFromMake = true
+ m.SkipInstall()
+ }
} else if strings.HasPrefix(variant, ProductVariationPrefix) {
m.Properties.ImageVariationPrefix = ProductVariationPrefix
m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 63b9d48..000228d 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -100,7 +100,7 @@
pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string {
return xcrunSdk(ctx, "--show-sdk-path")
})
- pctx.StaticVariable("macMinVersion", "10.8")
+ pctx.StaticVariable("macMinVersion", "10.9")
pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string {
return xcrun(ctx, "--find", "ar")
})
diff --git a/cc/pgo.go b/cc/pgo.go
index 8eb3400..d5c4b87 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -256,6 +256,12 @@
}
}
+ // PGO profile use is not feasible for a Clang coverage build because
+ // -fprofile-use and -fprofile-instr-generate are incompatible.
+ if ctx.DeviceConfig().ClangCoverageEnabled() {
+ return
+ }
+
if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") &&
proptools.BoolDefault(pgo.Properties.Pgo.Enable_profile_use, true) {
if profileFile := pgo.Properties.getPgoProfileFile(ctx); profileFile.Valid() {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 6f9dbef..5663aa7 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -350,6 +350,12 @@
s.Diag.Cfi = nil
}
+ // Also disable CFI if building against snapshot.
+ vndkVersion := ctx.DeviceConfig().VndkVersion()
+ if ctx.useVndk() && vndkVersion != "current" && vndkVersion != "" {
+ s.Cfi = nil
+ }
+
// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
// Keep libc instrumented so that ramdisk / recovery can run hwasan-instrumented code if necessary.
if (ctx.inRamdisk() || ctx.inRecovery()) && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
@@ -739,7 +745,11 @@
return false
}
- if d, ok := child.(*Module); ok && d.static() && d.sanitize != nil {
+ d, ok := child.(*Module)
+ if !ok || !d.static() {
+ return false
+ }
+ if d.sanitize != nil {
if enableMinimalRuntime(d.sanitize) {
// If a static dependency is built with the minimal runtime,
// make sure we include the ubsan minimal runtime.
@@ -757,9 +767,18 @@
}
return true
- } else {
- return false
}
+
+ if p, ok := d.linker.(*vendorSnapshotLibraryDecorator); ok {
+ if Bool(p.properties.Sanitize_minimal_dep) {
+ c.sanitize.Properties.MinimalRuntimeDep = true
+ }
+ if Bool(p.properties.Sanitize_ubsan_dep) {
+ c.sanitize.Properties.UbsanRuntimeDep = true
+ }
+ }
+
+ return false
})
}
}
@@ -900,12 +919,31 @@
// Note that by adding dependency with {static|shared}DepTag, the lib is
// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
if c.staticBinary() {
+ deps := append(extraStaticDeps, runtimeLibrary)
+ // If we're using snapshots and in vendor, redirect to snapshot whenever possible
+ if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() {
+ snapshots := vendorSnapshotStaticLibs(mctx.Config())
+ for idx, dep := range deps {
+ if lib, ok := snapshots.get(dep, mctx.Arch().ArchType); ok {
+ deps[idx] = lib
+ }
+ }
+ }
+
// static executable gets static runtime libs
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "static"},
c.ImageVariation(),
- }...), StaticDepTag, append([]string{runtimeLibrary}, extraStaticDeps...)...)
+ }...), StaticDepTag, deps...)
} else if !c.static() && !c.header() {
+ // If we're using snapshots and in vendor, redirect to snapshot whenever possible
+ if c.VndkVersion() == mctx.DeviceConfig().VndkVersion() {
+ snapshots := vendorSnapshotSharedLibs(mctx.Config())
+ if lib, ok := snapshots.get(runtimeLibrary, mctx.Arch().ArchType); ok {
+ runtimeLibrary = lib
+ }
+ }
+
// dynamic executable and shared libs get shared runtime libs
mctx.AddFarVariationDependencies(append(mctx.Target().Variations(), []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index 1c872c2..8f48f86 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -31,6 +31,33 @@
var _ snapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
var _ snapshotLibraryInterface = (*libraryDecorator)(nil)
+type snapshotMap struct {
+ snapshots map[string]string
+}
+
+func newSnapshotMap() *snapshotMap {
+ return &snapshotMap{
+ snapshots: make(map[string]string),
+ }
+}
+
+func snapshotMapKey(name string, arch android.ArchType) string {
+ return name + ":" + arch.String()
+}
+
+// Adds a snapshot name for given module name and architecture.
+// e.g. add("libbase", X86, "libbase.vndk.29.x86")
+func (s *snapshotMap) add(name string, arch android.ArchType, snapshot string) {
+ s.snapshots[snapshotMapKey(name, arch)] = snapshot
+}
+
+// Returns snapshot name for given module name and architecture, if found.
+// e.g. get("libcutils", X86) => "libcutils.vndk.29.x86", true
+func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string, found bool) {
+ snapshot, found = s.snapshots[snapshotMapKey(name, arch)]
+ return snapshot, found
+}
+
func exportedHeaders(ctx android.SingletonContext, l exportedFlagsProducer) android.Paths {
var ret android.Paths
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index d952a4c..d92caa1 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -18,14 +18,358 @@
"path/filepath"
"sort"
"strings"
+ "sync"
"github.com/google/blueprint/proptools"
"android/soong/android"
)
+const (
+ vendorSnapshotHeaderSuffix = ".vendor_header."
+ vendorSnapshotSharedSuffix = ".vendor_shared."
+ vendorSnapshotStaticSuffix = ".vendor_static."
+ vendorSnapshotBinarySuffix = ".vendor_binary."
+)
+
+var (
+ vendorSnapshotsLock sync.Mutex
+ vendorSuffixModulesKey = android.NewOnceKey("vendorSuffixModules")
+ vendorSnapshotHeaderLibsKey = android.NewOnceKey("vendorSnapshotHeaderLibs")
+ vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs")
+ vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs")
+ vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries")
+)
+
+// vendor snapshot maps hold names of vendor snapshot modules per arch.
+func vendorSuffixModules(config android.Config) map[string]bool {
+ return config.Once(vendorSuffixModulesKey, func() interface{} {
+ return make(map[string]bool)
+ }).(map[string]bool)
+}
+
+func vendorSnapshotHeaderLibs(config android.Config) *snapshotMap {
+ return config.Once(vendorSnapshotHeaderLibsKey, func() interface{} {
+ return newSnapshotMap()
+ }).(*snapshotMap)
+}
+
+func vendorSnapshotSharedLibs(config android.Config) *snapshotMap {
+ return config.Once(vendorSnapshotSharedLibsKey, func() interface{} {
+ return newSnapshotMap()
+ }).(*snapshotMap)
+}
+
+func vendorSnapshotStaticLibs(config android.Config) *snapshotMap {
+ return config.Once(vendorSnapshotStaticLibsKey, func() interface{} {
+ return newSnapshotMap()
+ }).(*snapshotMap)
+}
+
+func vendorSnapshotBinaries(config android.Config) *snapshotMap {
+ return config.Once(vendorSnapshotBinariesKey, func() interface{} {
+ return newSnapshotMap()
+ }).(*snapshotMap)
+}
+
+type vendorSnapshotLibraryProperties struct {
+ // snapshot version.
+ Version string
+
+ // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
+ Target_arch string
+
+ // Prebuilt file for each arch.
+ Src *string `android:"arch_variant"`
+
+ // list of flags that will be used for any module that links against this module.
+ Export_flags []string `android:"arch_variant"`
+
+ // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
+ // etc).
+ Check_elf_files *bool
+
+ // Whether this prebuilt needs to depend on sanitize ubsan runtime or not.
+ Sanitize_ubsan_dep *bool `android:"arch_variant"`
+
+ // Whether this prebuilt needs to depend on sanitize minimal runtime or not.
+ Sanitize_minimal_dep *bool `android:"arch_variant"`
+}
+
+type vendorSnapshotLibraryDecorator struct {
+ *libraryDecorator
+ properties vendorSnapshotLibraryProperties
+ androidMkVendorSuffix bool
+}
+
+func (p *vendorSnapshotLibraryDecorator) Name(name string) string {
+ return name + p.NameSuffix()
+}
+
+func (p *vendorSnapshotLibraryDecorator) NameSuffix() string {
+ versionSuffix := p.version()
+ if p.arch() != "" {
+ versionSuffix += "." + p.arch()
+ }
+
+ var linkageSuffix string
+ if p.buildShared() {
+ linkageSuffix = vendorSnapshotSharedSuffix
+ } else if p.buildStatic() {
+ linkageSuffix = vendorSnapshotStaticSuffix
+ } else {
+ linkageSuffix = vendorSnapshotHeaderSuffix
+ }
+
+ return linkageSuffix + versionSuffix
+}
+
+func (p *vendorSnapshotLibraryDecorator) version() string {
+ return p.properties.Version
+}
+
+func (p *vendorSnapshotLibraryDecorator) arch() string {
+ return p.properties.Target_arch
+}
+
+func (p *vendorSnapshotLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
+ p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
+ return p.libraryDecorator.linkerFlags(ctx, flags)
+}
+
+func (p *vendorSnapshotLibraryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+ arches := config.Arches()
+ if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
+ return false
+ }
+ if !p.header() && p.properties.Src == nil {
+ return false
+ }
+ return true
+}
+
+func (p *vendorSnapshotLibraryDecorator) link(ctx ModuleContext,
+ flags Flags, deps PathDeps, objs Objects) android.Path {
+ m := ctx.Module().(*Module)
+ p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
+
+ if p.header() {
+ return p.libraryDecorator.link(ctx, flags, deps, objs)
+ }
+
+ if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ return nil
+ }
+
+ p.libraryDecorator.exportIncludes(ctx)
+ p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
+
+ in := android.PathForModuleSrc(ctx, *p.properties.Src)
+ p.unstrippedOutputFile = in
+
+ if p.shared() {
+ libName := in.Base()
+ builderFlags := flagsToBuilderFlags(flags)
+
+ // Optimize out relinking against shared libraries whose interface hasn't changed by
+ // depending on a table of contents file instead of the library itself.
+ tocFile := android.PathForModuleOut(ctx, libName+".toc")
+ p.tocFile = android.OptionalPathForPath(tocFile)
+ TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
+ }
+
+ return in
+}
+
+func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool {
+ return false
+}
+
+func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) {
+ if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) {
+ p.baseInstaller.install(ctx, file)
+ }
+}
+
+type vendorSnapshotInterface interface {
+ version() string
+}
+
+func vendorSnapshotLoadHook(ctx android.LoadHookContext, p vendorSnapshotInterface) {
+ if p.version() != ctx.DeviceConfig().VndkVersion() {
+ ctx.Module().Disable()
+ return
+ }
+}
+
+func vendorSnapshotLibrary() (*Module, *vendorSnapshotLibraryDecorator) {
+ module, library := NewLibrary(android.DeviceSupported)
+
+ module.stl = nil
+ module.sanitize = nil
+ library.StripProperties.Strip.None = BoolPtr(true)
+
+ prebuilt := &vendorSnapshotLibraryDecorator{
+ libraryDecorator: library,
+ }
+
+ prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
+ prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
+
+ // Prevent default system libs (libc, libm, and libdl) from being linked
+ if prebuilt.baseLinker.Properties.System_shared_libs == nil {
+ prebuilt.baseLinker.Properties.System_shared_libs = []string{}
+ }
+
+ module.compiler = nil
+ module.linker = prebuilt
+ module.installer = prebuilt
+
+ module.AddProperties(
+ &prebuilt.properties,
+ )
+
+ return module, prebuilt
+}
+
+func VendorSnapshotSharedFactory() android.Module {
+ module, prebuilt := vendorSnapshotLibrary()
+ prebuilt.libraryDecorator.BuildOnlyShared()
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ vendorSnapshotLoadHook(ctx, prebuilt)
+ })
+ return module.Init()
+}
+
+func VendorSnapshotStaticFactory() android.Module {
+ module, prebuilt := vendorSnapshotLibrary()
+ prebuilt.libraryDecorator.BuildOnlyStatic()
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ vendorSnapshotLoadHook(ctx, prebuilt)
+ })
+ return module.Init()
+}
+
+func VendorSnapshotHeaderFactory() android.Module {
+ module, prebuilt := vendorSnapshotLibrary()
+ prebuilt.libraryDecorator.HeaderOnly()
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ vendorSnapshotLoadHook(ctx, prebuilt)
+ })
+ return module.Init()
+}
+
+type vendorSnapshotBinaryProperties struct {
+ // snapshot version.
+ Version string
+
+ // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab')
+ Target_arch string
+
+ // Prebuilt file for each arch.
+ Src *string `android:"arch_variant"`
+}
+
+type vendorSnapshotBinaryDecorator struct {
+ *binaryDecorator
+ properties vendorSnapshotBinaryProperties
+ androidMkVendorSuffix bool
+}
+
+func (p *vendorSnapshotBinaryDecorator) Name(name string) string {
+ return name + p.NameSuffix()
+}
+
+func (p *vendorSnapshotBinaryDecorator) NameSuffix() string {
+ versionSuffix := p.version()
+ if p.arch() != "" {
+ versionSuffix += "." + p.arch()
+ }
+ return vendorSnapshotBinarySuffix + versionSuffix
+}
+
+func (p *vendorSnapshotBinaryDecorator) version() string {
+ return p.properties.Version
+}
+
+func (p *vendorSnapshotBinaryDecorator) arch() string {
+ return p.properties.Target_arch
+}
+
+func (p *vendorSnapshotBinaryDecorator) matchesWithDevice(config android.DeviceConfig) bool {
+ if config.DeviceArch() != p.arch() {
+ return false
+ }
+ if p.properties.Src == nil {
+ return false
+ }
+ return true
+}
+
+func (p *vendorSnapshotBinaryDecorator) link(ctx ModuleContext,
+ flags Flags, deps PathDeps, objs Objects) android.Path {
+ if !p.matchesWithDevice(ctx.DeviceConfig()) {
+ return nil
+ }
+
+ in := android.PathForModuleSrc(ctx, *p.properties.Src)
+ builderFlags := flagsToBuilderFlags(flags)
+ p.unstrippedOutputFile = in
+ binName := in.Base()
+ if p.needsStrip(ctx) {
+ stripped := android.PathForModuleOut(ctx, "stripped", binName)
+ p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ in = stripped
+ }
+
+ m := ctx.Module().(*Module)
+ p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()]
+
+ // use cpExecutable to make it executable
+ outputFile := android.PathForModuleOut(ctx, binName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpExecutable,
+ Description: "prebuilt",
+ Output: outputFile,
+ Input: in,
+ })
+
+ return outputFile
+}
+
+func VendorSnapshotBinaryFactory() android.Module {
+ module, binary := NewBinary(android.DeviceSupported)
+ binary.baseLinker.Properties.No_libcrt = BoolPtr(true)
+ binary.baseLinker.Properties.Nocrt = BoolPtr(true)
+
+ // Prevent default system libs (libc, libm, and libdl) from being linked
+ if binary.baseLinker.Properties.System_shared_libs == nil {
+ binary.baseLinker.Properties.System_shared_libs = []string{}
+ }
+
+ prebuilt := &vendorSnapshotBinaryDecorator{
+ binaryDecorator: binary,
+ }
+
+ module.compiler = nil
+ module.sanitize = nil
+ module.stl = nil
+ module.linker = prebuilt
+
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ vendorSnapshotLoadHook(ctx, prebuilt)
+ })
+
+ module.AddProperties(&prebuilt.properties)
+ return module.Init()
+}
+
func init() {
android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
+ android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory)
+ android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory)
+ android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
+ android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
}
func VendorSnapshotSingleton() android.Singleton {
@@ -367,3 +711,120 @@
func (c *vendorSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("SOONG_VENDOR_SNAPSHOT_ZIP", c.vendorSnapshotZipFile.String())
}
+
+type snapshotInterface interface {
+ matchesWithDevice(config android.DeviceConfig) bool
+}
+
+var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil)
+var _ snapshotInterface = (*vendorSnapshotLibraryDecorator)(nil)
+var _ snapshotInterface = (*vendorSnapshotBinaryDecorator)(nil)
+
+// gathers all snapshot modules for vendor, and disable unnecessary snapshots
+// TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules
+func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) {
+ vndkVersion := ctx.DeviceConfig().VndkVersion()
+ // don't need snapshot if current
+ if vndkVersion == "current" || vndkVersion == "" {
+ return
+ }
+
+ module, ok := ctx.Module().(*Module)
+ if !ok || !module.Enabled() || module.VndkVersion() != vndkVersion {
+ return
+ }
+
+ snapshot, ok := module.linker.(snapshotInterface)
+ if !ok {
+ return
+ }
+
+ if !snapshot.matchesWithDevice(ctx.DeviceConfig()) {
+ // Disable unnecessary snapshot module, but do not disable
+ // vndk_prebuilt_shared because they might be packed into vndk APEX
+ if !module.IsVndk() {
+ module.Disable()
+ }
+ return
+ }
+
+ var snapshotMap *snapshotMap
+
+ if lib, ok := module.linker.(libraryInterface); ok {
+ if lib.static() {
+ snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
+ } else if lib.shared() {
+ snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
+ } else {
+ // header
+ snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
+ }
+ } else if _, ok := module.linker.(*vendorSnapshotBinaryDecorator); ok {
+ snapshotMap = vendorSnapshotBinaries(ctx.Config())
+ } else {
+ return
+ }
+
+ vendorSnapshotsLock.Lock()
+ defer vendorSnapshotsLock.Unlock()
+ snapshotMap.add(module.BaseModuleName(), ctx.Arch().ArchType, ctx.ModuleName())
+}
+
+// Disables source modules which have snapshots
+func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) {
+ vndkVersion := ctx.DeviceConfig().VndkVersion()
+ // don't need snapshot if current
+ if vndkVersion == "current" || vndkVersion == "" {
+ return
+ }
+
+ module, ok := ctx.Module().(*Module)
+ if !ok {
+ return
+ }
+
+ if module.HasVendorVariant() {
+ vendorSnapshotsLock.Lock()
+ defer vendorSnapshotsLock.Unlock()
+
+ vendorSuffixModules(ctx.Config())[ctx.ModuleName()] = true
+ }
+
+ if module.isSnapshotPrebuilt() || module.VndkVersion() != ctx.DeviceConfig().VndkVersion() {
+ // only non-snapshot modules with BOARD_VNDK_VERSION
+ return
+ }
+
+ var snapshotMap *snapshotMap
+
+ if lib, ok := module.linker.(libraryInterface); ok {
+ if lib.static() {
+ snapshotMap = vendorSnapshotStaticLibs(ctx.Config())
+ } else if lib.shared() {
+ snapshotMap = vendorSnapshotSharedLibs(ctx.Config())
+ } else {
+ // header
+ snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
+ }
+ } else if _, ok := module.linker.(*binaryDecorator); ok {
+ snapshotMap = vendorSnapshotBinaries(ctx.Config())
+ } else if _, ok := module.linker.(*prebuiltBinaryLinker); ok {
+ snapshotMap = vendorSnapshotBinaries(ctx.Config())
+ } else {
+ return
+ }
+
+ if _, ok := snapshotMap.get(ctx.ModuleName(), ctx.Arch().ArchType); !ok {
+ // Corresponding snapshot doesn't exist
+ return
+ }
+
+ // Disables source modules if corresponding snapshot exists.
+ if lib, ok := module.linker.(libraryInterface); ok && lib.buildStatic() && lib.buildShared() {
+ // But do not disable because the shared variant depends on the static variant.
+ module.SkipInstall()
+ module.Properties.HideFromMake = true
+ } else {
+ module.Disable()
+ }
+}
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index c941c46..50bc325 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -31,7 +31,8 @@
//
// vndk_prebuilt_shared {
// name: "libfoo",
-// version: "27.1.0",
+// version: "27",
+// target_arch: "arm64",
// vendor_available: true,
// vndk: {
// enabled: true,
@@ -61,10 +62,6 @@
// Prebuilt files for each arch.
Srcs []string `android:"arch_variant"`
- // list of directories relative to the Blueprints file that will be added to the include
- // path (using -isystem) for any module that links against this module.
- Export_system_include_dirs []string `android:"arch_variant"`
-
// list of flags that will be used for any module that links against this module.
Export_flags []string `android:"arch_variant"`
@@ -137,11 +134,26 @@
if len(p.properties.Srcs) > 0 && p.shared() {
p.libraryDecorator.exportIncludes(ctx)
- p.libraryDecorator.reexportSystemDirs(
- android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
// current VNDK prebuilts are only shared libs.
- return p.singleSourcePath(ctx)
+
+ in := p.singleSourcePath(ctx)
+ builderFlags := flagsToBuilderFlags(flags)
+ p.unstrippedOutputFile = in
+ libName := in.Base()
+ if p.needsStrip(ctx) {
+ stripped := android.PathForModuleOut(ctx, "stripped", libName)
+ p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
+ in = stripped
+ }
+
+ // Optimize out relinking against shared libraries whose interface hasn't changed by
+ // depending on a table of contents file instead of the library itself.
+ tocFile := android.PathForModuleOut(ctx, libName+".toc")
+ p.tocFile = android.OptionalPathForPath(tocFile)
+ TransformSharedObjectToToc(ctx, in, tocFile, builderFlags)
+
+ return in
}
ctx.Module().SkipInstall()
@@ -212,6 +224,15 @@
&prebuilt.properties,
)
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ // Only vndk snapshots of BOARD_VNDK_VERSION will be used when building.
+ if prebuilt.version() != ctx.DeviceConfig().VndkVersion() {
+ module.SkipInstall()
+ module.Properties.HideFromMake = true
+ return
+ }
+ })
+
return module
}
@@ -220,7 +241,8 @@
//
// vndk_prebuilt_shared {
// name: "libfoo",
-// version: "27.1.0",
+// version: "27",
+// target_arch: "arm64",
// vendor_available: true,
// vndk: {
// enabled: true,
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index ac5b691..4d8ccb5 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -41,12 +41,21 @@
"android/soong/android"
+ "github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
)
const SystemPartition = "/system/"
const SystemOtherPartition = "/system_other/"
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+var SystemServerDepTag = dependencyTag{name: "system-server-dep"}
+var SystemServerForcedDepTag = dependencyTag{name: "system-server-forced-dep"}
+
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.PathContext,
@@ -78,7 +87,7 @@
bootProfileCommand(ctx, global, module, rule)
}
- if !dexpreoptDisabled(global, module) {
+ if !dexpreoptDisabled(ctx, global, module) {
// Don't preopt individual boot jars, they will be preopted together.
if !contains(global.BootJars, module.Name) {
appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) &&
@@ -95,14 +104,21 @@
return rule, nil
}
-func dexpreoptDisabled(global GlobalConfig, module ModuleConfig) bool {
+func dexpreoptDisabled(ctx android.PathContext, global GlobalConfig, module ModuleConfig) bool {
if contains(global.DisablePreoptModules, module.Name) {
return true
}
// Don't preopt system server jars that are updatable.
for _, p := range global.UpdatableSystemServerJars {
- if _, jar := SplitApexJarPair(p); jar == module.Name {
+ if _, jar := android.SplitApexJarPair(p); jar == module.Name {
+ return true
+ }
+ }
+
+ // Don't preopt system server jars that are not Soong modules.
+ if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) {
+ if _, ok := ctx.(android.ModuleContext); !ok {
return true
}
}
@@ -236,7 +252,8 @@
var conditionalClassLoaderContextHost29 android.Paths
var conditionalClassLoaderContextTarget29 []string
- var classLoaderContextHostString string
+ var classLoaderContextHostString, classLoaderContextDeviceString string
+ var classLoaderDeps android.Paths
if module.EnforceUsesLibraries {
usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...)
@@ -282,6 +299,30 @@
filepath.Join("/system/framework", hidlBase+".jar"))
classLoaderContextHostString = strings.Join(classLoaderContextHost.Strings(), ":")
+ } else if android.InList(module.Name, NonUpdatableSystemServerJars(ctx, global)) {
+ // We expect that all dexpreopted system server jars are Soong modules.
+ mctx, isModule := ctx.(android.ModuleContext)
+ if !isModule {
+ panic("Cannot dexpreopt system server jar that is not a soong module.")
+ }
+
+ // System server jars should be dexpreopted together: class loader context of each jar
+ // should include preceding jars (which can be found as dependencies of the current jar
+ // with a special tag).
+ var jarsOnHost android.Paths
+ var jarsOnDevice []string
+ mctx.VisitDirectDepsWithTag(SystemServerDepTag, func(dep android.Module) {
+ depName := mctx.OtherModuleName(dep)
+ if jar, ok := dep.(interface{ DexJar() android.Path }); ok {
+ jarsOnHost = append(jarsOnHost, jar.DexJar())
+ jarsOnDevice = append(jarsOnDevice, "/system/framework/"+depName+".jar")
+ } else {
+ mctx.ModuleErrorf("module \"%s\" is not a jar", depName)
+ }
+ })
+ classLoaderContextHostString = strings.Join(jarsOnHost.Strings(), ":")
+ classLoaderContextDeviceString = strings.Join(jarsOnDevice, ":")
+ classLoaderDeps = jarsOnHost
} else {
// Pass special class loader context to skip the classpath and collision check.
// This will get removed once LOCAL_USES_LIBRARIES is enforced.
@@ -293,8 +334,13 @@
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
// Set values in the environment of the rule. These may be modified by construct_context.sh.
- rule.Command().FlagWithArg("class_loader_context_arg=--class-loader-context=", classLoaderContextHostString)
- rule.Command().Text(`stored_class_loader_context_arg=""`)
+ if classLoaderContextHostString == `\&` {
+ rule.Command().Text(`class_loader_context_arg=--class-loader-context=\&`)
+ rule.Command().Text(`stored_class_loader_context_arg=""`)
+ } else {
+ rule.Command().Text("class_loader_context_arg=--class-loader-context=PCL[" + classLoaderContextHostString + "]")
+ rule.Command().Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + classLoaderContextDeviceString + "]")
+ }
if module.EnforceUsesLibraries {
if module.ManifestPath != nil {
@@ -348,7 +394,7 @@
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", module.PreoptBootClassPathDexFiles, ":").
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
Flag("${class_loader_context_arg}").
- Flag("${stored_class_loader_context_arg}").
+ Flag("${stored_class_loader_context_arg}").Implicits(classLoaderDeps).
FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
FlagWithInput("--dex-file=", module.DexPath).
FlagWithArg("--dex-location=", dexLocationArg).
@@ -537,19 +583,29 @@
}
// Expected format for apexJarValue = <apex name>:<jar name>
-func SplitApexJarPair(apexJarValue string) (string, string) {
- var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2)
- if apexJarPair == nil || len(apexJarPair) != 2 {
- panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>",
- apexJarValue))
- }
- return apexJarPair[0], apexJarPair[1]
+func GetJarLocationFromApexJarPair(apexJarValue string) string {
+ apex, jar := android.SplitApexJarPair(apexJarValue)
+ return filepath.Join("/apex", apex, "javalib", jar+".jar")
}
-// Expected format for apexJarValue = <apex name>:<jar name>
-func GetJarLocationFromApexJarPair(apexJarValue string) string {
- apex, jar := SplitApexJarPair(apexJarValue)
- return filepath.Join("/apex", apex, "javalib", jar+".jar")
+func GetJarsFromApexJarPairs(apexJarPairs []string) []string {
+ modules := make([]string, len(apexJarPairs))
+ for i, p := range apexJarPairs {
+ _, jar := android.SplitApexJarPair(p)
+ modules[i] = jar
+ }
+ return modules
+}
+
+var nonUpdatableSystemServerJarsKey = android.NewOnceKey("nonUpdatableSystemServerJars")
+
+// TODO: eliminate the superficial global config parameter by moving global config definition
+// from java subpackage to dexpreopt.
+func NonUpdatableSystemServerJars(ctx android.PathContext, global GlobalConfig) []string {
+ return ctx.Config().Once(nonUpdatableSystemServerJarsKey, func() interface{} {
+ return android.RemoveListFromList(global.SystemServerJars,
+ GetJarsFromApexJarPairs(global.UpdatableSystemServerJars))
+ }).([]string)
}
func contains(l []string, s string) bool {
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 4c9add8..7d0bd8f 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -70,12 +70,11 @@
// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
// ctx.Config().
-func systemServerClasspath(ctx android.PathContext) []string {
+func systemServerClasspath(ctx android.MakeVarsContext) []string {
return ctx.Config().OnceStringSlice(systemServerClasspathKey, func() []string {
global := dexpreoptGlobalConfig(ctx)
-
var systemServerClasspathLocations []string
- for _, m := range global.SystemServerJars {
+ for _, m := range *DexpreoptedSystemServerJars(ctx.Config()) {
systemServerClasspathLocations = append(systemServerClasspathLocations,
filepath.Join("/system/framework", m+".jar"))
}
@@ -112,19 +111,10 @@
return moduleName
}
-func getJarsFromApexJarPairs(apexJarPairs []string) []string {
- modules := make([]string, len(apexJarPairs))
- for i, p := range apexJarPairs {
- _, jar := dexpreopt.SplitApexJarPair(p)
- modules[i] = jar
- }
- return modules
-}
-
var (
- bootImageConfigKey = android.NewOnceKey("bootImageConfig")
- artBootImageName = "art"
- frameworkBootImageName = "boot"
+ bootImageConfigKey = android.NewOnceKey("bootImageConfig")
+ artBootImageName = "art"
+ frameworkBootImageName = "boot"
)
// Construct the global boot image configs.
@@ -141,7 +131,7 @@
artModules = append(artModules, "jacocoagent")
}
frameworkModules := android.RemoveListFromList(global.BootJars,
- concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars)))
+ concat(artModules, dexpreopt.GetJarsFromApexJarPairs(global.UpdatableBootJars)))
artSubdir := "apex/com.android.art/javalib"
frameworkSubdir := "system/framework"
@@ -179,8 +169,8 @@
}
configs := map[string]*bootImageConfig{
- artBootImageName: &artCfg,
- frameworkBootImageName: &frameworkCfg,
+ artBootImageName: &artCfg,
+ frameworkBootImageName: &frameworkCfg,
}
// common to all configs
diff --git a/java/java.go b/java/java.go
index 279d674..d84d162 100644
--- a/java/java.go
+++ b/java/java.go
@@ -23,12 +23,14 @@
"path/filepath"
"strconv"
"strings"
+ "sync"
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/dexpreopt"
"android/soong/java/config"
"android/soong/tradefed"
)
@@ -52,6 +54,8 @@
PropertyName: "java_tests",
},
})
+
+ android.PostDepsMutators(RegisterPostDepsMutators)
}
func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
@@ -76,6 +80,44 @@
ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
}
+func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("ordered_system_server_jars", systemServerJarsDepsMutator)
+}
+
+var (
+ dexpreoptedSystemServerJarsKey = android.NewOnceKey("dexpreoptedSystemServerJars")
+ dexpreoptedSystemServerJarsLock sync.Mutex
+)
+
+func DexpreoptedSystemServerJars(config android.Config) *[]string {
+ return config.Once(dexpreoptedSystemServerJarsKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+// A PostDepsMutator pass that enforces total order on non-updatable system server jars. A total
+// order is neededed because such jars must be dexpreopted together (each jar on the list must have
+// all preceding jars in its class loader context). The total order must be compatible with the
+// partial order imposed by genuine dependencies between system server jars (which is not always
+// respected by the PRODUCT_SYSTEM_SERVER_JARS variable).
+//
+// An earlier mutator pass creates genuine dependencies, and this pass traverses the jars in that
+// order (which is partial and non-deterministic). This pass adds additional dependencies between
+// jars, making the order total and deterministic. It also constructs a global ordered list.
+func systemServerJarsDepsMutator(ctx android.BottomUpMutatorContext) {
+ jars := dexpreopt.NonUpdatableSystemServerJars(ctx, dexpreoptGlobalConfig(ctx))
+ name := ctx.ModuleName()
+ if android.InList(name, jars) {
+ dexpreoptedSystemServerJarsLock.Lock()
+ defer dexpreoptedSystemServerJarsLock.Unlock()
+ jars := DexpreoptedSystemServerJars(ctx.Config())
+ for _, dep := range *jars {
+ ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerDepTag, dep)
+ }
+ *jars = append(*jars, name)
+ }
+}
+
func (j *Module) checkSdkVersion(ctx android.ModuleContext) {
if j.SocSpecific() || j.DeviceSpecific() ||
(j.ProductSpecific() && ctx.Config().EnforceProductPartitionInterface()) {
@@ -659,6 +701,11 @@
} else if j.shouldInstrumentStatic(ctx) {
ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent")
}
+
+ // services depend on com.android.location.provider, but dependency in not registered in a Blueprint file
+ if ctx.ModuleName() == "services" {
+ ctx.AddDependency(ctx.Module(), dexpreopt.SystemServerForcedDepTag, "com.android.location.provider")
+ }
}
func hasSrcExt(srcs []string, ext string) bool {