Merge "Export htmlnotice, xmlnotice, and textnotice."
diff --git a/android/bazel.go b/android/bazel.go
index 5d1507c..fee1de2 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -497,15 +497,18 @@
// java deps
"android_icu4j_srcgen", // depends on unconverted modules: currysrc
+ "bin2c_fastdeployagent", // depends on deployagent, a java binary
"currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
- "bin2c_fastdeployagent", // depends on unconverted module: deployagent
- "timezone-host", // depends on unconverted modules: art.module.api.annotations
"robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
- "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
+ "timezone-host", // depends on unconverted modules: art.module.api.annotations
"truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
+ "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
"generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
"generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
+
+ "art-script", // depends on unconverted modules: dalvikvm, dex2oat
+ "dex2oat-script", // depends on unconverted modules: dex2oat
}
// Per-module denylist of cc_library modules to only generate the static
@@ -713,6 +716,7 @@
if err != nil {
return "", err
}
+ defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 91bbce6..bd73645 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -378,6 +378,7 @@
ctx.PropertyErrorf("from", "failed to open %q: %s", from, err)
return (map[string]blueprint.ModuleFactory)(nil)
}
+ defer r.Close()
mtDef, errs := soongconfig.Parse(r, from)
if ctx.Config().runningAsBp2Build {
diff --git a/apex/apex.go b/apex/apex.go
index 0ac6eaa..d12a786 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -888,9 +888,18 @@
// APEX, but shared across APEXes via the VNDK APEX.
useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
- if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
- mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
- return
+ if proptools.Bool(a.properties.Use_vndk_as_stable) {
+ if !useVndk {
+ mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
+ }
+ mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
+ if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
+ mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
+ }
+ })
+ if mctx.Failed() {
+ return
+ }
}
continueApexDepsWalk := func(child, parent android.Module) bool {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c546fa1..6d77b06 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2713,7 +2713,33 @@
ensureListNotContains(t, requireNativeLibs, ":vndk")
}
+func TestVendorApex_use_vndk_as_stable_TryingToIncludeVNDKLib(t *testing.T) {
+ testApexError(t, `Trying to include a VNDK library`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["libc++"], // libc++ is a VNDK lib
+ vendor: true,
+ use_vndk_as_stable: true,
+ updatable: false,
+ }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }`)
+}
+
func TestVendorApex_use_vndk_as_stable(t *testing.T) {
+ // myapex myapex2
+ // | |
+ // mybin ------. mybin2
+ // \ \ / |
+ // (stable) .---\--------` |
+ // \ / \ |
+ // \ / \ /
+ // libvndk libvendor
+ // (vndk)
ctx := testApex(t, `
apex {
name: "myapex",
@@ -2744,28 +2770,95 @@
cc_library {
name: "libvendor",
vendor: true,
+ stl: "none",
+ }
+ apex {
+ name: "myapex2",
+ key: "myapex.key",
+ binaries: ["mybin2"],
+ vendor: true,
+ use_vndk_as_stable: false,
+ updatable: false,
+ }
+ cc_binary {
+ name: "mybin2",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor"],
}
`)
vendorVariant := "android_vendor.29_arm64_armv8-a"
- ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld")
- libs := names(ldRule.Args["libFlags"])
- // VNDK libs(libvndk/libc++) as they are
- ensureListContains(t, libs, "out/soong/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
- ensureListContains(t, libs, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"libc++/"+vendorVariant+"_shared/libc++.so")
- // non-stable Vendor libs as APEX variants
- ensureListContains(t, libs, "out/soong/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so")
+ for _, tc := range []struct {
+ name string
+ apexName string
+ moduleName string
+ moduleVariant string
+ libs []string
+ contents []string
+ requireVndkNamespace bool
+ }{
+ {
+ name: "use_vndk_as_stable",
+ apexName: "myapex",
+ moduleName: "mybin",
+ moduleVariant: vendorVariant + "_apex10000",
+ libs: []string{
+ // should link with vendor variants of VNDK libs(libvndk/libc++)
+ "out/soong/.intermediates/libvndk/" + vendorVariant + "_shared/libvndk.so",
+ "out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared/libc++.so",
+ // unstable Vendor libs as APEX variant
+ "out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
+ },
+ contents: []string{
+ "bin/mybin",
+ "lib64/libvendor.so",
+ // VNDK libs (libvndk/libc++) are not included
+ },
+ requireVndkNamespace: true,
+ },
+ {
+ name: "!use_vndk_as_stable",
+ apexName: "myapex2",
+ moduleName: "mybin2",
+ moduleVariant: vendorVariant + "_myapex2",
+ libs: []string{
+ // should link with "unique" APEX(myapex2) variant of VNDK libs(libvndk/libc++)
+ "out/soong/.intermediates/libvndk/" + vendorVariant + "_shared_myapex2/libvndk.so",
+ "out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared_myapex2/libc++.so",
+ // unstable vendor libs have "merged" APEX variants
+ "out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
+ },
+ contents: []string{
+ "bin/mybin2",
+ "lib64/libvendor.so",
+ // VNDK libs are included as well
+ "lib64/libvndk.so",
+ "lib64/libc++.so",
+ },
+ requireVndkNamespace: false,
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ // Check linked libs
+ ldRule := ctx.ModuleForTests(tc.moduleName, tc.moduleVariant).Rule("ld")
+ libs := names(ldRule.Args["libFlags"])
+ for _, lib := range tc.libs {
+ ensureListContains(t, libs, lib)
+ }
+ // Check apex contents
+ ensureExactContents(t, ctx, tc.apexName, "android_common_"+tc.apexName+"_image", tc.contents)
- // VNDK libs are not included when use_vndk_as_stable: true
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "bin/mybin",
- "lib64/libvendor.so",
- })
-
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
- ensureListContains(t, requireNativeLibs, ":vndk")
+ // Check "requireNativeLibs"
+ apexManifestRule := ctx.ModuleForTests(tc.apexName, "android_common_"+tc.apexName+"_image").Rule("apexManifestRule")
+ requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
+ if tc.requireVndkNamespace {
+ ensureListContains(t, requireNativeLibs, ":vndk")
+ } else {
+ ensureListNotContains(t, requireNativeLibs, ":vndk")
+ }
+ })
+ }
}
func TestProductVariant(t *testing.T) {
@@ -2796,7 +2889,7 @@
)
cflags := strings.Fields(
- ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
+ ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_myapex").Rule("cc").Args["cFlags"])
ensureListContains(t, cflags, "-D__ANDROID_VNDK__")
ensureListContains(t, cflags, "-D__ANDROID_APEX__")
ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__")
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 8f44fc5..ce6b7f7 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -553,12 +553,66 @@
`prebuilt_com.android.art`,
})
+ // The boot images are installed in the APEX by Soong, so there shouldn't be any dexpreopt-related Make modules.
+ ensureDoesNotContainRequiredDeps(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "mybootclasspathfragment-dexpreopt-arm64-boot.art",
+ "mybootclasspathfragment-dexpreopt-arm64-boot.oat",
+ "mybootclasspathfragment-dexpreopt-arm64-boot.vdex",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.art",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.oat",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.vdex",
+ "mybootclasspathfragment-dexpreopt-arm-boot.art",
+ "mybootclasspathfragment-dexpreopt-arm-boot.oat",
+ "mybootclasspathfragment-dexpreopt-arm-boot.vdex",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.art",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.oat",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.vdex",
+ })
+
// Make sure that the prebuilt bootclasspath_fragment copies its dex files to the predefined
// locations for the art image.
module := result.ModuleForTests("prebuilt_mybootclasspathfragment", "android_common_com.android.art")
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
+ t.Run("boot image files from preferred prebuilt no boot image in apex", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ commonPreparer,
+
+ // Configure some libraries in the art bootclasspath_fragment that match the source
+ // bootclasspath_fragment's contents property.
+ java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
+ addSource("foo", "bar"),
+
+ // Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
+ addPrebuilt(true, "foo", "bar"),
+
+ java.FixtureSetBootImageInstallDirOnDevice("art", "system/framework"),
+ ).RunTest(t)
+
+ ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "etc/boot-image.prof",
+ "etc/classpaths/bootclasspath.pb",
+ "javalib/bar.jar",
+ "javalib/foo.jar",
+ })
+
+ ensureContainsRequiredDeps(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "mybootclasspathfragment-dexpreopt-arm64-boot.art",
+ "mybootclasspathfragment-dexpreopt-arm64-boot.oat",
+ "mybootclasspathfragment-dexpreopt-arm64-boot.vdex",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.art",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.oat",
+ "mybootclasspathfragment-dexpreopt-arm64-boot-bar.vdex",
+ "mybootclasspathfragment-dexpreopt-arm-boot.art",
+ "mybootclasspathfragment-dexpreopt-arm-boot.oat",
+ "mybootclasspathfragment-dexpreopt-arm-boot.vdex",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.art",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.oat",
+ "mybootclasspathfragment-dexpreopt-arm-boot-bar.vdex",
+ })
+ })
+
t.Run("source with inconsistency between config and contents", func(t *testing.T) {
android.GroupFixturePreparers(
commonPreparer,
@@ -631,6 +685,7 @@
// Configure some libraries in the art bootclasspath_fragment.
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
+ java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
)
bp := `
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 02d8075..158c804 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -65,7 +65,8 @@
// Installed locations of symlinks for backward compatibility.
compatSymlinks android.InstallPaths
- hostRequired []string
+ hostRequired []string
+ requiredModuleNames []string
}
type sanitizedPrebuilt interface {
@@ -195,9 +196,19 @@
}
p.apexFilesForAndroidMk = append(p.apexFilesForAndroidMk, af)
}
- } else if tag == exportedBootclasspathFragmentTag ||
- tag == exportedSystemserverclasspathFragmentTag {
- // Visit the children of the bootclasspath_fragment and systemserver_fragment.
+ } else if tag == exportedBootclasspathFragmentTag {
+ bcpfModule, ok := child.(*java.PrebuiltBootclasspathFragmentModule)
+ if !ok {
+ ctx.PropertyErrorf("exported_bootclasspath_fragments", "%q is not a prebuilt_bootclasspath_fragment module", name)
+ return false
+ }
+ for _, makeModuleName := range bcpfModule.BootImageDeviceInstallMakeModules() {
+ p.requiredModuleNames = append(p.requiredModuleNames, makeModuleName)
+ }
+ // Visit the children of the bootclasspath_fragment.
+ return true
+ } else if tag == exportedSystemserverclasspathFragmentTag {
+ // Visit the children of the systemserver_fragment.
return true
}
@@ -211,6 +222,7 @@
entries.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", fi.targetRequiredModuleNames...)
entries.AddStrings("LOCAL_HOST_REQUIRED_MODULES", fi.hostRequiredModuleNames...)
}
+ entries.AddStrings("LOCAL_REQUIRED_MODULES", p.requiredModuleNames...)
}
func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/cc/cc.go b/cc/cc.go
index 46e3b91..2a84f55 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3465,6 +3465,14 @@
return c.IsStubs() || c.Target().NativeBridge == android.NativeBridgeEnabled
}
+// Overrides android.ApexModuleBase.UniqueApexVariations
+func (c *Module) UniqueApexVariations() bool {
+ // When a vendor APEX needs a VNDK lib in it (use_vndk_as_stable: false), it should be a unique
+ // APEX variation. Otherwise, another vendor APEX with use_vndk_as_stable:true may use a wrong
+ // variation of the VNDK lib because APEX variations are merged/grouped.
+ return c.UseVndk() && c.IsVndk()
+}
+
var _ snapshot.RelativeInstallPath = (*Module)(nil)
type moduleType int
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 2d6bcb8..979c825 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -33,7 +33,9 @@
},
"armv8-a-branchprot": []string{
"-march=armv8-a",
- "-mbranch-protection=standard",
+ // Disable BTI until drm vendors stop using OS libraries as sources
+ // of gadgets (https://issuetracker.google.com/216395195).
+ "-mbranch-protection=pac-ret",
},
"armv8-2a": []string{
"-march=armv8.2-a",
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index 853d818..5c7f926 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -41,7 +41,6 @@
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,--build-id=md5",
- "-Wl,--warn-shared-textrel",
"-Wl,--fatal-warnings",
"-Wl,--hash-style=gnu",
"-Wl,--no-undefined-version",
diff --git a/cc/config/global.go b/cc/config/global.go
index cf39d3c..48a8b48 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -142,7 +142,6 @@
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,--build-id=md5",
- "-Wl,--warn-shared-textrel",
"-Wl,--fatal-warnings",
"-Wl,--no-undefined-version",
// TODO: Eventually we should link against a libunwind.a with hidden symbols, and then these
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index fdc246c..ba1043b 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -62,8 +62,9 @@
}, ",")
// clang-analyzer-* checks are too slow to be in the default for WITH_TIDY=1.
// nightly builds add CLANG_ANALYZER_CHECKS=1 to run those checks.
+ // The insecureAPI.DeprecatedOrUnsafeBufferHandling warning does not apply to Android.
if ctx.Config().IsEnvTrue("CLANG_ANALYZER_CHECKS") {
- checks += ",clang-analyzer-*"
+ checks += ",clang-analyzer-*,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling"
}
return checks
})
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 4b7ba6a..976cc25 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -47,7 +47,6 @@
"-Wl,-z,relro",
"-Wl,-z,now",
"-Wl,--build-id=md5",
- "-Wl,--warn-shared-textrel",
"-Wl,--fatal-warnings",
"-Wl,--hash-style=gnu",
"-Wl,--no-undefined-version",
diff --git a/cc/library.go b/cc/library.go
index cefbf6c..de5d46f 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -757,9 +757,10 @@
if dir == "external/eigen" {
// Only these two directories contains exported headers.
for _, subdir := range []string{"Eigen", "unsupported/Eigen"} {
- glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil)
+ globDir := "external/eigen/" + subdir + "/**/*"
+ glob, err := ctx.GlobWithDeps(globDir, nil)
if err != nil {
- ctx.ModuleErrorf("glob failed: %#v", err)
+ ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
return nil
}
for _, header := range glob {
@@ -775,9 +776,10 @@
}
continue
}
- glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
+ globDir := dir + "/**/*"
+ glob, err := ctx.GlobWithDeps(globDir, nil)
if err != nil {
- ctx.ModuleErrorf("glob failed: %#v", err)
+ ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
return nil
}
isLibcxx := strings.HasPrefix(dir, "external/libcxx/include")
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 13b20f4..d80051c 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -23,6 +23,7 @@
"path/filepath"
"strconv"
"strings"
+ "syscall"
"time"
"android/soong/shared"
@@ -205,6 +206,15 @@
config.Parallel(), config.RemoteParallel(), config.HighmemParallel())
{
+ var limits syscall.Rlimit
+ err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limits)
+ if err != nil {
+ buildCtx.Verbosef("Failed to get file limit:", err)
+ }
+ buildCtx.Verbosef("Current file limits: %d soft, %d hard", limits.Cur, limits.Max)
+ }
+
+ {
// The order of the function calls is important. The last defer function call
// is the first one that is executed to save the rbe metrics to a protobuf
// file. The soong metrics file is then next. Bazel profiles are written
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index 658e8e2..36513b6 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -210,6 +210,34 @@
Subcontexts []*ClassLoaderContext
}
+// excludeLibs excludes the libraries from this ClassLoaderContext.
+//
+// This treats the supplied context as being immutable (as it may come from a dependency). So, it
+// implements copy-on-exclusion logic. That means that if any of the excluded libraries are used
+// within this context then this will return a deep copy of this without those libraries.
+//
+// If this ClassLoaderContext matches one of the libraries to exclude then this returns (nil, true)
+// to indicate that this context should be excluded from the containing list.
+//
+// If any of this ClassLoaderContext's Subcontexts reference the excluded libraries then this
+// returns a pointer to a copy of this without the excluded libraries and true to indicate that this
+// was copied.
+//
+// Otherwise, this returns a pointer to this and false to indicate that this was not copied.
+func (c *ClassLoaderContext) excludeLibs(excludedLibs []string) (*ClassLoaderContext, bool) {
+ if android.InList(c.Name, excludedLibs) {
+ return nil, true
+ }
+
+ if excludedList, modified := excludeLibsFromCLCList(c.Subcontexts, excludedLibs); modified {
+ clcCopy := *c
+ clcCopy.Subcontexts = excludedList
+ return &clcCopy, true
+ }
+
+ return c, false
+}
+
// ClassLoaderContextMap is a map from SDK version to CLC. There is a special entry with key
// AnySdkVersion that stores unconditional CLC that is added regardless of the target SDK version.
//
@@ -408,6 +436,67 @@
return string(bytes)
}
+// excludeLibsFromCLCList excludes the libraries from the ClassLoaderContext in this list.
+//
+// This treats the supplied list as being immutable (as it may come from a dependency). So, it
+// implements copy-on-exclusion logic. That means that if any of the excluded libraries are used
+// within the contexts in the list then this will return a deep copy of the list without those
+// libraries.
+//
+// If any of the ClassLoaderContext in the list reference the excluded libraries then this returns a
+// copy of this list without the excluded libraries and true to indicate that this was copied.
+//
+// Otherwise, this returns the list and false to indicate that this was not copied.
+func excludeLibsFromCLCList(clcList []*ClassLoaderContext, excludedLibs []string) ([]*ClassLoaderContext, bool) {
+ modifiedList := false
+ copiedList := make([]*ClassLoaderContext, 0, len(clcList))
+ for _, clc := range clcList {
+ resultClc, modifiedClc := clc.excludeLibs(excludedLibs)
+ if resultClc != nil {
+ copiedList = append(copiedList, resultClc)
+ }
+ modifiedList = modifiedList || modifiedClc
+ }
+
+ if modifiedList {
+ return copiedList, true
+ } else {
+ return clcList, false
+ }
+}
+
+// ExcludeLibs excludes the libraries from the ClassLoaderContextMap.
+//
+// If the list o libraries is empty then this returns the ClassLoaderContextMap.
+//
+// This treats the ClassLoaderContextMap as being immutable (as it may come from a dependency). So,
+// it implements copy-on-exclusion logic. That means that if any of the excluded libraries are used
+// within the contexts in the map then this will return a deep copy of the map without those
+// libraries.
+//
+// Otherwise, this returns the map unchanged.
+func (clcMap ClassLoaderContextMap) ExcludeLibs(excludedLibs []string) ClassLoaderContextMap {
+ if len(excludedLibs) == 0 {
+ return clcMap
+ }
+
+ excludedClcMap := make(ClassLoaderContextMap)
+ modifiedMap := false
+ for sdkVersion, clcList := range clcMap {
+ excludedList, modifiedList := excludeLibsFromCLCList(clcList, excludedLibs)
+ if len(excludedList) != 0 {
+ excludedClcMap[sdkVersion] = excludedList
+ }
+ modifiedMap = modifiedMap || modifiedList
+ }
+
+ if modifiedMap {
+ return excludedClcMap
+ } else {
+ return clcMap
+ }
+}
+
// Now that the full unconditional context is known, reconstruct conditional context.
// Apply filters for individual libraries, mirroring what the PackageManager does when it
// constructs class loader context on device.
diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go
index 4a3d390..5d3a9d9 100644
--- a/dexpreopt/class_loader_context_test.go
+++ b/dexpreopt/class_loader_context_test.go
@@ -284,6 +284,111 @@
})
}
+func TestCLCMExcludeLibs(t *testing.T) {
+ ctx := testContext()
+ const optional = false
+ const implicit = true
+
+ excludeLibs := func(t *testing.T, m ClassLoaderContextMap, excluded_libs ...string) ClassLoaderContextMap {
+ // Dump the CLCM before creating a new copy that excludes a specific set of libraries.
+ before := m.Dump()
+
+ // Create a new CLCM that excludes some libraries.
+ c := m.ExcludeLibs(excluded_libs)
+
+ // Make sure that the original CLCM was not changed.
+ after := m.Dump()
+ android.AssertStringEquals(t, "input CLCM modified", before, after)
+
+ return c
+ }
+
+ t.Run("exclude nothing", func(t *testing.T) {
+ m := make(ClassLoaderContextMap)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+
+ a := excludeLibs(t, m)
+
+ android.AssertStringEquals(t, "output CLCM ", `{
+ "28": [
+ {
+ "Name": "a",
+ "Optional": false,
+ "Implicit": true,
+ "Host": "out/soong/a.jar",
+ "Device": "/system/a.jar",
+ "Subcontexts": []
+ }
+ ]
+}`, a.Dump())
+ })
+
+ t.Run("one item from list", func(t *testing.T) {
+ m := make(ClassLoaderContextMap)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+
+ a := excludeLibs(t, m, "a")
+
+ expected := `{
+ "28": [
+ {
+ "Name": "b",
+ "Optional": false,
+ "Implicit": true,
+ "Host": "out/soong/b.jar",
+ "Device": "/system/b.jar",
+ "Subcontexts": []
+ }
+ ]
+}`
+ android.AssertStringEquals(t, "output CLCM ", expected, a.Dump())
+ })
+
+ t.Run("all items from a list", func(t *testing.T) {
+ m := make(ClassLoaderContextMap)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 28, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+
+ a := excludeLibs(t, m, "a", "b")
+
+ android.AssertStringEquals(t, "output CLCM ", `{}`, a.Dump())
+ })
+
+ t.Run("items from a subcontext", func(t *testing.T) {
+ s := make(ClassLoaderContextMap)
+ s.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ s.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+
+ m := make(ClassLoaderContextMap)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), s)
+
+ a := excludeLibs(t, m, "b")
+
+ android.AssertStringEquals(t, "output CLCM ", `{
+ "28": [
+ {
+ "Name": "a",
+ "Optional": false,
+ "Implicit": true,
+ "Host": "out/soong/a.jar",
+ "Device": "/system/a.jar",
+ "Subcontexts": [
+ {
+ "Name": "c",
+ "Optional": false,
+ "Implicit": true,
+ "Host": "out/soong/c.jar",
+ "Device": "/system/c.jar",
+ "Subcontexts": []
+ }
+ ]
+ }
+ ]
+}`, a.Dump())
+ })
+}
+
func checkError(t *testing.T, have error, want string) {
if have == nil {
t.Errorf("\nwant error: '%s'\nhave: none", want)
diff --git a/finder/finder.go b/finder/finder.go
index 5413fa6..b4834b1 100644
--- a/finder/finder.go
+++ b/finder/finder.go
@@ -847,6 +847,7 @@
if err != nil {
return errors.New("No data to load from database\n")
}
+ defer reader.Close()
bufferedReader := bufio.NewReader(reader)
if !f.validateCacheHeader(bufferedReader) {
return errors.New("Cache header does not match")
diff --git a/finder/fs/test.go b/finder/fs/test.go
index cb2140e..ed981fd 100644
--- a/finder/fs/test.go
+++ b/finder/fs/test.go
@@ -74,6 +74,7 @@
if err != nil {
t.Fatalf(err.Error())
}
+ defer reader.Close()
bytes, err := ioutil.ReadAll(reader)
if err != nil {
t.Fatal(err.Error())
diff --git a/java/aar.go b/java/aar.go
index 4687424..51aad8d 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -267,11 +267,15 @@
})
func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext android.SdkContext,
- classLoaderContexts dexpreopt.ClassLoaderContextMap, extraLinkFlags ...string) {
+ classLoaderContexts dexpreopt.ClassLoaderContextMap, excludedLibs []string,
+ extraLinkFlags ...string) {
transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags :=
aaptLibs(ctx, sdkContext, classLoaderContexts)
+ // Exclude any libraries from the supplied list.
+ classLoaderContexts = classLoaderContexts.ExcludeLibs(excludedLibs)
+
// App manifest file
manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile)
@@ -530,7 +534,7 @@
func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.aapt.isLibrary = true
a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx)
- a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts)
+ a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, nil)
a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
diff --git a/java/app.go b/java/app.go
index 9f2f99a..e4432ff 100755
--- a/java/app.go
+++ b/java/app.go
@@ -425,7 +425,8 @@
a.aapt.splitNames = a.appProperties.Package_splits
a.aapt.LoggingParent = String(a.overridableAppProperties.Logging_parent)
- a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts, aaptLinkFlags...)
+ a.aapt.buildActions(ctx, android.SdkContext(a), a.classLoaderContexts,
+ a.usesLibraryProperties.Exclude_uses_libs, aaptLinkFlags...)
// apps manifests are handled by aapt, don't let Module see them
a.properties.Manifest = nil
@@ -1211,6 +1212,23 @@
// libraries, because SDK ones are automatically picked up by Soong. The <uses-library> name
// normally is the same as the module name, but there are exceptions.
Provides_uses_lib *string
+
+ // A list of shared library names to exclude from the classpath of the APK. Adding a library here
+ // will prevent it from being used when precompiling the APK and prevent it from being implicitly
+ // added to the APK's manifest's <uses-library> elements.
+ //
+ // Care must be taken when using this as it could result in runtime errors if the APK actually
+ // uses classes provided by the library and which are not provided in any other way.
+ //
+ // This is primarily intended for use by various CTS tests that check the runtime handling of the
+ // android.test.base shared library (and related libraries) but which depend on some common
+ // libraries that depend on the android.test.base library. Without this those tests will end up
+ // with a <uses-library android:name="android.test.base"/> in their manifest which would either
+ // render the tests worthless (as they would be testing the wrong behavior), or would break the
+ // test altogether by providing access to classes that the tests were not expecting. Those tests
+ // provide the android.test.base statically and use jarjar to rename them so they do not collide
+ // with the classes provided by the android.test.base library.
+ Exclude_uses_libs []string
}
// usesLibrary provides properties and helper functions for AndroidApp and AndroidAppImport to verify that the
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 4794180..a36bd6a 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -1073,7 +1073,7 @@
// At the moment this is basically just a bootclasspath_fragment module that can be used as a
// prebuilt. Eventually as more functionality is migrated into the bootclasspath_fragment module
// type from the various singletons then this will diverge.
-type prebuiltBootclasspathFragmentModule struct {
+type PrebuiltBootclasspathFragmentModule struct {
BootclasspathFragmentModule
prebuilt android.Prebuilt
@@ -1081,16 +1081,16 @@
prebuiltProperties prebuiltBootclasspathFragmentProperties
}
-func (module *prebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
+func (module *PrebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
return &module.prebuilt
}
-func (module *prebuiltBootclasspathFragmentModule) Name() string {
+func (module *PrebuiltBootclasspathFragmentModule) Name() string {
return module.prebuilt.Name(module.ModuleBase.Name())
}
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
-func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
+func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
pathForOptionalSrc := func(src *string, defaultPath android.Path) android.Path {
if src == nil {
return defaultPath
@@ -1131,7 +1131,7 @@
}
// produceBootImageFiles extracts the boot image files from the APEX if available.
-func (module *prebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
+func (module *PrebuiltBootclasspathFragmentModule) produceBootImageFiles(ctx android.ModuleContext, imageConfig *bootImageConfig) bootImageFilesByArch {
if !shouldCopyBootFilesToPredefinedLocations(ctx, imageConfig) {
return nil
}
@@ -1141,37 +1141,53 @@
return nil // An error has been reported by FindDeapexerProviderForModule.
}
- files := bootImageFilesByArch{}
- for _, variant := range imageConfig.apexVariants() {
- arch := variant.target.Arch.ArchType
- for _, toPath := range variant.imagesDeps {
- apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
- // Get the path to the file that the deapexer extracted from the prebuilt apex file.
- fromPath := di.PrebuiltExportPath(apexRelativePath)
-
- // Return the toPath as the calling code expects the paths in the returned map to be the
- // paths predefined in the bootImageConfig.
- files[arch] = append(files[arch], toPath)
-
- // Copy the file to the predefined location.
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: fromPath,
- Output: toPath,
- })
- }
+ profile := (android.WritablePath)(nil)
+ if imageConfig.profileInstallPathInApex != "" {
+ profile = di.PrebuiltExportPath(imageConfig.profileInstallPathInApex)
}
- // Build the boot image files for the host variants. These are built from the dex files provided
- // by the contents of this module as prebuilt versions of the host boot image files are not
- // available, i.e. there is no host specific prebuilt apex containing them. This has to be built
- // without a profile as the prebuilt modules do not provide a profile.
- buildBootImageVariantsForBuildOs(ctx, imageConfig, nil)
+ // Build the boot image files for the host variants. These are always built from the dex files
+ // provided by the contents of this module as prebuilt versions of the host boot image files are
+ // not available, i.e. there is no host specific prebuilt apex containing them. This has to be
+ // built without a profile as the prebuilt modules do not provide a profile.
+ buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
- return files
+ if imageConfig.shouldInstallInApex() {
+ // If the boot image files for the android variants are in the prebuilt apex, we must use those
+ // rather than building new ones because those boot image files are going to be used on device.
+ files := bootImageFilesByArch{}
+ for _, variant := range imageConfig.apexVariants() {
+ arch := variant.target.Arch.ArchType
+ for _, toPath := range variant.imagesDeps {
+ apexRelativePath := apexRootRelativePathToBootImageFile(arch, toPath.Base())
+ // Get the path to the file that the deapexer extracted from the prebuilt apex file.
+ fromPath := di.PrebuiltExportPath(apexRelativePath)
+
+ // Return the toPath as the calling code expects the paths in the returned map to be the
+ // paths predefined in the bootImageConfig.
+ files[arch] = append(files[arch], toPath)
+
+ // Copy the file to the predefined location.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: fromPath,
+ Output: toPath,
+ })
+ }
+ }
+ return files
+ } else {
+ if profile == nil {
+ ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")
+ return nil
+ }
+ // Build boot image files for the android variants from the dex files provided by the contents
+ // of this module.
+ return buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+ }
}
-var _ commonBootclasspathFragment = (*prebuiltBootclasspathFragmentModule)(nil)
+var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil)
// createBootImageTag creates the tag to uniquely identify the boot image file among all of the
// files that a module requires from the prebuilt .apex file.
@@ -1185,16 +1201,22 @@
//
// If there is no image config associated with this fragment then it returns nil. Otherwise, it
// returns the files that are listed in the image config.
-func (module *prebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
+func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
imageConfig := module.getImageConfig(ctx)
if imageConfig != nil {
- // Add the boot image files, e.g. .art, .oat and .vdex files.
files := []string{}
- for _, variant := range imageConfig.apexVariants() {
- arch := variant.target.Arch.ArchType
- for _, path := range variant.imagesDeps.Paths() {
- base := path.Base()
- files = append(files, apexRootRelativePathToBootImageFile(arch, base))
+ if imageConfig.profileInstallPathInApex != "" {
+ // Add the boot image profile.
+ files = append(files, imageConfig.profileInstallPathInApex)
+ }
+ if imageConfig.shouldInstallInApex() {
+ // Add the boot image files, e.g. .art, .oat and .vdex files.
+ for _, variant := range imageConfig.apexVariants() {
+ arch := variant.target.Arch.ArchType
+ for _, path := range variant.imagesDeps.Paths() {
+ base := path.Base()
+ files = append(files, apexRootRelativePathToBootImageFile(arch, base))
+ }
}
}
return files
@@ -1206,10 +1228,10 @@
return filepath.Join("javalib", arch.String(), base)
}
-var _ android.RequiredFilesFromPrebuiltApex = (*prebuiltBootclasspathFragmentModule)(nil)
+var _ android.RequiredFilesFromPrebuiltApex = (*PrebuiltBootclasspathFragmentModule)(nil)
func prebuiltBootclasspathFragmentFactory() android.Module {
- m := &prebuiltBootclasspathFragmentModule{}
+ m := &PrebuiltBootclasspathFragmentModule{}
m.AddProperties(&m.properties, &m.prebuiltProperties)
// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
// array.
diff --git a/java/rro.go b/java/rro.go
index 0b4d091..be84aff 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -139,7 +139,7 @@
aaptLinkFlags = append(aaptLinkFlags,
"--rename-overlay-target-package "+*r.overridableProperties.Target_package_name)
}
- r.aapt.buildActions(ctx, r, nil, aaptLinkFlags...)
+ r.aapt.buildActions(ctx, r, nil, nil, aaptLinkFlags...)
// Sign the built package
_, certificates := collectAppDeps(ctx, r, false, false)
diff --git a/mk2rbc/cmd/mk2rbc.go b/mk2rbc/cmd/mk2rbc.go
index d9b4e86..8e23a53 100644
--- a/mk2rbc/cmd/mk2rbc.go
+++ b/mk2rbc/cmd/mk2rbc.go
@@ -57,6 +57,7 @@
cpuProfile = flag.String("cpu_profile", "", "write cpu profile to file")
traceCalls = flag.Bool("trace_calls", false, "trace function calls")
inputVariables = flag.String("input_variables", "", "starlark file containing product config and global variables")
+ makefileList = flag.String("makefile_list", "", "path to a list of all makefiles in the source tree, generated by soong's finder. If not provided, mk2rbc will find the makefiles itself (more slowly than if this flag was provided)")
)
func init() {
@@ -79,7 +80,7 @@
var backupSuffix string
var tracedVariables []string
var errorLogger = errorSink{data: make(map[string]datum)}
-var makefileFinder = &LinuxMakefileFinder{}
+var makefileFinder mk2rbc.MakefileFinder
func main() {
flag.Usage = func() {
@@ -133,6 +134,16 @@
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
+
+ if *makefileList != "" {
+ makefileFinder = &FileListMakefileFinder{
+ cachedMakefiles: nil,
+ filePath: *makefileList,
+ }
+ } else {
+ makefileFinder = &FindCommandMakefileFinder{}
+ }
+
// Find out global variables
getConfigVariables()
getSoongVariables()
@@ -519,17 +530,17 @@
return res, len(sorted)
}
-type LinuxMakefileFinder struct {
+// FindCommandMakefileFinder is an implementation of mk2rbc.MakefileFinder that
+// runs the unix find command to find all the makefiles in the source tree.
+type FindCommandMakefileFinder struct {
cachedRoot string
cachedMakefiles []string
}
-func (l *LinuxMakefileFinder) Find(root string) []string {
+func (l *FindCommandMakefileFinder) Find(root string) []string {
if l.cachedMakefiles != nil && l.cachedRoot == root {
return l.cachedMakefiles
}
- l.cachedRoot = root
- l.cachedMakefiles = make([]string, 0)
// Return all *.mk files but not in hidden directories.
@@ -548,9 +559,60 @@
panic(fmt.Errorf("cannot get the output from %s: %s", cmd, err))
}
scanner := bufio.NewScanner(stdout)
+ result := make([]string, 0)
for scanner.Scan() {
- l.cachedMakefiles = append(l.cachedMakefiles, strings.TrimPrefix(scanner.Text(), "./"))
+ result = append(result, strings.TrimPrefix(scanner.Text(), "./"))
}
stdout.Close()
+ err = scanner.Err()
+ if err != nil {
+ panic(fmt.Errorf("cannot get the output from %s: %s", cmd, err))
+ }
+ l.cachedRoot = root
+ l.cachedMakefiles = result
+ return l.cachedMakefiles
+}
+
+// FileListMakefileFinder is an implementation of mk2rbc.MakefileFinder that
+// reads a file containing the list of makefiles in the android source tree.
+// This file is generated by soong's finder, so that it can be computed while
+// soong is already walking the source tree looking for other files. If the root
+// to find makefiles under is not the root of the android source tree, it will
+// fall back to using FindCommandMakefileFinder.
+type FileListMakefileFinder struct {
+ FindCommandMakefileFinder
+ cachedMakefiles []string
+ filePath string
+}
+
+func (l *FileListMakefileFinder) Find(root string) []string {
+ root, err1 := filepath.Abs(root)
+ wd, err2 := filepath.Abs(*rootDir)
+ if root != wd || err1 != nil || err2 != nil {
+ return l.FindCommandMakefileFinder.Find(root)
+ }
+ if l.cachedMakefiles != nil {
+ return l.cachedMakefiles
+ }
+
+ file, err := os.Open(l.filePath)
+ if err != nil {
+ panic(fmt.Errorf("Cannot read makefile list: %s\n", err))
+ }
+ defer file.Close()
+
+ result := make([]string, 0)
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := scanner.Text()
+ if len(line) > 0 {
+ result = append(result, line)
+ }
+ }
+
+ if err = scanner.Err(); err != nil {
+ panic(fmt.Errorf("Cannot read makefile list: %s\n", err))
+ }
+ l.cachedMakefiles = result
return l.cachedMakefiles
}
diff --git a/rust/library.go b/rust/library.go
index baac3f0..62eaefd 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -773,9 +773,10 @@
// Glob together the headers from the modules include_dirs property
for _, path := range android.CopyOfPaths(l.includeDirs) {
dir := path.String()
- glob, err := ctx.GlobWithDeps(dir+"/**/*", nil)
+ globDir := dir + "/**/*"
+ glob, err := ctx.GlobWithDeps(globDir, nil)
if err != nil {
- ctx.ModuleErrorf("glob failed: %#v", err)
+ ctx.ModuleErrorf("glob of %q failed: %s", globDir, err)
return
}
diff --git a/scripts/rbc-run b/scripts/rbc-run
index 7243421..b8a6c0c 100755
--- a/scripts/rbc-run
+++ b/scripts/rbc-run
@@ -9,9 +9,10 @@
declare -r runner="${output_root}/soong/rbcrun"
declare -r converter="${output_root}/soong/mk2rbc"
declare -r launcher="${output_root}/rbc/launcher.rbc"
+declare -r makefile_list="${output_root}/.module_paths/configuration.list"
declare -r makefile="$1"
declare -r input_variables="$2"
shift 2
-"${converter}" -mode=write -r --outdir "${output_root}/rbc" --input_variables "${input_variables}" --launcher="${launcher}" "${makefile}"
+"${converter}" -mode=write -r --outdir "${output_root}/rbc" --input_variables "${input_variables}" --launcher="${launcher}" --makefile_list="${makefile_list}" "${makefile}"
"${runner}" RBC_OUT="make,global" RBC_DEBUG="${RBC_DEBUG:-}" $@ "${launcher}"
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index a3a1aaf..1c80cff 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -171,6 +171,7 @@
productOut("recovery"),
productOut("root"),
productOut("system"),
+ productOut("system_dlkm"),
productOut("system_other"),
productOut("vendor"),
productOut("vendor_dlkm"),
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 8f74969..68efe21 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -87,8 +87,8 @@
// Bazel top-level file to mark a directory as a Bazel workspace.
"WORKSPACE",
},
- // Bazel Starlark configuration files.
- IncludeSuffixes: []string{".bzl"},
+ // Bazel Starlark configuration files and all .mk files for product/board configuration.
+ IncludeSuffixes: []string{".bzl", ".mk"},
}
dumpDir := config.FileListDir()
f, err = finder.New(cacheParams, filesystem, logger.New(ioutil.Discard),
@@ -110,6 +110,19 @@
return entries.DirNames, matches
}
+func findProductAndBoardConfigFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
+ matches := []string{}
+ for _, foundName := range entries.FileNames {
+ if foundName != "Android.mk" &&
+ foundName != "AndroidProducts.mk" &&
+ foundName != "CleanSpec.mk" &&
+ strings.HasSuffix(foundName, ".mk") {
+ matches = append(matches, foundName)
+ }
+ }
+ return entries.DirNames, matches
+}
+
// FindSources searches for source files known to <f> and writes them to the filesystem for
// use later.
func FindSources(ctx Context, config Config, f *finder.Finder) {
@@ -172,6 +185,13 @@
ctx.Fatalf("Could not find modules: %v", err)
}
+ // Recursively look for all product/board config files.
+ configurationFiles := f.FindMatching(".", findProductAndBoardConfigFiles)
+ err = dumpListToFile(ctx, config, configurationFiles, filepath.Join(dumpDir, "configuration.list"))
+ if err != nil {
+ ctx.Fatalf("Could not export product/board configuration list: %v", err)
+ }
+
if config.Dist() {
f.WaitForDbDump()
// Dist the files.db plain text database.