Merge changes Ie274263a,I45993324
* changes:
Adds droidstubs support to sdk module
Simplify building an SDK snapshot from the command line
diff --git a/android/makevars.go b/android/makevars.go
index c011ea6..38a028c 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -80,6 +80,12 @@
// Eval().
StrictRaw(name, value string)
CheckRaw(name, value string)
+
+ // GlobWithDeps returns a list of files that match the specified pattern but do not match any
+ // of the patterns in excludes. It also adds efficient dependencies to rerun the primary
+ // builder whenever a file matching the pattern as added or removed, without rerunning if a
+ // file that does not match the pattern is added to a searched directory.
+ GlobWithDeps(pattern string, excludes []string) ([]string, error)
}
var _ PathContext = MakeVarsContext(nil)
diff --git a/android/module.go b/android/module.go
index fa6388c..891babc 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1771,7 +1771,7 @@
}
// A module that implements OutputFileProducer can be referenced from any property that is tagged with `android:"path"`
-// using the ":module" syntax or ":module{.tag}" syntax and provides a list of otuput files to be used as if they were
+// using the ":module" syntax or ":module{.tag}" syntax and provides a list of output files to be used as if they were
// listed in the property.
type OutputFileProducer interface {
OutputFiles(tag string) (Paths, error)
diff --git a/apex/apex.go b/apex/apex.go
index 4dfbdb4..d7f6d53 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path"
"path/filepath"
"sort"
"strings"
@@ -118,16 +119,11 @@
func apexMutator(mctx android.BottomUpMutatorContext) {
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
am.CreateApexVariations(mctx)
- } else if a, ok := mctx.Module().(*apexBundle); ok {
+ } else if _, ok := mctx.Module().(*apexBundle); ok {
// apex bundle itself is mutated so that it and its modules have same
// apex variant.
apexBundleName := mctx.ModuleName()
mctx.CreateVariations(apexBundleName)
-
- // collects APEX list
- if mctx.Device() && a.installable() {
- addApexFileContextsInfos(mctx, a)
- }
} else if o, ok := mctx.Module().(*OverrideApex); ok {
apexBundleName := o.GetOverriddenModuleName()
if apexBundleName == "" {
@@ -150,14 +146,11 @@
}).(*[]string)
}
-func addApexFileContextsInfos(ctx android.BaseModuleContext, a *apexBundle) {
- apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
- fileContextsName := proptools.StringDefault(a.properties.File_contexts, ctx.ModuleName())
-
+func addFlattenedFileContextsInfos(ctx android.BaseModuleContext, fileContextsInfo string) {
apexFileContextsInfosMutex.Lock()
defer apexFileContextsInfosMutex.Unlock()
apexFileContextsInfos := apexFileContextsInfos(ctx.Config())
- *apexFileContextsInfos = append(*apexFileContextsInfos, apexName+":"+fileContextsName)
+ *apexFileContextsInfos = append(*apexFileContextsInfos, fileContextsInfo)
}
func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
@@ -272,10 +265,9 @@
Apex_name *string
// Determines the file contexts file for setting security context to each file in this APEX bundle.
- // Specifically, when this is set to <value>, /system/sepolicy/apex/<value>_file_contexts file is
- // used.
- // Default: <name_of_this_module>
- File_contexts *string
+ // For platform APEXes, this should points to a file under /system/sepolicy
+ // Default: /system/sepolicy/apex/<module_name>_file_contexts.
+ File_contexts *string `android:"path"`
// List of native shared libs that are embedded inside this APEX bundle
Native_shared_libs []string
@@ -481,6 +473,8 @@
container_certificate_file android.Path
container_private_key_file android.Path
+ fileContexts android.Path
+
// list of files to be included in this apex
filesInfo []apexFile
@@ -1168,12 +1162,29 @@
// prepend the name of this APEX to the module names. These names will be the names of
// modules that will be defined if the APEX is flattened.
for i := range filesInfo {
- filesInfo[i].moduleName = filesInfo[i].moduleName + "." + ctx.ModuleName() + a.suffix
+ filesInfo[i].moduleName = filesInfo[i].moduleName + "." + a.Name() + a.suffix
}
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = filesInfo
+ if a.properties.ApexType != zipApex {
+ if a.properties.File_contexts == nil {
+ a.fileContexts = android.PathForSource(ctx, "system/sepolicy/apex", ctx.ModuleName()+"-file_contexts")
+ } else {
+ a.fileContexts = android.PathForModuleSrc(ctx, *a.properties.File_contexts)
+ if a.Platform() {
+ if matched, err := path.Match("system/sepolicy/**/*", a.fileContexts.String()); err != nil || !matched {
+ ctx.PropertyErrorf("file_contexts", "should be under system/sepolicy, but %q", a.fileContexts)
+ }
+ }
+ }
+ if !android.ExistentPathForSource(ctx, a.fileContexts.String()).Valid() {
+ ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", a.fileContexts)
+ return
+ }
+ }
+
// prepare apex_manifest.json
a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
@@ -1184,7 +1195,7 @@
a.buildUnflattenedApex(ctx)
}
- apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
+ apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f4b8e35..4d7777d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -263,50 +263,57 @@
symbol_file: "",
native_bridge_supported: true,
}
+
+ filegroup {
+ name: "myapex-file_contexts",
+ srcs: [
+ "system/sepolicy/apex/myapex-file_contexts",
+ ],
+ }
`
bp = bp + java.GatherRequiredDepsForTest()
fs := map[string][]byte{
- "Android.bp": []byte(bp),
- "a.java": nil,
- "PrebuiltAppFoo.apk": nil,
- "PrebuiltAppFooPriv.apk": nil,
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/myapex_keytest-file_contexts": nil,
- "system/sepolicy/apex/otherapex-file_contexts": nil,
- "system/sepolicy/apex/commonapex-file_contexts": nil,
- "mylib.cpp": nil,
- "mylib_common.cpp": nil,
- "mytest.cpp": nil,
- "mytest1.cpp": nil,
- "mytest2.cpp": nil,
- "mytest3.cpp": nil,
- "myprebuilt": nil,
- "my_include": nil,
- "foo/bar/MyClass.java": nil,
- "prebuilt.jar": nil,
- "vendor/foo/devkeys/test.x509.pem": nil,
- "vendor/foo/devkeys/test.pk8": nil,
- "testkey.x509.pem": nil,
- "testkey.pk8": nil,
- "testkey.override.x509.pem": nil,
- "testkey.override.pk8": nil,
- "vendor/foo/devkeys/testkey.avbpubkey": nil,
- "vendor/foo/devkeys/testkey.pem": nil,
- "NOTICE": nil,
- "custom_notice": nil,
- "testkey2.avbpubkey": nil,
- "testkey2.pem": nil,
- "myapex-arm64.apex": nil,
- "myapex-arm.apex": nil,
- "frameworks/base/api/current.txt": nil,
- "framework/aidl/a.aidl": nil,
- "build/make/core/proguard.flags": nil,
- "build/make/core/proguard_basic_keeps.flags": nil,
- "dummy.txt": nil,
+ "Android.bp": []byte(bp),
+ "a.java": nil,
+ "PrebuiltAppFoo.apk": nil,
+ "PrebuiltAppFooPriv.apk": nil,
+ "build/make/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "AndroidManifest.xml": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/otherapex-file_contexts": nil,
+ "system/sepolicy/apex/commonapex-file_contexts": nil,
+ "system/sepolicy/apex/com.android.vndk-file_contexts": nil,
+ "mylib.cpp": nil,
+ "mylib_common.cpp": nil,
+ "mytest.cpp": nil,
+ "mytest1.cpp": nil,
+ "mytest2.cpp": nil,
+ "mytest3.cpp": nil,
+ "myprebuilt": nil,
+ "my_include": nil,
+ "foo/bar/MyClass.java": nil,
+ "prebuilt.jar": nil,
+ "vendor/foo/devkeys/test.x509.pem": nil,
+ "vendor/foo/devkeys/test.pk8": nil,
+ "testkey.x509.pem": nil,
+ "testkey.pk8": nil,
+ "testkey.override.x509.pem": nil,
+ "testkey.override.pk8": nil,
+ "vendor/foo/devkeys/testkey.avbpubkey": nil,
+ "vendor/foo/devkeys/testkey.pem": nil,
+ "NOTICE": nil,
+ "custom_notice": nil,
+ "testkey2.avbpubkey": nil,
+ "testkey2.pem": nil,
+ "myapex-arm64.apex": nil,
+ "myapex-arm.apex": nil,
+ "frameworks/base/api/current.txt": nil,
+ "framework/aidl/a.aidl": nil,
+ "build/make/core/proguard.flags": nil,
+ "build/make/core/proguard_basic_keeps.flags": nil,
+ "dummy.txt": nil,
}
for _, handler := range handlers {
@@ -1201,6 +1208,7 @@
key: "myapex.key",
certificate: ":myapex.certificate",
native_shared_libs: ["mylib"],
+ file_contexts: ":myapex-file_contexts",
}
cc_library {
@@ -1411,7 +1419,6 @@
apex_vndk {
name: "myapex",
key: "myapex.key",
- file_contexts: "myapex",
}
apex_key {
@@ -1462,7 +1469,6 @@
apex_vndk {
name: "myapex",
key: "myapex.key",
- file_contexts: "myapex",
}
apex_key {
@@ -1541,7 +1547,7 @@
apex_vndk {
name: "myapex_v27",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
vndk_version: "27",
}
@@ -1606,13 +1612,13 @@
apex_vndk {
name: "myapex_v27",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
vndk_version: "27",
}
apex_vndk {
name: "myapex_v27_other",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
vndk_version: "27",
}
@@ -1652,12 +1658,12 @@
apex_vndk {
name: "myapex",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex_vndk {
name: "myapex_v28",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
vndk_version: "28",
}
apex_key {
@@ -1683,7 +1689,7 @@
apex_vndk {
name: "myapex",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex_key {
@@ -1726,7 +1732,7 @@
apex_vndk {
name: "myapex",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
native_bridge_supported: true,
}
@@ -1756,7 +1762,7 @@
apex_vndk {
name: "myapex_v27",
key: "myapex.key",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
vndk_version: "27",
}
@@ -1822,7 +1828,7 @@
key: "myapex.key",
native_shared_libs: ["lib_nodep"],
compile_multilib: "both",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex {
@@ -1830,7 +1836,7 @@
key: "myapex.key",
native_shared_libs: ["lib_dep"],
compile_multilib: "both",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex {
@@ -1838,7 +1844,7 @@
key: "myapex.key",
native_shared_libs: ["libfoo"],
compile_multilib: "both",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex {
@@ -1846,7 +1852,7 @@
key: "myapex.key",
native_shared_libs: ["lib_dep", "libfoo"],
compile_multilib: "both",
- file_contexts: "myapex",
+ file_contexts: ":myapex-file_contexts",
}
apex_key {
@@ -2145,6 +2151,7 @@
key: "myapex.key",
native_shared_libs: ["mylib"],
product_specific: true,
+ file_contexts: "myapex_file_contexts",
}
apex_key {
@@ -2160,7 +2167,9 @@
system_shared_libs: [],
stl: "none",
}
- `)
+ `, withFiles(map[string][]byte{
+ "myapex_file_contexts": nil,
+ }))
apex := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
expected := buildDir + "/target/product/test_device/product/apex"
@@ -2170,6 +2179,112 @@
}
}
+func TestFileContexts(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+ module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ apexRule := module.Rule("apexRule")
+ actual := apexRule.Args["file_contexts"]
+ expected := "system/sepolicy/apex/myapex-file_contexts"
+ if actual != expected {
+ t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
+ }
+
+ testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "my_own_file_contexts",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `, withFiles(map[string][]byte{
+ "my_own_file_contexts": nil,
+ }))
+
+ testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: "product_specific_file_contexts",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `)
+
+ ctx, _ = testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: "product_specific_file_contexts",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `, withFiles(map[string][]byte{
+ "product_specific_file_contexts": nil,
+ }))
+ module = ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ apexRule = module.Rule("apexRule")
+ actual = apexRule.Args["file_contexts"]
+ expected = "product_specific_file_contexts"
+ if actual != expected {
+ t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
+ }
+
+ ctx, _ = testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ product_specific: true,
+ file_contexts: ":my-file-contexts",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ filegroup {
+ name: "my-file-contexts",
+ srcs: ["product_specific_file_contexts"],
+ }
+ `, withFiles(map[string][]byte{
+ "product_specific_file_contexts": nil,
+ }))
+ module = ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ apexRule = module.Rule("apexRule")
+ actual = apexRule.Args["file_contexts"]
+ expected = "product_specific_file_contexts"
+ if actual != expected {
+ t.Errorf("wrong file_contexts. expected %q. actual %q", expected, actual)
+ }
+}
+
func TestApexKeyFromOtherModule(t *testing.T) {
ctx, _ := testApex(t, `
apex_key {
@@ -2819,7 +2934,7 @@
}
func TestOverrideApex(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx, config := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2859,6 +2974,23 @@
ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
ensureContains(t, copyCmds, "image.apex/app/app/override_app.apk")
+
+ apexBundle := module.Module().(*apexBundle)
+ name := apexBundle.Name()
+ if name != "override_myapex" {
+ t.Errorf("name should be \"override_myapex\", but was %q", name)
+ }
+
+ data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+ var builder strings.Builder
+ data.Custom(&builder, name, "TARGET_", "", data)
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_MODULE := app.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
+ ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
}
func TestMain(m *testing.M) {
diff --git a/apex/builder.go b/apex/builder.go
index b29bc2c..70f3e1a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -244,7 +244,7 @@
apexType := a.properties.ApexType
suffix := apexType.suffix()
- unsignedOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+suffix+".unsigned")
+ unsignedOutputFile := android.PathForModuleOut(ctx, a.Name()+suffix+".unsigned")
filesToCopy := []android.Path{}
for _, f := range a.filesInfo {
@@ -253,7 +253,7 @@
copyCommands := []string{}
emitCommands := []string{}
- imageContentFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-content.txt")
+ imageContentFile := android.PathForModuleOut(ctx, a.Name()+"-content.txt")
emitCommands = append(emitCommands, "echo ./apex_manifest.json >> "+imageContentFile.String())
for i, src := range filesToCopy {
dest := filepath.Join(a.filesInfo[i].installDir, src.Base())
@@ -284,7 +284,7 @@
implicitInputs = append(implicitInputs, imageContentFile)
whitelistedFilesFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.Whitelisted_files))
- phonyOutput := android.PathForModuleOut(ctx, ctx.ModuleName()+"-diff-phony-output")
+ phonyOutput := android.PathForModuleOut(ctx, a.Name()+"-diff-phony-output")
ctx.Build(pctx, android.BuildParams{
Rule: diffApexContentRule,
Implicits: implicitInputs,
@@ -293,7 +293,7 @@
Args: map[string]string{
"whitelisted_files_file": whitelistedFilesFile.String(),
"image_content_file": imageContentFile.String(),
- "apex_module_name": ctx.ModuleName(),
+ "apex_module_name": a.Name(),
},
})
@@ -340,22 +340,13 @@
},
})
- fcName := proptools.StringDefault(a.properties.File_contexts, ctx.ModuleName())
- fileContextsPath := "system/sepolicy/apex/" + fcName + "-file_contexts"
- fileContextsOptionalPath := android.ExistentPathForSource(ctx, fileContextsPath)
- if !fileContextsOptionalPath.Valid() {
- ctx.ModuleErrorf("Cannot find file_contexts file: %q", fileContextsPath)
- return
- }
- fileContexts := fileContextsOptionalPath.Path()
-
optFlags := []string{}
// Additional implicit inputs.
- implicitInputs = append(implicitInputs, cannedFsConfig, fileContexts, a.private_key_file, a.public_key_file)
+ implicitInputs = append(implicitInputs, cannedFsConfig, a.fileContexts, a.private_key_file, a.public_key_file)
optFlags = append(optFlags, "--pubkey "+a.public_key_file.String())
- manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(ctx.ModuleName())
+ manifestPackageName, overridden := ctx.DeviceConfig().OverrideManifestPackageNameFor(a.Name())
if overridden {
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
}
@@ -377,7 +368,7 @@
}
optFlags = append(optFlags, "--target_sdk_version "+targetSdkVersion)
- noticeFile := a.buildNoticeFile(ctx, ctx.ModuleName()+suffix)
+ noticeFile := a.buildNoticeFile(ctx, a.Name()+suffix)
if noticeFile.Valid() {
// If there's a NOTICE file, embed it as an asset file in the APEX.
implicitInputs = append(implicitInputs, noticeFile.Path())
@@ -409,15 +400,15 @@
"manifest_json_full": a.manifestJsonFullOut.String(),
"manifest_json": a.manifestJsonOut.String(),
"manifest": a.manifestPbOut.String(),
- "file_contexts": fileContexts.String(),
+ "file_contexts": a.fileContexts.String(),
"canned_fs_config": cannedFsConfig.String(),
"key": a.private_key_file.String(),
"opt_flags": strings.Join(optFlags, " "),
},
})
- apexProtoFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".pb"+suffix)
- bundleModuleFile := android.PathForModuleOut(ctx, ctx.ModuleName()+suffix+"-base.zip")
+ apexProtoFile := android.PathForModuleOut(ctx, a.Name()+".pb"+suffix)
+ bundleModuleFile := android.PathForModuleOut(ctx, a.Name()+suffix+"-base.zip")
a.bundleModuleFile = bundleModuleFile
ctx.Build(pctx, android.BuildParams{
@@ -452,7 +443,7 @@
})
}
- a.outputFile = android.PathForModuleOut(ctx, ctx.ModuleName()+suffix)
+ a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix)
ctx.Build(pctx, android.BuildParams{
Rule: java.Signapk,
Description: "signapk",
@@ -470,7 +461,7 @@
// Install to $OUT/soong/{target,host}/.../apex
if a.installable() {
- ctx.InstallFile(a.installDir, ctx.ModuleName()+suffix, a.outputFile)
+ ctx.InstallFile(a.installDir, a.Name()+suffix, a.outputFile)
}
a.buildFilesInfo(ctx)
}
@@ -485,6 +476,11 @@
apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
a.outputFile = android.PathForModuleInstall(&factx, "apex", apexName)
+ if a.installable() {
+ installPath := android.PathForModuleInstall(ctx, "apex", apexName)
+ devicePath := android.InstallPathToOnDevicePath(ctx, installPath)
+ addFlattenedFileContextsInfos(ctx, apexName+":"+devicePath+":"+a.fileContexts.String())
+ }
a.buildFilesInfo(ctx)
}
@@ -505,8 +501,8 @@
if a.installable() {
// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
// with other ordinary files.
- a.filesInfo = append(a.filesInfo, apexFile{a.manifestJsonOut, "apex_manifest.json." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil})
- a.filesInfo = append(a.filesInfo, apexFile{a.manifestPbOut, "apex_manifest.pb." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{a.manifestJsonOut, "apex_manifest.json." + a.Name() + a.suffix, ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{a.manifestPbOut, "apex_manifest.pb." + a.Name() + a.suffix, ".", etc, nil, nil})
// rename to apex_pubkey
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
@@ -515,10 +511,10 @@
Input: a.public_key_file,
Output: copiedPubkey,
})
- a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, "apex_pubkey." + ctx.ModuleName() + a.suffix, ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{copiedPubkey, "apex_pubkey." + a.Name() + a.suffix, ".", etc, nil, nil})
if a.properties.ApexType == flattenedApex {
- apexName := proptools.StringDefault(a.properties.Apex_name, ctx.ModuleName())
+ apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
for _, fi := range a.filesInfo {
dir := filepath.Join("apex", apexName, fi.installDir)
target := ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.builtFile.Base(), fi.builtFile)
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 476d805..bb89bb4 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -117,45 +117,46 @@
// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
// from a dependency. This may cause issues when dependencies have explicit
// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func collectAllSharedDependencies(
- module android.Module,
- sharedDeps map[string]android.Path,
- ctx android.SingletonContext) {
+func collectAllSharedDependencies(ctx android.SingletonContext, module android.Module) android.Paths {
var fringe []android.Module
+ seen := make(map[android.Module]bool)
+
// Enumerate the first level of dependencies, as we discard all non-library
// modules in the BFS loop below.
ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep, sharedDeps) {
+ if isValidSharedDependency(dep) {
fringe = append(fringe, dep)
}
})
+ var sharedLibraries android.Paths
+
for i := 0; i < len(fringe); i++ {
module := fringe[i]
- if _, exists := sharedDeps[module.Name()]; exists {
+ if seen[module] {
continue
}
+ seen[module] = true
ccModule := module.(*Module)
- sharedDeps[ccModule.Name()] = ccModule.UnstrippedOutputFile()
+ sharedLibraries = append(sharedLibraries, ccModule.UnstrippedOutputFile())
ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep, sharedDeps) {
+ if isValidSharedDependency(dep) && !seen[dep] {
fringe = append(fringe, dep)
}
})
}
+
+ return sharedLibraries
}
// This function takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
-// - The module already exists in `sharedDeps`, or
// - The module is not a shared library, or
// - The module is a header, stub, or vendor-linked library.
-func isValidSharedDependency(
- dependency android.Module,
- sharedDeps map[string]android.Path) bool {
+func isValidSharedDependency(dependency android.Module) bool {
// TODO(b/144090547): We should be parsing these modules using
// ModuleDependencyTag instead of the current brute-force checking.
@@ -177,10 +178,6 @@
}
}
- // If this library has already been traversed, we don't need to do any more work.
- if _, exists := sharedDeps[dependency.Name()]; exists {
- return false
- }
return true
}
@@ -236,10 +233,16 @@
}
// Grab the list of required shared libraries.
- sharedLibraries := make(map[string]android.Path)
+ seen := make(map[android.Module]bool)
+ var sharedLibraries android.Paths
ctx.WalkDeps(func(child, parent android.Module) bool {
- if isValidSharedDependency(child, sharedLibraries) {
- sharedLibraries[child.Name()] = child.(*Module).UnstrippedOutputFile()
+ if seen[child] {
+ return false
+ }
+ seen[child] = true
+
+ if isValidSharedDependency(child) {
+ sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
return true
}
return false
@@ -250,8 +253,6 @@
sharedLibraryInstallLocation(
lib, ctx.Host(), ctx.Arch().ArchType.String()))
}
-
- sort.Strings(fuzz.installedSharedDeps)
}
func NewFuzz(hod android.HostOrDeviceSupported) *Module {
@@ -305,19 +306,21 @@
DestinationPathPrefix string
}
-type archAndLibraryKey struct {
- ArchDir android.OutputPath
- Library android.Path
+type archOs struct {
+ hostOrTarget string
+ arch string
+ dir string
}
func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
// Map between each architecture + host/device combination, and the files that
// need to be packaged (in the tuple of {source file, destination folder in
// archive}).
- archDirs := make(map[android.OutputPath][]fileToZip)
+ archDirs := make(map[archOs][]fileToZip)
- // List of shared library dependencies for each architecture + host/device combo.
- archSharedLibraryDeps := make(map[archAndLibraryKey]bool)
+ // Map tracking whether each shared library has an install rule to avoid duplicate install rules from
+ // multiple fuzzers that depend on the same shared library.
+ sharedLibraryInstalled := make(map[string]bool)
// List of individual fuzz targets, so that 'make fuzz' also installs the targets
// to the correct output directories as well.
@@ -351,10 +354,10 @@
archString := ccModule.Arch().ArchType.String()
archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
+ archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()}
// Grab the list of required shared libraries.
- sharedLibraries := make(map[string]android.Path)
- collectAllSharedDependencies(module, sharedLibraries, ctx)
+ sharedLibraries := collectAllSharedDependencies(ctx, module)
var files []fileToZip
builder := android.NewRuleBuilder()
@@ -374,16 +377,15 @@
for _, library := range sharedLibraries {
files = append(files, fileToZip{library, "lib"})
- if _, exists := archSharedLibraryDeps[archAndLibraryKey{archDir, library}]; exists {
- continue
- }
-
// For each architecture-specific shared library dependency, we need to
// install it to the output directory. Setup the install destination here,
// which will be used by $(copy-many-files) in the Make backend.
- archSharedLibraryDeps[archAndLibraryKey{archDir, library}] = true
installDestination := sharedLibraryInstallLocation(
library, ccModule.Host(), archString)
+ if sharedLibraryInstalled[installDestination] {
+ continue
+ }
+ sharedLibraryInstalled[installDestination] = true
// Escape all the variables, as the install destination here will be called
// via. $(eval) in Make.
installDestination = strings.ReplaceAll(
@@ -421,12 +423,19 @@
builder.Build(pctx, ctx, "create-"+fuzzZip.String(),
"Package "+module.Name()+" for "+archString+"-"+hostOrTargetString)
- archDirs[archDir] = append(archDirs[archDir], fileToZip{fuzzZip, ""})
+ archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""})
})
- for archDir, filesToZip := range archDirs {
- arch := archDir.Base()
- hostOrTarget := filepath.Base(filepath.Dir(archDir.String()))
+ var archOsList []archOs
+ for archOs := range archDirs {
+ archOsList = append(archOsList, archOs)
+ }
+ sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir })
+
+ for _, archOs := range archOsList {
+ filesToZip := archDirs[archOs]
+ arch := archOs.arch
+ hostOrTarget := archOs.hostOrTarget
builder := android.NewRuleBuilder()
outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip")
s.packages = append(s.packages, outputFile)
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 9215eff..f38d892 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -44,9 +44,10 @@
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
+ SystemServerJars []string // jars that form the system server
+ SystemServerApps []string // apps that are loaded into system server
+ UpdatableSystemServerJars []string // jars within apex that are loaded into system server
+ SpeedApps []string // apps that should be speed optimized
PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified
@@ -285,6 +286,7 @@
ProductUpdatableBootLocations: nil,
SystemServerJars: nil,
SystemServerApps: nil,
+ UpdatableSystemServerJars: nil,
SpeedApps: nil,
PreoptFlags: nil,
DefaultCompilerFilter: "",
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index a6661b3..15f11e1 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"path/filepath"
"strings"
@@ -65,6 +66,16 @@
var dexpreoptGlobalConfigKey = android.NewOnceKey("DexpreoptGlobalConfig")
var dexpreoptTestGlobalConfigKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
+// Expected format for apexJarValue = <apex name>:<jar name>
+func splitApexJarPair(apexJarValue string) (string, string) {
+ var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2)
+ if apexJarPair == nil || len(apexJarPair) != 2 {
+ panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>",
+ apexJarValue))
+ }
+ return apexJarPair[0], apexJarPair[1]
+}
+
// systemServerClasspath returns the on-device locations of the modules in the system server classpath. It is computed
// once the first time it is called for any ctx.Config(), and returns the same slice for all future calls with the same
// ctx.Config().
@@ -77,6 +88,11 @@
systemServerClasspathLocations = append(systemServerClasspathLocations,
filepath.Join("/system/framework", m+".jar"))
}
+ for _, m := range global.UpdatableSystemServerJars {
+ apex, jar := splitApexJarPair(m)
+ systemServerClasspathLocations = append(systemServerClasspathLocations,
+ filepath.Join("/apex", apex, "javalib", jar + ".jar"))
+ }
return systemServerClasspathLocations
})
}