Merge "Don't hide *.kotlin_module in turbine dependencies"
diff --git a/Android.bp b/Android.bp
index afac2b5..e2d606e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -638,6 +638,7 @@
kernel_headers {
name: "device_kernel_headers",
vendor: true,
+ recovery_available: true,
}
cc_genrule {
diff --git a/android/config.go b/android/config.go
index b142042..15e2ad4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -369,14 +369,14 @@
}
func (c *config) fromEnv() error {
- switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") {
- case "", "1.8":
- // Nothing, we always use OpenJDK9
+ switch c.Getenv("EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9") {
+ case "":
+ // Nothing, this is the default
case "true":
- // Use OpenJDK9 and target 1.9
+ // Use -source 9 -target 9
c.targetOpenJDK9 = true
default:
- return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "1.8", or "true"`)
+ return fmt.Errorf(`Invalid value for EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9, should be "" or "true"`)
}
return nil
diff --git a/android/module.go b/android/module.go
index fb5c00a..3906fd7 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1299,6 +1299,10 @@
a.commonProperties.Product_services_specific = boolPtr(false)
}
+func (a *ModuleBase) EnableNativeBridgeSupportByDefault() {
+ a.commonProperties.Native_bridge_supported = boolPtr(true)
+}
+
func (a *androidModuleContext) InstallInData() bool {
return a.module.InstallInData()
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 2556770..5087b18 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -50,6 +50,11 @@
return "prebuilt_" + name
}
+// The below source-related functions and the srcs, src fields are based on an assumption that
+// prebuilt modules have a static source property at the moment. Currently there is only one
+// exception, android_app_import, which chooses a source file depending on the product's DPI
+// preference configs. We'll want to add native support for dynamic source cases if we end up having
+// more modules like this.
func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
if p.srcs != nil {
if len(*p.srcs) == 0 {
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 34e673c..88c5304 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -879,7 +879,6 @@
}
`,
},
-
{
desc: "prebuilt_etc_PRODUCT_OUT/system/etc",
in: `
@@ -1065,6 +1064,80 @@
`,
},
{
+ desc: "prebuilt_usr_share",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_usr_share {
+ name: "foo",
+
+ src: "foo.txt",
+}
+`,
+ },
+ {
+ desc: "prebuilt_usr_share subdir_bar",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/usr/share/bar
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_usr_share {
+ name: "foo",
+
+ src: "foo.txt",
+ sub_dir: "bar",
+}
+`,
+ },
+ {
+ desc: "prebuilt_usr_share_host",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_usr_share_host {
+ name: "foo",
+
+ src: "foo.txt",
+}
+`,
+ },
+ {
+ desc: "prebuilt_usr_share_host subdir_bar",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(HOST_OUT)/usr/share/bar
+LOCAL_SRC_FILES := foo.txt
+include $(BUILD_PREBUILT)
+`,
+ expected: `
+prebuilt_usr_share_host {
+ name: "foo",
+
+ src: "foo.txt",
+ sub_dir: "bar",
+}
+`,
+ },
+ {
desc: "vts_config",
in: `
include $(CLEAR_VARS)
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 706c0ec..f217da6 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -431,14 +431,6 @@
return ""
}
-// Create sub_dir: attribute for the given path
-func makePrebuiltEtcDestination(mod *parser.Module, path string) {
- mod.Properties = append(mod.Properties, &parser.Property{
- Name: "sub_dir",
- Value: &parser.String{Value: path},
- })
-}
-
// Set the value of the given attribute to the error message
func indicateAttributeError(mod *parser.Module, attributeName string, format string, a ...interface{}) error {
msg := fmt.Sprintf(format, a...)
@@ -464,16 +456,52 @@
return val
}
-// A prefix to strip before setting 'filename' attribute and an array of boolean attributes to set.
-type filenamePrefixToFlags struct {
+// etcPrebuiltModuleUpdate contains information on updating certain parts of a defined module such as:
+// * changing the module type from prebuilt_etc to a different one
+// * stripping the prefix of the install path based on the module type
+// * appending additional boolean properties to the prebuilt module
+type etcPrebuiltModuleUpdate struct {
+ // The prefix of the install path defined in local_module_path. The prefix is removed from local_module_path
+ // before setting the 'filename' attribute.
prefix string
- flags []string
+
+ // There is only one prebuilt module type in makefiles. In Soong, there are multiple versions of
+ // prebuilts based on local_module_path. By default, it is "prebuilt_etc" if modType is blank. An
+ // example is if the local_module_path contains $(TARGET_OUT)/usr/share, the module type is
+ // considered as prebuilt_usr_share.
+ modType string
+
+ // Additional boolean attributes to be added in the prebuilt module. Each added boolean attribute
+ // has a value of true.
+ flags []string
}
-var localModulePathRewrite = map[string][]filenamePrefixToFlags{
- "HOST_OUT": {{prefix: "/etc"}},
+func (f etcPrebuiltModuleUpdate) update(m *parser.Module, path string) bool {
+ updated := false
+ if path == f.prefix {
+ updated = true
+ } else if trimmedPath := strings.TrimPrefix(path, f.prefix+"/"); trimmedPath != path {
+ m.Properties = append(m.Properties, &parser.Property{
+ Name: "sub_dir",
+ Value: &parser.String{Value: trimmedPath},
+ })
+ updated = true
+ }
+ if updated {
+ for _, flag := range f.flags {
+ m.Properties = append(m.Properties, &parser.Property{Name: flag, Value: &parser.Bool{Value: true, Token: "true"}})
+ }
+ if f.modType != "" {
+ m.Type = f.modType
+ }
+ }
+ return updated
+}
+
+var localModuleUpdate = map[string][]etcPrebuiltModuleUpdate{
+ "HOST_OUT": {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
"PRODUCT_OUT": {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
- "TARGET_OUT": {{prefix: "/etc"}},
+ "TARGET_OUT": {{prefix: "/etc"}, {prefix: "/usr/share", modType: "prebuilt_usr_share"}},
"TARGET_OUT_ETC": {{prefix: ""}},
"TARGET_OUT_PRODUCT": {{prefix: "/etc", flags: []string{"product_specific"}}},
"TARGET_OUT_PRODUCT_ETC": {{prefix: "", flags: []string{"product_specific"}}},
@@ -526,37 +554,23 @@
if prop_local_module_path, ok := mod.GetProperty(local_module_path); ok {
removeProperty(mod, local_module_path)
prefixVariableName := getStringProperty(prop_local_module_path, "var")
- path := getStringProperty(prop_local_module_path, "fixed")
- if prefixRewrites, ok := localModulePathRewrite[prefixVariableName]; ok {
- rewritten := false
- for _, prefixRewrite := range prefixRewrites {
- if path == prefixRewrite.prefix {
- rewritten = true
- } else if trimmedPath := strings.TrimPrefix(path, prefixRewrite.prefix+"/"); trimmedPath != path {
- makePrebuiltEtcDestination(mod, trimmedPath)
- rewritten = true
- }
- if rewritten {
- for _, flag := range prefixRewrite.flags {
- mod.Properties = append(mod.Properties, &parser.Property{Name: flag, Value: &parser.Bool{Value: true, Token: "true"}})
- }
- break
- }
+ if moduleUpdates, ok := localModuleUpdate[prefixVariableName]; ok {
+ path := getStringProperty(prop_local_module_path, "fixed")
+ updated := false
+ for i := 0; i < len(moduleUpdates) && !updated; i++ {
+ updated = moduleUpdates[i].update(mod, path)
}
- if !rewritten {
+ if !updated {
expectedPrefices := ""
sep := ""
- for _, prefixRewrite := range prefixRewrites {
+ for _, moduleUpdate := range moduleUpdates {
expectedPrefices += sep
sep = ", "
- expectedPrefices += prefixRewrite.prefix
+ expectedPrefices += moduleUpdate.prefix
}
return indicateAttributeError(mod, "filename",
"LOCAL_MODULE_PATH value under $(%s) should start with %s", prefixVariableName, expectedPrefices)
}
- if prefixVariableName == "HOST_OUT" {
- mod.Type = "prebuilt_etc_host"
- }
} else {
return indicateAttributeError(mod, "filename", "Cannot handle $(%s) for the prebuilt_etc", prefixVariableName)
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 79469ee..c7883e2 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -86,7 +86,7 @@
if len(c.Properties.AndroidMkWholeStaticLibs) > 0 {
fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
}
- fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.getMakeLinkType())
+ fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.makeLinkType)
if c.useVndk() {
fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
}
diff --git a/cc/cc.go b/cc/cc.go
index bb24942..eaf41d8 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -246,14 +246,14 @@
sdkVersion() string
useVndk() bool
isNdk() bool
- isLlndk() bool
- isLlndkPublic() bool
- isVndkPrivate() bool
+ isLlndk(config android.Config) bool
+ isLlndkPublic(config android.Config) bool
+ isVndkPrivate(config android.Config) bool
isVndk() bool
isVndkSp() bool
isVndkExt() bool
inRecovery() bool
- shouldCreateVndkSourceAbiDump() bool
+ shouldCreateVndkSourceAbiDump(config android.Config) bool
selectedStl() string
baseModuleName() string
getVndkExtendsModuleName() string
@@ -408,6 +408,8 @@
// only non-nil when this is a shared library that reuses the objects of a static library
staticVariant *Module
+
+ makeLinkType string
}
func (c *Module) OutputFile() android.OptionalPath {
@@ -510,19 +512,19 @@
return inList(c.Name(), ndkMigratedLibs)
}
-func (c *Module) isLlndk() bool {
+func (c *Module) isLlndk(config android.Config) bool {
// Returns true for both LLNDK (public) and LLNDK-private libs.
- return inList(c.Name(), llndkLibraries)
+ return inList(c.Name(), *llndkLibraries(config))
}
-func (c *Module) isLlndkPublic() bool {
+func (c *Module) isLlndkPublic(config android.Config) bool {
// Returns true only for LLNDK (public) libs.
- return c.isLlndk() && !c.isVndkPrivate()
+ return c.isLlndk(config) && !c.isVndkPrivate(config)
}
-func (c *Module) isVndkPrivate() bool {
+func (c *Module) isVndkPrivate(config android.Config) bool {
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
- return inList(c.Name(), vndkPrivateLibraries)
+ return inList(c.Name(), *vndkPrivateLibraries(config))
}
func (c *Module) isVndk() bool {
@@ -687,16 +689,16 @@
return ctx.mod.isNdk()
}
-func (ctx *moduleContextImpl) isLlndk() bool {
- return ctx.mod.isLlndk()
+func (ctx *moduleContextImpl) isLlndk(config android.Config) bool {
+ return ctx.mod.isLlndk(config)
}
-func (ctx *moduleContextImpl) isLlndkPublic() bool {
- return ctx.mod.isLlndkPublic()
+func (ctx *moduleContextImpl) isLlndkPublic(config android.Config) bool {
+ return ctx.mod.isLlndkPublic(config)
}
-func (ctx *moduleContextImpl) isVndkPrivate() bool {
- return ctx.mod.isVndkPrivate()
+func (ctx *moduleContextImpl) isVndkPrivate(config android.Config) bool {
+ return ctx.mod.isVndkPrivate(config)
}
func (ctx *moduleContextImpl) isVndk() bool {
@@ -728,7 +730,7 @@
}
// Check whether ABI dumps should be created for this module.
-func (ctx *moduleContextImpl) shouldCreateVndkSourceAbiDump() bool {
+func (ctx *moduleContextImpl) shouldCreateVndkSourceAbiDump(config android.Config) bool {
if ctx.ctx.Config().IsEnvTrue("SKIP_ABI_CHECKS") {
return false
}
@@ -753,10 +755,10 @@
if ctx.isNdk() {
return true
}
- if ctx.isLlndkPublic() {
+ if ctx.isLlndkPublic(config) {
return true
}
- if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate() {
+ if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(config) {
// Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext and this is not
// VNDK-private.
return true
@@ -907,6 +909,8 @@
}
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
+ c.makeLinkType = c.getMakeLinkType(actx.Config())
+
ctx := &moduleContext{
ModuleContext: actx,
moduleContextImpl: moduleContextImpl{
@@ -1186,6 +1190,9 @@
//
// The caller can then know to add the variantLibs dependencies differently from the
// nonvariantLibs
+
+ llndkLibraries := llndkLibraries(actx.Config())
+ vendorPublicLibraries := vendorPublicLibraries(actx.Config())
rewriteNdkLibs := func(list []string) (nonvariantLibs []string, variantLibs []string) {
variantLibs = []string{}
nonvariantLibs = []string{}
@@ -1198,9 +1205,9 @@
} else {
variantLibs = append(variantLibs, name+ndkLibrarySuffix)
}
- } else if ctx.useVndk() && inList(name, llndkLibraries) {
+ } else if ctx.useVndk() && inList(name, *llndkLibraries) {
nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix)
- } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, vendorPublicLibraries) {
+ } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, *vendorPublicLibraries) {
vendorPublicLib := name + vendorPublicLibrarySuffix
if actx.OtherModuleExists(vendorPublicLib) {
nonvariantLibs = append(nonvariantLibs, vendorPublicLib)
@@ -1501,6 +1508,7 @@
// it is subject to be double loaded. Such lib should be explicitly marked as double_loadable: true
// or as vndk-sp (vndk: { enabled: true, support_system_process: true}).
func checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
+ llndkLibraries := llndkLibraries(ctx.Config())
check := func(child, parent android.Module) bool {
to, ok := child.(*Module)
if !ok {
@@ -1517,7 +1525,7 @@
return true
}
- if to.isVndkSp() || inList(child.Name(), llndkLibraries) || Bool(to.VendorProperties.Double_loadable) {
+ if to.isVndkSp() || inList(child.Name(), *llndkLibraries) || Bool(to.VendorProperties.Double_loadable) {
return false
}
@@ -1532,7 +1540,7 @@
}
if module, ok := ctx.Module().(*Module); ok {
if lib, ok := module.linker.(*libraryDecorator); ok && lib.shared() {
- if inList(ctx.ModuleName(), llndkLibraries) || Bool(module.VendorProperties.Double_loadable) {
+ if inList(ctx.ModuleName(), *llndkLibraries) || Bool(module.VendorProperties.Double_loadable) {
ctx.WalkDeps(check)
}
}
@@ -1546,6 +1554,9 @@
directStaticDeps := []*Module{}
directSharedDeps := []*Module{}
+ llndkLibraries := llndkLibraries(ctx.Config())
+ vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
+
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
@@ -1788,8 +1799,8 @@
libName := strings.TrimSuffix(depName, llndkLibrarySuffix)
libName = strings.TrimSuffix(libName, vendorPublicLibrarySuffix)
libName = strings.TrimPrefix(libName, "prebuilt_")
- isLLndk := inList(libName, llndkLibraries)
- isVendorPublicLib := inList(libName, vendorPublicLibraries)
+ isLLndk := inList(libName, *llndkLibraries)
+ isVendorPublicLib := inList(libName, *vendorPublicLibraries)
bothVendorAndCoreVariantsExist := ccDep.hasVendorVariant() || isLLndk
if ctx.DeviceConfig().VndkUseCoreVariant() && ccDep.isVndk() && !ccDep.mustUseVendorVariant() {
@@ -1919,10 +1930,12 @@
return false
}
-func (c *Module) getMakeLinkType() string {
+func (c *Module) getMakeLinkType(config android.Config) string {
if c.useVndk() {
- if inList(c.Name(), vndkCoreLibraries) || inList(c.Name(), vndkSpLibraries) || inList(c.Name(), llndkLibraries) {
- if inList(c.Name(), vndkPrivateLibraries) {
+ if inList(c.Name(), *vndkCoreLibraries(config)) ||
+ inList(c.Name(), *vndkSpLibraries(config)) ||
+ inList(c.Name(), *llndkLibraries(config)) {
+ if inList(c.Name(), *vndkPrivateLibraries(config)) {
return "native:vndk_private"
} else {
return "native:vndk"
@@ -1937,7 +1950,7 @@
// TODO(b/114741097): use the correct ndk stl once build errors have been fixed
//family, link := getNdkStlFamilyAndLinkType(c)
//return fmt.Sprintf("native:ndk:%s:%s", family, link)
- } else if inList(c.Name(), vndkUsingCoreVariantLibraries) {
+ } else if inList(c.Name(), *vndkUsingCoreVariantLibraries(config)) {
return "native:platform_vndk"
} else {
return "native:platform"
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 347bfab..94a8257 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -101,8 +101,9 @@
// not emit the table by default on Android since NDK still uses GNU binutils.
"-faddrsig",
- // -Wimplicit-fallthrough is not enabled by -Wall.
+ // Make implicit fallthrough an error in the future.
"-Wimplicit-fallthrough",
+ "-Wno-error=implicit-fallthrough",
// Help catch common 32/64-bit errors.
"-Werror=int-conversion",
diff --git a/cc/library.go b/cc/library.go
index 1f79bec..c2ab098 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -429,7 +429,7 @@
if library.Properties.Header_abi_checker.Enabled != nil {
return Bool(library.Properties.Header_abi_checker.Enabled)
}
- return ctx.shouldCreateVndkSourceAbiDump()
+ return ctx.shouldCreateVndkSourceAbiDump(ctx.Config())
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -783,7 +783,7 @@
}
func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
- isLlndkOrNdk := inList(ctx.baseModuleName(), llndkLibraries) || inList(ctx.baseModuleName(), ndkMigratedLibs)
+ isLlndkOrNdk := inList(ctx.baseModuleName(), *llndkLibraries(ctx.Config())) || inList(ctx.baseModuleName(), ndkMigratedLibs)
refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isLlndkOrNdk, ctx.isVndk(), false)
refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isLlndkOrNdk, ctx.isVndk(), true)
@@ -827,7 +827,7 @@
refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName)
if refAbiDumpFile != nil {
library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
- refAbiDumpFile, fileName, exportedHeaderFlags, ctx.isLlndk(), ctx.isNdk(), ctx.isVndkExt())
+ refAbiDumpFile, fileName, exportedHeaderFlags, ctx.isLlndk(ctx.Config()), ctx.isNdk(), ctx.isVndkExt())
}
}
}
diff --git a/cc/makevars.go b/cc/makevars.go
index dc91525..3c24f34 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -64,6 +64,8 @@
}
func makeVarsProvider(ctx android.MakeVarsContext) {
+ vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
+
ctx.Strict("LLVM_RELEASE_VERSION", "${config.ClangShortVersion}")
ctx.Strict("LLVM_PREBUILTS_VERSION", "${config.ClangVersion}")
ctx.Strict("LLVM_PREBUILTS_BASE", "${config.ClangBase}")
@@ -92,18 +94,18 @@
ctx.Strict("BOARD_VNDK_VERSION", ctx.DeviceConfig().VndkVersion())
- ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(vndkCoreLibraries, " "))
- ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(vndkSpLibraries, " "))
- ctx.Strict("LLNDK_LIBRARIES", strings.Join(llndkLibraries, " "))
- ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(vndkPrivateLibraries, " "))
- ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(vndkUsingCoreVariantLibraries, " "))
+ ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(*vndkCoreLibraries(ctx.Config()), " "))
+ ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(*vndkSpLibraries(ctx.Config()), " "))
+ ctx.Strict("LLNDK_LIBRARIES", strings.Join(*llndkLibraries(ctx.Config()), " "))
+ ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(*vndkPrivateLibraries(ctx.Config()), " "))
+ ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(*vndkUsingCoreVariantLibraries(ctx.Config()), " "))
// Filter vendor_public_library that are exported to make
exportedVendorPublicLibraries := []string{}
ctx.VisitAllModules(func(module android.Module) {
if ccModule, ok := module.(*Module); ok {
baseName := ccModule.BaseModuleName()
- if inList(baseName, vendorPublicLibraries) && module.ExportedToMake() {
+ if inList(baseName, *vendorPublicLibraries) && module.ExportedToMake() {
if !inList(baseName, exportedVendorPublicLibraries) {
exportedVendorPublicLibraries = append(exportedVendorPublicLibraries, baseName)
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index c63b200..ff990b5 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -38,9 +38,12 @@
ndkLibrarySuffix = ".ndk"
ndkPrebuiltSharedLibs = []string{
+ "aaudio",
+ "amidi",
"android",
"binder_ndk",
"c",
+ "camera2ndk",
"dl",
"EGL",
"GLESv1_CM",
@@ -49,6 +52,7 @@
"jnigraphics",
"log",
"mediandk",
+ "nativewindow",
"m",
"OpenMAXAL",
"OpenSLES",
@@ -382,5 +386,6 @@
func ndkLibraryFactory() android.Module {
module := newStubLibrary()
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
+ module.ModuleBase.EnableNativeBridgeSupportByDefault()
return module
}
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index 8451295..026ff22 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -70,6 +70,7 @@
// ./prebuilts/ndk/current/platforms/android-<sdk_version>/arch-$(HOST_ARCH)/usr/lib/<NAME>.o.
func ndkPrebuiltObjectFactory() android.Module {
module := newBaseModule(android.DeviceSupported, android.MultilibBoth)
+ module.ModuleBase.EnableNativeBridgeSupportByDefault()
module.linker = &ndkPrebuiltObjectLinker{
objectLinker: objectLinker{
baseLinker: NewBaseLinker(nil),
@@ -134,6 +135,7 @@
}
module.installer = nil
module.Properties.HideFromMake = true
+ module.ModuleBase.EnableNativeBridgeSupportByDefault()
return module.Init()
}
diff --git a/cc/sabi.go b/cc/sabi.go
index 4a86499..451176f 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -78,7 +78,7 @@
func sabiDepsMutator(mctx android.TopDownMutatorContext) {
if c, ok := mctx.Module().(*Module); ok &&
- ((c.isVndk() && c.useVndk()) || inList(c.Name(), llndkLibraries) ||
+ ((c.isVndk() && c.useVndk()) || inList(c.Name(), *llndkLibraries(mctx.Config())) ||
(c.sabi != nil && c.sabi.Properties.CreateSAbiDumps)) {
mctx.VisitDirectDeps(func(m android.Module) {
tag := mctx.OtherModuleDependencyTag(m)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 2d80c22..acf2bef 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -817,7 +817,7 @@
}
if mctx.Device() && runtimeLibrary != "" {
- if inList(runtimeLibrary, llndkLibraries) && !c.static() && c.useVndk() {
+ if inList(runtimeLibrary, *llndkLibraries(mctx.Config())) && !c.static() && c.useVndk() {
runtimeLibrary = runtimeLibrary + llndkLibrarySuffix
}
diff --git a/cc/vendor_public_library.go b/cc/vendor_public_library.go
index 2072ad9..5738d25 100644
--- a/cc/vendor_public_library.go
+++ b/cc/vendor_public_library.go
@@ -24,10 +24,16 @@
var (
vendorPublicLibrarySuffix = ".vendorpublic"
- vendorPublicLibraries = []string{}
+ vendorPublicLibrariesKey = android.NewOnceKey("vendorPublicLibraries")
vendorPublicLibrariesLock sync.Mutex
)
+func vendorPublicLibraries(config android.Config) *[]string {
+ return config.Once(vendorPublicLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
// Creates a stub shared library for a vendor public library. Vendor public libraries
// are vendor libraries (owned by them and installed to /vendor partition) that are
// exposed to Android apps via JNI. The libraries are made public by being listed in
@@ -82,12 +88,13 @@
vendorPublicLibrariesLock.Lock()
defer vendorPublicLibrariesLock.Unlock()
- for _, lib := range vendorPublicLibraries {
+ vendorPublicLibraries := vendorPublicLibraries(ctx.Config())
+ for _, lib := range *vendorPublicLibraries {
if lib == name {
return
}
}
- vendorPublicLibraries = append(vendorPublicLibraries, name)
+ *vendorPublicLibraries = append(*vendorPublicLibraries, name)
}
func (stub *vendorPublicLibraryStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags {
diff --git a/cc/vndk.go b/cc/vndk.go
index 44a83e7..7859fa2 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -192,29 +192,63 @@
}
var (
- vndkCoreLibraries []string
- vndkSpLibraries []string
- llndkLibraries []string
- vndkPrivateLibraries []string
- vndkUsingCoreVariantLibraries []string
- vndkLibrariesLock sync.Mutex
+ vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires")
+ vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires")
+ llndkLibrariesKey = android.NewOnceKey("llndkLibrarires")
+ vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires")
+ vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires")
+ vndkLibrariesLock sync.Mutex
)
+func vndkCoreLibraries(config android.Config) *[]string {
+ return config.Once(vndkCoreLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+func vndkSpLibraries(config android.Config) *[]string {
+ return config.Once(vndkSpLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+func llndkLibraries(config android.Config) *[]string {
+ return config.Once(llndkLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+func vndkPrivateLibraries(config android.Config) *[]string {
+ return config.Once(vndkPrivateLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+func vndkUsingCoreVariantLibraries(config android.Config) *[]string {
+ return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
// gather list of vndk-core, vndk-sp, and ll-ndk libs
func VndkMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*Module); ok && m.Enabled() {
if lib, ok := m.linker.(*llndkStubDecorator); ok {
vndkLibrariesLock.Lock()
defer vndkLibrariesLock.Unlock()
+
+ llndkLibraries := llndkLibraries(mctx.Config())
+ vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+
name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix)
- if !inList(name, llndkLibraries) {
- llndkLibraries = append(llndkLibraries, name)
- sort.Strings(llndkLibraries)
+ if !inList(name, *llndkLibraries) {
+ *llndkLibraries = append(*llndkLibraries, name)
+ sort.Strings(*llndkLibraries)
}
if !Bool(lib.Properties.Vendor_available) {
- if !inList(name, vndkPrivateLibraries) {
- vndkPrivateLibraries = append(vndkPrivateLibraries, name)
- sort.Strings(vndkPrivateLibraries)
+ if !inList(name, *vndkPrivateLibraries) {
+ *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
+ sort.Strings(*vndkPrivateLibraries)
}
}
} else {
@@ -225,27 +259,33 @@
if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
vndkLibrariesLock.Lock()
defer vndkLibrariesLock.Unlock()
+
+ vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config())
+ vndkSpLibraries := vndkSpLibraries(mctx.Config())
+ vndkCoreLibraries := vndkCoreLibraries(mctx.Config())
+ vndkPrivateLibraries := vndkPrivateLibraries(mctx.Config())
+
if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) {
- if !inList(name, vndkUsingCoreVariantLibraries) {
- vndkUsingCoreVariantLibraries = append(vndkUsingCoreVariantLibraries, name)
- sort.Strings(vndkUsingCoreVariantLibraries)
+ if !inList(name, *vndkUsingCoreVariantLibraries) {
+ *vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name)
+ sort.Strings(*vndkUsingCoreVariantLibraries)
}
}
if m.vndkdep.isVndkSp() {
- if !inList(name, vndkSpLibraries) {
- vndkSpLibraries = append(vndkSpLibraries, name)
- sort.Strings(vndkSpLibraries)
+ if !inList(name, *vndkSpLibraries) {
+ *vndkSpLibraries = append(*vndkSpLibraries, name)
+ sort.Strings(*vndkSpLibraries)
}
} else {
- if !inList(name, vndkCoreLibraries) {
- vndkCoreLibraries = append(vndkCoreLibraries, name)
- sort.Strings(vndkCoreLibraries)
+ if !inList(name, *vndkCoreLibraries) {
+ *vndkCoreLibraries = append(*vndkCoreLibraries, name)
+ sort.Strings(*vndkCoreLibraries)
}
}
if !Bool(m.VendorProperties.Vendor_available) {
- if !inList(name, vndkPrivateLibraries) {
- vndkPrivateLibraries = append(vndkPrivateLibraries, name)
- sort.Strings(vndkPrivateLibraries)
+ if !inList(name, *vndkPrivateLibraries) {
+ *vndkPrivateLibraries = append(*vndkPrivateLibraries, name)
+ sort.Strings(*vndkPrivateLibraries)
}
}
}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 3b77042..1e0f862 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -176,7 +176,7 @@
// 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, error) {
+func LoadGlobalConfig(ctx android.PathContext, path string) (GlobalConfig, []byte, error) {
type GlobalJSONConfig struct {
GlobalConfig
@@ -199,9 +199,9 @@
}
config := GlobalJSONConfig{}
- err := loadConfig(ctx, path, &config)
+ data, err := loadConfig(ctx, path, &config)
if err != nil {
- return config.GlobalConfig, err
+ return config.GlobalConfig, nil, err
}
// Construct paths that require a PathContext.
@@ -217,7 +217,7 @@
config.GlobalConfig.Tools.VerifyUsesLibraries = constructPath(ctx, config.Tools.VerifyUsesLibraries)
config.GlobalConfig.Tools.ConstructContext = constructPath(ctx, config.Tools.ConstructContext)
- return config.GlobalConfig, nil
+ return config.GlobalConfig, data, nil
}
// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct. It is not used in Soong, which
@@ -241,7 +241,7 @@
config := ModuleJSONConfig{}
- err := loadConfig(ctx, path, &config)
+ _, err := loadConfig(ctx, path, &config)
if err != nil {
return config.ModuleConfig, err
}
@@ -259,24 +259,24 @@
return config.ModuleConfig, nil
}
-func loadConfig(ctx android.PathContext, path string, config interface{}) error {
+func loadConfig(ctx android.PathContext, path string, config interface{}) ([]byte, error) {
r, err := ctx.Fs().Open(path)
if err != nil {
- return err
+ return nil, err
}
defer r.Close()
data, err := ioutil.ReadAll(r)
if err != nil {
- return err
+ return nil, err
}
err = json.Unmarshal(data, config)
if err != nil {
- return err
+ return nil, err
}
- return nil
+ return data, nil
}
func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index c72f684..d54ddb1 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -78,7 +78,7 @@
ctx := &pathContext{android.TestConfig(*outDir, nil)}
- globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
+ globalConfig, _, err := dexpreopt.LoadGlobalConfig(ctx, *globalConfigPath)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalConfigPath, err)
os.Exit(2)
diff --git a/java/app.go b/java/app.go
index ec021fc..db9c5dd 100644
--- a/java/app.go
+++ b/java/app.go
@@ -17,17 +17,20 @@
// This file contains the module types for compiling Android apps.
import (
- "path/filepath"
- "strings"
-
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
+ "path/filepath"
+ "reflect"
+ "strings"
"android/soong/android"
"android/soong/cc"
"android/soong/tradefed"
)
+var supportedDpis = [...]string{"Ldpi", "Mdpi", "Hdpi", "Xhdpi", "Xxhdpi", "Xxxhdpi"}
+var dpiVariantsStruct reflect.Type
+
func init() {
android.RegisterModuleType("android_app", AndroidAppFactory)
android.RegisterModuleType("android_test", AndroidTestFactory)
@@ -35,6 +38,22 @@
android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
android.RegisterModuleType("android_app_import", AndroidAppImportFactory)
+
+ // Dynamically construct a struct for the dpi_variants property in android_app_import.
+ perDpiStruct := reflect.StructOf([]reflect.StructField{
+ {
+ Name: "Apk",
+ Type: reflect.TypeOf((*string)(nil)),
+ },
+ })
+ dpiVariantsFields := make([]reflect.StructField, len(supportedDpis))
+ for i, dpi := range supportedDpis {
+ dpiVariantsFields[i] = reflect.StructField{
+ Name: string(dpi),
+ Type: perDpiStruct,
+ }
+ }
+ dpiVariantsStruct = reflect.StructOf(dpiVariantsFields)
}
// AndroidManifest.xml merging
@@ -635,6 +654,26 @@
// A prebuilt apk to import
Apk string
+ // Per-DPI settings. This property makes it possible to specify a different source apk path for
+ // each DPI.
+ //
+ // Example:
+ //
+ // android_app_import {
+ // name: "example_import",
+ // apk: "prebuilts/example.apk",
+ // dpi_variants: {
+ // mdpi: {
+ // apk: "prebuilts/example_mdpi.apk",
+ // },
+ // xhdpi: {
+ // apk: "prebuilts/example_xhdpi.apk",
+ // },
+ // },
+ // certificate: "PRESIGNED",
+ // }
+ Dpi_variants interface{}
+
// The name of a certificate in the default certificate directory, blank to use the default
// product certificate, or an android_app_certificate module name in the form ":module".
Certificate *string
@@ -656,6 +695,41 @@
Overrides []string
}
+func getApkPathForDpi(dpiVariantsValue reflect.Value, dpi string) string {
+ dpiField := dpiVariantsValue.FieldByName(proptools.FieldNameForProperty(dpi))
+ if !dpiField.IsValid() {
+ return ""
+ }
+ apkValue := dpiField.FieldByName("Apk").Elem()
+ if apkValue.IsValid() {
+ return apkValue.String()
+ }
+ return ""
+}
+
+// Chooses a source APK path to use based on the module's per-DPI settings and the product config.
+func (a *AndroidAppImport) getSrcApkPath(ctx android.ModuleContext) string {
+ config := ctx.Config()
+ dpiVariantsValue := reflect.ValueOf(a.properties.Dpi_variants).Elem()
+ if !dpiVariantsValue.IsValid() {
+ return a.properties.Apk
+ }
+ // Match PRODUCT_AAPT_PREF_CONFIG first and then PRODUCT_AAPT_PREBUILT_DPI.
+ if config.ProductAAPTPreferredConfig() != "" {
+ if apk := getApkPathForDpi(dpiVariantsValue, config.ProductAAPTPreferredConfig()); apk != "" {
+ return apk
+ }
+ }
+ for _, dpi := range config.ProductAAPTPrebuiltDPI() {
+ if apk := getApkPathForDpi(dpiVariantsValue, dpi); apk != "" {
+ return apk
+ }
+ }
+
+ // No match. Use the generic one.
+ return a.properties.Apk
+}
+
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
cert := android.SrcIsModule(String(a.properties.Certificate))
if cert != "" {
@@ -690,6 +764,19 @@
return shouldUncompressDex(ctx, &a.dexpreopter)
}
+func (a *AndroidAppImport) uncompressDex(
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ Textf(`if (zipinfo %s '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then`, inputPath).
+ Tool(ctx.Config().HostToolPath(ctx, "zip2zip")).
+ FlagWithInput("-i ", inputPath).
+ FlagWithOutput("-o ", outputPath).
+ FlagWithArg("-0 ", "'classes*.dex'").
+ Textf(`; else cp -f %s %s; fi`, inputPath, outputPath)
+ rule.Build(pctx, ctx, "uncompress-dex", "Uncompress dex files")
+}
+
func (a *AndroidAppImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if String(a.properties.Certificate) == "" && !Bool(a.properties.Presigned) {
ctx.PropertyErrorf("certificate", "No certificate specified for prebuilt")
@@ -701,10 +788,9 @@
_, certificates := collectAppDeps(ctx)
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
- // TODO: LOCAL_DPI_VARIANTS
// TODO: LOCAL_PACKAGE_SPLITS
- srcApk := a.prebuilt.SingleSourcePath(ctx)
+ srcApk := android.PathForModuleSrc(ctx, a.getSrcApkPath(ctx))
// TODO: Install or embed JNI libraries
@@ -718,6 +804,11 @@
a.dexpreopter.isPresignedPrebuilt = Bool(a.properties.Presigned)
a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
dexOutput := a.dexpreopter.dexpreopt(ctx, jnisUncompressed)
+ if a.dexpreopter.uncompressedDex {
+ dexUncompressed := android.PathForModuleOut(ctx, "dex-uncompressed", ctx.ModuleName()+".apk")
+ a.uncompressDex(ctx, dexOutput, dexUncompressed.OutputPath)
+ dexOutput = dexUncompressed
+ }
// Sign or align the package
// TODO: Handle EXTERNAL
@@ -754,6 +845,7 @@
// android_app_import imports a prebuilt apk with additional processing specified in the module.
func AndroidAppImportFactory() android.Module {
module := &AndroidAppImport{}
+ module.properties.Dpi_variants = reflect.New(dpiVariantsStruct).Interface()
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)
diff --git a/java/app_test.go b/java/app_test.go
index e4c6afe..bc35e21 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -15,15 +15,18 @@
package java
import (
- "android/soong/android"
- "android/soong/cc"
-
"fmt"
"path/filepath"
"reflect"
+ "regexp"
"sort"
"strings"
"testing"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+ "android/soong/cc"
)
var (
@@ -1052,3 +1055,81 @@
t.Errorf("can't find aligning rule")
}
}
+
+func TestAndroidAppImport_DpiVariants(t *testing.T) {
+ bp := `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ dpi_variants: {
+ xhdpi: {
+ apk: "prebuilts/apk/app_xhdpi.apk",
+ },
+ xxhdpi: {
+ apk: "prebuilts/apk/app_xxhdpi.apk",
+ },
+ },
+ certificate: "PRESIGNED",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `
+ testCases := []struct {
+ name string
+ aaptPreferredConfig *string
+ aaptPrebuiltDPI []string
+ expected string
+ }{
+ {
+ name: "no preferred",
+ aaptPreferredConfig: nil,
+ aaptPrebuiltDPI: []string{},
+ expected: "prebuilts/apk/app.apk",
+ },
+ {
+ name: "AAPTPreferredConfig matches",
+ aaptPreferredConfig: proptools.StringPtr("xhdpi"),
+ aaptPrebuiltDPI: []string{"xxhdpi", "lhdpi"},
+ expected: "prebuilts/apk/app_xhdpi.apk",
+ },
+ {
+ name: "AAPTPrebuiltDPI matches",
+ aaptPreferredConfig: proptools.StringPtr("mdpi"),
+ aaptPrebuiltDPI: []string{"xxhdpi", "xhdpi"},
+ expected: "prebuilts/apk/app_xxhdpi.apk",
+ },
+ {
+ name: "non-first AAPTPrebuiltDPI matches",
+ aaptPreferredConfig: proptools.StringPtr("mdpi"),
+ aaptPrebuiltDPI: []string{"ldpi", "xhdpi"},
+ expected: "prebuilts/apk/app_xhdpi.apk",
+ },
+ {
+ name: "no matches",
+ aaptPreferredConfig: proptools.StringPtr("mdpi"),
+ aaptPrebuiltDPI: []string{"ldpi", "xxxhdpi"},
+ expected: "prebuilts/apk/app.apk",
+ },
+ }
+
+ jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
+ for _, test := range testCases {
+ config := testConfig(nil)
+ config.TestProductVariables.AAPTPreferredConfig = test.aaptPreferredConfig
+ config.TestProductVariables.AAPTPrebuiltDPI = test.aaptPrebuiltDPI
+ ctx := testAppContext(config, bp, nil)
+
+ run(t, ctx, config)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+ jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
+ matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
+ if len(matches) != 2 {
+ t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
+ }
+ if test.expected != matches[1] {
+ t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
+ }
+ }
+}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 092a133..2a1a901 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -56,6 +56,7 @@
dexPaths android.WritablePaths
dir android.OutputPath
symbolsDir android.OutputPath
+ targets []android.Target
images map[android.ArchType]android.OutputPath
zip android.WritablePath
}
@@ -114,6 +115,8 @@
type dexpreoptBootJars struct {
defaultBootImage *bootImage
otherImages []*bootImage
+
+ dexpreoptConfigForMake android.WritablePath
}
// dexpreoptBoot singleton rules
@@ -122,6 +125,9 @@
return
}
+ d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config")
+ writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake)
+
global := dexpreoptGlobalConfig(ctx)
// Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
@@ -191,16 +197,9 @@
var allFiles android.Paths
if !global.DisablePreopt {
- targets := ctx.Config().Targets[android.Android]
- if ctx.Config().SecondArchIsTranslated() {
- targets = targets[:1]
- }
-
- for _, target := range targets {
- if target.NativeBridge == android.NativeBridgeDisabled {
- files := buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
- allFiles = append(allFiles, files.Paths()...)
- }
+ for _, target := range image.targets {
+ files := buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
+ allFiles = append(allFiles, files.Paths()...)
}
}
@@ -459,8 +458,24 @@
}
+func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) {
+ data := dexpreoptGlobalConfigRaw(ctx).data
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: path,
+ Args: map[string]string{
+ "content": string(data),
+ },
+ })
+}
+
// Export paths for default boot image to Make
func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
+ if d.dexpreoptConfigForMake != nil {
+ ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String())
+ }
+
image := d.defaultBootImage
if image != nil {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index a0b1ea5..d903f45 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -15,40 +15,50 @@
package java
import (
- "android/soong/android"
- "android/soong/dexpreopt"
"path/filepath"
"strings"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
)
// dexpreoptGlobalConfig returns the global dexpreopt.config. It is loaded once the first time it is called for any
// ctx.Config(), and returns the same data for all future calls with the same ctx.Config(). A value can be inserted
// for tests using setDexpreoptTestGlobalConfig.
func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
+ return dexpreoptGlobalConfigRaw(ctx).global
+}
+
+type globalConfigAndRaw struct {
+ global dexpreopt.GlobalConfig
+ data []byte
+}
+
+func dexpreoptGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
ctx.AddNinjaFileDeps(f)
- globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, f)
+ globalConfig, data, err := dexpreopt.LoadGlobalConfig(ctx, f)
if err != nil {
panic(err)
}
- return globalConfig
+ return globalConfigAndRaw{globalConfig, data}
}
// No global config filename set, see if there is a test config set
return ctx.Config().Once(dexpreoptTestGlobalConfigKey, func() interface{} {
// Nope, return a config with preopting disabled
- return dexpreopt.GlobalConfig{
+ return globalConfigAndRaw{dexpreopt.GlobalConfig{
DisablePreopt: true,
- }
+ }, nil}
})
- }).(dexpreopt.GlobalConfig)
+ }).(globalConfigAndRaw)
}
// setDexpreoptTestGlobalConfig sets a GlobalConfig that future calls to dexpreoptGlobalConfig will return. It must
// be called before the first call to dexpreoptGlobalConfig for the config.
func setDexpreoptTestGlobalConfig(config android.Config, globalConfig dexpreopt.GlobalConfig) {
- config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfig })
+ config.Once(dexpreoptTestGlobalConfigKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
@@ -72,6 +82,23 @@
var systemServerClasspathKey = android.NewOnceKey("systemServerClasspath")
+// dexpreoptTargets returns the list of targets that are relevant to dexpreopting, which excludes architectures
+// supported through native bridge.
+func dexpreoptTargets(ctx android.PathContext) []android.Target {
+ var targets []android.Target
+ for i, target := range ctx.Config().Targets[android.Android] {
+ if ctx.Config().SecondArchIsTranslated() && i > 0 {
+ break
+ }
+
+ if target.NativeBridge == android.NativeBridgeDisabled {
+ targets = append(targets, target)
+ }
+ }
+
+ return targets
+}
+
// defaultBootImageConfig returns the bootImageConfig that will be used to dexpreopt modules. 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().
@@ -113,7 +140,9 @@
images := make(map[android.ArchType]android.OutputPath)
zip := dir.Join(ctx, "boot.zip")
- for _, target := range ctx.Config().Targets[android.Android] {
+ targets := dexpreoptTargets(ctx)
+
+ for _, target := range targets {
images[target.Arch.ArchType] = dir.Join(ctx,
"system/framework", target.Arch.ArchType.String()).Join(ctx, "boot.art")
}
@@ -126,6 +155,7 @@
dir: dir,
symbolsDir: symbolsDir,
images: images,
+ targets: targets,
zip: zip,
}
}).(bootImageConfig)
@@ -168,7 +198,9 @@
symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_apexjars_unstripped")
images := make(map[android.ArchType]android.OutputPath)
- for _, target := range ctx.Config().Targets[android.Android] {
+ targets := dexpreoptTargets(ctx)
+
+ for _, target := range targets {
images[target.Arch.ArchType] = dir.Join(ctx,
"system/framework", target.Arch.ArchType.String(), "apex.art")
}
@@ -180,6 +212,7 @@
dexPaths: bootDexPaths,
dir: dir,
symbolsDir: symbolsDir,
+ targets: targets,
images: images,
}
}).(bootImageConfig)
diff --git a/java/java.go b/java/java.go
index 4ca7838..866b33c 100644
--- a/java/java.go
+++ b/java/java.go
@@ -639,7 +639,7 @@
switch {
case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
name == "stub-annotations" || name == "private-stub-annotations-jar" ||
- name == "core-lambda-stubs":
+ name == "core-lambda-stubs" || name == "core-generated-annotation-stubs":
return javaCore, true
case ver == "core_current":
return javaCore, false
diff --git a/java/java_test.go b/java/java_test.go
index 53df6f4..370e796 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -164,7 +164,9 @@
"prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "current"],}`),
- "prebuilts/apk/app.apk": nil,
+ "prebuilts/apk/app.apk": nil,
+ "prebuilts/apk/app_xhdpi.apk": nil,
+ "prebuilts/apk/app_xxhdpi.apk": nil,
// For framework-res, which is an implicit dependency for framework
"AndroidManifest.xml": nil,
@@ -1005,8 +1007,8 @@
}
`
- t.Run("1.8", func(t *testing.T) {
- // Test default javac 1.8
+ t.Run("Java language level 8", func(t *testing.T) {
+ // Test default javac -source 1.8 -target 1.8
ctx := testJava(t, bp)
checkPatchModuleFlag(t, ctx, "foo", "")
@@ -1014,9 +1016,9 @@
checkPatchModuleFlag(t, ctx, "baz", "")
})
- t.Run("1.9", func(t *testing.T) {
- // Test again with javac 1.9
- config := testConfig(map[string]string{"EXPERIMENTAL_USE_OPENJDK9": "true"})
+ t.Run("Java language level 9", func(t *testing.T) {
+ // Test again with javac -source 9 -target 9
+ config := testConfig(map[string]string{"EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9": "true"})
ctx := testContext(config, bp, nil)
run(t, ctx, config)
diff --git a/java/sdk_test.go b/java/sdk_test.go
index e446129..cc4da2e 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -272,8 +272,8 @@
}
}
- t.Run("1.8", func(t *testing.T) {
- // Test default javac 1.8
+ t.Run("Java language level 8", func(t *testing.T) {
+ // Test default javac -source 1.8 -target 1.8
config := testConfig(nil)
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
@@ -299,9 +299,9 @@
}
})
- // Test again with javac 1.9
- t.Run("1.9", func(t *testing.T) {
- config := testConfig(map[string]string{"EXPERIMENTAL_USE_OPENJDK9": "true"})
+ // Test again with javac -source 9 -target 9
+ t.Run("Java language level 9", func(t *testing.T) {
+ config := testConfig(map[string]string{"EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9": "true"})
if testcase.unbundled {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 483c273..c6e5ddc 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -224,7 +224,6 @@
"BUILD_BROKEN_USES_BUILD_HOST_NATIVE_TEST",
"BUILD_BROKEN_USES_BUILD_HOST_PREBUILT",
"BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_HOST_SHARED_TEST_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_STATIC_TEST_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_TEST_CONFIG",
@@ -238,7 +237,6 @@
"BUILD_BROKEN_USES_BUILD_PREBUILT",
"BUILD_BROKEN_USES_BUILD_RRO_PACKAGE",
"BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_SHARED_TEST_LIBRARY",
"BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY",
"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
"BUILD_BROKEN_USES_BUILD_STATIC_TEST_LIBRARY",
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 54006d2..4a30391 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -102,6 +102,7 @@
"python3": Allowed,
"realpath": Allowed,
"rsync": Allowed,
+ "sed": Allowed,
"sh": Allowed,
"tar": Allowed,
"timeout": Allowed,
@@ -155,7 +156,6 @@
"readlink": LinuxOnlyPrebuilt,
"rm": LinuxOnlyPrebuilt,
"rmdir": LinuxOnlyPrebuilt,
- "sed": LinuxOnlyPrebuilt,
"seq": LinuxOnlyPrebuilt,
"setsid": LinuxOnlyPrebuilt,
"sha1sum": LinuxOnlyPrebuilt,