Merge "Merge Android10 QPR1 into AOSP master"
diff --git a/Android.bp b/Android.bp
index 0ca11d3..6910d75 100644
--- a/Android.bp
+++ b/Android.bp
@@ -503,6 +503,7 @@
"soong-java",
],
srcs: [
+ "sdk/bp.go",
"sdk/sdk.go",
"sdk/update.go",
],
diff --git a/android/module.go b/android/module.go
index 2ae2961..b4f8f1a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -778,6 +778,13 @@
*m.hostAndDeviceProperties.Device_supported)
}
+func (m *ModuleBase) HostSupported() bool {
+ return m.commonProperties.HostOrDeviceSupported == HostSupported ||
+ m.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
+ (m.hostAndDeviceProperties.Host_supported != nil &&
+ *m.hostAndDeviceProperties.Host_supported)
+}
+
func (m *ModuleBase) Platform() bool {
return !m.DeviceSpecific() && !m.SocSpecific() && !m.ProductSpecific() && !m.SystemExtSpecific()
}
diff --git a/android/paths.go b/android/paths.go
index 8dbb086..1a37a34 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -247,6 +247,33 @@
return ret
}
+// OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection.
+type OutputPaths []OutputPath
+
+// Paths returns the OutputPaths as a Paths
+func (p OutputPaths) Paths() Paths {
+ if p == nil {
+ return nil
+ }
+ ret := make(Paths, len(p))
+ for i, path := range p {
+ ret[i] = path
+ }
+ return ret
+}
+
+// Strings returns the string forms of the writable paths.
+func (p OutputPaths) Strings() []string {
+ if p == nil {
+ return nil
+ }
+ ret := make([]string, len(p))
+ for i, path := range p {
+ ret[i] = path.String()
+ }
+ return ret
+}
+
// PathsAndMissingDepsForModuleSrcExcludes returns Paths rooted from the module's local source directory, excluding
// paths listed in the excludes arguments, and a list of missing dependencies. It expands globs, references to
// SourceFileProducer modules using the ":name" syntax, and references to OutputFileProducer modules using the
diff --git a/android/sdk.go b/android/sdk.go
index 73cb256..01e18ed 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -167,16 +167,39 @@
// Unzip the supplied zip into the snapshot relative directory destDir.
UnzipToSnapshot(zipPath Path, destDir string)
- // Get the AndroidBpFile for the snapshot.
- AndroidBpFile() GeneratedSnapshotFile
-
- // Get a versioned name appropriate for the SDK snapshot version being taken.
- VersionedSdkMemberName(unversionedName string) interface{}
+ // Add a new prebuilt module to the snapshot. The returned module
+ // must be populated with the module type specific properties. The following
+ // properties will be automatically populated.
+ //
+ // * name
+ // * sdk_member_name
+ // * prefer
+ //
+ // This will result in two Soong modules being generated in the Android. One
+ // that is versioned, coupled to the snapshot version and marked as
+ // prefer=true. And one that is not versioned, not marked as prefer=true and
+ // will only be used if the equivalently named non-prebuilt module is not
+ // present.
+ AddPrebuiltModule(name string, moduleType string) BpModule
}
-// Provides support for generating a file, e.g. the Android.bp file.
-type GeneratedSnapshotFile interface {
- Printfln(format string, args ...interface{})
- Indent()
- Dedent()
+// A set of properties for use in a .bp file.
+type BpPropertySet interface {
+ // Add a property, the value can be one of the following types:
+ // * string
+ // * array of the above
+ // * bool
+ // * BpPropertySet
+ //
+ // It is an error is multiples properties with the same name are added.
+ AddProperty(name string, value interface{})
+
+ // Add a property set with the specified name and return so that additional
+ // properties can be added.
+ AddPropertySet(name string) BpPropertySet
+}
+
+// A .bp module definition.
+type BpModule interface {
+ BpPropertySet
}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 35c2b44..83e3673 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -41,7 +41,7 @@
BootJars []string // modules for jars that form the boot class path
UpdatableBootJars []string // jars within apex that form the boot class path
- ArtApexJars []string // modules for jars that are in the ART APEX
+ ArtApexJars []string // modules for jars that are in the ART APEX
SystemServerJars []string // jars that form the system server
SystemServerApps []string // apps that are loaded into system server
@@ -117,9 +117,10 @@
UsesLibraries []string
LibraryPaths map[string]android.Path
- Archs []android.ArchType
- DexPreoptImages []android.Path
- DexPreoptImagesDeps []android.Paths
+ Archs []android.ArchType
+ DexPreoptImages []android.Path
+ DexPreoptImagesDeps []android.OutputPaths
+ DexPreoptImageLocations []string
PreoptBootClassPathDexFiles android.Paths // file paths of boot class path files
PreoptBootClassPathDexLocations []string // virtual locations of boot class path files
@@ -225,6 +226,7 @@
ProfileClassListing string
LibraryPaths map[string]string
DexPreoptImages []string
+ DexPreoptImageLocations []string
PreoptBootClassPathDexFiles []string
}
@@ -242,10 +244,11 @@
config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
+ config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
// This needs to exist, but dependencies are already handled in Make, so we don't need to pass them through JSON.
- config.ModuleConfig.DexPreoptImagesDeps = make([]android.Paths, len(config.ModuleConfig.DexPreoptImages))
+ config.ModuleConfig.DexPreoptImagesDeps = make([]android.OutputPaths, len(config.ModuleConfig.DexPreoptImages))
return config.ModuleConfig, nil
}
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index f3bf2ff..40986c3 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -86,10 +86,8 @@
generateDM := shouldGenerateDM(module, global)
- for i, arch := range module.Archs {
- image := module.DexPreoptImages[i]
- imageDeps := module.DexPreoptImagesDeps[i]
- dexpreoptCommand(ctx, global, module, rule, arch, profile, image, imageDeps, appImage, generateDM)
+ for archIdx, _ := range module.Archs {
+ dexpreoptCommand(ctx, global, module, rule, archIdx, profile, appImage, generateDM)
}
}
}
@@ -193,7 +191,9 @@
}
func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder,
- arch android.ArchType, profile, bootImage android.Path, bootImageDeps android.Paths, appImage, generateDM bool) {
+ archIdx int, profile android.WritablePath, appImage bool, generateDM bool) {
+
+ arch := module.Archs[archIdx]
// HACK: make soname in Soong-generated .odex files match Make.
base := filepath.Base(module.DexLocation)
@@ -222,13 +222,6 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- // bootImage is .../dex_bootjars/system/framework/arm64/boot.art, but dex2oat wants
- // .../dex_bootjars/system/framework/boot.art on the command line
- var bootImageLocation string
- if bootImage != nil {
- bootImageLocation = PathToLocation(bootImage, arch)
- }
-
// The class loader context using paths in the build
var classLoaderContextHost android.Paths
@@ -356,7 +349,7 @@
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
Flag("${class_loader_context_arg}").
Flag("${stored_class_loader_context_arg}").
- FlagWithArg("--boot-image=", bootImageLocation).Implicits(bootImageDeps).
+ FlagWithArg("--boot-image=", strings.Join(module.DexPreoptImageLocations, ":")).Implicits(module.DexPreoptImagesDeps[archIdx].Paths()).
FlagWithInput("--dex-file=", module.DexPath).
FlagWithArg("--dex-location=", dexLocationArg).
FlagWithOutput("--oat-file=", odexPath).ImplicitOutput(vdexPath).
@@ -555,9 +548,9 @@
}
// Expected format for apexJarValue = <apex name>:<jar name>
-func GetJarLocationFromApexJarPair(apexJarValue string) (string) {
+func GetJarLocationFromApexJarPair(apexJarValue string) string {
apex, jar := SplitApexJarPair(apexJarValue)
- return filepath.Join("/apex", apex, "javalib", jar + ".jar")
+ return filepath.Join("/apex", apex, "javalib", jar+".jar")
}
func contains(l []string, s string) bool {
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 6f8120e..254be0a 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -49,7 +49,8 @@
LibraryPaths: nil,
Archs: []android.ArchType{android.Arm},
DexPreoptImages: android.Paths{android.PathForTesting("system/framework/arm/boot.art")},
- DexPreoptImagesDeps: []android.Paths{android.Paths{}},
+ DexPreoptImagesDeps: []android.OutputPaths{android.OutputPaths{}},
+ DexPreoptImageLocations: []string{},
PreoptBootClassPathDexFiles: nil,
PreoptBootClassPathDexLocations: nil,
PreoptExtractedApk: false,
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 2b1c994..479dec6 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -124,7 +124,7 @@
}
var images android.Paths
- var imagesDeps []android.Paths
+ var imagesDeps []android.OutputPaths
for _, arch := range archs {
images = append(images, bootImage.images[arch])
imagesDeps = append(imagesDeps, bootImage.imagesDeps[arch])
@@ -169,15 +169,16 @@
UsesLibraries: d.usesLibs,
LibraryPaths: d.libraryPaths,
- Archs: archs,
- DexPreoptImages: images,
- DexPreoptImagesDeps: imagesDeps,
+ Archs: archs,
+ DexPreoptImages: images,
+ DexPreoptImagesDeps: imagesDeps,
+ DexPreoptImageLocations: bootImage.imageLocations,
// We use the dex paths and dex locations of the default boot image, as it
// contains the full dexpreopt boot classpath. Other images may just contain a subset of
// the dexpreopt boot classpath.
- PreoptBootClassPathDexFiles: defaultBootImage.dexPaths.Paths(),
- PreoptBootClassPathDexLocations: defaultBootImage.dexLocations,
+ PreoptBootClassPathDexFiles: defaultBootImage.dexPathsDeps.Paths(),
+ PreoptBootClassPathDexLocations: defaultBootImage.dexLocationsDeps,
PreoptExtractedApk: false,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a29665e..5e72cee 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -22,7 +22,6 @@
"android/soong/android"
"android/soong/dexpreopt"
- "github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -50,38 +49,77 @@
// will then reconstruct the real path, so the rules must have a dependency on the real path.
type bootImageConfig struct {
- name string
- stem string
- modules []string
- dexLocations []string
- dexPaths android.WritablePaths
- dir android.OutputPath
- symbolsDir android.OutputPath
- targets []android.Target
- images map[android.ArchType]android.OutputPath
- imagesDeps map[android.ArchType]android.Paths
- zip android.WritablePath
+ // Whether this image is an extension.
+ extension bool
+
+ // Image name (used in directory names and ninja rule names).
+ name string
+
+ // Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
+ stem string
+
+ // Output directory for the image files.
+ dir android.OutputPath
+
+ // Output directory for the image files with debug symbols.
+ symbolsDir android.OutputPath
+
+ // Subdirectory where the image files are installed.
+ installSubdir string
+
+ // Targets for which the image is generated.
+ targets []android.Target
+
+ // The names of jars that constitute this image.
+ modules []string
+
+ // The "locations" of jars.
+ dexLocations []string // for this image
+ dexLocationsDeps []string // for the dependency images and in this image
+
+ // File paths to jars.
+ dexPaths android.WritablePaths // for this image
+ dexPathsDeps android.WritablePaths // for the dependency images and in this image
+
+ // The "locations" of the dependency images and in this image.
+ imageLocations []string
+
+ // Paths to image files (grouped by target).
+ images map[android.ArchType]android.OutputPath // first image file
+ imagesDeps map[android.ArchType]android.OutputPaths // all files
+
+ // File path to a zip archive with all image files (or nil, if not needed).
+ zip android.WritablePath
}
-func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) []android.OutputPath {
- ret := make([]android.OutputPath, 0, len(image.modules)*len(exts))
-
- // dex preopt on the bootclasspath produces multiple files. The first dex file
- // is converted into to 'name'.art (to match the legacy assumption that 'name'.art
+func (image bootImageConfig) moduleName(idx int) string {
+ // Dexpreopt on the boot class path produces multiple files. The first dex file
+ // is converted into 'name'.art (to match the legacy assumption that 'name'.art
// exists), and the rest are converted to 'name'-<jar>.art.
- // In addition, each .art file has an associated .oat and .vdex file, and an
- // unstripped .oat file
- for i, m := range image.modules {
- name := image.stem
- if i != 0 {
- name += "-" + stemOf(m)
- }
+ m := image.modules[idx]
+ name := image.stem
+ if idx != 0 || image.extension {
+ name += "-" + stemOf(m)
+ }
+ return name
+}
+func (image bootImageConfig) firstModuleNameOrStem() string {
+ if len(image.modules) > 0 {
+ return image.moduleName(0)
+ } else {
+ return image.stem
+ }
+}
+
+func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths {
+ ret := make(android.OutputPaths, 0, len(image.modules)*len(exts))
+ for i := range image.modules {
+ name := image.moduleName(i)
for _, ext := range exts {
ret = append(ret, dir.Join(ctx, name+ext))
}
}
-
return ret
}
@@ -140,12 +178,6 @@
return false
}
-func skipDexpreoptArtBootJars(ctx android.BuilderContext) bool {
- // with EMMA_INSTRUMENT_FRAMEWORK=true ART boot class path libraries have dependencies on framework,
- // therefore dexpreopt ART libraries cannot be dexpreopted in isolation => no ART boot image
- return ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK")
-}
-
type dexpreoptBootJars struct {
defaultBootImage *bootImage
otherImages []*bootImage
@@ -154,8 +186,8 @@
}
// Accessor function for the apex package. Returns nil if dexpreopt is disabled.
-func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.Paths {
- if skipDexpreoptBootJars(ctx) || skipDexpreoptArtBootJars(ctx) {
+func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths {
+ if skipDexpreoptBootJars(ctx) {
return nil
}
return artBootImageConfig(ctx).imagesDeps
@@ -184,10 +216,8 @@
// Always create the default boot image first, to get a unique profile rule for all images.
d.defaultBootImage = buildBootImage(ctx, defaultBootImageConfig(ctx))
- if !skipDexpreoptArtBootJars(ctx) {
- // Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
- buildBootImage(ctx, artBootImageConfig(ctx))
- }
+ // Create boot image for the ART apex (build artifacts are accessed via the global boot image config).
+ buildBootImage(ctx, artBootImageConfig(ctx))
if global.GenerateApexImage {
// Create boot images for the JIT-zygote experiment.
d.otherImages = append(d.otherImages, buildBootImage(ctx, apexBootImageConfig(ctx)))
@@ -201,7 +231,6 @@
image := newBootImage(ctx, config)
bootDexJars := make(android.Paths, len(image.modules))
-
ctx.VisitAllModules(func(module android.Module) {
// Collect dex jar paths for the modules listed above.
if j, ok := module.(interface{ DexJar() android.Path }); ok {
@@ -265,11 +294,12 @@
global := dexpreoptGlobalConfig(ctx)
- symbolsDir := image.symbolsDir.Join(ctx, "system/framework", arch.String())
+ symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
- outputDir := image.dir.Join(ctx, "system/framework", arch.String())
- outputPath := image.images[arch]
- oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath, arch), "oat")
+ outputDir := image.dir.Join(ctx, image.installSubdir, arch.String())
+ outputPath := outputDir.Join(ctx, image.stem+".oat")
+ oatLocation := dexpreopt.PathToLocation(outputPath, arch)
+ imagePath := outputPath.ReplaceExtension(ctx, "art")
rule := android.NewRuleBuilder()
rule.MissingDeps(missingDeps)
@@ -312,18 +342,27 @@
cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
}
+ if image.extension {
+ artImage := artBootImageConfig(ctx).images[arch]
+ cmd.
+ Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
+ Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
+ FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage)
+ } else {
+ cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress())
+ }
+
cmd.
FlagForEachInput("--dex-file=", image.dexPaths.Paths()).
FlagForEachArg("--dex-location=", image.dexLocations).
Flag("--generate-debug-info").
Flag("--generate-build-id").
Flag("--image-format=lz4hc").
- FlagWithOutput("--oat-symbols=", symbolsFile).
+ FlagWithArg("--oat-symbols=", symbolsFile.String()).
Flag("--strip").
- FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat")).
+ FlagWithArg("--oat-file=", outputPath.String()).
FlagWithArg("--oat-location=", oatLocation).
- FlagWithOutput("--image=", outputPath).
- FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
+ FlagWithArg("--image=", imagePath.String()).
FlagWithArg("--instruction-set=", arch.String()).
FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]).
FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]).
@@ -341,8 +380,8 @@
cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape(failureMessage))
- installDir := filepath.Join("/system/framework", arch.String())
- vdexInstallDir := filepath.Join("/system/framework")
+ installDir := filepath.Join("/", image.installSubdir, arch.String())
+ vdexInstallDir := filepath.Join("/", image.installSubdir)
var vdexInstalls android.RuleBuilderInstalls
var unstrippedInstalls android.RuleBuilderInstalls
@@ -425,8 +464,8 @@
Text(`ANDROID_LOG_TAGS="*:e"`).
Tool(tools.Profman).
FlagWithInput("--create-profile-from=", bootImageProfile).
- FlagForEachInput("--apk=", image.dexPaths.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocations).
+ FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
+ FlagForEachArg("--dex-location=", image.dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.prof")
@@ -477,8 +516,8 @@
Tool(tools.Profman).
Flag("--generate-boot-profile").
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
- FlagForEachInput("--apk=", image.dexPaths.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocations).
+ FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
+ FlagForEachArg("--dex-location=", image.dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.bprof")
@@ -506,8 +545,8 @@
rule.Command().
// TODO: for now, use the debug version for better error reporting
BuiltTool(ctx, "oatdumpd").
- FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPaths.Paths(), ":").
- FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocations, ":").
+ FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
+ FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
FlagWithArg("--image=", dexpreopt.PathToLocation(image.images[arch], arch)).Implicit(image.images[arch]).
FlagWithOutput("--output=", output).
FlagWithArg("--instruction-set=", arch.String())
@@ -556,8 +595,9 @@
image := d.defaultBootImage
if image != nil {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
- ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPaths.Strings(), " "))
- ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocations, " "))
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
+ ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS", strings.Join(image.imageLocations, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+image.name, image.zip.String())
var imageNames []string
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 29a5abe..87d5e30 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -48,7 +48,7 @@
pathCtx := android.PathContextForTesting(config, nil)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- dexpreoptConfig.ArtApexJars = []string{"foo", "bar", "baz"}
+ dexpreoptConfig.BootJars = []string{"foo", "bar", "baz"}
setDexpreoptTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext(bp, nil)
@@ -59,9 +59,10 @@
dexpreoptBootJars := ctx.SingletonForTests("dex_bootjars")
- bootArt := dexpreoptBootJars.Output("boot.art")
+ bootArt := dexpreoptBootJars.Output("boot-foo.art")
expectedInputs := []string{
+ "dex_artjars/apex/com.android.art/javalib/arm64/boot.art",
"dex_bootjars_input/foo.jar",
"dex_bootjars_input/bar.jar",
"dex_bootjars_input/baz.jar",
@@ -82,19 +83,19 @@
expectedOutputs := []string{
"dex_bootjars/system/framework/arm64/boot.invocation",
- "dex_bootjars/system/framework/arm64/boot.art",
+ "dex_bootjars/system/framework/arm64/boot-foo.art",
"dex_bootjars/system/framework/arm64/boot-bar.art",
"dex_bootjars/system/framework/arm64/boot-baz.art",
- "dex_bootjars/system/framework/arm64/boot.oat",
+ "dex_bootjars/system/framework/arm64/boot-foo.oat",
"dex_bootjars/system/framework/arm64/boot-bar.oat",
"dex_bootjars/system/framework/arm64/boot-baz.oat",
- "dex_bootjars/system/framework/arm64/boot.vdex",
+ "dex_bootjars/system/framework/arm64/boot-foo.vdex",
"dex_bootjars/system/framework/arm64/boot-bar.vdex",
"dex_bootjars/system/framework/arm64/boot-baz.vdex",
- "dex_bootjars_unstripped/system/framework/arm64/boot.oat",
+ "dex_bootjars_unstripped/system/framework/arm64/boot-foo.oat",
"dex_bootjars_unstripped/system/framework/arm64/boot-bar.oat",
"dex_bootjars_unstripped/system/framework/arm64/boot-baz.oat",
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 4dd7cfe..57a770e 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -119,118 +119,147 @@
return modules
}
-// Construct a variant of the global config for dexpreopted bootclasspath jars. The variants differ
-// in the list of input jars (libcore, framework, or both), in the naming scheme for the dexpreopt
-// files (ART recognizes "apex" names as special), and whether to include a zip archive.
-//
-// 'name' is a string unique for each profile (used in directory names and ninja rule names)
-// 'stem' is the basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}.
-func getBootImageConfig(ctx android.PathContext, key android.OnceKey, name string, stem string,
- needZip bool, artApexJarsOnly bool) bootImageConfig {
+var (
+ bootImageConfigKey = android.NewOnceKey("bootImageConfig")
+ artBootImageName = "art"
+ frameworkBootImageName = "boot"
+ apexBootImageName = "apex"
+)
- return ctx.Config().Once(key, func() interface{} {
+// Construct the global boot image configs.
+func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig {
+ return ctx.Config().Once(bootImageConfigKey, func() interface{} {
+
global := dexpreoptGlobalConfig(ctx)
+ targets := dexpreoptTargets(ctx)
+ deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
artModules := global.ArtApexJars
- imageModules := artModules
+ // In coverage builds ART boot class path jars are instrumented and have additional dependencies.
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ artModules = append(artModules, "jacocoagent")
+ }
+ frameworkModules := android.RemoveListFromList(global.BootJars,
+ concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars)))
- var bootLocations []string
+ artSubdir := "apex/com.android.art/javalib"
+ frameworkSubdir := "system/framework"
+ var artLocations, frameworkLocations []string
for _, m := range artModules {
- bootLocations = append(bootLocations,
- filepath.Join("/apex/com.android.art/javalib", stemOf(m)+".jar"))
+ artLocations = append(artLocations, filepath.Join("/"+artSubdir, stemOf(m)+".jar"))
+ }
+ for _, m := range frameworkModules {
+ frameworkLocations = append(frameworkLocations, filepath.Join("/"+frameworkSubdir, stemOf(m)+".jar"))
}
- if !artApexJarsOnly {
- nonFrameworkModules := concat(artModules, getJarsFromApexJarPairs(global.UpdatableBootJars))
- frameworkModules := android.RemoveListFromList(global.BootJars, nonFrameworkModules)
- imageModules = concat(imageModules, frameworkModules)
+ // ART config for the primary boot image in the ART apex.
+ // It includes the Core Libraries.
+ artCfg := bootImageConfig{
+ extension: false,
+ name: artBootImageName,
+ stem: "boot",
+ installSubdir: artSubdir,
+ modules: artModules,
+ dexLocations: artLocations,
+ dexLocationsDeps: artLocations,
+ }
- for _, m := range frameworkModules {
- bootLocations = append(bootLocations,
- filepath.Join("/system/framework", stemOf(m)+".jar"))
+ // Framework config for the boot image extension.
+ // It includes framework libraries and depends on the ART config.
+ frameworkCfg := bootImageConfig{
+ extension: true,
+ name: frameworkBootImageName,
+ stem: "boot",
+ installSubdir: frameworkSubdir,
+ modules: frameworkModules,
+ dexLocations: frameworkLocations,
+ dexLocationsDeps: append(artLocations, frameworkLocations...),
+ }
+
+ // Apex config for the boot image used in the JIT-zygote experiment.
+ // It includes both the Core libraries and framework.
+ apexCfg := bootImageConfig{
+ extension: false,
+ name: apexBootImageName,
+ stem: "apex",
+ installSubdir: frameworkSubdir,
+ modules: concat(artModules, frameworkModules),
+ dexLocations: concat(artLocations, frameworkLocations),
+ dexLocationsDeps: concat(artLocations, frameworkLocations),
+ }
+
+ configs := map[string]*bootImageConfig{
+ artBootImageName: &artCfg,
+ frameworkBootImageName: &frameworkCfg,
+ apexBootImageName: &apexCfg,
+ }
+
+ // common to all configs
+ for _, c := range configs {
+ c.targets = targets
+
+ c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars")
+ c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
+
+ // expands to <stem>.art for primary image and <stem>-<1st module>.art for extension
+ imageName := c.firstModuleNameOrStem() + ".art"
+
+ c.imageLocations = []string{c.dir.Join(ctx, c.installSubdir, imageName).String()}
+
+ // The path to bootclasspath dex files needs to be known at module
+ // GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled.
+ // Set up known paths for them, the singleton rules will copy them there.
+ // TODO(b/143682396): use module dependencies instead
+ inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input")
+ for _, m := range c.modules {
+ c.dexPaths = append(c.dexPaths, inputDir.Join(ctx, stemOf(m)+".jar"))
+ }
+ c.dexPathsDeps = c.dexPaths
+
+ c.images = make(map[android.ArchType]android.OutputPath)
+ c.imagesDeps = make(map[android.ArchType]android.OutputPaths)
+
+ for _, target := range targets {
+ arch := target.Arch.ArchType
+ imageDir := c.dir.Join(ctx, c.installSubdir, arch.String())
+ c.images[arch] = imageDir.Join(ctx, imageName)
+ c.imagesDeps[arch] = c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex")
}
}
- // The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
- // the bootclasspath modules have been compiled. Set up known paths for them, the singleton rules will copy
- // them there.
- // TODO(b/143682396): use module dependencies instead
- var bootDexPaths android.WritablePaths
- for _, m := range imageModules {
- bootDexPaths = append(bootDexPaths,
- android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_input", m+".jar"))
- }
+ // specific to the framework config
+ frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
+ frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
+ frameworkCfg.zip = frameworkCfg.dir.Join(ctx, frameworkCfg.stem+".zip")
- dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars")
- symbolsDir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_"+name+"jars_unstripped")
-
- var zip android.WritablePath
- if needZip {
- zip = dir.Join(ctx, stem+".zip")
- }
-
- targets := dexpreoptTargets(ctx)
-
- imageConfig := bootImageConfig{
- name: name,
- stem: stem,
- modules: imageModules,
- dexLocations: bootLocations,
- dexPaths: bootDexPaths,
- dir: dir,
- symbolsDir: symbolsDir,
- targets: targets,
- images: make(map[android.ArchType]android.OutputPath),
- imagesDeps: make(map[android.ArchType]android.Paths),
- zip: zip,
- }
-
- for _, target := range targets {
- imageDir := dir.Join(ctx, "system/framework", target.Arch.ArchType.String())
- imageConfig.images[target.Arch.ArchType] = imageDir.Join(ctx, stem+".art")
-
- imagesDeps := make([]android.Path, 0, len(imageConfig.modules)*3)
- for _, dep := range imageConfig.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex") {
- imagesDeps = append(imagesDeps, dep)
- }
- imageConfig.imagesDeps[target.Arch.ArchType] = imagesDeps
- }
-
- return imageConfig
- }).(bootImageConfig)
+ return configs
+ }).(map[string]*bootImageConfig)
}
-// Default config is the one that goes in the system image. It includes both libcore and framework.
-var defaultBootImageConfigKey = android.NewOnceKey("defaultBootImageConfig")
-
-func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
- return getBootImageConfig(ctx, defaultBootImageConfigKey, "boot", "boot", true, false)
-}
-
-// Apex config is used for the JIT-zygote experiment. It includes both libcore and framework, but AOT-compiles only libcore.
-var apexBootImageConfigKey = android.NewOnceKey("apexBootImageConfig")
-
-func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
- return getBootImageConfig(ctx, apexBootImageConfigKey, "apex", "apex", false, false)
-}
-
-// ART config is the one used for the ART apex. It includes only libcore.
-var artBootImageConfigKey = android.NewOnceKey("artBootImageConfig")
-
func artBootImageConfig(ctx android.PathContext) bootImageConfig {
- return getBootImageConfig(ctx, artBootImageConfigKey, "art", "boot", false, true)
+ return *genBootImageConfigs(ctx)[artBootImageName]
+}
+
+func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
+ return *genBootImageConfigs(ctx)[frameworkBootImageName]
+}
+
+func apexBootImageConfig(ctx android.PathContext) bootImageConfig {
+ return *genBootImageConfigs(ctx)[apexBootImageName]
}
func defaultBootclasspath(ctx android.PathContext) []string {
return ctx.Config().OnceStringSlice(defaultBootclasspathKey, func() []string {
global := dexpreoptGlobalConfig(ctx)
image := defaultBootImageConfig(ctx)
+
updatableBootclasspath := make([]string, len(global.UpdatableBootJars))
for i, p := range global.UpdatableBootJars {
updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(p)
}
- bootclasspath := append(copyOf(image.dexLocations), updatableBootclasspath...)
+
+ bootclasspath := append(copyOf(image.dexLocationsDeps), updatableBootclasspath...)
return bootclasspath
})
}
@@ -245,7 +274,7 @@
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
- ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocations, ":"))
+ ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocationsDeps, ":"))
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 96c8416..16e6921 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1979,28 +1979,6 @@
snapshotRelativeDir := filepath.Join("java", d.Name()+"_stubs_sources")
builder.UnzipToSnapshot(stubsSrcJar, snapshotRelativeDir)
- d.generatePrebuiltStubsSources(builder, snapshotRelativeDir, true)
-
- // This module is for the case when the source tree for the unversioned module
- // doesn't exist (i.e. building in an unbundled tree). "prefer:" is set to false
- // so that this module does not eclipse the unversioned module if it exists.
- d.generatePrebuiltStubsSources(builder, snapshotRelativeDir, false)
-}
-
-func (d *Droidstubs) generatePrebuiltStubsSources(builder android.SnapshotBuilder, snapshotRelativeDir string, versioned bool) {
- bp := builder.AndroidBpFile()
- name := d.Name()
- bp.Printfln("prebuilt_stubs_sources {")
- bp.Indent()
- if versioned {
- bp.Printfln("name: %q,", builder.VersionedSdkMemberName(name))
- bp.Printfln("sdk_member_name: %q,", name)
- } else {
- bp.Printfln("name: %q,", name)
- bp.Printfln("prefer: false,")
- }
- bp.Printfln("srcs: [%q],", snapshotRelativeDir)
- bp.Dedent()
- bp.Printfln("}")
- bp.Printfln("")
+ pbm := builder.AddPrebuiltModule(sdkModuleContext.OtherModuleName(d), "prebuilt_stubs_sources")
+ pbm.AddProperty("srcs", []string{snapshotRelativeDir})
}
diff --git a/java/java.go b/java/java.go
index 5cd074a..9c0fcba 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1737,30 +1737,8 @@
}
}
- j.generateJavaImport(builder, snapshotRelativeJavaLibPath, true)
-
- // This module is for the case when the source tree for the unversioned module
- // doesn't exist (i.e. building in an unbundled tree). "prefer:" is set to false
- // so that this module does not eclipse the unversioned module if it exists.
- j.generateJavaImport(builder, snapshotRelativeJavaLibPath, false)
-}
-
-func (j *Library) generateJavaImport(builder android.SnapshotBuilder, snapshotRelativeJavaLibPath string, versioned bool) {
- bp := builder.AndroidBpFile()
- name := j.Name()
- bp.Printfln("java_import {")
- bp.Indent()
- if versioned {
- bp.Printfln("name: %q,", builder.VersionedSdkMemberName(name))
- bp.Printfln("sdk_member_name: %q,", name)
- } else {
- bp.Printfln("name: %q,", name)
- bp.Printfln("prefer: false,")
- }
- bp.Printfln("jars: [%q],", snapshotRelativeJavaLibPath)
- bp.Dedent()
- bp.Printfln("}")
- bp.Printfln("")
+ module := builder.AddPrebuiltModule(sdkModuleContext.OtherModuleName(j), "java_import")
+ module.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
}
// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
diff --git a/rust/androidmk.go b/rust/androidmk.go
index edd5c5f..2636d97 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -90,11 +90,7 @@
func (test *testDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
test.binaryDecorator.AndroidMk(ctx, ret)
ret.Class = "NATIVE_TESTS"
- stem := String(test.baseCompiler.Properties.Stem)
- if stem != "" && !strings.HasSuffix(ctx.Name(), "_"+stem) {
- // Avoid repeated suffix in the module name.
- ret.SubName = "_" + stem
- }
+ ret.SubName = test.getMutatedModuleSubName(ctx.Name())
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
if len(test.Properties.Test_suites) > 0 {
fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
diff --git a/rust/test.go b/rust/test.go
index cb64e8f..b391103 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -69,15 +69,28 @@
return append(test.binaryDecorator.compilerProps(), &test.Properties)
}
+func (test *testDecorator) getMutatedModuleSubName(moduleName string) string {
+ stem := String(test.baseCompiler.Properties.Stem)
+ if stem != "" && !strings.HasSuffix(moduleName, "_"+stem) {
+ // Avoid repeated suffix in the module name.
+ return "_" + stem
+ }
+ return ""
+}
+
func (test *testDecorator) install(ctx ModuleContext, file android.Path) {
name := ctx.ModuleName() // default executable name
- if stem := String(test.baseCompiler.Properties.Stem); stem != "" {
- name = stem
+ if ctx.Device() { // on device, use mutated module name
+ name = name + test.getMutatedModuleSubName(name)
+ } else { // on host, use stem name in relative_install_path
+ if stem := String(test.baseCompiler.Properties.Stem); stem != "" {
+ name = stem
+ }
+ if path := test.baseCompiler.relativeInstallPath(); path != "" {
+ name = path + "/" + name
+ }
}
- if path := test.baseCompiler.relativeInstallPath(); path != "" {
- name = path + "/" + name
- }
- test.testConfig = tradefed.AutoGenRustHostTestConfig(ctx, name,
+ test.testConfig = tradefed.AutoGenRustTestConfig(ctx, name,
test.Properties.Test_config,
test.Properties.Test_config_template,
test.Properties.Test_suites,
diff --git a/sdk/bp.go b/sdk/bp.go
new file mode 100644
index 0000000..19fb70d
--- /dev/null
+++ b/sdk/bp.go
@@ -0,0 +1,141 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sdk
+
+import (
+ "fmt"
+
+ "android/soong/android"
+)
+
+type bpPropertySet struct {
+ properties map[string]interface{}
+ order []string
+}
+
+var _ android.BpPropertySet = (*bpPropertySet)(nil)
+
+func (s *bpPropertySet) init() {
+ s.properties = make(map[string]interface{})
+}
+
+func (s *bpPropertySet) AddProperty(name string, value interface{}) {
+ if s.properties[name] != nil {
+ panic("Property %q already exists in property set")
+ }
+
+ s.properties[name] = value
+ s.order = append(s.order, name)
+}
+
+func (s *bpPropertySet) AddPropertySet(name string) android.BpPropertySet {
+ set := &bpPropertySet{}
+ set.init()
+ s.AddProperty(name, set)
+ return set
+}
+
+func (s *bpPropertySet) getValue(name string) interface{} {
+ return s.properties[name]
+}
+
+func (s *bpPropertySet) copy() bpPropertySet {
+ propertiesCopy := make(map[string]interface{})
+ for p, v := range s.properties {
+ propertiesCopy[p] = v
+ }
+
+ return bpPropertySet{
+ properties: propertiesCopy,
+ order: append([]string(nil), s.order...),
+ }
+}
+
+func (s *bpPropertySet) setProperty(name string, value interface{}) {
+ if s.properties[name] == nil {
+ s.AddProperty(name, value)
+ } else {
+ s.properties[name] = value
+ }
+}
+
+func (s *bpPropertySet) insertAfter(position string, name string, value interface{}) {
+ if s.properties[name] != nil {
+ panic("Property %q already exists in property set")
+ }
+
+ // Add the name to the end of the order, to ensure it has necessary capacity
+ // and to handle the case when the position does not exist.
+ s.order = append(s.order, name)
+
+ // Search through the order for the item that matches supplied position. If
+ // found then insert the name of the new property after it.
+ for i, v := range s.order {
+ if v == position {
+ // Copy the items after the one where the new property should be inserted.
+ copy(s.order[i+2:], s.order[i+1:])
+ // Insert the item in the list.
+ s.order[i+1] = name
+ }
+ }
+
+ s.properties[name] = value
+}
+
+type bpModule struct {
+ bpPropertySet
+ moduleType string
+}
+
+var _ android.BpModule = (*bpModule)(nil)
+
+func (m *bpModule) copy() *bpModule {
+ return &bpModule{
+ bpPropertySet: m.bpPropertySet.copy(),
+ moduleType: m.moduleType,
+ }
+}
+
+// A .bp file
+type bpFile struct {
+ modules map[string]*bpModule
+ order []*bpModule
+}
+
+// Add a module.
+//
+// The module must have had its "name" property set to a string value that
+// is unique within this file.
+func (f *bpFile) AddModule(module android.BpModule) {
+ m := module.(*bpModule)
+ if name, ok := m.getValue("name").(string); ok {
+ if f.modules[name] != nil {
+ panic(fmt.Sprintf("Module %q already exists in bp file", name))
+ }
+
+ f.modules[name] = m
+ f.order = append(f.order, m)
+ } else {
+ panic("Module does not have a name property, or it is not a string")
+ }
+}
+
+func (f *bpFile) newModule(moduleType string) *bpModule {
+ module := &bpModule{
+ moduleType: moduleType,
+ }
+ (&module.bpPropertySet).init()
+ return module
+}
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 1bbd286..6b92d27 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -544,15 +544,9 @@
sdk_snapshot {
name: "mysdk@current",
- java_libs: [
- "mysdk_myjavalib@current",
- ],
- stubs_sources: [
- "mysdk_myjavaapistubs@current",
- ],
- native_shared_libs: [
- "mysdk_mynativelib@current",
- ],
+ java_libs: ["mysdk_myjavalib@current"],
+ stubs_sources: ["mysdk_myjavaapistubs@current"],
+ native_shared_libs: ["mysdk_mynativelib@current"],
}
`)
@@ -602,6 +596,198 @@
}
}
+func TestHostSnapshot(t *testing.T) {
+ ctx, config := testSdk(t, `
+ sdk {
+ name: "mysdk",
+ device_supported: false,
+ host_supported: true,
+ java_libs: ["myjavalib"],
+ native_shared_libs: ["mynativelib"],
+ stubs_sources: ["myjavaapistubs"],
+ }
+
+ java_library {
+ name: "myjavalib",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["Test.java"],
+ aidl: {
+ export_include_dirs: ["aidl"],
+ },
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+
+ cc_library_shared {
+ name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ srcs: [
+ "Test.cpp",
+ "aidl/foo/bar/Test.aidl",
+ ],
+ export_include_dirs: ["include"],
+ aidl: {
+ export_aidl_headers: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ droidstubs {
+ name: "myjavaapistubs",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["foo/bar/Foo.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ }
+ `)
+
+ sdk := ctx.ModuleForTests("mysdk", "linux_glibc_common").Module().(*sdk)
+
+ checkSnapshotAndroidBpContents(t, sdk, `// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ device_supported: false,
+ host_supported: true,
+ jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+ name: "myjavalib",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ jars: ["java/myjavalib.jar"],
+}
+
+prebuilt_stubs_sources {
+ name: "mysdk_myjavaapistubs@current",
+ sdk_member_name: "myjavaapistubs",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+prebuilt_stubs_sources {
+ name: "myjavaapistubs",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+cc_prebuilt_library_shared {
+ name: "mysdk_mynativelib@current",
+ sdk_member_name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86_64/include/include",
+ "x86_64/include_gen/mynativelib",
+ ],
+ },
+ x86: {
+ srcs: ["x86/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86/include/include",
+ "x86/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_shared {
+ name: "mynativelib",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86_64/include/include",
+ "x86_64/include_gen/mynativelib",
+ ],
+ },
+ x86: {
+ srcs: ["x86/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86/include/include",
+ "x86/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ java_libs: ["mysdk_myjavalib@current"],
+ stubs_sources: ["mysdk_myjavaapistubs@current"],
+ native_shared_libs: ["mysdk_mynativelib@current"],
+}
+
+`)
+
+ var copySrcs []string
+ var copyDests []string
+ buildParams := sdk.BuildParamsForTests()
+ var zipBp android.BuildParams
+ for _, bp := range buildParams {
+ ruleString := bp.Rule.String()
+ if ruleString == "android/soong/android.Cp" {
+ copySrcs = append(copySrcs, bp.Input.String())
+ copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root
+ } else if ruleString == "<local rule>:m.mysdk_linux_glibc_common.snapshot" {
+ zipBp = bp
+ }
+ }
+
+ buildDir := config.BuildDir()
+ ensureListContains(t, copySrcs, "aidl/foo/bar/Test.aidl")
+ ensureListContains(t, copySrcs, "include/Test.h")
+ ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BnTest.h"))
+ ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BpTest.h"))
+ ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/Test.h"))
+ ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/myjavalib/linux_glibc_common/javac/myjavalib.jar"))
+ ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so"))
+
+ ensureListContains(t, copyDests, "aidl/aidl/foo/bar/Test.aidl")
+ ensureListContains(t, copyDests, "x86_64/include/include/Test.h")
+ ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h")
+ ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/BpTest.h")
+ ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h")
+ ensureListContains(t, copyDests, "java/myjavalib.jar")
+ ensureListContains(t, copyDests, "x86_64/lib/mynativelib.so")
+
+ // Ensure that the droidstubs .srcjar as repackaged into a temporary zip file
+ // and then merged together with the intermediate snapshot zip.
+ snapshotCreationInputs := zipBp.Implicits.Strings()
+ ensureListContains(t, snapshotCreationInputs,
+ filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"))
+ ensureListContains(t, snapshotCreationInputs,
+ filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/mysdk-current.unmerged.zip"))
+ actual := zipBp.Output.String()
+ expected := filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/mysdk-current.zip")
+ if actual != expected {
+ t.Errorf("Expected snapshot output to be %q but was %q", expected, actual)
+ }
+}
+
func checkSnapshotAndroidBpContents(t *testing.T, s *sdk, expectedContents string) {
t.Helper()
androidBpContents := strings.NewReplacer("\\n", "\n").Replace(s.GetAndroidBpContentsForTests())
diff --git a/sdk/update.go b/sdk/update.go
index 000d200..8159d3b 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "reflect"
"strings"
"github.com/google/blueprint/proptools"
@@ -28,34 +29,37 @@
var pctx = android.NewPackageContext("android/soong/sdk")
-// generatedFile abstracts operations for writing contents into a file and emit a build rule
-// for the file.
-type generatedFile struct {
- path android.OutputPath
+type generatedContents struct {
content strings.Builder
indentLevel int
}
+// generatedFile abstracts operations for writing contents into a file and emit a build rule
+// for the file.
+type generatedFile struct {
+ generatedContents
+ path android.OutputPath
+}
+
func newGeneratedFile(ctx android.ModuleContext, path ...string) *generatedFile {
return &generatedFile{
- path: android.PathForModuleOut(ctx, path...).OutputPath,
- indentLevel: 0,
+ path: android.PathForModuleOut(ctx, path...).OutputPath,
}
}
-func (gf *generatedFile) Indent() {
- gf.indentLevel++
+func (gc *generatedContents) Indent() {
+ gc.indentLevel++
}
-func (gf *generatedFile) Dedent() {
- gf.indentLevel--
+func (gc *generatedContents) Dedent() {
+ gc.indentLevel--
}
-func (gf *generatedFile) Printfln(format string, args ...interface{}) {
+func (gc *generatedContents) Printfln(format string, args ...interface{}) {
// ninja consumes newline characters in rspfile_content. Prevent it by
// escaping the backslash in the newline character. The extra backslash
// is removed when the rspfile is written to the actual script file
- fmt.Fprintf(&(gf.content), strings.Repeat(" ", gf.indentLevel)+format+"\\n", args...)
+ fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format+"\\n", args...)
}
func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
@@ -239,15 +243,19 @@
snapshotDir := android.PathForModuleOut(ctx, "snapshot")
bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
- bp.Printfln("// This is auto-generated. DO NOT EDIT.")
- bp.Printfln("")
+
+ bpFile := &bpFile{
+ modules: make(map[string]*bpModule),
+ }
builder := &snapshotBuilder{
- ctx: ctx,
- version: "current",
- snapshotDir: snapshotDir.OutputPath,
- filesToZip: []android.Path{bp.path},
- androidBpFile: bp,
+ ctx: ctx,
+ sdk: s,
+ version: "current",
+ snapshotDir: snapshotDir.OutputPath,
+ filesToZip: []android.Path{bp.path},
+ bpFile: bpFile,
+ prebuiltModules: make(map[string]*bpModule),
}
s.builderForTests = builder
@@ -269,41 +277,38 @@
buildSharedNativeLibSnapshot(ctx, info, builder)
}
- // generate Android.bp
+ for _, unversioned := range builder.prebuiltOrder {
+ // Copy the unversioned module so it can be modified to make it versioned.
+ versioned := unversioned.copy()
+ name := versioned.properties["name"].(string)
+ versioned.setProperty("name", builder.versionedSdkMemberName(name))
+ versioned.insertAfter("name", "sdk_member_name", name)
+ bpFile.AddModule(versioned)
- bp.Printfln("sdk_snapshot {")
- bp.Indent()
- bp.Printfln("name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+builder.version)
+ // Set prefer: false - this is not strictly required as that is the default.
+ unversioned.insertAfter("name", "prefer", false)
+ bpFile.AddModule(unversioned)
+ }
+
+ // Create the snapshot module.
+ snapshotName := ctx.ModuleName() + string(android.SdkVersionSeparator) + builder.version
+ snapshotModule := bpFile.newModule("sdk_snapshot")
+ snapshotModule.AddProperty("name", snapshotName)
+ addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule)
if len(s.properties.Java_libs) > 0 {
- bp.Printfln("java_libs: [")
- bp.Indent()
- for _, m := range s.properties.Java_libs {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // java_libs
+ snapshotModule.AddProperty("java_libs", builder.versionedSdkMemberNames(s.properties.Java_libs))
}
if len(s.properties.Stubs_sources) > 0 {
- bp.Printfln("stubs_sources: [")
- bp.Indent()
- for _, m := range s.properties.Stubs_sources {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // stubs_sources
+ snapshotModule.AddProperty("stubs_sources", builder.versionedSdkMemberNames(s.properties.Stubs_sources))
}
if len(s.properties.Native_shared_libs) > 0 {
- bp.Printfln("native_shared_libs: [")
- bp.Indent()
- for _, m := range s.properties.Native_shared_libs {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // native_shared_libs
+ snapshotModule.AddProperty("native_shared_libs", builder.versionedSdkMemberNames(s.properties.Native_shared_libs))
}
- bp.Dedent()
- bp.Printfln("}") // sdk_snapshot
- bp.Printfln("")
+ bpFile.AddModule(snapshotModule)
+
+ // generate Android.bp
+ bp = newGeneratedFile(ctx, "snapshot", "Android.bp")
+ generateBpContents(&bp.generatedContents, bpFile)
bp.build(pctx, ctx, nil)
@@ -351,8 +356,61 @@
return outputZipFile
}
+func generateBpContents(contents *generatedContents, bpFile *bpFile) {
+ contents.Printfln("// This is auto-generated. DO NOT EDIT.")
+ for _, bpModule := range bpFile.order {
+ contents.Printfln("")
+ contents.Printfln("%s {", bpModule.moduleType)
+ outputPropertySet(contents, &bpModule.bpPropertySet)
+ contents.Printfln("}")
+ }
+ contents.Printfln("")
+}
+
+func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
+ contents.Indent()
+ for _, name := range set.order {
+ value := set.properties[name]
+
+ reflectedValue := reflect.ValueOf(value)
+ t := reflectedValue.Type()
+
+ kind := t.Kind()
+ switch kind {
+ case reflect.Slice:
+ length := reflectedValue.Len()
+ if length > 1 {
+ contents.Printfln("%s: [", name)
+ contents.Indent()
+ for i := 0; i < length; i = i + 1 {
+ contents.Printfln("%q,", reflectedValue.Index(i).Interface())
+ }
+ contents.Dedent()
+ contents.Printfln("],")
+ } else if length == 0 {
+ contents.Printfln("%s: [],", name)
+ } else {
+ contents.Printfln("%s: [%q],", name, reflectedValue.Index(0).Interface())
+ }
+ case reflect.Bool:
+ contents.Printfln("%s: %t,", name, reflectedValue.Bool())
+
+ case reflect.Ptr:
+ contents.Printfln("%s: {", name)
+ outputPropertySet(contents, reflectedValue.Interface().(*bpPropertySet))
+ contents.Printfln("},")
+
+ default:
+ contents.Printfln("%s: %q,", name, value)
+ }
+ }
+ contents.Dedent()
+}
+
func (s *sdk) GetAndroidBpContentsForTests() string {
- return s.builderForTests.androidBpFile.content.String()
+ contents := &generatedContents{}
+ generateBpContents(contents, s.builderForTests.bpFile)
+ return contents.content.String()
}
func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
@@ -406,81 +464,58 @@
}
}
- info.generatePrebuiltLibrary(ctx, builder, true)
-
- // This module is for the case when the source tree for the unversioned module
- // doesn't exist (i.e. building in an unbundled tree). "prefer:" is set to false
- // so that this module does not eclipse the unversioned module if it exists.
- info.generatePrebuiltLibrary(ctx, builder, false)
+ info.generatePrebuiltLibrary(ctx, builder)
}
-func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder, versioned bool) {
- bp := builder.AndroidBpFile()
- bp.Printfln("cc_prebuilt_library_shared {")
- bp.Indent()
- name := info.name
- if versioned {
- bp.Printfln("name: %q,", builder.VersionedSdkMemberName(name))
- bp.Printfln("sdk_member_name: %q,", name)
- } else {
- bp.Printfln("name: %q,", name)
- bp.Printfln("prefer: false,")
- }
+func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder) {
// a function for emitting include dirs
- printExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, systemInclude bool) {
+ addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
if len(includeDirs) == 0 {
return
}
+ var propertyName string
if !systemInclude {
- bp.Printfln("export_include_dirs: [")
+ propertyName = "export_include_dirs"
} else {
- bp.Printfln("export_system_include_dirs: [")
+ propertyName = "export_system_include_dirs"
}
- bp.Indent()
- for _, dir := range includeDirs {
- bp.Printfln("%q,", dir)
- }
- bp.Dedent()
- bp.Printfln("],")
+ properties.AddProperty(propertyName, includeDirs)
}
+ pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
+
if !info.hasArchSpecificFlags {
- printExportedDirsForNativeLibs(info.archVariants[0], false /*systemInclude*/)
- printExportedDirsForNativeLibs(info.archVariants[0], true /*systemInclude*/)
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
}
- bp.Printfln("arch: {")
- bp.Indent()
+ archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariants {
- bp.Printfln("%s: {", av.archType)
- bp.Indent()
- bp.Printfln("srcs: [%q],", nativeStubFilePathFor(av))
+ archTypeProperties := archProperties.AddPropertySet(av.archType)
+ archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
if info.hasArchSpecificFlags {
// export_* properties are added inside the arch: {<arch>: {...}} block
- printExportedDirsForNativeLibs(av, false /*systemInclude*/)
- printExportedDirsForNativeLibs(av, true /*systemInclude*/)
+ addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
}
- bp.Dedent()
- bp.Printfln("},") // <arch>
}
- bp.Dedent()
- bp.Printfln("},") // arch
- bp.Printfln("stl: \"none\",")
- bp.Printfln("system_shared_libs: [],")
- bp.Dedent()
- bp.Printfln("}") // cc_prebuilt_library_shared
- bp.Printfln("")
+ pbm.AddProperty("stl", "none")
+ pbm.AddProperty("system_shared_libs", []string{})
}
type snapshotBuilder struct {
- ctx android.ModuleContext
- version string
- snapshotDir android.OutputPath
- androidBpFile *generatedFile
- filesToZip android.Paths
- zipsToMerge android.Paths
+ ctx android.ModuleContext
+ sdk *sdk
+ version string
+ snapshotDir android.OutputPath
+ bpFile *bpFile
+ filesToZip android.Paths
+ zipsToMerge android.Paths
+
+ prebuiltModules map[string]*bpModule
+ prebuiltOrder []*bpModule
}
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
@@ -512,10 +547,38 @@
s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
}
-func (s *snapshotBuilder) AndroidBpFile() android.GeneratedSnapshotFile {
- return s.androidBpFile
+func (s *snapshotBuilder) AddPrebuiltModule(name string, moduleType string) android.BpModule {
+ if s.prebuiltModules[name] != nil {
+ panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
+ }
+
+ m := s.bpFile.newModule(moduleType)
+ m.AddProperty("name", name)
+ addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m)
+
+ s.prebuiltModules[name] = m
+ s.prebuiltOrder = append(s.prebuiltOrder, m)
+ return m
}
-func (s *snapshotBuilder) VersionedSdkMemberName(unversionedName string) interface{} {
+func addHostDeviceSupportedProperties(module *android.ModuleBase, bpModule *bpModule) {
+ if !module.DeviceSupported() {
+ bpModule.AddProperty("device_supported", false)
+ }
+ if module.HostSupported() {
+ bpModule.AddProperty("host_supported", true)
+ }
+}
+
+// Get a versioned name appropriate for the SDK snapshot version being taken.
+func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string) string {
return versionedSdkMemberName(s.ctx, unversionedName, s.version)
}
+
+func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string {
+ var references []string = nil
+ for _, m := range members {
+ references = append(references, s.versionedSdkMemberName(m))
+ }
+ return references
+}
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 905acfa..c35d8b9 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -197,11 +197,14 @@
return path
}
-func AutoGenRustHostTestConfig(ctx android.ModuleContext, name string, testConfigProp *string,
+func AutoGenRustTestConfig(ctx android.ModuleContext, name string, testConfigProp *string,
testConfigTemplateProp *string, testSuites []string, autoGenConfig *bool) android.Path {
path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig)
if autogenPath != nil {
templatePathString := "${RustHostTestConfigTemplate}"
+ if ctx.Device() {
+ templatePathString = "${RustDeviceTestConfigTemplate}"
+ }
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
if templatePath.Valid() {
templatePathString = templatePath.String()
diff --git a/tradefed/config.go b/tradefed/config.go
index 8249ffe..a289073 100644
--- a/tradefed/config.go
+++ b/tradefed/config.go
@@ -31,6 +31,7 @@
pctx.SourcePathVariable("NativeHostTestConfigTemplate", "build/make/core/native_host_test_config_template.xml")
pctx.SourcePathVariable("NativeTestConfigTemplate", "build/make/core/native_test_config_template.xml")
pctx.SourcePathVariable("PythonBinaryHostTestConfigTemplate", "build/make/core/python_binary_host_test_config_template.xml")
+ pctx.SourcePathVariable("RustDeviceTestConfigTemplate", "build/make/core/rust_device_test_config_template.xml")
pctx.SourcePathVariable("RustHostTestConfigTemplate", "build/make/core/rust_host_test_config_template.xml")
pctx.SourcePathVariable("EmptyTestConfig", "build/make/core/empty_test_config.xml")
diff --git a/tradefed/makevars.go b/tradefed/makevars.go
index e6b88ea..d4cf7a8 100644
--- a/tradefed/makevars.go
+++ b/tradefed/makevars.go
@@ -31,6 +31,7 @@
ctx.Strict("NATIVE_HOST_TEST_CONFIG_TEMPLATE", "${NativeHostTestConfigTemplate}")
ctx.Strict("NATIVE_TEST_CONFIG_TEMPLATE", "${NativeTestConfigTemplate}")
ctx.Strict("PYTHON_BINARY_HOST_TEST_CONFIG_TEMPLATE", "${PythonBinaryHostTestConfigTemplate}")
+ ctx.Strict("RUST_DEVICE_TEST_CONFIG_TEMPLATE", "${RustDeviceTestConfigTemplate}")
ctx.Strict("RUST_HOST_TEST_CONFIG_TEMPLATE", "${RustHostTestConfigTemplate}")
ctx.Strict("EMPTY_TEST_CONFIG", "${EmptyTestConfig}")