Merge "Set usesNonSdkApi in manifest when Platform_apis=true"
diff --git a/Android.bp b/Android.bp
index b407314..36a428a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -250,6 +250,7 @@
"java/builder.go",
"java/dex.go",
"java/dexpreopt.go",
+ "java/dexpreopt_bootjars.go",
"java/droiddoc.go",
"java/gen.go",
"java/genrule.go",
@@ -267,6 +268,7 @@
"java/sdk_library.go",
"java/support_libraries.go",
"java/system_modules.go",
+ "java/testing.go",
],
testSrcs: [
"java/app_test.go",
diff --git a/android/config.go b/android/config.go
index 63788b7..9217aab 100644
--- a/android/config.go
+++ b/android/config.go
@@ -779,7 +779,11 @@
return c.productVariables.PreoptBootJars
}
-func (c *config) DisableDexPreopt(name string) bool {
+func (c *config) DisableDexPreopt() bool {
+ return Bool(c.productVariables.DisableDexPreopt)
+}
+
+func (c *config) DisableDexPreoptForModule(name string) bool {
return Bool(c.productVariables.DisableDexPreopt) || InList(name, c.productVariables.DisableDexPreoptModules)
}
diff --git a/android/paths.go b/android/paths.go
index 31500ab..3366db1 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -677,6 +677,15 @@
return OutputPath{basePath{path, ctx.Config(), ""}}
}
+// PathsForOutput returns Paths rooted from buildDir
+func PathsForOutput(ctx PathContext, paths []string) WritablePaths {
+ ret := make(WritablePaths, len(paths))
+ for i, path := range paths {
+ ret[i] = PathForOutput(ctx, path)
+ }
+ return ret
+}
+
func (p OutputPath) writablePath() {}
func (p OutputPath) String() string {
@@ -707,6 +716,18 @@
return ret
}
+// InSameDir creates a new OutputPath from the directory of the current OutputPath joined with the elements in paths.
+func (p OutputPath) InSameDir(ctx PathContext, paths ...string) OutputPath {
+ path, err := validatePath(paths...)
+ if err != nil {
+ reportPathError(ctx, err)
+ }
+
+ ret := PathForOutput(ctx, filepath.Dir(p.path), path)
+ ret.rel = p.rel
+ return ret
+}
+
// PathForIntermediates returns an OutputPath representing the top-level
// intermediates directory.
func PathForIntermediates(ctx PathContext, paths ...string) OutputPath {
@@ -1019,6 +1040,14 @@
return p.path
}
+type testWritablePath struct {
+ testPath
+}
+
+func (p testPath) writablePath() {}
+
+// PathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be used from
+// within tests.
func PathForTesting(paths ...string) Path {
p, err := validateSafePath(paths...)
if err != nil {
@@ -1027,7 +1056,8 @@
return testPath{basePath{path: p, rel: p}}
}
-func PathsForTesting(strs []string) Paths {
+// PathsForTesting returns a Path constructed from each element in strs. It should only be used from within tests.
+func PathsForTesting(strs ...string) Paths {
p := make(Paths, len(strs))
for i, s := range strs {
p[i] = PathForTesting(s)
@@ -1036,6 +1066,45 @@
return p
}
+// WritablePathForTesting returns a Path constructed from joining the elements of paths with '/'. It should only be
+// used from within tests.
+func WritablePathForTesting(paths ...string) WritablePath {
+ p, err := validateSafePath(paths...)
+ if err != nil {
+ panic(err)
+ }
+ return testWritablePath{testPath{basePath{path: p, rel: p}}}
+}
+
+// WritablePathsForTesting returns a Path constructed from each element in strs. It should only be used from within
+// tests.
+func WritablePathsForTesting(strs ...string) WritablePaths {
+ p := make(WritablePaths, len(strs))
+ for i, s := range strs {
+ p[i] = WritablePathForTesting(s)
+ }
+
+ return p
+}
+
+type testPathContext struct {
+ config Config
+ fs pathtools.FileSystem
+}
+
+func (x *testPathContext) Fs() pathtools.FileSystem { return x.fs }
+func (x *testPathContext) Config() Config { return x.config }
+func (x *testPathContext) AddNinjaFileDeps(...string) {}
+
+// PathContextForTesting returns a PathContext that can be used in tests, for example to create an OutputPath with
+// PathForOutput.
+func PathContextForTesting(config Config, fs map[string][]byte) PathContext {
+ return &testPathContext{
+ config: config,
+ fs: pathtools.MockFs(fs),
+ }
+}
+
// Rel performs the same function as filepath.Rel, but reports errors to a PathContext, and reports an error if
// targetPath is not inside basePath.
func Rel(ctx PathContext, basePath string, targetPath string) string {
diff --git a/android/paths_test.go b/android/paths_test.go
index 1972591..3b6d2ec 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -703,3 +703,15 @@
// Output:
// out/system/framework/boot.art out/system/framework/boot.oat
}
+
+func ExampleOutputPath_FileInSameDir() {
+ ctx := &configErrorWrapper{
+ config: TestConfig("out", nil),
+ }
+ p := PathForOutput(ctx, "system/framework/boot.art")
+ p2 := p.InSameDir(ctx, "oat", "arm", "boot.vdex")
+ fmt.Println(p, p2)
+
+ // Output:
+ // out/system/framework/boot.art out/system/framework/oat/arm/boot.vdex
+}
diff --git a/cc/builder.go b/cc/builder.go
index 6e24d56..97ae806 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -197,8 +197,8 @@
sAbiDiff = pctx.AndroidRuleFunc("sAbiDiff",
func(ctx android.PackageRuleContext) blueprint.RuleParams {
// TODO(b/78139997): Add -check-all-apis back
- commandStr := "($sAbiDiffer $allowFlags -lib $libName -arch $arch -o ${out} -new $in -old $referenceDump)"
- commandStr += "|| (echo ' ---- Please update abi references by running $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l ${libName} ----'"
+ commandStr := "($sAbiDiffer ${allowFlags} -lib ${libName} -arch ${arch} -o ${out} -new ${in} -old ${referenceDump})"
+ commandStr += "|| (echo 'error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py ${createReferenceDumpFlags} -l ${libName}'"
commandStr += " && (mkdir -p $$DIST_DIR/abidiffs && cp ${out} $$DIST_DIR/abidiffs/)"
commandStr += " && exit 1)"
return blueprint.RuleParams{
@@ -206,7 +206,7 @@
CommandDeps: []string{"$sAbiDiffer"},
}
},
- "allowFlags", "referenceDump", "libName", "arch")
+ "allowFlags", "referenceDump", "libName", "arch", "createReferenceDumpFlags")
unzipRefSAbiDump = pctx.AndroidStaticRule("unzipRefSAbiDump",
blueprint.RuleParams{
@@ -711,16 +711,19 @@
}
func SourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceDump android.Path,
- baseName, exportedHeaderFlags string, isVndkExt bool) android.OptionalPath {
+ baseName, exportedHeaderFlags string, isLlndk, isVndkExt bool) android.OptionalPath {
outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
+ createReferenceDumpFlags := ""
+
localAbiCheckAllowFlags := append([]string(nil), abiCheckAllowFlags...)
if exportedHeaderFlags == "" {
localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-advice-only")
}
- if inList(libName, llndkLibraries) {
+ if isLlndk {
localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-consider-opaque-types-different")
+ createReferenceDumpFlags = "--llndk"
}
if isVndkExt {
localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-allow-extensions")
@@ -733,10 +736,11 @@
Input: inputDump,
Implicit: referenceDump,
Args: map[string]string{
- "referenceDump": referenceDump.String(),
- "libName": libName,
- "arch": ctx.Arch().ArchType.Name,
- "allowFlags": strings.Join(localAbiCheckAllowFlags, " "),
+ "referenceDump": referenceDump.String(),
+ "libName": libName,
+ "arch": ctx.Arch().ArchType.Name,
+ "allowFlags": strings.Join(localAbiCheckAllowFlags, " "),
+ "createReferenceDumpFlags": createReferenceDumpFlags,
},
})
return android.OptionalPathForPath(outputFile)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 22ac0d9..a0914c8 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1039,7 +1039,7 @@
func TestSplitListForSize(t *testing.T) {
for _, testCase := range splitListForSizeTestCases {
- out, _ := splitListForSize(android.PathsForTesting(testCase.in), testCase.size)
+ out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
var outStrings [][]string
diff --git a/cc/coverage.go b/cc/coverage.go
index cf67c9f..0549705 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -109,8 +109,6 @@
if mctx.Host() {
// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
// Just turn off for now.
- } else if c.useVndk() || c.hasVendorVariant() {
- // Do not enable coverage for VNDK libraries
} else if c.IsStubs() {
// Do not enable coverage for platform stub libraries
} else if c.isNDKStubLibrary() {
diff --git a/cc/library.go b/cc/library.go
index a48b45d..c23f26b 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -794,7 +794,7 @@
refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName)
if refAbiDumpFile != nil {
library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
- refAbiDumpFile, fileName, exportedHeaderFlags, ctx.isVndkExt())
+ refAbiDumpFile, fileName, exportedHeaderFlags, ctx.isLlndk(), ctx.isVndkExt())
}
}
}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index c7f0638..0eb162d 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -34,11 +34,12 @@
DisableGenerateProfile bool // don't generate profiles
- PreoptBootClassPathDexFiles []string // file paths of boot class path files
- PreoptBootClassPathDexLocations []string // virtual locations of boot class path files
+ BootJars []string // modules for jars that form the boot class path
- BootJars []string // modules for jars that form the boot class path
- PreoptBootJars []string // modules for jars that form the boot image
+ TargetCoreJars []string // modules for jars that are in the runtime apex
+ ProductUpdatableBootModules []string
+ ProductUpdatableBootLocations []string
+
SystemServerJars []string // jars that form the system server
SystemServerApps []string // apps that are loaded into system server
SpeedApps []string // apps that should be speed optimized
@@ -64,15 +65,22 @@
DefaultAppImages bool // build app images (TODO: .art files?) by default
- Dex2oatXmx string // max heap size
- Dex2oatXms string // initial heap size
+ Dex2oatXmx string // max heap size for dex2oat
+ Dex2oatXms string // initial heap size for dex2oat
EmptyDirectory string // path to an empty directory
- DefaultDexPreoptImage map[android.ArchType]string // default boot image location for each architecture
CpuVariant map[android.ArchType]string // cpu variant for each architecture
InstructionSetFeatures map[android.ArchType]string // instruction set for each architecture
+ // Only used for boot image
+ DirtyImageObjects string // path to a dirty-image-objects file
+ PreloadedClasses string // path to a preloaded-classes file
+ BootImageProfiles []string // path to a boot-image-profile.txt file
+ BootFlags string // extra flags to pass to dex2oat for the boot image
+ Dex2oatImageXmx string // max heap size for dex2oat for the boot image
+ Dex2oatImageXms string // initial heap size for dex2oat for the boot image
+
Tools Tools // paths to tools possibly used by the generated commands
}
@@ -109,6 +117,9 @@
Archs []android.ArchType
DexPreoptImages []string
+ PreoptBootClassPathDexFiles []string // file paths of boot class path files
+ PreoptBootClassPathDexLocations []string // virtual locations of boot class path files
+
PreoptExtractedApk bool // Overrides OnlyPreoptModules
NoCreateAppImage bool
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 68bd3ea..eacb86a 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -199,9 +199,6 @@
pathtools.ReplaceExtension(filepath.Base(path), "odex"))
}
- bcp := strings.Join(global.PreoptBootClassPathDexFiles, ":")
- bcp_locations := strings.Join(global.PreoptBootClassPathDexLocations, ":")
-
odexPath := toOdexPath(filepath.Join(filepath.Dir(module.BuildPath), base))
odexInstallPath := toOdexPath(module.DexLocation)
if odexOnSystemOther(module, global) {
@@ -320,9 +317,8 @@
FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatXms).
Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatXmx).
- Flag("--runtime-arg").FlagWithArg("-Xbootclasspath:", bcp).
- Implicits(global.PreoptBootClassPathDexFiles).
- Flag("--runtime-arg").FlagWithArg("-Xbootclasspath-locations:", bcp_locations).
+ Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", module.PreoptBootClassPathDexFiles, ":").
+ Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", module.PreoptBootClassPathDexLocations, ":").
Flag("${class_loader_context_arg}").
Flag("${stored_class_loader_context_arg}").
FlagWithArg("--boot-image=", bootImageLocation).Implicit(bootImage).
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 40c694f..a2c6f77 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -29,6 +29,9 @@
PatternsOnSystemOther: nil,
DisableGenerateProfile: false,
BootJars: nil,
+ TargetCoreJars: nil,
+ ProductUpdatableBootModules: nil,
+ ProductUpdatableBootLocations: nil,
SystemServerJars: nil,
SystemServerApps: nil,
SpeedApps: nil,
@@ -49,9 +52,14 @@
Dex2oatXmx: "",
Dex2oatXms: "",
EmptyDirectory: "",
- DefaultDexPreoptImage: nil,
CpuVariant: nil,
InstructionSetFeatures: nil,
+ DirtyImageObjects: "",
+ PreloadedClasses: "",
+ BootImageProfiles: nil,
+ BootFlags: "",
+ Dex2oatImageXmx: "",
+ Dex2oatImageXms: "",
Tools: Tools{
Profman: "profman",
Dex2oat: "dex2oat",
@@ -64,28 +72,30 @@
}
var testModuleConfig = ModuleConfig{
- Name: "",
- DexLocation: "",
- BuildPath: "",
- DexPath: "",
- UncompressedDex: false,
- HasApkLibraries: false,
- PreoptFlags: nil,
- ProfileClassListing: "",
- ProfileIsTextListing: false,
- EnforceUsesLibraries: false,
- OptionalUsesLibraries: nil,
- UsesLibraries: nil,
- LibraryPaths: nil,
- Archs: []android.ArchType{android.Arm},
- DexPreoptImages: []string{"system/framework/arm/boot.art"},
- PreoptExtractedApk: false,
- NoCreateAppImage: false,
- ForceCreateAppImage: false,
- PresignedPrebuilt: false,
- NoStripping: false,
- StripInputPath: "",
- StripOutputPath: "",
+ Name: "",
+ DexLocation: "",
+ BuildPath: "",
+ DexPath: "",
+ UncompressedDex: false,
+ HasApkLibraries: false,
+ PreoptFlags: nil,
+ ProfileClassListing: "",
+ ProfileIsTextListing: false,
+ EnforceUsesLibraries: false,
+ OptionalUsesLibraries: nil,
+ UsesLibraries: nil,
+ LibraryPaths: nil,
+ Archs: []android.ArchType{android.Arm},
+ DexPreoptImages: []string{"system/framework/arm/boot.art"},
+ PreoptBootClassPathDexFiles: nil,
+ PreoptBootClassPathDexLocations: nil,
+ PreoptExtractedApk: false,
+ NoCreateAppImage: false,
+ ForceCreateAppImage: false,
+ PresignedPrebuilt: false,
+ NoStripping: false,
+ StripInputPath: "",
+ StripOutputPath: "",
}
func TestDexPreopt(t *testing.T) {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 127deab..0a56529 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -56,7 +56,11 @@
}
func (d *dexpreopter) dexpreoptDisabled(ctx android.ModuleContext) bool {
- if ctx.Config().DisableDexPreopt(ctx.ModuleName()) {
+ if ctx.Config().DisableDexPreopt() {
+ return true
+ }
+
+ if ctx.Config().DisableDexPreoptForModule(ctx.ModuleName()) {
return true
}
@@ -83,8 +87,8 @@
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
-func getGlobalConfig(ctx android.ModuleContext) dexpreopt.GlobalConfig {
- globalConfig := ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
+func dexpreoptGlobalConfig(ctx android.PathContext) dexpreopt.GlobalConfig {
+ return ctx.Config().Once(dexpreoptGlobalConfigKey, func() interface{} {
if f := ctx.Config().DexpreoptGlobalConfig(); f != "" {
ctx.AddNinjaFileDeps(f)
globalConfig, err := dexpreopt.LoadGlobalConfig(f)
@@ -95,11 +99,10 @@
}
return dexpreopt.GlobalConfig{}
}).(dexpreopt.GlobalConfig)
- return globalConfig
}
func odexOnSystemOther(ctx android.ModuleContext, installPath android.OutputPath) bool {
- return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), getGlobalConfig(ctx))
+ return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreoptGlobalConfig(ctx))
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.ModuleOutPath) android.ModuleOutPath {
@@ -107,7 +110,7 @@
return dexJarFile
}
- globalConfig := getGlobalConfig(ctx)
+ info := dexpreoptBootJarsInfo(ctx)
var archs []android.ArchType
for _, a := range ctx.MultiTargets() {
@@ -118,7 +121,7 @@
for _, target := range ctx.Config().Targets[android.Android] {
archs = append(archs, target.Arch.ArchType)
}
- if inList(ctx.ModuleName(), globalConfig.SystemServerJars) && !d.isSDKLibrary {
+ if inList(ctx.ModuleName(), info.global.SystemServerJars) && !d.isSDKLibrary {
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
archs = archs[:1]
}
@@ -130,7 +133,7 @@
var images []string
for _, arch := range archs {
- images = append(images, globalConfig.DefaultDexPreoptImage[arch])
+ images = append(images, info.images[arch].String())
}
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
@@ -178,6 +181,9 @@
Archs: archs,
DexPreoptImages: images,
+ PreoptBootClassPathDexFiles: info.preoptBootDex.Strings(),
+ PreoptBootClassPathDexLocations: info.preoptBootLocations,
+
PreoptExtractedApk: false,
NoCreateAppImage: !BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, true),
@@ -188,7 +194,7 @@
StripOutputPath: strippedDexJarFile.String(),
}
- dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(globalConfig, dexpreoptConfig)
+ dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(info.global, dexpreoptConfig)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return dexJarFile
@@ -198,7 +204,7 @@
d.builtInstalled = dexpreoptRule.Installs().String()
- stripRule, err := dexpreopt.GenerateStripRule(globalConfig, dexpreoptConfig)
+ stripRule, err := dexpreopt.GenerateStripRule(info.global, dexpreoptConfig)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt strip rule: %s", err.Error())
return dexJarFile
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
new file mode 100644
index 0000000..0656ff4
--- /dev/null
+++ b/java/dexpreopt_bootjars.go
@@ -0,0 +1,463 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "path/filepath"
+ "strings"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+
+ "github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ android.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
+}
+
+// The image "location" is a symbolic path that with multiarchitecture
+// support doesn't really exist on the device. Typically it is
+// /system/framework/boot.art and should be the same for all supported
+// architectures on the device. The concrete architecture specific
+// content actually ends up in a "filename" that contains an
+// architecture specific directory name such as arm, arm64, mips,
+// mips64, x86, x86_64.
+//
+// Here are some example values for an x86_64 / x86 configuration:
+//
+// bootImages["x86_64"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art"
+// dexpreopt.PathToLocation(bootImages["x86_64"], "x86_64") = "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
+//
+// bootImages["x86"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86/boot.art"
+// dexpreopt.PathToLocation(bootImages["x86"])= "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
+//
+// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
+// will then reconstruct the real path, so the rules must have a dependency on the real path.
+
+type bootJarsInfo struct {
+ dir android.OutputPath
+ symbolsDir android.OutputPath
+ images map[android.ArchType]android.OutputPath
+ installs map[android.ArchType]android.RuleBuilderInstalls
+
+ vdexInstalls map[android.ArchType]android.RuleBuilderInstalls
+ unstrippedInstalls map[android.ArchType]android.RuleBuilderInstalls
+ profileInstalls android.RuleBuilderInstalls
+
+ global dexpreopt.GlobalConfig
+
+ preoptBootModules []string
+ preoptBootLocations []string
+ preoptBootDex android.WritablePaths
+ allBootModules []string
+ allBootLocations []string
+ bootclasspath string
+ systemServerClasspath string
+}
+
+var dexpreoptBootJarsInfoKey = android.NewOnceKey("dexpreoptBootJarsInfoKey")
+
+// dexpreoptBootJarsInfo creates all the paths for singleton files the first time it is called, which may be
+// from a ModuleContext that needs to reference a file that will be created by a singleton rule that hasn't
+// yet been created.
+func dexpreoptBootJarsInfo(ctx android.PathContext) *bootJarsInfo {
+ return ctx.Config().Once(dexpreoptBootJarsInfoKey, func() interface{} {
+
+ info := &bootJarsInfo{
+ dir: android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars"),
+ symbolsDir: android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_unstripped"),
+ images: make(map[android.ArchType]android.OutputPath),
+ installs: make(map[android.ArchType]android.RuleBuilderInstalls),
+
+ vdexInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
+ unstrippedInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
+ }
+
+ for _, target := range ctx.Config().Targets[android.Android] {
+ info.images[target.Arch.ArchType] = info.dir.Join(ctx,
+ "system/framework", target.Arch.ArchType.String(), "boot.art")
+ }
+
+ info.global = dexpreoptGlobalConfig(ctx)
+ computeBootClasspath(ctx, info)
+ computeSystemServerClasspath(ctx, info)
+
+ return info
+ }).(*bootJarsInfo)
+}
+
+func concat(lists ...[]string) []string {
+ var size int
+ for _, l := range lists {
+ size += len(l)
+ }
+ ret := make([]string, 0, size)
+ for _, l := range lists {
+ ret = append(ret, l...)
+ }
+ return ret
+}
+
+func computeBootClasspath(ctx android.PathContext, info *bootJarsInfo) {
+ runtimeModules := android.RemoveListFromList(info.global.TargetCoreJars, info.global.ProductUpdatableBootModules)
+ nonFrameworkModules := concat(runtimeModules, info.global.ProductUpdatableBootModules)
+ frameworkModules := android.RemoveListFromList(info.global.BootJars, nonFrameworkModules)
+
+ var nonUpdatableBootModules []string
+ var nonUpdatableBootLocations []string
+
+ for _, m := range runtimeModules {
+ nonUpdatableBootModules = append(nonUpdatableBootModules, m)
+ nonUpdatableBootLocations = append(nonUpdatableBootLocations,
+ filepath.Join("/apex/com.android.runtime/javalib", m+".jar"))
+ }
+
+ for _, m := range frameworkModules {
+ nonUpdatableBootModules = append(nonUpdatableBootModules, m)
+ nonUpdatableBootLocations = append(nonUpdatableBootLocations,
+ filepath.Join("/system/framework", m+".jar"))
+ }
+
+ // 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: use module dependencies instead
+ var nonUpdatableBootDex android.WritablePaths
+ for _, m := range nonUpdatableBootModules {
+ nonUpdatableBootDex = append(nonUpdatableBootDex,
+ android.PathForOutput(ctx, ctx.Config().DeviceName(), "dex_bootjars_input", m+".jar"))
+ }
+
+ allBootModules := concat(nonUpdatableBootModules, info.global.ProductUpdatableBootModules)
+ allBootLocations := concat(nonUpdatableBootLocations, info.global.ProductUpdatableBootLocations)
+
+ bootclasspath := strings.Join(allBootLocations, ":")
+
+ info.preoptBootModules = nonUpdatableBootModules
+ info.preoptBootLocations = nonUpdatableBootLocations
+ info.preoptBootDex = nonUpdatableBootDex
+ info.allBootModules = allBootModules
+ info.allBootLocations = allBootLocations
+ info.bootclasspath = bootclasspath
+}
+
+func computeSystemServerClasspath(ctx android.PathContext, info *bootJarsInfo) {
+ var systemServerClasspathLocations []string
+ for _, m := range info.global.SystemServerJars {
+ systemServerClasspathLocations = append(systemServerClasspathLocations,
+ filepath.Join("/system/framework", m+".jar"))
+ }
+
+ info.systemServerClasspath = strings.Join(systemServerClasspathLocations, ":")
+}
+func dexpreoptBootJarsFactory() android.Singleton {
+ return dexpreoptBootJars{}
+}
+
+func skipDexpreoptBootJars(ctx android.PathContext) bool {
+ if ctx.Config().UnbundledBuild() {
+ return true
+ }
+
+ if len(ctx.Config().Targets[android.Android]) == 0 {
+ // Host-only build
+ return true
+ }
+
+ return false
+}
+
+type dexpreoptBootJars struct{}
+
+// dexpreoptBoot singleton rules
+func (dexpreoptBootJars) GenerateBuildActions(ctx android.SingletonContext) {
+ if skipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ info := dexpreoptBootJarsInfo(ctx)
+
+ // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths
+ // and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds.
+ // Note: this is technically incorrect. Compiled code contains stack checks which may depend
+ // on ASAN settings.
+ if len(ctx.Config().SanitizeDevice()) == 1 &&
+ ctx.Config().SanitizeDevice()[0] == "address" &&
+ info.global.SanitizeLite {
+ return
+ }
+
+ bootDexJars := make(android.Paths, len(info.preoptBootModules))
+
+ ctx.VisitAllModules(func(module android.Module) {
+ // Collect dex jar paths for the modules listed above.
+ if j, ok := module.(Dependency); ok {
+ name := ctx.ModuleName(module)
+ if i := android.IndexList(name, info.preoptBootModules); i != -1 {
+ bootDexJars[i] = j.DexJar()
+ }
+ }
+ })
+
+ var missingDeps []string
+ // Ensure all modules were converted to paths
+ for i := range bootDexJars {
+ if bootDexJars[i] == nil {
+ if ctx.Config().AllowMissingDependencies() {
+ missingDeps = append(missingDeps, info.preoptBootModules[i])
+ bootDexJars[i] = android.PathForOutput(ctx, "missing")
+ } else {
+ ctx.Errorf("failed to find dex jar path for module %q",
+ info.preoptBootModules[i])
+ }
+ }
+ }
+
+ // The path to bootclasspath dex files needs to be known at module GenerateAndroidBuildAction time, before
+ // the bootclasspath modules have been compiled. Copy the dex jars there so the module rules that have
+ // already been set up can find them.
+ for i := range bootDexJars {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: bootDexJars[i],
+ Output: info.preoptBootDex[i],
+ })
+ }
+
+ profile := bootImageProfileRule(ctx, info, missingDeps)
+
+ if !ctx.Config().DisableDexPreopt() {
+ targets := ctx.Config().Targets[android.Android]
+ if ctx.Config().SecondArchIsTranslated() {
+ targets = targets[:1]
+ }
+
+ for _, target := range targets {
+ dexPreoptBootImageRule(ctx, info, target.Arch.ArchType, profile, missingDeps)
+ }
+ }
+}
+
+func dexPreoptBootImageRule(ctx android.SingletonContext, info *bootJarsInfo,
+ arch android.ArchType, profile android.Path, missingDeps []string) {
+
+ symbolsDir := info.symbolsDir.Join(ctx, "system/framework", arch.String())
+ symbolsFile := symbolsDir.Join(ctx, "boot.oat")
+ outputDir := info.dir.Join(ctx, "system/framework", arch.String())
+ outputPath := info.images[arch]
+ oatLocation := pathtools.ReplaceExtension(dexpreopt.PathToLocation(outputPath.String(), arch), "oat")
+
+ rule := android.NewRuleBuilder()
+ rule.MissingDeps(missingDeps)
+
+ rule.Command().Text("mkdir").Flag("-p").Flag(symbolsDir.String())
+ rule.Command().Text("rm").Flag("-f").
+ Flag(symbolsDir.Join(ctx, "*.art").String()).
+ Flag(symbolsDir.Join(ctx, "*.oat").String()).
+ Flag(symbolsDir.Join(ctx, "*.invocation").String())
+ rule.Command().Text("rm").Flag("-f").
+ Flag(outputDir.Join(ctx, "*.art").String()).
+ Flag(outputDir.Join(ctx, "*.oat").String()).
+ Flag(outputDir.Join(ctx, "*.invocation").String())
+
+ cmd := rule.Command()
+
+ extraFlags := ctx.Config().Getenv("ART_BOOT_IMAGE_EXTRA_ARGS")
+ if extraFlags == "" {
+ // Use ANDROID_LOG_TAGS to suppress most logging by default...
+ cmd.Text(`ANDROID_LOG_TAGS="*:e"`)
+ } else {
+ // ...unless the boot image is generated specifically for testing, then allow all logging.
+ cmd.Text(`ANDROID_LOG_TAGS="*:v"`)
+ }
+
+ invocationPath := outputPath.ReplaceExtension(ctx, "invocation")
+
+ cmd.Tool(info.global.Tools.Dex2oat).
+ Flag("--avoid-storing-invocation").
+ FlagWithOutput("--write-invocation-to=", invocationPath.String()).ImplicitOutput(invocationPath.String()).
+ Flag("--runtime-arg").FlagWithArg("-Xms", info.global.Dex2oatImageXms).
+ Flag("--runtime-arg").FlagWithArg("-Xmx", info.global.Dex2oatImageXmx)
+
+ if profile == nil {
+ cmd.FlagWithArg("--image-classes=", info.global.PreloadedClasses)
+ } else {
+ cmd.FlagWithArg("--compiler-filter=", "speed-profile")
+ cmd.FlagWithInput("--profile-file=", profile.String())
+ }
+
+ if info.global.DirtyImageObjects != "" {
+ cmd.FlagWithArg("--dirty-image-objects=", info.global.DirtyImageObjects)
+ }
+
+ cmd.
+ FlagForEachInput("--dex-file=", info.preoptBootDex.Strings()).
+ FlagForEachArg("--dex-location=", info.preoptBootLocations).
+ Flag("--generate-debug-info").
+ Flag("--generate-build-id").
+ FlagWithArg("--oat-symbols=", symbolsFile.String()).
+ Flag("--strip").
+ FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat").String()).
+ FlagWithArg("--oat-location=", oatLocation).
+ FlagWithOutput("--image=", outputPath.String()).
+ FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()).
+ FlagWithArg("--instruction-set=", arch.String()).
+ FlagWithArg("--instruction-set-variant=", info.global.CpuVariant[arch]).
+ FlagWithArg("--instruction-set-features=", info.global.InstructionSetFeatures[arch]).
+ FlagWithArg("--android-root=", info.global.EmptyDirectory).
+ FlagWithArg("--no-inline-from=", "core-oj.jar").
+ Flag("--abort-on-hard-verifier-error")
+
+ if info.global.BootFlags != "" {
+ cmd.Flag(info.global.BootFlags)
+ }
+
+ if extraFlags != "" {
+ cmd.Flag(extraFlags)
+ }
+
+ cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape([]string{failureMessage})[0])
+
+ installDir := filepath.Join("/system/framework", arch.String())
+ vdexInstallDir := filepath.Join("/system/framework")
+
+ var extraFiles android.WritablePaths
+ var vdexInstalls android.RuleBuilderInstalls
+ var unstrippedInstalls android.RuleBuilderInstalls
+
+ // dex preopt on the bootclasspath produces multiple files. The first dex file
+ // is converted into to boot.art (to match the legacy assumption that boot.art
+ // exists), and the rest are converted to boot-<name>.art.
+ // In addition, each .art file has an associated .oat and .vdex file, and an
+ // unstripped .oat file
+ for i, m := range info.preoptBootModules {
+ name := "boot"
+ if i != 0 {
+ name += "-" + m
+ }
+
+ art := outputDir.Join(ctx, name+".art")
+ oat := outputDir.Join(ctx, name+".oat")
+ vdex := outputDir.Join(ctx, name+".vdex")
+ unstrippedOat := symbolsDir.Join(ctx, name+".oat")
+
+ extraFiles = append(extraFiles, art, oat, vdex, unstrippedOat)
+
+ // Install the .oat and .art files.
+ rule.Install(art.String(), filepath.Join(installDir, art.Base()))
+ rule.Install(oat.String(), filepath.Join(installDir, oat.Base()))
+
+ // The vdex files are identical between architectures, install them to a shared location. The Make rules will
+ // only use the install rules for one architecture, and will create symlinks into the architecture-specific
+ // directories.
+ vdexInstalls = append(vdexInstalls,
+ android.RuleBuilderInstall{vdex.String(), filepath.Join(vdexInstallDir, vdex.Base())})
+
+ // Install the unstripped oat files. The Make rules will put these in $(TARGET_OUT_UNSTRIPPED)
+ unstrippedInstalls = append(unstrippedInstalls,
+ android.RuleBuilderInstall{unstrippedOat.String(), filepath.Join(installDir, unstrippedOat.Base())})
+ }
+
+ cmd.ImplicitOutputs(extraFiles.Strings())
+
+ rule.Build(pctx, ctx, "bootJarsDexpreopt_"+arch.String(), "dexpreopt boot jars "+arch.String())
+
+ // save output and installed files for makevars
+ info.installs[arch] = rule.Installs()
+ info.vdexInstalls[arch] = vdexInstalls
+ info.unstrippedInstalls[arch] = unstrippedInstalls
+}
+
+const failureMessage = `ERROR: Dex2oat failed to compile a boot image.
+It is likely that the boot classpath is inconsistent.
+Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
+
+func bootImageProfileRule(ctx android.SingletonContext, info *bootJarsInfo, missingDeps []string) android.WritablePath {
+ if len(info.global.BootImageProfiles) == 0 {
+ return nil
+ }
+
+ tools := info.global.Tools
+
+ rule := android.NewRuleBuilder()
+ rule.MissingDeps(missingDeps)
+
+ var bootImageProfile string
+ if len(info.global.BootImageProfiles) > 1 {
+ combinedBootImageProfile := info.dir.Join(ctx, "boot-image-profile.txt")
+ rule.Command().Text("cat").Inputs(info.global.BootImageProfiles).Output(combinedBootImageProfile.String())
+ bootImageProfile = combinedBootImageProfile.String()
+ } else {
+ bootImageProfile = info.global.BootImageProfiles[0]
+ }
+
+ profile := info.dir.Join(ctx, "boot.prof")
+
+ rule.Command().
+ Text(`ANDROID_LOG_TAGS="*:e"`).
+ Tool(tools.Profman).
+ FlagWithArg("--create-profile-from=", bootImageProfile).
+ FlagForEachInput("--apk=", info.preoptBootDex.Strings()).
+ FlagForEachArg("--dex-location=", info.preoptBootLocations).
+ FlagWithOutput("--reference-profile-file=", profile.String())
+
+ rule.Install(profile.String(), "/system/etc/boot-image.prof")
+
+ rule.Build(pctx, ctx, "bootJarsProfile", "profile boot jars")
+
+ info.profileInstalls = rule.Installs()
+
+ return profile
+}
+
+func init() {
+ android.RegisterMakeVarsProvider(pctx, bootImageMakeVars)
+}
+
+// Export paths to Make. INTERNAL_PLATFORM_HIDDENAPI_FLAGS is used by Make rules in art/ and cts/.
+// Both paths are used to call dist-for-goals.
+func bootImageMakeVars(ctx android.MakeVarsContext) {
+ if skipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ info := dexpreoptBootJarsInfo(ctx)
+ for arch, _ := range info.images {
+ ctx.Strict("DEXPREOPT_IMAGE_"+arch.String(), info.images[arch].String())
+
+ var builtInstalled []string
+ for _, install := range info.installs[arch] {
+ builtInstalled = append(builtInstalled, install.From+":"+install.To)
+ }
+
+ var unstrippedBuiltInstalled []string
+ for _, install := range info.unstrippedInstalls[arch] {
+ unstrippedBuiltInstalled = append(unstrippedBuiltInstalled, install.From+":"+install.To)
+ }
+
+ ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+arch.String(), info.installs[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+arch.String(), info.unstrippedInstalls[arch].String())
+ ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+arch.String(), info.vdexInstalls[arch].String())
+ }
+
+ ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", info.profileInstalls.String())
+
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(info.preoptBootDex.Strings(), " "))
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(info.preoptBootLocations, " "))
+ ctx.Strict("PRODUCT_BOOTCLASSPATH", info.bootclasspath)
+ ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", info.systemServerClasspath)
+}
diff --git a/java/java_test.go b/java/java_test.go
index 034e905..8d3efcb 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -15,7 +15,6 @@
package java
import (
- "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -54,16 +53,7 @@
}
func testConfig(env map[string]string) android.Config {
- if env == nil {
- env = make(map[string]string)
- }
- if env["ANDROID_JAVA8_HOME"] == "" {
- env["ANDROID_JAVA8_HOME"] = "jdk8"
- }
- config := android.TestArchConfig(buildDir, env)
- config.TestProductVariables.DeviceSystemSdkVersions = []string{"14", "15"}
- return config
-
+ return TestConfig(buildDir, env)
}
func testContext(config android.Config, bp string,
@@ -113,53 +103,7 @@
ctx.Register()
- extraModules := []string{
- "core-lambda-stubs",
- "framework",
- "ext",
- "android_stubs_current",
- "android_system_stubs_current",
- "android_test_stubs_current",
- "core.current.stubs",
- "core.platform.api.stubs",
- "kotlin-stdlib",
- "kotlin-annotations",
- }
-
- for _, extra := range extraModules {
- bp += fmt.Sprintf(`
- java_library {
- name: "%s",
- srcs: ["a.java"],
- no_standard_libs: true,
- sdk_version: "core_current",
- system_modules: "core-platform-api-stubs-system-modules",
- }
- `, extra)
- }
-
- bp += `
- android_app {
- name: "framework-res",
- no_framework_libs: true,
- }
- `
-
- systemModules := []string{
- "core-system-modules",
- "core-platform-api-stubs-system-modules",
- "android_stubs_current_system_modules",
- "android_system_stubs_current_system_modules",
- "android_test_stubs_current_system_modules",
- }
-
- for _, extra := range systemModules {
- bp += fmt.Sprintf(`
- java_system_modules {
- name: "%s",
- }
- `, extra)
- }
+ bp += GatherRequiredDepsForTest()
mockFS := map[string][]byte{
"Android.bp": []byte(bp),
diff --git a/java/testing.go b/java/testing.go
new file mode 100644
index 0000000..6febfa1
--- /dev/null
+++ b/java/testing.go
@@ -0,0 +1,88 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "fmt"
+
+ "android/soong/android"
+)
+
+func TestConfig(buildDir string, env map[string]string) android.Config {
+ if env == nil {
+ env = make(map[string]string)
+ }
+ if env["ANDROID_JAVA8_HOME"] == "" {
+ env["ANDROID_JAVA8_HOME"] = "jdk8"
+ }
+ config := android.TestArchConfig(buildDir, env)
+ config.TestProductVariables.DeviceSystemSdkVersions = []string{"14", "15"}
+
+ return config
+}
+
+func GatherRequiredDepsForTest() string {
+ var bp string
+
+ extraModules := []string{
+ "core-lambda-stubs",
+ "framework",
+ "ext",
+ "android_stubs_current",
+ "android_system_stubs_current",
+ "android_test_stubs_current",
+ "core.current.stubs",
+ "core.platform.api.stubs",
+ "kotlin-stdlib",
+ "kotlin-annotations",
+ }
+
+ for _, extra := range extraModules {
+ bp += fmt.Sprintf(`
+ java_library {
+ name: "%s",
+ srcs: ["a.java"],
+ no_standard_libs: true,
+ sdk_version: "core_current",
+ system_modules: "core-platform-api-stubs-system-modules",
+ }
+ `, extra)
+ }
+
+ bp += `
+ android_app {
+ name: "framework-res",
+ no_framework_libs: true,
+ }
+ `
+
+ systemModules := []string{
+ "core-system-modules",
+ "core-platform-api-stubs-system-modules",
+ "android_stubs_current_system_modules",
+ "android_system_stubs_current_system_modules",
+ "android_test_stubs_current_system_modules",
+ }
+
+ for _, extra := range systemModules {
+ bp += fmt.Sprintf(`
+ java_system_modules {
+ name: "%s",
+ }
+ `, extra)
+ }
+
+ return bp
+}
diff --git a/python/binary.go b/python/binary.go
index bf9acb4..140f07a 100644
--- a/python/binary.go
+++ b/python/binary.go
@@ -42,6 +42,11 @@
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
Test_suites []string `android:"arch_variant"`
+
+ // whether to use `main` when starting the executable. The default is true, when set to
+ // false it will act much like the normal `python` executable, but with the sources and
+ // libraries automatically included in the PYTHONPATH.
+ Autorun *bool `android:"arch_variant"`
}
type binaryDecorator struct {
@@ -74,6 +79,10 @@
return module.Init()
}
+func (binary *binaryDecorator) autorun() bool {
+ return BoolDefault(binary.binaryProperties.Autorun, true)
+}
+
func (binary *binaryDecorator) bootstrapperProps() []interface{} {
return []interface{}{&binary.binaryProperties}
}
@@ -82,7 +91,10 @@
embeddedLauncher bool, srcsPathMappings []pathMapping, srcsZip android.Path,
depsSrcsZips android.Paths) android.OptionalPath {
- main := binary.getPyMainFile(ctx, srcsPathMappings)
+ main := ""
+ if binary.autorun() {
+ main = binary.getPyMainFile(ctx, srcsPathMappings)
+ }
var launcherPath android.OptionalPath
if embeddedLauncher {
diff --git a/python/builder.go b/python/builder.go
index e277bfd..e3b490c 100644
--- a/python/builder.go
+++ b/python/builder.go
@@ -54,7 +54,6 @@
embeddedPar = pctx.AndroidStaticRule("embeddedPar",
blueprint.RuleParams{
- // `echo -n` to trim the newline, since the python code just wants the name
Command: `rm -f $out.main && ` +
`sed 's/ENTRY_POINT/$main/' build/soong/python/scripts/main.py >$out.main &&` +
`$mergeParCmd -p -pm $out.main --prefix $launcher $out $srcsZips && ` +
@@ -62,6 +61,14 @@
CommandDeps: []string{"$mergeParCmd", "$parCmd", "build/soong/python/scripts/main.py"},
},
"main", "srcsZips", "launcher")
+
+ embeddedParNoMain = pctx.AndroidStaticRule("embeddedParNoMain",
+ blueprint.RuleParams{
+ Command: `$mergeParCmd -p --prefix $launcher $out $srcsZips && ` +
+ `chmod +x $out`,
+ CommandDeps: []string{"$mergeParCmd"},
+ },
+ "srcsZips", "launcher")
)
func init() {
@@ -107,17 +114,30 @@
// added launcherPath to the implicits Ninja dependencies.
implicits = append(implicits, launcherPath.Path())
- ctx.Build(pctx, android.BuildParams{
- Rule: embeddedPar,
- Description: "embedded python archive",
- Output: binFile,
- Implicits: implicits,
- Args: map[string]string{
- "main": strings.Replace(strings.TrimSuffix(main, pyExt), "/", ".", -1),
- "srcsZips": strings.Join(srcsZips.Strings(), " "),
- "launcher": launcherPath.String(),
- },
- })
+ if main == "" {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: embeddedParNoMain,
+ Description: "embedded python archive",
+ Output: binFile,
+ Implicits: implicits,
+ Args: map[string]string{
+ "srcsZips": strings.Join(srcsZips.Strings(), " "),
+ "launcher": launcherPath.String(),
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: embeddedPar,
+ Description: "embedded python archive",
+ Output: binFile,
+ Implicits: implicits,
+ Args: map[string]string{
+ "main": strings.Replace(strings.TrimSuffix(main, pyExt), "/", ".", -1),
+ "srcsZips": strings.Join(srcsZips.Strings(), " "),
+ "launcher": launcherPath.String(),
+ },
+ })
+ }
}
return binFile
diff --git a/python/python.go b/python/python.go
index ddc3f1f..4445f40 100644
--- a/python/python.go
+++ b/python/python.go
@@ -156,6 +156,8 @@
bootstrap(ctx android.ModuleContext, ActualVersion string, embeddedLauncher bool,
srcsPathMappings []pathMapping, srcsZip android.Path,
depsSrcsZips android.Paths) android.OptionalPath
+
+ autorun() bool
}
type installer interface {
@@ -307,9 +309,14 @@
if p.bootstrapper != nil && p.isEmbeddedLauncherEnabled(pyVersion2) {
ctx.AddVariationDependencies(nil, pythonLibTag, "py2-stdlib")
+
+ launcherModule := "py2-launcher"
+ if p.bootstrapper.autorun() {
+ launcherModule = "py2-launcher-autorun"
+ }
ctx.AddFarVariationDependencies([]blueprint.Variation{
{Mutator: "arch", Variation: ctx.Target().String()},
- }, launcherTag, "py2-launcher")
+ }, launcherTag, launcherModule)
// Add py2-launcher shared lib dependencies. Ideally, these should be
// derived from the `shared_libs` property of "py2-launcher". However, we
@@ -422,7 +429,11 @@
p.properties.Actual_version, ctx.ModuleName()))
}
expandedSrcs := ctx.ExpandSources(srcs, exclude_srcs)
- if len(expandedSrcs) == 0 {
+ requiresSrcs := true
+ if p.bootstrapper != nil && !p.bootstrapper.autorun() {
+ requiresSrcs = false
+ }
+ if len(expandedSrcs) == 0 && requiresSrcs {
ctx.ModuleErrorf("doesn't have any source files!")
}
@@ -656,4 +667,5 @@
}
var Bool = proptools.Bool
+var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 92e0af4..745e424 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -19,7 +19,6 @@
"android/soong/cc"
"android/soong/java"
- "fmt"
"io/ioutil"
"os"
"strings"
@@ -90,54 +89,7 @@
ctx.Register()
- extraModules := []string{
- "core-lambda-stubs",
- "framework",
- "ext",
- "updatable_media_stubs",
-
- "android_stubs_current",
- "android_system_stubs_current",
- "android_test_stubs_current",
- "core.current.stubs",
- "core.platform.api.stubs",
- }
-
- for _, extra := range extraModules {
- bp += fmt.Sprintf(`
- java_library {
- name: "%s",
- srcs: ["a.java"],
- no_standard_libs: true,
- sdk_version: "core_current",
- system_modules: "core-platform-api-stubs-system-modules",
- }
- `, extra)
- }
-
- bp += `
- android_app {
- name: "framework-res",
- no_framework_libs: true,
- }
- `
-
- systemModules := []string{
- "core-system-modules",
- "core-platform-api-stubs-system-modules",
- "android_stubs_current_system_modules",
- "android_system_stubs_current_system_modules",
- "android_test_stubs_current_system_modules",
- }
-
- for _, extra := range systemModules {
- bp += fmt.Sprintf(`
- java_system_modules {
- name: "%s",
- }
- `, extra)
- }
-
+ bp += java.GatherRequiredDepsForTest()
bp += cc.GatherRequiredDepsForTest(android.Android)
mockFS := map[string][]byte{
@@ -224,16 +176,12 @@
}
func testConfig(env map[string]string) android.Config {
- if env == nil {
- env = make(map[string]string)
- }
- if env["ANDROID_JAVA8_HOME"] == "" {
- env["ANDROID_JAVA8_HOME"] = "jdk8"
- }
- config := android.TestArchConfig(buildDir, env)
+ config := java.TestConfig(buildDir, env)
+
config.TestProductVariables.DeviceSystemSdkVersions = []string{"28"}
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
+
return config
}