Merge changes I059e639b,I4ebe1da8,Idf4fd37a,Id90082b5
* changes:
Do not disable llndk libraries
Create only one vendor variant depending on path
Implement cc_object vendor snapshot
Refine logic choosing vendor snapshot modules
diff --git a/OWNERS b/OWNERS
index e1db459..adf2b4c 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,10 @@
-per-file * = asmundak@google.com,ccross@android.com,dwillemsen@google.com,jungjw@google.com,paulduffin@google.com
+per-file * = asmundak@google.com
+per-file * = ccross@android.com
+per-file * = dwillemsen@google.com
+per-file * = eakammer@google.com
+per-file * = jungjw@google.com
+per-file * = patricearruda@google.com
+per-file * = paulduffin@google.com
per-file ndk_*.go, *gen_stub_libs.py = danalbert@google.com
per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 9321ad2..1b3a4ba 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -81,7 +81,7 @@
seenDataOutPaths := make(map[string]bool)
for _, fi := range a.filesInfo {
- if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
+ if ccMod, ok := fi.module.(*cc.Module); ok && ccMod.Properties.HideFromMake {
continue
}
@@ -178,7 +178,8 @@
if fi.jacocoReportClassesFile != nil {
fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", fi.jacocoReportClassesFile.String())
}
- if fi.class == javaSharedLib {
+ switch fi.class {
+ case javaSharedLib:
javaModule := fi.module.(java.Dependency)
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
@@ -189,7 +190,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
- } else if fi.class == app {
+ case app:
fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", fi.certificate.AndroidMkString())
// soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
@@ -199,19 +200,26 @@
fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", strings.Join(app.JniCoverageOutputs().Strings(), " "))
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
- } else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
+ case appSet:
+ as, ok := fi.module.(*java.AndroidAppSet)
+ if !ok {
+ panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module))
+ }
+ fmt.Fprintln(w, "LOCAL_APK_SET_MASTER_FILE :=", as.MasterFile())
+ fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk")
+ case nativeSharedLib, nativeExecutable, nativeTest:
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
- if cc, ok := fi.module.(*cc.Module); ok {
- if cc.UnstrippedOutputFile() != nil {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", cc.UnstrippedOutputFile().String())
+ if ccMod, ok := fi.module.(*cc.Module); ok {
+ if ccMod.UnstrippedOutputFile() != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", ccMod.UnstrippedOutputFile().String())
}
- cc.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
- if cc.CoverageOutputFile().Valid() {
- fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", cc.CoverageOutputFile().String())
+ ccMod.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
+ if ccMod.CoverageOutputFile().Valid() {
+ fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", ccMod.CoverageOutputFile().String())
}
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
- } else {
+ default:
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
if fi.builtFile == a.manifestPbOut && apexType == flattenedApex {
if a.primaryApexType {
diff --git a/apex/apex.go b/apex/apex.go
index b9fc4e1..2f7b2e5 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1115,6 +1115,7 @@
javaSharedLib
nativeTest
app
+ appSet
)
func (class apexFileClass) NameInMake() string {
@@ -1129,7 +1130,7 @@
return "JAVA_LIBRARIES"
case nativeTest:
return "NATIVE_TESTS"
- case app:
+ case app, appSet:
// b/142537672 Why isn't this APP? We want to have full control over
// the paths and file names of the apk file under the flattend APEX.
// If this is set to APP, then the paths and file names are modified
@@ -1998,6 +1999,15 @@
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
+ } else if ap, ok := child.(*java.AndroidAppSet); ok {
+ appDir := "app"
+ if ap.Privileged() {
+ appDir = "priv-app"
+ }
+ af := newApexFile(ctx, ap.OutputFile(), ap.Name(),
+ filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
+ af.certificate = java.PresignedCertificate
+ filesInfo = append(filesInfo, af)
} else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e45cd00..d6a5d09 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -96,7 +96,7 @@
// - X86 (secondary)
// - Arm64 on X86_64 (native bridge)
// - Arm on X86 (native bridge)
-func withNativeBridgeEnabled(fs map[string][]byte, config android.Config) {
+func withNativeBridgeEnabled(_ map[string][]byte, config android.Config) {
config.Targets[android.Android] = []android.Target{
{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}},
NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
@@ -115,15 +115,15 @@
}
}
-func withBinder32bit(fs map[string][]byte, config android.Config) {
+func withBinder32bit(_ map[string][]byte, config android.Config) {
config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
}
-func withUnbundledBuild(fs map[string][]byte, config android.Config) {
+func withUnbundledBuild(_ map[string][]byte, config android.Config) {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
}
-func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
android.ClearApexDependency()
bp = bp + `
@@ -187,6 +187,7 @@
"baz": nil,
"bar/baz": nil,
"testdata/baz": nil,
+ "AppSet.apks": nil,
}
cc.GatherRequiredFilesForTest(fs)
@@ -258,7 +259,7 @@
}
func tearDown() {
- os.RemoveAll(buildDir)
+ _ = os.RemoveAll(buildDir)
}
// ensure that 'result' equals 'expected'
@@ -294,6 +295,17 @@
}
}
+func ensureMatches(t *testing.T, result string, expectedRex string) {
+ ok, err := regexp.MatchString(expectedRex, result)
+ if err != nil {
+ t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
+ return
+ }
+ if !ok {
+ t.Errorf("%s does not match regular expession %s", result, expectedRex)
+ }
+}
+
func ensureListContains(t *testing.T, result []string, expected string) {
t.Helper()
if !android.InList(expected, result) {
@@ -4772,6 +4784,38 @@
ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
}
+func TestAppSetBundle(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apps: ["AppSet"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ android_app_set {
+ name: "AppSet",
+ set: "AppSet.apks",
+ }`)
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ bundleConfigRule := mod.Description("Bundle Config")
+ content := bundleConfigRule.Args["content"]
+ ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
+ s := mod.Rule("apexRule").Args["copy_commands"]
+ copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
+ if len(copyCmds) != 3 {
+ t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
+ }
+ ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
+ ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
+ ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
+}
+
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
t.Helper()
@@ -4931,7 +4975,7 @@
func TestNoUpdatableJarsInBootImage(t *testing.T) {
- var error string
+ var err string
var transform func(*dexpreopt.GlobalConfig)
t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
@@ -4942,35 +4986,35 @@
})
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
- error = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
+ err = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"com.android.art.something:some-art-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
+ err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
+ err = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
- error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
+ err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
@@ -4981,27 +5025,27 @@
})
t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
- error = "failed to find a dex jar path for module 'nonexistent'"
+ err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"platform:nonexistent"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
- error = "failed to find a dex jar path for module 'nonexistent'"
+ err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"platform:nonexistent"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-platform-lib' is not allowed in the ART boot image"
+ err = "module 'some-platform-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"platform:some-platform-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 0108d06..17eac1a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -69,11 +69,14 @@
// by default set to (uid/gid/mode) = (1000/1000/0644)
// TODO(b/113082813) make this configurable using config.fs syntax
generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{
- Command: `echo '/ 1000 1000 0755' > ${out} && ` +
- `echo ${ro_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0644"}' >> ${out} && ` +
- `echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 0 2000 0755"}' >> ${out}`,
- Description: "fs_config ${out}",
- }, "ro_paths", "exec_paths")
+ Command: `( echo '/ 1000 1000 0755' ` +
+ `&& for i in ${ro_paths}; do echo "/$$i 1000 1000 0644"; done ` +
+ `&& for i in ${exec_paths}; do echo "/$$i 0 2000 0755"; done ` +
+ `&& ( tr ' ' '\n' <${out}.apklist | for i in ${apk_paths}; do read apk; echo "/$$i 0 2000 0755"; zipinfo -1 $$apk | sed "s:\(.*\):/$$i/\1 1000 1000 0644:"; done ) ) > ${out}`,
+ Description: "fs_config ${out}",
+ Rspfile: "$out.apklist",
+ RspfileContent: "$in",
+ }, "ro_paths", "exec_paths", "apk_paths")
apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
Command: `rm -f $out && ${jsonmodify} $in ` +
@@ -287,7 +290,7 @@
// collect the manifest names and paths of android apps
// if their manifest names are overridden
for _, fi := range a.filesInfo {
- if fi.class != app {
+ if fi.class != app && fi.class != appSet {
continue
}
packageName := fi.overriddenPackageName
@@ -337,13 +340,22 @@
var copyCommands []string
for _, fi := range a.filesInfo {
destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.Path()).String()
- copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(destPath))
+ destPathDir := filepath.Dir(destPath)
+ if fi.class == appSet {
+ copyCommands = append(copyCommands, "rm -rf "+destPathDir)
+ }
+ copyCommands = append(copyCommands, "mkdir -p "+destPathDir)
if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() {
// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
pathOnDevice := filepath.Join("/system", fi.Path())
copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
} else {
- copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
+ if fi.class == appSet {
+ copyCommands = append(copyCommands,
+ fmt.Sprintf("unzip -q -d %s %s", destPathDir, fi.builtFile.String()))
+ } else {
+ copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
+ }
implicitInputs = append(implicitInputs, fi.builtFile)
}
// create additional symlinks pointing the file inside the APEX
@@ -416,6 +428,8 @@
// files and dirs that will be created in APEX
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
+ var extractedAppSetPaths android.Paths
+ var extractedAppSetDirs []string
for _, f := range a.filesInfo {
pathInApex := f.Path()
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
@@ -426,6 +440,9 @@
for _, s := range f.symlinks {
executablePaths = append(executablePaths, filepath.Join(f.installDir, s))
}
+ } else if f.class == appSet {
+ extractedAppSetPaths = append(extractedAppSetPaths, f.builtFile)
+ extractedAppSetDirs = append(extractedAppSetDirs, f.installDir)
} else {
readOnlyPaths = append(readOnlyPaths, pathInApex)
}
@@ -446,9 +463,11 @@
Rule: generateFsConfig,
Output: cannedFsConfig,
Description: "generate fs config",
+ Inputs: extractedAppSetPaths,
Args: map[string]string{
"ro_paths": strings.Join(readOnlyPaths, " "),
"exec_paths": strings.Join(executablePaths, " "),
+ "apk_paths": strings.Join(extractedAppSetDirs, " "),
},
})
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 0148161..3440f8e 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -100,6 +100,15 @@
ConstructContext android.Path
}
+// LibraryPath contains paths to the library DEX jar on host and on device.
+type LibraryPath struct {
+ Host android.Path
+ Device string
+}
+
+// LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar.
+type LibraryPaths map[string]*LibraryPath
+
type ModuleConfig struct {
Name string
DexLocation string // dex location on device
@@ -117,7 +126,7 @@
EnforceUsesLibraries bool
PresentOptionalUsesLibraries []string
UsesLibraries []string
- LibraryPaths map[string]android.Path
+ LibraryPaths LibraryPaths
Archs []android.ArchType
DexPreoptImages []android.Path
@@ -165,14 +174,6 @@
return ret
}
-func constructPathMap(ctx android.PathContext, paths map[string]string) map[string]android.Path {
- ret := map[string]android.Path{}
- for key, path := range paths {
- ret[key] = constructPath(ctx, path)
- }
- return ret
-}
-
func constructWritablePath(ctx android.PathContext, path string) android.WritablePath {
if path == "" {
return nil
@@ -264,6 +265,13 @@
// from Make to read the module dexpreopt.config written in the Make config
// stage.
func ParseModuleConfig(ctx android.PathContext, data []byte) (*ModuleConfig, error) {
+ type jsonLibraryPath struct {
+ Host string
+ Device string
+ }
+
+ type jsonLibraryPaths map[string]jsonLibraryPath
+
type ModuleJSONConfig struct {
*ModuleConfig
@@ -273,12 +281,24 @@
DexPath string
ManifestPath string
ProfileClassListing string
- LibraryPaths map[string]string
+ LibraryPaths jsonLibraryPaths
DexPreoptImages []string
DexPreoptImageLocations []string
PreoptBootClassPathDexFiles []string
}
+ // convert JSON map of library paths to LibraryPaths
+ constructLibraryPaths := func(ctx android.PathContext, paths jsonLibraryPaths) LibraryPaths {
+ m := LibraryPaths{}
+ for lib, path := range paths {
+ m[lib] = &LibraryPath{
+ constructPath(ctx, path.Host),
+ path.Device,
+ }
+ }
+ return m
+ }
+
config := ModuleJSONConfig{}
err := json.Unmarshal(data, &config)
@@ -291,7 +311,7 @@
config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath)
config.ModuleConfig.ManifestPath = constructPath(ctx, config.ManifestPath)
config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
- config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
+ config.ModuleConfig.LibraryPaths = constructLibraryPaths(ctx, config.LibraryPaths)
config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 8e65ca6..57a9250 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -229,8 +229,9 @@
func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) {
clc := m.getValue(sdkVer)
for _, lib := range libs {
- clc.Host = append(clc.Host, pathForLibrary(module, lib))
- clc.Target = append(clc.Target, filepath.Join("/system/framework", lib+".jar"))
+ p := pathForLibrary(module, lib)
+ clc.Host = append(clc.Host, p.Host)
+ clc.Target = append(clc.Target, p.Device)
}
}
@@ -557,7 +558,7 @@
return filepath.Join(filepath.Dir(filepath.Dir(path.String())), filepath.Base(path.String()))
}
-func pathForLibrary(module *ModuleConfig, lib string) android.Path {
+func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath {
path, ok := module.LibraryPaths[lib]
if !ok {
panic(fmt.Errorf("unknown library path for %q", lib))
diff --git a/java/app.go b/java/app.go
index fb02c99..5f36e85 100755
--- a/java/app.go
+++ b/java/app.go
@@ -28,6 +28,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/dexpreopt"
"android/soong/tradefed"
)
@@ -96,6 +97,14 @@
return Bool(as.properties.Privileged)
}
+func (as *AndroidAppSet) OutputFile() android.Path {
+ return as.packedOutput
+}
+
+func (as *AndroidAppSet) MasterFile() string {
+ return as.masterFile
+}
+
var TargetCpuAbi = map[string]string{
"arm": "ARMEABI_V7A",
"arm64": "ARM64_V8A",
@@ -120,7 +129,7 @@
}
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- as.packedOutput = android.PathForModuleOut(ctx, "extracted.zip")
+ as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
// We are assuming here that the master file in the APK
// set has `.apk` suffix. If it doesn't the build will fail.
// APK sets containing APEX files are handled elsewhere.
@@ -145,26 +154,17 @@
"stem": ctx.ModuleName(),
},
})
- // TODO(asmundak): add this (it's wrong now, will cause copying extracted.zip)
- /*
- var installDir android.InstallPath
- if Bool(as.properties.Privileged) {
- installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
- } else if ctx.InstallInTestcases() {
- installDir = android.PathForModuleInstall(ctx, as.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
- } else {
- installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
- }
- ctx.InstallFile(installDir, as.masterFile", as.packedOutput)
- */
}
// android_app_set extracts a set of APKs based on the target device
// configuration and installs this set as "split APKs".
-// The set will always contain `base-master.apk` and every APK built
-// to the target device. All density-specific APK will be included, too,
-// unless PRODUCT_APPT_PREBUILT_DPI is defined (should contain comma-sepearated
-// list of density names (LDPI, MDPI, HDPI, etc.)
+// The extracted set always contains 'master' APK whose name is
+// _module_name_.apk and every split APK matching target device.
+// The extraction of the density-specific splits depends on
+// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
+// be a list density names: LDPI, MDPI, HDPI, etc.), only listed
+// splits will be extracted. Otherwise all density-specific splits
+// will be extracted.
func AndroidApkSetFactory() android.Module {
module := &AndroidAppSet{}
module.AddProperties(&module.properties)
@@ -335,7 +335,7 @@
presigned bool
}
-var presignedCertificate = Certificate{presigned: true}
+var PresignedCertificate = Certificate{presigned: true}
func (c Certificate) AndroidMkString() string {
if c.presigned {
@@ -1186,7 +1186,7 @@
android.OverrideModuleBase
}
-func (i *OverrideAndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1207,7 +1207,7 @@
android.OverrideModuleBase
}
-func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1229,7 +1229,7 @@
android.OverrideModuleBase
}
-func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1474,7 +1474,7 @@
// Sign or align the package if package has not been preprocessed
if a.preprocessed {
a.outputFile = srcApk
- a.certificate = presignedCertificate
+ a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
@@ -1494,7 +1494,7 @@
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
TransformZipAlign(ctx, alignedApk, dexOutput)
a.outputFile = alignedApk
- a.certificate = presignedCertificate
+ a.certificate = PresignedCertificate
}
// TODO: Optionally compress the output apk.
@@ -1552,7 +1552,7 @@
return Bool(a.properties.Privileged)
}
-func (a *AndroidAppImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
// android_app_import might have extra dependencies via uses_libs property.
// Don't track the dependency as we don't automatically add those libraries
// to the classpath. It should be explicitly added to java_libs property of APEX
@@ -1875,24 +1875,30 @@
return optionalUsesLibs
}
-// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
-func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
- usesLibPaths := make(map[string]android.Path)
+// usesLibraryPaths returns a map of module names of shared library dependencies to the paths
+// to their dex jars on host and on device.
+func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) dexpreopt.LibraryPaths {
+ usesLibPaths := make(dexpreopt.LibraryPaths)
if !ctx.Config().UnbundledBuild() {
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
+ dep := ctx.OtherModuleName(m)
if lib, ok := m.(Dependency); ok {
if dexJar := lib.DexJarBuildPath(); dexJar != nil {
- usesLibPaths[ctx.OtherModuleName(m)] = dexJar
+ usesLibPaths[dep] = &dexpreopt.LibraryPath{
+ dexJar,
+ // TODO(b/132357300): propagate actual install paths here.
+ filepath.Join("/system/framework", dep+".jar"),
+ }
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
- ctx.OtherModuleName(m))
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must"+
+ " produce a dex jar, does it have installable: true?", dep)
}
} else if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
+ ctx.AddMissingDependencies([]string{dep})
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
- ctx.OtherModuleName(m))
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be "+
+ "a java library", dep)
}
})
}
diff --git a/java/app_test.go b/java/app_test.go
index eb583be..eeba161 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -149,7 +149,7 @@
prerelease: true,
}`)
module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "extracted.zip"
+ const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
if params.Rule == nil {
t.Errorf("expected output %s is missing", packedSplitApks)
@@ -218,7 +218,7 @@
ctx := testContext()
run(t, ctx, config)
module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "extracted.zip"
+ const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
for k, v := range test.expected {
if actual := params.Args[k]; actual != v {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 4725b07..2911fd9 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -37,7 +37,7 @@
usesLibs []string
optionalUsesLibs []string
enforceUsesLibs bool
- libraryPaths map[string]android.Path
+ libraryPaths dexpreopt.LibraryPaths
builtInstalled string
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index b16c9cd..d61c62c 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1334,13 +1334,10 @@
d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
- if len(d.properties.Merge_annotations_dirs) == 0 {
- ctx.PropertyErrorf("merge_annotations_dirs",
- "has to be non-empty if annotations was enabled!")
+ if len(d.properties.Merge_annotations_dirs) != 0 {
+ d.mergeAnnoDirFlags(ctx, cmd)
}
- d.mergeAnnoDirFlags(ctx, cmd)
-
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
FlagWithArg("--hide ", "SuperfluousPrefix").
diff --git a/java/java.go b/java/java.go
index 368dcc6..0ba1f5a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -836,41 +836,46 @@
}
func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
- ver := m.sdkVersion()
- switch {
- case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
- name == "stub-annotations" || name == "private-stub-annotations-jar" ||
- name == "core-lambda-stubs" || name == "core-generated-annotation-stubs":
+ switch name {
+ case "core.current.stubs", "core.platform.api.stubs", "stub-annotations",
+ "private-stub-annotations-jar", "core-lambda-stubs", "core-generated-annotation-stubs":
return javaCore, true
- case ver.kind == sdkCore:
- return javaCore, false
- case name == "android_system_stubs_current":
- return javaSystem, true
- case ver.kind == sdkSystem:
- return javaSystem, false
- case name == "android_test_stubs_current":
- return javaSystem, true
- case ver.kind == sdkTest:
- return javaPlatform, false
- case name == "android_stubs_current":
+ case "android_stubs_current":
return javaSdk, true
- case ver.kind == sdkPublic:
- return javaSdk, false
- case name == "android_module_lib_stubs_current":
+ case "android_system_stubs_current":
+ return javaSystem, true
+ case "android_module_lib_stubs_current":
return javaModule, true
- case ver.kind == sdkModule:
- return javaModule, false
- case name == "android_system_server_stubs_current":
+ case "android_system_server_stubs_current":
return javaSystemServer, true
- case ver.kind == sdkSystemServer:
- return javaSystemServer, false
- case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
- return javaPlatform, false
- case !ver.valid():
- panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
- default:
- return javaSdk, false
+ case "android_test_stubs_current":
+ return javaSystem, true
}
+
+ if stub, linkType := moduleStubLinkType(name); stub {
+ return linkType, true
+ }
+
+ ver := m.sdkVersion()
+ switch ver.kind {
+ case sdkCore:
+ return javaCore, false
+ case sdkSystem:
+ return javaSystem, false
+ case sdkPublic:
+ return javaSdk, false
+ case sdkModule:
+ return javaModule, false
+ case sdkSystemServer:
+ return javaSystemServer, false
+ case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest:
+ return javaPlatform, false
+ }
+
+ if !ver.valid() {
+ panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
+ }
+ return javaSdk, false
}
func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) {
diff --git a/java/sdk.go b/java/sdk.go
index 9310f78..2a08f32 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -35,6 +35,7 @@
var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
+var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
type sdkContext interface {
@@ -447,7 +448,7 @@
return toModule([]string{"core.current.stubs"}, "", nil)
case sdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", nonUpdatableFrameworkAidlPath(ctx))
case sdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
return toModule([]string{"android_system_server_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
@@ -506,6 +507,7 @@
}
createSdkFrameworkAidl(ctx)
+ createNonUpdatableFrameworkAidl(ctx)
createAPIFingerprint(ctx)
}
@@ -517,6 +519,31 @@
"android_system_stubs_current",
}
+ combinedAidl := sdkFrameworkAidlPath(ctx)
+ tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+ rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+ commitChangeForRestat(rule, tempPath, combinedAidl)
+
+ rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+}
+
+// Creates a version of framework.aidl for the non-updatable part of the platform.
+func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
+ stubsModules := []string{"android_module_lib_stubs_current"}
+
+ combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
+ tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+ rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+ commitChangeForRestat(rule, tempPath, combinedAidl)
+
+ rule.Build(pctx, ctx, "framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
+}
+
+func createFrameworkAidl(stubsModules []string, path android.OutputPath, ctx android.SingletonContext) *android.RuleBuilder {
stubsJars := make([]android.Paths, len(stubsModules))
ctx.VisitAllModules(func(module android.Module) {
@@ -536,8 +563,7 @@
if ctx.Config().AllowMissingDependencies() {
missingDeps = append(missingDeps, stubsModules[i])
} else {
- ctx.Errorf("failed to find dex jar path for module %q",
- stubsModules[i])
+ ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
}
}
}
@@ -561,20 +587,15 @@
}
}
- combinedAidl := sdkFrameworkAidlPath(ctx)
- tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
-
rule.Command().
- Text("rm -f").Output(tempPath)
+ Text("rm -f").Output(path)
rule.Command().
Text("cat").
Inputs(aidls).
Text("| sort -u >").
- Output(tempPath)
+ Output(path)
- commitChangeForRestat(rule, tempPath, combinedAidl)
-
- rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+ return rule
}
func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
@@ -583,6 +604,12 @@
}).(android.OutputPath)
}
+func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
+ return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
+ return android.PathForOutput(ctx, "framework_non_updatable.aidl")
+ }).(android.OutputPath)
+}
+
// Create api_fingerprint.txt
func createAPIFingerprint(ctx android.SingletonContext) {
out := ApiFingerprintPath(ctx)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 67b0bd6..de5ee03 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1113,7 +1113,9 @@
props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
- props.Java_version = module.properties.Java_version
+ // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
+ // interop with older developer tools that don't support 1.9.
+ props.Java_version = proptools.StringPtr("1.8")
if module.deviceProperties.Compile_dex != nil {
props.Compile_dex = module.deviceProperties.Compile_dex
}
@@ -1575,6 +1577,24 @@
var _ sdkLibraryComponentNamingScheme = (*frameworkModulesNamingScheme)(nil)
+func moduleStubLinkType(name string) (stub bool, ret linkType) {
+ // This suffix-based approach is fragile and could potentially mis-trigger.
+ // TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
+ if strings.HasSuffix(name, ".stubs.public") || strings.HasSuffix(name, "-stubs-publicapi") {
+ return true, javaSdk
+ }
+ if strings.HasSuffix(name, ".stubs.system") || strings.HasSuffix(name, "-stubs-systemapi") {
+ return true, javaSystem
+ }
+ if strings.HasSuffix(name, ".stubs.module_lib") || strings.HasSuffix(name, "-stubs-module_libs_api") {
+ return true, javaModule
+ }
+ if strings.HasSuffix(name, ".stubs.test") {
+ return true, javaSystem
+ }
+ return false, javaPlatform
+}
+
// java_sdk_library is a special Java library that provides optional platform APIs to apps.
// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
// are linked against to, 2) droiddoc module that internally generates API stubs source files,
diff --git a/java/sdk_test.go b/java/sdk_test.go
index fb86463..52d2df5 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -252,7 +252,7 @@
bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
system: "core-current-stubs-system-modules",
java9classpath: []string{"android_module_lib_stubs_current"},
- aidl: "-p" + buildDir + "/framework.aidl",
+ aidl: "-p" + buildDir + "/framework_non_updatable.aidl",
},
{
name: "system_server_current",
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index a559330..7dc4915 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -54,18 +54,16 @@
var ret map[string]string
if len(makeVars) > 0 {
+ // It's not safe to use the same TMPDIR as the build, as that can be removed.
tmpDir, err := ioutil.TempDir("", "dumpvars")
if err != nil {
return nil, err
}
defer os.RemoveAll(tmpDir)
- // It's not safe to use the same TMPDIR as the build, as that can be removed.
- config.Environment().Set("TMPDIR", tmpDir)
+ SetupLitePath(ctx, config, tmpDir)
- SetupLitePath(ctx, config)
-
- ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
+ ret, err = dumpMakeVars(ctx, config, goals, makeVars, false, tmpDir)
if err != nil {
return ret, err
}
@@ -82,7 +80,7 @@
return ret, nil
}
-func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
+func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool, tmpDir string) (map[string]string, error) {
ctx.BeginTrace(metrics.RunKati, "dumpvars")
defer ctx.EndTrace()
@@ -98,6 +96,9 @@
cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
}
cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
+ if tmpDir != "" {
+ cmd.Environment.Set("TMPDIR", tmpDir)
+ }
cmd.Sandbox = dumpvarsSandbox
output := bytes.Buffer{}
cmd.Stdout = &output
@@ -253,7 +254,7 @@
"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
}, exportEnvVars...), BannerVars...)
- make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
+ make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "")
if err != nil {
ctx.Fatalln("Error dumping make vars:", err)
}
diff --git a/ui/build/path.go b/ui/build/path.go
index 7122927..6f5cf78 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -55,8 +55,9 @@
}
// A "lite" version of SetupPath used for dumpvars, or other places that need
-// minimal overhead (but at the expense of logging).
-func SetupLitePath(ctx Context, config Config) {
+// minimal overhead (but at the expense of logging). If tmpDir is empty, the
+// default TMPDIR is used from config.
+func SetupLitePath(ctx Context, config Config, tmpDir string) {
if config.pathReplaced {
return
}
@@ -65,8 +66,11 @@
defer ctx.EndTrace()
origPath, _ := config.Environment().Get("PATH")
- myPath, _ := config.Environment().Get("TMPDIR")
- myPath = filepath.Join(myPath, "path")
+
+ if tmpDir == "" {
+ tmpDir, _ = config.Environment().Get("TMPDIR")
+ }
+ myPath := filepath.Join(tmpDir, "path")
ensureEmptyDirectoriesExist(ctx, myPath)
os.Setenv("PATH", origPath)