Merge "Add unit tests for class loader context."
diff --git a/Android.bp b/Android.bp
index 3075d67..4d69877 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,6 +47,7 @@
defaults: ["linux_bionic_supported"],
vendor_available: true,
ramdisk_available: true,
+ vendor_ramdisk_available: true,
recovery_available: true,
native_bridge_supported: true,
@@ -94,6 +95,7 @@
defaults: ["linux_bionic_supported"],
vendor_available: true,
ramdisk_available: true,
+ vendor_ramdisk_available: true,
recovery_available: true,
native_bridge_supported: true,
sdk_version: "current",
diff --git a/android/apex.go b/android/apex.go
index 3039e79..e70ec4f 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -67,6 +67,15 @@
return i.ApexVariationName == ""
}
+func (i ApexInfo) InApex(apex string) bool {
+ for _, a := range i.InApexes {
+ if a == apex {
+ return true
+ }
+ }
+ return false
+}
+
// ApexTestForInfo stores the contents of APEXes for which this module is a test and thus has
// access to APEX internals.
type ApexTestForInfo struct {
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 210d67a8..c87a945 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -29,10 +29,16 @@
"github.com/google/blueprint/bootstrap"
)
+type CqueryRequestType int
+
+const (
+ getAllFiles CqueryRequestType = iota
+)
+
// Map key to describe bazel cquery requests.
type cqueryKey struct {
- label string
- starlarkExpr string
+ label string
+ requestType CqueryRequestType
}
type BazelContext interface {
@@ -61,6 +67,7 @@
bazelPath string
outputBase string
workspaceDir string
+ buildDir string
requests map[cqueryKey]bool // cquery requests that have not yet been issued to Bazel
requestMutex sync.Mutex // requests can be written in parallel
@@ -96,8 +103,7 @@
var _ BazelContext = MockBazelContext{}
func (bazelCtx *bazelContext) GetAllFiles(label string) ([]string, bool) {
- starlarkExpr := "', '.join([f.path for f in target.files.to_list()])"
- result, ok := bazelCtx.cquery(label, starlarkExpr)
+ result, ok := bazelCtx.cquery(label, getAllFiles)
if ok {
bazelOutput := strings.TrimSpace(result)
return strings.Split(bazelOutput, ", "), true
@@ -119,11 +125,13 @@
}
func NewBazelContext(c *config) (BazelContext, error) {
- if c.Getenv("USE_BAZEL") != "1" {
+ // TODO(cparsons): Assess USE_BAZEL=1 instead once "mixed Soong/Bazel builds"
+ // are production ready.
+ if c.Getenv("USE_BAZEL_ANALYSIS") != "1" {
return noopBazelContext{}, nil
}
- bazelCtx := bazelContext{requests: make(map[cqueryKey]bool)}
+ bazelCtx := bazelContext{buildDir: c.buildDir, requests: make(map[cqueryKey]bool)}
missingEnvVars := []string{}
if len(c.Getenv("BAZEL_HOME")) > 1 {
bazelCtx.homeDir = c.Getenv("BAZEL_HOME")
@@ -161,8 +169,8 @@
// If the given request was already made (and the results are available), then
// returns (result, true). If the request is queued but no results are available,
// then returns ("", false).
-func (context *bazelContext) cquery(label string, starlarkExpr string) (string, bool) {
- key := cqueryKey{label, starlarkExpr}
+func (context *bazelContext) cquery(label string, requestType CqueryRequestType) (string, bool) {
+ key := cqueryKey{label, requestType}
if result, ok := context.results[key]; ok {
return result, true
} else {
@@ -184,7 +192,8 @@
func (context *bazelContext) issueBazelCommand(command string, labels []string,
extraFlags ...string) (string, error) {
- cmdFlags := []string{"--output_base=" + context.outputBase, command}
+ cmdFlags := []string{"--bazelrc=build/bazel/common.bazelrc",
+ "--output_base=" + context.outputBase, command}
cmdFlags = append(cmdFlags, labels...)
cmdFlags = append(cmdFlags, extraFlags...)
@@ -202,27 +211,113 @@
}
}
+func (context *bazelContext) mainBzlFileContents() []byte {
+ contents := `
+# This file is generated by soong_build. Do not edit.
+def _mixed_build_root_impl(ctx):
+ return [DefaultInfo(files = depset(ctx.files.deps))]
+
+mixed_build_root = rule(
+ implementation = _mixed_build_root_impl,
+ attrs = {"deps" : attr.label_list()},
+)
+`
+ return []byte(contents)
+}
+
+func (context *bazelContext) mainBuildFileContents() []byte {
+ formatString := `
+# This file is generated by soong_build. Do not edit.
+load(":main.bzl", "mixed_build_root")
+
+mixed_build_root(name = "buildroot",
+ deps = [%s],
+)
+`
+ var buildRootDeps []string = nil
+ for val, _ := range context.requests {
+ buildRootDeps = append(buildRootDeps, fmt.Sprintf("\"%s\"", val.label))
+ }
+ buildRootDepsString := strings.Join(buildRootDeps, ",\n ")
+
+ return []byte(fmt.Sprintf(formatString, buildRootDepsString))
+}
+
+func (context *bazelContext) cqueryStarlarkFileContents() []byte {
+ formatString := `
+# This file is generated by soong_build. Do not edit.
+getAllFilesLabels = {
+ %s
+}
+
+def format(target):
+ if str(target.label) in getAllFilesLabels:
+ return str(target.label) + ">>" + ', '.join([f.path for f in target.files.to_list()])
+ else:
+ # This target was not requested via cquery, and thus must be a dependency
+ # of a requested target.
+ return ""
+`
+ var buildRootDeps []string = nil
+ // TODO(cparsons): Sort by request type instead of assuming all requests
+ // are of GetAllFiles type.
+ for val, _ := range context.requests {
+ buildRootDeps = append(buildRootDeps, fmt.Sprintf("\"%s\" : True", val.label))
+ }
+ buildRootDepsString := strings.Join(buildRootDeps, ",\n ")
+
+ return []byte(fmt.Sprintf(formatString, buildRootDepsString))
+}
+
// Issues commands to Bazel to receive results for all cquery requests
// queued in the BazelContext.
func (context *bazelContext) InvokeBazel() error {
context.results = make(map[cqueryKey]string)
- var labels []string
var cqueryOutput string
var err error
+ err = ioutil.WriteFile(
+ absolutePath(filepath.Join(context.buildDir, "main.bzl")),
+ context.mainBzlFileContents(), 0666)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(
+ absolutePath(filepath.Join(context.buildDir, "BUILD.bazel")),
+ context.mainBuildFileContents(), 0666)
+ if err != nil {
+ return err
+ }
+ cquery_file_relpath := filepath.Join(context.buildDir, "buildroot.cquery")
+ err = ioutil.WriteFile(
+ absolutePath(cquery_file_relpath),
+ context.cqueryStarlarkFileContents(), 0666)
+ if err != nil {
+ return err
+ }
+ buildroot_label := fmt.Sprintf("//%s:buildroot", context.buildDir)
+ cqueryOutput, err = context.issueBazelCommand("cquery",
+ []string{fmt.Sprintf("deps(%s)", buildroot_label)},
+ "--output=starlark",
+ "--starlark:file="+cquery_file_relpath)
+
+ if err != nil {
+ return err
+ }
+
+ cqueryResults := map[string]string{}
+ for _, outputLine := range strings.Split(cqueryOutput, "\n") {
+ if strings.Contains(outputLine, ">>") {
+ splitLine := strings.SplitN(outputLine, ">>", 2)
+ cqueryResults[splitLine[0]] = splitLine[1]
+ }
+ }
+
for val, _ := range context.requests {
- labels = append(labels, val.label)
-
- // TODO(cparsons): Combine requests into a batch cquery request.
- // TODO(cparsons): Use --query_file to avoid command line limits.
- cqueryOutput, err = context.issueBazelCommand("cquery", []string{val.label},
- "--output=starlark",
- "--starlark:expr="+val.starlarkExpr)
-
- if err != nil {
- return err
+ if cqueryResult, ok := cqueryResults[val.label]; ok {
+ context.results[val] = string(cqueryResult)
} else {
- context.results[val] = string(cqueryOutput)
+ return fmt.Errorf("missing result for bazel target %s", val.label)
}
}
@@ -231,7 +326,7 @@
// bazel actions should either be added to the Ninja file and executed later,
// or bazel should handle execution.
// TODO(cparsons): Use --target_pattern_file to avoid command line limits.
- _, err = context.issueBazelCommand("build", labels)
+ _, err = context.issueBazelCommand("build", []string{buildroot_label})
if err != nil {
return err
diff --git a/android/config.go b/android/config.go
index 5f1acf6..a499057 100644
--- a/android/config.go
+++ b/android/config.go
@@ -793,6 +793,11 @@
return Bool(c.productVariables.Always_use_prebuilt_sdks)
}
+// Returns true if the boot jars check should be skipped.
+func (c *config) SkipBootJarsCheck() bool {
+ return Bool(c.productVariables.Skip_boot_jars_check)
+}
+
func (c *config) Fuchsia() bool {
return Bool(c.productVariables.Fuchsia)
}
@@ -1341,6 +1346,11 @@
return l.jars[idx]
}
+// Apex component of idx-th pair on the list.
+func (l *ConfiguredJarList) Apex(idx int) string {
+ return l.apexes[idx]
+}
+
// If the list contains a pair with the given jar.
func (l *ConfiguredJarList) ContainsJar(jar string) bool {
return InList(jar, l.jars)
@@ -1361,14 +1371,31 @@
return IndexList(jar, l.jars)
}
+func copyAndAppend(list []string, item string) []string {
+ // Create the result list to be 1 longer than the input.
+ result := make([]string, len(list)+1)
+
+ // Copy the whole input list into the result.
+ count := copy(result, list)
+
+ // Insert the extra item at the end.
+ result[count] = item
+
+ return result
+}
+
// Append an (apex, jar) pair to the list.
-func (l *ConfiguredJarList) Append(apex string, jar string) {
- l.apexes = append(l.apexes, apex)
- l.jars = append(l.jars, jar)
+func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
+ // Create a copy of the backing arrays before appending to avoid sharing backing
+ // arrays that are mutated across instances.
+ apexes := copyAndAppend(l.apexes, apex)
+ jars := copyAndAppend(l.jars, jar)
+
+ return ConfiguredJarList{apexes, jars}
}
// Filter out sublist.
-func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) {
+func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
apexes := make([]string, 0, l.Len())
jars := make([]string, 0, l.Len())
@@ -1380,13 +1407,7 @@
}
}
- l.apexes = apexes
- l.jars = jars
-}
-
-// A copy of itself.
-func (l *ConfiguredJarList) CopyOf() ConfiguredJarList {
- return ConfiguredJarList{CopyOf(l.apexes), CopyOf(l.jars)}
+ return ConfiguredJarList{apexes, jars}
}
// A copy of the list of strings containing jar components.
@@ -1469,6 +1490,14 @@
return paths
}
+func (l *ConfiguredJarList) String() string {
+ var pairs []string
+ for i := 0; i < l.Len(); i++ {
+ pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
+ }
+ return strings.Join(pairs, ",")
+}
+
func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
// Now we need to populate this list by splitting each item in the slice of
// pairs and appending them to the appropriate list of apexes or jars.
@@ -1497,10 +1526,10 @@
}
}
-func CreateConfiguredJarList(ctx PathContext, list []string) ConfiguredJarList {
+func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
if err != nil {
- ReportPathErrorf(ctx, "%s", err)
+ panic(err)
}
return ConfiguredJarList{apexes, jars}
@@ -1519,3 +1548,11 @@
return list
}).([]string)
}
+
+func (c *config) NonUpdatableBootJars() ConfiguredJarList {
+ return c.productVariables.BootJars
+}
+
+func (c *config) UpdatableBootJars() ConfiguredJarList {
+ return c.productVariables.UpdatableBootJars
+}
diff --git a/android/config_test.go b/android/config_test.go
index 274d59f..68f68a0 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -91,3 +91,49 @@
t.Errorf("Expected false")
}
}
+
+func assertStringEquals(t *testing.T, expected, actual string) {
+ if actual != expected {
+ t.Errorf("expected %q found %q", expected, actual)
+ }
+}
+
+func TestConfiguredJarList(t *testing.T) {
+ list1 := CreateTestConfiguredJarList([]string{"apex1:jarA"})
+
+ t.Run("create", func(t *testing.T) {
+ assertStringEquals(t, "apex1:jarA", list1.String())
+ })
+
+ list2 := list1.Append("apex2", "jarB")
+ t.Run("append", func(t *testing.T) {
+ assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
+ })
+
+ t.Run("append does not modify", func(t *testing.T) {
+ assertStringEquals(t, "apex1:jarA", list1.String())
+ })
+
+ // Make sure that two lists created by appending to the same list do not share storage.
+ list3 := list1.Append("apex3", "jarC")
+ t.Run("append does not share", func(t *testing.T) {
+ assertStringEquals(t, "apex1:jarA,apex2:jarB", list2.String())
+ assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
+ })
+
+ list4 := list3.RemoveList(list1)
+ t.Run("remove", func(t *testing.T) {
+ assertStringEquals(t, "apex3:jarC", list4.String())
+ })
+
+ t.Run("remove does not modify", func(t *testing.T) {
+ assertStringEquals(t, "apex1:jarA,apex3:jarC", list3.String())
+ })
+
+ // Make sure that two lists created by removing from the same list do not share storage.
+ list5 := list3.RemoveList(CreateTestConfiguredJarList([]string{"apex3:jarC"}))
+ t.Run("remove", func(t *testing.T) {
+ assertStringEquals(t, "apex3:jarC", list4.String())
+ assertStringEquals(t, "apex1:jarA", list5.String())
+ })
+}
diff --git a/android/variable.go b/android/variable.go
index 7999f0f..a9a9c87 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -224,6 +224,7 @@
Unbundled_build *bool `json:",omitempty"`
Unbundled_build_apps *bool `json:",omitempty"`
Always_use_prebuilt_sdks *bool `json:",omitempty"`
+ Skip_boot_jars_check *bool `json:",omitempty"`
Malloc_not_svelte *bool `json:",omitempty"`
Malloc_zero_contents *bool `json:",omitempty"`
Malloc_pattern_fill_contents *bool `json:",omitempty"`
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index c7223c4..3fa3a10 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -419,7 +419,10 @@
ndk_crtend_so.21(minSdkVersion:(no version))
ndk_crtend_so.27(minSdkVersion:(no version))
ndk_libc++_static(minSdkVersion:(no version))
+ndk_libc++_static(minSdkVersion:16)
ndk_libc++abi(minSdkVersion:(no version))
+ndk_libc++abi(minSdkVersion:16)
+ndk_libunwind(minSdkVersion:16)
net-utils-framework-common(minSdkVersion:current)
netd_aidl_interface-unstable-java(minSdkVersion:29)
netd_event_listener_interface-ndk_platform(minSdkVersion:29)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index f400936..7e83070 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5791,12 +5791,9 @@
var err string
var transform func(*dexpreopt.GlobalConfig)
- config := android.TestArchConfig(buildDir, nil, "", nil)
- ctx := android.PathContextForTesting(config)
-
t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"com.android.art.something:some-art-lib"})
+ config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"com.android.art.something:some-art-lib"})
}
testNoUpdatableJarsInBootImage(t, "", transform)
})
@@ -5804,7 +5801,7 @@
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
err = `module "some-art-lib" from updatable apexes \["com.android.art.something"\] is not allowed in the framework boot image`
transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateConfiguredJarList(ctx, []string{"com.android.art.something:some-art-lib"})
+ config.BootJars = android.CreateTestConfiguredJarList([]string{"com.android.art.something:some-art-lib"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
@@ -5812,7 +5809,7 @@
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
+ config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"some-updatable-apex:some-updatable-apex-lib"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
@@ -5820,7 +5817,7 @@
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
err = `module "some-non-updatable-apex-lib" is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
+ config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
@@ -5828,14 +5825,14 @@
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image`
transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateConfiguredJarList(ctx, []string{"some-updatable-apex:some-updatable-apex-lib"})
+ config.BootJars = android.CreateTestConfiguredJarList([]string{"some-updatable-apex:some-updatable-apex-lib"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateConfiguredJarList(ctx, []string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
+ config.BootJars = android.CreateTestConfiguredJarList([]string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
}
testNoUpdatableJarsInBootImage(t, "", transform)
})
@@ -5843,7 +5840,7 @@
t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"platform:nonexistent"})
+ config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"platform:nonexistent"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
@@ -5851,7 +5848,7 @@
t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateConfiguredJarList(ctx, []string{"platform:nonexistent"})
+ config.BootJars = android.CreateTestConfiguredJarList([]string{"platform:nonexistent"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
@@ -5859,14 +5856,14 @@
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
err = `module "some-platform-lib" is not allowed in the ART boot image`
transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateConfiguredJarList(ctx, []string{"platform:some-platform-lib"})
+ config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"platform:some-platform-lib"})
}
testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateConfiguredJarList(ctx, []string{"platform:some-platform-lib"})
+ config.BootJars = android.CreateTestConfiguredJarList([]string{"platform:some-platform-lib"})
}
testNoUpdatableJarsInBootImage(t, "", transform)
})
@@ -5905,7 +5902,7 @@
for _, apexBootJar := range apexBootJars {
updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
}
- config.TestProductVariables.UpdatableBootJars = android.CreateConfiguredJarList(nil, updatableBootJars)
+ config.TestProductVariables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
ctx.Register(config)
diff --git a/bazel/bazelenv.sh b/bazel/bazelenv.sh
index 2ca8baf..fcf71f1 100755
--- a/bazel/bazelenv.sh
+++ b/bazel/bazelenv.sh
@@ -59,12 +59,16 @@
export BAZEL_PATH="$(which bazel)"
fi
-export USE_BAZEL=1
+# TODO(cparsons): Use USE_BAZEL=1 instead once "mixed Soong/Bazel builds" are
+# production ready.
+export USE_BAZEL_ANALYSIS=1
+# TODO(cparsons): Retrieve this information in either envsetup.sh or
+# bazel.sh.
export BAZEL_HOME="$BASE_DIR/bazelhome"
export BAZEL_OUTPUT_BASE="$BASE_DIR/output"
export BAZEL_WORKSPACE="$(gettop)"
-echo "USE_BAZEL=${USE_BAZEL}"
+echo "USE_BAZEL_ANALYSIS=${USE_BAZEL_ANALYSIS}"
echo "BAZEL_PATH=${BAZEL_PATH}"
echo "BAZEL_HOME=${BAZEL_HOME}"
echo "BAZEL_OUTPUT_BASE=${BAZEL_OUTPUT_BASE}"
diff --git a/build_test.bash b/build_test.bash
index ee979e7..a53a585 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -43,5 +43,16 @@
;;
esac
+function bazel_cleanup {
+ "${TOP}/tools/bazel" shutdown
+}
+trap bazel_cleanup EXIT
+
+echo
+echo "Running Bazel smoke test..."
+"${TOP}/tools/bazel" info
+
+echo
+echo "Running Soong test..."
soong_build_go multiproduct_kati android/soong/cmd/multiproduct_kati
exec "$(getoutdir)/multiproduct_kati" "$@"
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 91eb886..38269cb 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -487,9 +487,21 @@
entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
c.libraryDecorator.androidMkWriteExportedFlags(entries)
+ // Specifying stem is to pass check_elf_files when vendor modules link against vndk prebuilt.
+ // We can't use install path because VNDKs are not installed. Instead, Srcs is directly used.
+ _, file := filepath.Split(c.properties.Srcs[0])
+ stem, suffix, ext := android.SplitFileExt(file)
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+ entries.SetString("LOCAL_MODULE_STEM", stem)
+
if c.tocFile.Valid() {
entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
}
+
+ // VNDK libraries available to vendor are not installed because
+ // they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
})
}
diff --git a/cc/cc.go b/cc/cc.go
index c93bdeb..3b01fb2 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3085,6 +3085,12 @@
}
}
+func squashVendorRamdiskSrcs(m *Module) {
+ if lib, ok := m.compiler.(*libraryDecorator); ok {
+ lib.baseCompiler.Properties.Exclude_srcs = append(lib.baseCompiler.Properties.Exclude_srcs, lib.baseCompiler.Properties.Target.Vendor_ramdisk.Exclude_srcs...)
+ }
+}
+
func (c *Module) IsSdkVariant() bool {
return c.Properties.IsSdkVariant || c.AlwaysSdk()
}
diff --git a/cc/compiler.go b/cc/compiler.go
index 21da2fc..e2a33d7 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -177,6 +177,15 @@
// build the recovery variant of the C/C++ module.
Exclude_generated_sources []string
}
+ Vendor_ramdisk struct {
+ // list of source files that should not be used to
+ // build the vendor ramdisk variant of the C/C++ module.
+ Exclude_srcs []string `android:"path"`
+
+ // List of additional cflags that should be used to build the vendor ramdisk
+ // variant of the C/C++ module.
+ Cflags []string
+ }
}
Proto struct {
@@ -290,6 +299,7 @@
CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
CheckBadCompilerFlags(ctx, "recovery.cflags", compiler.Properties.Target.Recovery.Cflags)
+ CheckBadCompilerFlags(ctx, "vendor_ramdisk.cflags", compiler.Properties.Target.Vendor_ramdisk.Cflags)
esc := proptools.NinjaAndShellEscapeList
@@ -471,6 +481,10 @@
flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Recovery.Cflags)...)
}
+ if ctx.inVendorRamdisk() {
+ flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor_ramdisk.Cflags)...)
+ }
+
// We can enforce some rules more strictly in the code we own. strict
// indicates if this is code that we can be stricter with. If we have
// rules that we want to apply to *our* code (but maybe can't for
diff --git a/cc/image.go b/cc/image.go
index ba091e1..7b9425f 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -353,8 +353,11 @@
func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) {
m := module.(*Module)
- if variant == android.RamdiskVariation || variant == android.VendorRamdiskVariation {
+ if variant == android.RamdiskVariation {
m.MakeAsPlatform()
+ } else if variant == android.VendorRamdiskVariation {
+ m.MakeAsPlatform()
+ squashVendorRamdiskSrcs(m)
} else if variant == android.RecoveryVariation {
m.MakeAsPlatform()
squashRecoverySrcs(m)
diff --git a/cc/library.go b/cc/library.go
index 0e0f143..910fc31 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -833,6 +833,13 @@
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_shared_libs)
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Ramdisk.Exclude_static_libs)
}
+ if ctx.inVendorRamdisk() {
+ deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
+ deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
+ deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
+ deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
+ deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
+ }
return deps
}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index fcf6069..fa6b326 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -383,12 +383,25 @@
}
func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
+ addOutputFile := true
ccModule := variant.(*Module)
- // If the library has some link types then it produces an output binary file, otherwise it
- // is header only.
- if !p.memberType.noOutputFiles {
- p.outputFile = getRequiredMemberOutputFile(ctx, ccModule)
+ if s := ccModule.sanitize; s != nil {
+ // We currently do not capture sanitizer flags for libs with sanitizers
+ // enabled, because they may vary among variants that cannot be represented
+ // in the input blueprint files. In particular, sanitizerDepsMutator enables
+ // various sanitizers on dependencies, but in many cases only on static
+ // ones, and we cannot specify sanitizer flags at the link type level (i.e.
+ // in StaticOrSharedProperties).
+ if s.isUnsanitizedVariant() {
+ // This still captures explicitly disabled sanitizers, which may be
+ // necessary to avoid cyclic dependencies.
+ p.Sanitize = s.Properties.Sanitize
+ } else {
+ // Do not add the output file to the snapshot if we don't represent it
+ // properly.
+ addOutputFile = false
+ }
}
exportedInfo := ctx.SdkModuleContext().OtherModuleProvider(variant, FlagExporterInfoProvider).(FlagExporterInfo)
@@ -431,8 +444,8 @@
p.StubsVersions = ccModule.AllStubsVersions()
}
- if ccModule.sanitize != nil {
- p.Sanitize = ccModule.sanitize.Properties.Sanitize
+ if !p.memberType.noOutputFiles && addOutputFile {
+ p.outputFile = getRequiredMemberOutputFile(ctx, ccModule)
}
}
diff --git a/cc/linker.go b/cc/linker.go
index 12c8b2c..7f13e28 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -158,6 +158,15 @@
// the ramdisk variant of the C/C++ module.
Exclude_static_libs []string
}
+ Vendor_ramdisk struct {
+ // list of shared libs that should not be used to build
+ // the recovery variant of the C/C++ module.
+ Exclude_shared_libs []string
+
+ // list of static libs that should not be used to build
+ // the vendor ramdisk variant of the C/C++ module.
+ Exclude_static_libs []string
+ }
Platform struct {
// list of shared libs that should be use to build the platform variant
// of a module that sets sdk_version. This should rarely be necessary,
@@ -259,12 +268,20 @@
}
if ctx.inRamdisk() {
- deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs)
- deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs)
- deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Recovery.Static_libs...)
- deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
- deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Recovery.Exclude_static_libs)
- deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
+ deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Ramdisk.Exclude_shared_libs)
+ deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Ramdisk.Exclude_shared_libs)
+ deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Ramdisk.Static_libs...)
+ deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs)
+ deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Ramdisk.Exclude_static_libs)
+ deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Ramdisk.Exclude_static_libs)
+ }
+
+ if ctx.inVendorRamdisk() {
+ deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
+ deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_shared_libs)
+ deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
+ deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
+ deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Vendor_ramdisk.Exclude_static_libs)
}
if !ctx.useSdk() {
diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go
index 82a7732..dddd5ac 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -232,6 +232,14 @@
&prebuilt.properties,
)
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ // empty BOARD_VNDK_VERSION implies that the device won't support
+ // system only OTA. In this case, VNDK snapshots aren't needed.
+ if ctx.DeviceConfig().VndkVersion() == "" {
+ ctx.Module().Disable()
+ }
+ })
+
return module
}
diff --git a/java/Android.bp b/java/Android.bp
index 92e8ca4..9e8dc78 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -22,6 +22,7 @@
"androidmk.go",
"app_builder.go",
"app.go",
+ "boot_jars.go",
"builder.go",
"device_host_converter.go",
"dex.go",
diff --git a/java/androidmk.go b/java/androidmk.go
index c21c83a..e1a661f 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -217,10 +217,6 @@
func(entries *android.AndroidMkEntries) {
if prebuilt.dexJarFile != nil {
entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile)
- // TODO(b/125517186): export the dex jar as a classes jar to match some mis-uses in Make until
- // boot_jars_package_check.mk can check dex jars.
- entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.dexJarFile)
- entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.dexJarFile)
}
if len(prebuilt.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", prebuilt.dexpreopter.builtInstalled)
diff --git a/java/boot_jars.go b/java/boot_jars.go
new file mode 100644
index 0000000..900eb7a
--- /dev/null
+++ b/java/boot_jars.go
@@ -0,0 +1,123 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+)
+
+func init() {
+ android.RegisterSingletonType("boot_jars", bootJarsSingletonFactory)
+}
+
+func bootJarsSingletonFactory() android.Singleton {
+ return &bootJarsSingleton{}
+}
+
+type bootJarsSingleton struct{}
+
+func populateMapFromConfiguredJarList(ctx android.SingletonContext, moduleToApex map[string]string, list android.ConfiguredJarList, name string) bool {
+ for i := 0; i < list.Len(); i++ {
+ module := list.Jar(i)
+ // Ignore jacocoagent it is only added when instrumenting and so has no impact on
+ // app compatibility.
+ if module == "jacocoagent" {
+ continue
+ }
+ apex := list.Apex(i)
+ if existing, ok := moduleToApex[module]; ok {
+ ctx.Errorf("Configuration property %q is invalid as it contains multiple references to module (%s) in APEXes (%s and %s)",
+ module, existing, apex)
+ return false
+ }
+
+ moduleToApex[module] = apex
+ }
+
+ return true
+}
+
+func (b *bootJarsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ config := ctx.Config()
+ if config.SkipBootJarsCheck() {
+ return
+ }
+
+ // Populate a map from module name to APEX from the boot jars. If there is a problem
+ // such as duplicate modules then fail and return immediately.
+ moduleToApex := make(map[string]string)
+ if !populateMapFromConfiguredJarList(ctx, moduleToApex, config.NonUpdatableBootJars(), "BootJars") ||
+ !populateMapFromConfiguredJarList(ctx, moduleToApex, config.UpdatableBootJars(), "UpdatableBootJars") {
+ return
+ }
+
+ // Map from module name to the correct apex variant.
+ nameToApexVariant := make(map[string]android.Module)
+
+ // Scan all the modules looking for the module/apex variants corresponding to the
+ // boot jars.
+ ctx.VisitAllModules(func(module android.Module) {
+ name := ctx.ModuleName(module)
+ if apex, ok := moduleToApex[name]; ok {
+ apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ if (apex == "platform" && apexInfo.IsForPlatform()) || apexInfo.InApex(apex) {
+ // The module name/apex variant should be unique in the system but double check
+ // just in case something has gone wrong.
+ if existing, ok := nameToApexVariant[name]; ok {
+ ctx.Errorf("found multiple variants matching %s:%s: %q and %q", apex, name, existing, module)
+ }
+ nameToApexVariant[name] = module
+ }
+ }
+ })
+
+ timestamp := android.PathForOutput(ctx, "boot-jars-package-check/stamp")
+
+ rule := android.NewRuleBuilder()
+ checkBootJars := rule.Command().BuiltTool(ctx, "check_boot_jars").
+ Input(android.PathForSource(ctx, "build/soong/scripts/check_boot_jars/package_allowed_list.txt"))
+
+ // If this is not an unbundled build and missing dependencies are not allowed
+ // then all the boot jars listed must have been found.
+ strict := !config.UnbundledBuild() && !config.AllowMissingDependencies()
+
+ // Iterate over the module names on the boot classpath in order
+ for _, name := range android.SortedStringKeys(moduleToApex) {
+ if apexVariant, ok := nameToApexVariant[name]; ok {
+ if dep, ok := apexVariant.(Dependency); ok {
+ // Add the implementation jars for the module to be checked. This uses implementation
+ // and resources jar as that is what the previous make based check uses.
+ for _, jar := range dep.ImplementationAndResourcesJars() {
+ checkBootJars.Input(jar)
+ }
+ } else if _, ok := apexVariant.(*DexImport); ok {
+ // TODO(b/171479578): ignore deximport when doing package check until boot_jars.go can check dex jars.
+ } else {
+ ctx.Errorf("module %q is of type %q which is not supported as a boot jar", name, ctx.ModuleType(apexVariant))
+ }
+ } else if strict {
+ ctx.Errorf("boot jars package check failed as it could not find module %q for apex %q", name, moduleToApex[name])
+ }
+ }
+
+ checkBootJars.Text("&& touch").Output(timestamp)
+ rule.Build(pctx, ctx, "boot_jars_package_check", "check boot jar packages")
+
+ // The check-boot-jars phony target depends on the timestamp created if the check succeeds.
+ ctx.Phony("check-boot-jars", timestamp)
+
+ // The droidcore phony target depends on the check-boot-jars phony target
+ ctx.Phony("droidcore", android.PathForPhony(ctx, "check-boot-jars"))
+}
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 47110c9..ab31958 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -48,7 +48,7 @@
pathCtx := android.PathContextForTesting(config)
dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- dexpreoptConfig.BootJars = android.CreateConfiguredJarList(pathCtx, []string{"platform:foo", "platform:bar", "platform:baz"})
+ dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList([]string{"platform:foo", "platform:bar", "platform:baz"})
dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
ctx := testContext()
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 0f8888a..c315124 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -81,13 +81,12 @@
targets := dexpreoptTargets(ctx)
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
- artModules := global.ArtApexJars.CopyOf()
+ artModules := global.ArtApexJars
// With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- artModules.Append("com.android.art", "jacocoagent")
+ artModules = artModules.Append("com.android.art", "jacocoagent")
}
- frameworkModules := global.BootJars.CopyOf()
- frameworkModules.RemoveList(artModules)
+ frameworkModules := global.BootJars.RemoveList(artModules)
artSubdir := "apex/art_boot_images/javalib"
frameworkSubdir := "system/framework"
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 0c223d9..7acaae7 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -25,7 +25,7 @@
func testConfigWithBootJars(bp string, bootJars []string) android.Config {
config := testConfig(nil, bp, nil)
- config.TestProductVariables.BootJars = android.CreateConfiguredJarList(nil, bootJars)
+ config.TestProductVariables.BootJars = android.CreateTestConfiguredJarList(bootJars)
return config
}
diff --git a/java/java.go b/java/java.go
index 4b48a15..3167512 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1187,18 +1187,6 @@
// javaVersion flag.
flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
- // javac flags.
- javacFlags := j.properties.Javacflags
- if flags.javaVersion.usesJavaModules() {
- javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
- }
- if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
- // For non-host binaries, override the -g flag passed globally to remove
- // local variable debug info to reduce disk and memory usage.
- javacFlags = append(javacFlags, "-g:source,lines")
- }
- javacFlags = append(javacFlags, "-Xlint:-dep-ann")
-
if ctx.Config().RunErrorProne() {
if config.ErrorProneClasspath == nil {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
@@ -1249,24 +1237,42 @@
}
}
- if j.properties.Patch_module != nil && flags.javaVersion.usesJavaModules() {
- // Manually specify build directory in case it is not under the repo root.
- // (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
- // just adding a symlink under the root doesn't help.)
- patchPaths := ".:" + ctx.Config().BuildDir()
- classPath := flags.classpath.FormJavaClassPath("")
- if classPath != "" {
- patchPaths += ":" + classPath
- }
- javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths)
- }
-
// systemModules
flags.systemModules = deps.systemModules
// aidl flags.
flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
+ return flags
+}
+
+func (j *Module) collectJavacFlags(ctx android.ModuleContext, flags javaBuilderFlags) javaBuilderFlags {
+ // javac flags.
+ javacFlags := j.properties.Javacflags
+
+ if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() {
+ // For non-host binaries, override the -g flag passed globally to remove
+ // local variable debug info to reduce disk and memory usage.
+ javacFlags = append(javacFlags, "-g:source,lines")
+ }
+ javacFlags = append(javacFlags, "-Xlint:-dep-ann")
+
+ if flags.javaVersion.usesJavaModules() {
+ javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
+
+ if j.properties.Patch_module != nil {
+ // Manually specify build directory in case it is not under the repo root.
+ // (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so
+ // just adding a symlink under the root doesn't help.)
+ patchPaths := ".:" + ctx.Config().BuildDir()
+ classPath := flags.classpath.FormJavaClassPath("")
+ if classPath != "" {
+ patchPaths += ":" + classPath
+ }
+ javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths)
+ }
+ }
+
if len(javacFlags) > 0 {
// optimization.
ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))
@@ -1297,6 +1303,8 @@
srcFiles = j.genSources(ctx, srcFiles, flags)
+ flags = j.collectJavacFlags(ctx, flags)
+
srcJars := srcFiles.FilterByExt(".srcjar")
srcJars = append(srcJars, deps.srcJars...)
if aaptSrcJar != nil {
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index b5c70dc..3ad32fa 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -14,6 +14,7 @@
"frameworks/native/libs/binder/rust",
"packages/modules/Virtualization",
"prebuilts/rust",
+ "system/bt",
"system/extras/profcollectd",
"system/hardware/interfaces/keystore2",
"system/security",
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 92f5c53..dd03f28 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -1,4 +1,20 @@
python_binary_host {
+ name: "check_boot_jars",
+ main: "check_boot_jars/check_boot_jars.py",
+ srcs: [
+ "check_boot_jars/check_boot_jars.py",
+ ],
+ version: {
+ py2: {
+ enabled: true,
+ },
+ py3: {
+ enabled: false,
+ },
+ },
+}
+
+python_binary_host {
name: "manifest_fixer",
main: "manifest_fixer.py",
srcs: [
diff --git a/scripts/check_boot_jars/check_boot_jars.py b/scripts/check_boot_jars/check_boot_jars.py
new file mode 100755
index 0000000..cf4ef27
--- /dev/null
+++ b/scripts/check_boot_jars/check_boot_jars.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+"""
+Check boot jars.
+
+Usage: check_boot_jars.py <package_allow_list_file> <jar1> <jar2> ...
+"""
+import logging
+import os.path
+import re
+import subprocess
+import sys
+
+
+# The compiled allow list RE.
+allow_list_re = None
+
+
+def LoadAllowList(filename):
+ """ Load and compile allow list regular expressions from filename.
+ """
+ lines = []
+ with open(filename, 'r') as f:
+ for line in f:
+ line = line.strip()
+ if not line or line.startswith('#'):
+ continue
+ lines.append(line)
+ combined_re = r'^(%s)$' % '|'.join(lines)
+ global allow_list_re
+ try:
+ allow_list_re = re.compile(combined_re)
+ except re.error:
+ logging.exception(
+ 'Cannot compile package allow list regular expression: %r',
+ combined_re)
+ allow_list_re = None
+ return False
+ return True
+
+
+def CheckJar(allow_list_path, jar):
+ """Check a jar file.
+ """
+ # Get the list of files inside the jar file.
+ p = subprocess.Popen(args='jar tf %s' % jar,
+ stdout=subprocess.PIPE, shell=True)
+ stdout, _ = p.communicate()
+ if p.returncode != 0:
+ return False
+ items = stdout.split()
+ classes = 0
+ for f in items:
+ if f.endswith('.class'):
+ classes += 1
+ package_name = os.path.dirname(f)
+ package_name = package_name.replace('/', '.')
+ if not package_name or not allow_list_re.match(package_name):
+ print >> sys.stderr, ('Error: %s contains class file %s, whose package name %s is empty or'
+ ' not in the allow list %s of packages allowed on the bootclasspath.'
+ % (jar, f, package_name, allow_list_path))
+ return False
+ if classes == 0:
+ print >> sys.stderr, ('Error: %s does not contain any class files.' % jar)
+ return False
+ return True
+
+
+def main(argv):
+ if len(argv) < 2:
+ print __doc__
+ return 1
+ allow_list_path = argv[0]
+
+ if not LoadAllowList(allow_list_path):
+ return 1
+
+ passed = True
+ for jar in argv[1:]:
+ if not CheckJar(allow_list_path, jar):
+ passed = False
+ if not passed:
+ return 1
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
new file mode 100644
index 0000000..18ab427
--- /dev/null
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -0,0 +1,248 @@
+# Boot jar package name allowed list.
+# Each line is interpreted as a regular expression.
+
+###################################################
+# core-libart.jar & core-oj.jar
+java\.awt\.font
+java\.beans
+java\.io
+java\.lang
+java\.lang\.annotation
+java\.lang\.invoke
+java\.lang\.ref
+java\.lang\.reflect
+java\.math
+java\.net
+java\.nio
+java\.nio\.file
+java\.nio\.file\.spi
+java\.nio\.file\.attribute
+java\.nio\.channels
+java\.nio\.channels\.spi
+java\.nio\.charset
+java\.nio\.charset\.spi
+java\.security
+java\.security\.acl
+java\.security\.cert
+java\.security\.interfaces
+java\.security\.spec
+java\.sql
+java\.text
+java\.text\.spi
+java\.time
+java\.time\.chrono
+java\.time\.format
+java\.time\.temporal
+java\.time\.zone
+java\.util
+java\.util\.concurrent
+java\.util\.concurrent\.atomic
+java\.util\.concurrent\.locks
+java\.util\.function
+java\.util\.jar
+java\.util\.logging
+java\.util\.prefs
+java\.util\.regex
+java\.util\.spi
+java\.util\.stream
+java\.util\.zip
+# TODO: Remove javax.annotation.processing if possible, see http://b/132338110:
+javax\.annotation\.processing
+javax\.crypto
+javax\.crypto\.interfaces
+javax\.crypto\.spec
+javax\.net
+javax\.net\.ssl
+javax\.security\.auth
+javax\.security\.auth\.callback
+javax\.security\.auth\.login
+javax\.security\.auth\.x500
+javax\.security\.cert
+javax\.sql
+javax\.xml
+javax\.xml\.datatype
+javax\.xml\.namespace
+javax\.xml\.parsers
+javax\.xml\.transform
+javax\.xml\.transform\.dom
+javax\.xml\.transform\.sax
+javax\.xml\.transform\.stream
+javax\.xml\.validation
+javax\.xml\.xpath
+jdk\.internal\.util
+jdk\.internal\.vm\.annotation
+jdk\.net
+org\.w3c\.dom
+org\.w3c\.dom\.ls
+org\.w3c\.dom\.traversal
+# OpenJdk internal implementation.
+sun\.invoke\.util
+sun\.invoke\.empty
+sun\.misc
+sun\.util.*
+sun\.text.*
+sun\.security.*
+sun\.reflect.*
+sun\.nio.*
+sun\.net.*
+com\.sun\..*
+
+# TODO: Move these internal org.apache.harmony classes to libcore.*
+org\.apache\.harmony\.crypto\.internal
+org\.apache\.harmony\.dalvik
+org\.apache\.harmony\.dalvik\.ddmc
+org\.apache\.harmony\.luni\.internal\.util
+org\.apache\.harmony\.security
+org\.apache\.harmony\.security\.asn1
+org\.apache\.harmony\.security\.fortress
+org\.apache\.harmony\.security\.pkcs10
+org\.apache\.harmony\.security\.pkcs7
+org\.apache\.harmony\.security\.pkcs8
+org\.apache\.harmony\.security\.provider\.crypto
+org\.apache\.harmony\.security\.utils
+org\.apache\.harmony\.security\.x501
+org\.apache\.harmony\.security\.x509
+org\.apache\.harmony\.security\.x509\.tsp
+org\.apache\.harmony\.xml
+org\.apache\.harmony\.xml\.dom
+org\.apache\.harmony\.xml\.parsers
+
+org\.json
+org\.xmlpull\.v1
+org\.xmlpull\.v1\.sax2
+
+# TODO: jarjar org.kxml2.io to com.android org\.kxml2\.io
+org\.kxml2\.io
+org\.xml
+org\.xml\.sax
+org\.xml\.sax\.ext
+org\.xml\.sax\.helpers
+
+dalvik\..*
+libcore\..*
+android\..*
+com\.android\..*
+###################################################
+# android.test.base.jar
+junit\.extensions
+junit\.framework
+android\.test
+android\.test\.suitebuilder\.annotation
+
+
+###################################################
+# ext.jar
+# TODO: jarjar javax.sip to com.android
+javax\.sip
+javax\.sip\.address
+javax\.sip\.header
+javax\.sip\.message
+
+# TODO: jarjar org.apache.commons to com.android
+org\.apache\.commons\.codec
+org\.apache\.commons\.codec\.binary
+org\.apache\.commons\.codec\.language
+org\.apache\.commons\.codec\.net
+org\.apache\.commons\.logging
+org\.apache\.commons\.logging\.impl
+org\.apache\.http
+org\.apache\.http\.auth
+org\.apache\.http\.auth\.params
+org\.apache\.http\.client
+org\.apache\.http\.client\.entity
+org\.apache\.http\.client\.methods
+org\.apache\.http\.client\.params
+org\.apache\.http\.client\.protocol
+org\.apache\.http\.client\.utils
+org\.apache\.http\.conn
+org\.apache\.http\.conn\.params
+org\.apache\.http\.conn\.routing
+org\.apache\.http\.conn\.scheme
+org\.apache\.http\.conn\.ssl
+org\.apache\.http\.conn\.util
+org\.apache\.http\.cookie
+org\.apache\.http\.cookie\.params
+org\.apache\.http\.entity
+org\.apache\.http\.impl
+org\.apache\.http\.impl\.auth
+org\.apache\.http\.impl\.client
+org\.apache\.http\.impl\.client
+org\.apache\.http\.impl\.conn
+org\.apache\.http\.impl\.conn\.tsccm
+org\.apache\.http\.impl\.cookie
+org\.apache\.http\.impl\.entity
+org\.apache\.http\.impl\.io
+org\.apache\.http\.impl\.io
+org\.apache\.http\.io
+org\.apache\.http\.message
+org\.apache\.http\.params
+org\.apache\.http\.protocol
+org\.apache\.http\.util
+
+# TODO: jarjar gov.nist to com.android
+gov\.nist\.core
+gov\.nist\.core\.net
+gov\.nist\.javax\.sip
+gov\.nist\.javax\.sip\.address
+gov\.nist\.javax\.sip\.clientauthutils
+gov\.nist\.javax\.sip\.header
+gov\.nist\.javax\.sip\.header\.extensions
+gov\.nist\.javax\.sip\.header\.ims
+gov\.nist\.javax\.sip\.message
+gov\.nist\.javax\.sip\.parser
+gov\.nist\.javax\.sip\.parser\.extensions
+gov\.nist\.javax\.sip\.parser\.ims
+gov\.nist\.javax\.sip\.stack
+
+org\.ccil\.cowan\.tagsoup
+org\.ccil\.cowan\.tagsoup\.jaxp
+
+###################################################
+# framework.jar
+javax\.microedition\.khronos\.opengles
+javax\.microedition\.khronos\.egl
+
+android
+
+###################################################
+# apache-xml.jar
+org\.apache\.xml\.res
+org\.apache\.xml\.utils
+org\.apache\.xml\.utils\.res
+org\.apache\.xml\.dtm
+org\.apache\.xml\.dtm\.ref
+org\.apache\.xml\.dtm\.ref\.dom2dtm
+org\.apache\.xml\.dtm\.ref\.sax2dtm
+org\.apache\.xml\.serializer
+org\.apache\.xml\.serializer\.utils
+org\.apache\.xml\.serializer\.dom3
+org\.apache\.xpath
+org\.apache\.xpath\.operations
+org\.apache\.xpath\.domapi
+org\.apache\.xpath\.functions
+org\.apache\.xpath\.res
+org\.apache\.xpath\.axes
+org\.apache\.xpath\.objects
+org\.apache\.xpath\.patterns
+org\.apache\.xpath\.jaxp
+org\.apache\.xpath\.compiler
+org\.apache\.xalan
+org\.apache\.xalan\.res
+org\.apache\.xalan\.templates
+org\.apache\.xalan\.serialize
+org\.apache\.xalan\.extensions
+org\.apache\.xalan\.processor
+org\.apache\.xalan\.transformer
+org\.apache\.xalan\.xslt
+
+###################################################
+# Packages in the google namespace across all bootclasspath jars.
+com\.google\.android\..*
+com\.google\.vr\.platform.*
+com\.google\.i18n\.phonenumbers\..*
+com\.google\.i18n\.phonenumbers
+
+###################################################
+# Packages used for Android in Chrome OS
+org\.chromium\.arc
+org\.chromium\.arc\..*
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index c1813ec..84e4f28 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -464,7 +464,6 @@
arm64: {
export_system_include_dirs: ["arm64/include"],
sanitize: {
- hwaddress: true,
integer_overflow: false,
},
},
@@ -496,7 +495,6 @@
srcs: ["arm64/lib/mynativelib.so"],
export_system_include_dirs: ["arm64/include/arm64/include"],
sanitize: {
- hwaddress: true,
integer_overflow: false,
},
},
@@ -527,7 +525,6 @@
srcs: ["arm64/lib/mynativelib.so"],
export_system_include_dirs: ["arm64/include/arm64/include"],
sanitize: {
- hwaddress: true,
integer_overflow: false,
},
},
@@ -548,7 +545,7 @@
`),
checkAllCopyRules(`
include/Test.h -> include/include/Test.h
-.intermediates/mynativelib/android_arm64_armv8-a_shared_hwasan/mynativelib.so -> arm64/lib/mynativelib.so
+.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so
arm64/include/Arm64Test.h -> arm64/include/arm64/include/Arm64Test.h
.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`),
)
@@ -2727,3 +2724,75 @@
`),
)
}
+
+func TestNoSanitizerMembers(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["mynativelib"],
+ }
+
+ cc_library_shared {
+ name: "mynativelib",
+ srcs: ["Test.cpp"],
+ export_include_dirs: ["include"],
+ arch: {
+ arm64: {
+ export_system_include_dirs: ["arm64/include"],
+ sanitize: {
+ hwaddress: true,
+ },
+ },
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_mynativelib@current",
+ sdk_member_name: "mynativelib",
+ visibility: ["//visibility:public"],
+ installable: false,
+ compile_multilib: "both",
+ export_include_dirs: ["include/include"],
+ arch: {
+ arm64: {
+ export_system_include_dirs: ["arm64/include/arm64/include"],
+ },
+ arm: {
+ srcs: ["arm/lib/mynativelib.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "mynativelib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ compile_multilib: "both",
+ export_include_dirs: ["include/include"],
+ arch: {
+ arm64: {
+ export_system_include_dirs: ["arm64/include/arm64/include"],
+ },
+ arm: {
+ srcs: ["arm/lib/mynativelib.so"],
+ },
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ visibility: ["//visibility:public"],
+ native_shared_libs: ["mysdk_mynativelib@current"],
+}
+`),
+ checkAllCopyRules(`
+include/Test.h -> include/include/Test.h
+arm64/include/Arm64Test.h -> arm64/include/arm64/include/Arm64Test.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`),
+ )
+}