Merge "Update Rust toolchain to 1.50.0"
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index ff85661..317f5c4 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,6 @@
[Builtin Hooks]
gofmt = true
bpfmt = true
+
+[Hook Scripts]
+do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT}
diff --git a/android/apex.go b/android/apex.go
index 6bb0751..4637942 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -757,7 +757,6 @@
"captiveportal-lib": 28,
"flatbuffer_headers": 30,
"framework-permission": 30,
- "framework-statsd": 30,
"gemmlowp_headers": 30,
"ike-internals": 30,
"kotlinx-coroutines-android": 28,
@@ -790,11 +789,6 @@
"libprotobuf-java-lite": 30,
"libprotoutil": 30,
"libqemu_pipe": 30,
- "libstats_jni": 30,
- "libstatslog_statsd": 30,
- "libstatsmetadata": 30,
- "libstatspull": 30,
- "libstatssocket": 30,
"libsync": 30,
"libtextclassifier_hash_headers": 30,
"libtextclassifier_hash_static": 30,
@@ -807,9 +801,6 @@
"philox_random_headers": 30,
"philox_random": 30,
"service-permission": 30,
- "service-statsd": 30,
- "statsd-aidl-ndk_platform": 30,
- "statsd": 30,
"tensorflow_headers": 30,
"xz-java": 29,
})
diff --git a/android/arch.go b/android/arch.go
index b277381..6fb70c9 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1442,7 +1442,7 @@
func getNdkAbisConfig() []archConfig {
return []archConfig{
{"arm", "armv7-a", "", []string{"armeabi-v7a"}},
- {"arm64", "armv8-a", "", []string{"arm64-v8a"}},
+ {"arm64", "armv8-a-branchprot", "", []string{"arm64-v8a"}},
{"x86", "", "", []string{"x86"}},
{"x86_64", "", "", []string{"x86_64"}},
}
@@ -1609,13 +1609,15 @@
} else {
buildTargets = firstTarget(targets, "lib64", "lib32")
}
+ case "first_prefer32":
+ buildTargets = firstTarget(targets, "lib32", "lib64")
case "prefer32":
buildTargets = filterMultilibTargets(targets, "lib32")
if len(buildTargets) == 0 {
buildTargets = filterMultilibTargets(targets, "lib64")
}
default:
- return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", or "prefer32" found %q`,
+ return nil, fmt.Errorf(`compile_multilib must be "both", "first", "32", "64", "prefer32" or "first_prefer32" found %q`,
multilib)
}
diff --git a/android/arch_list.go b/android/arch_list.go
index 0c33b9d..d68a0d1 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -41,6 +41,7 @@
},
Arm64: {
"armv8_a",
+ "armv8_a_branchprot",
"armv8_2a",
"armv8-2a-dotprod",
"cortex-a53",
diff --git a/android/config.go b/android/config.go
index 9162eaa..095b1e4 100644
--- a/android/config.go
+++ b/android/config.go
@@ -128,7 +128,7 @@
// If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error
// in tests when a path doesn't exist.
- testAllowNonExistentPaths bool
+ TestAllowNonExistentPaths bool
// The list of files that when changed, must invalidate soong_build to
// regenerate build.ninja.
@@ -256,7 +256,7 @@
// Set testAllowNonExistentPaths so that test contexts don't need to specify every path
// passed to PathForSource or PathForModuleSrc.
- testAllowNonExistentPaths: true,
+ TestAllowNonExistentPaths: true,
BazelContext: noopBazelContext{},
}
@@ -946,13 +946,7 @@
// More info: https://source.android.com/devices/architecture/rros
func (c *config) EnforceRROForModule(name string) bool {
enforceList := c.productVariables.EnforceRROTargets
- // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency.
- exemptedList := c.productVariables.EnforceRROExemptedTargets
- if len(exemptedList) > 0 {
- if InList(name, exemptedList) {
- return false
- }
- }
+
if len(enforceList) > 0 {
if InList("*", enforceList) {
return true
@@ -961,11 +955,6 @@
}
return false
}
-
-func (c *config) EnforceRROExemptedForModule(name string) bool {
- return InList(name, c.productVariables.EnforceRROExemptedTargets)
-}
-
func (c *config) EnforceRROExcludedOverlay(path string) bool {
excluded := c.productVariables.EnforceRROExcludedOverlays
if len(excluded) > 0 {
diff --git a/android/paths.go b/android/paths.go
index 58e1f74..ada4da6 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -586,7 +586,7 @@
p := pathForModuleSrc(ctx, sPath)
if exists, _, err := ctx.Config().fs.Exists(p.String()); err != nil {
ReportPathErrorf(ctx, "%s: %s", p, err.Error())
- } else if !exists && !ctx.Config().testAllowNonExistentPaths {
+ } else if !exists && !ctx.Config().TestAllowNonExistentPaths {
ReportPathErrorf(ctx, "module source path %q does not exist", p)
}
@@ -1022,7 +1022,7 @@
}
} else if exists, _, err := ctx.Config().fs.Exists(path.String()); err != nil {
ReportPathErrorf(ctx, "%s: %s", path, err.Error())
- } else if !exists && !ctx.Config().testAllowNonExistentPaths {
+ } else if !exists && !ctx.Config().TestAllowNonExistentPaths {
ReportPathErrorf(ctx, "source path %q does not exist", path)
}
return path
diff --git a/android/variable.go b/android/variable.go
index 76666c5..dd000ad 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -199,11 +199,9 @@
CrossHostArch *string `json:",omitempty"`
CrossHostSecondaryArch *string `json:",omitempty"`
- DeviceResourceOverlays []string `json:",omitempty"`
- ProductResourceOverlays []string `json:",omitempty"`
- EnforceRROTargets []string `json:",omitempty"`
- // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency.
- EnforceRROExemptedTargets []string `json:",omitempty"`
+ DeviceResourceOverlays []string `json:",omitempty"`
+ ProductResourceOverlays []string `json:",omitempty"`
+ EnforceRROTargets []string `json:",omitempty"`
EnforceRROExcludedOverlays []string `json:",omitempty"`
AAPTCharacteristics *string `json:",omitempty"`
diff --git a/apex/allowed_deps.txt b/apex/allowed_deps.txt
index aee3fc4..4e7039c 100644
--- a/apex/allowed_deps.txt
+++ b/apex/allowed_deps.txt
@@ -176,12 +176,15 @@
ExtServices-core(minSdkVersion:current)
flatbuffer_headers(minSdkVersion:(no version))
fmtlib(minSdkVersion:29)
+fmtlib_ndk(minSdkVersion:29)
+framework-mediaprovider(minSdkVersion:30)
framework-permission(minSdkVersion:30)
framework-permission(minSdkVersion:current)
framework-permission-s(minSdkVersion:30)
framework-permission-s-shared(minSdkVersion:30)
framework-sdkextensions(minSdkVersion:30)
framework-sdkextensions(minSdkVersion:current)
+framework-statsd(minSdkVersion:30)
framework-statsd(minSdkVersion:current)
framework-tethering(minSdkVersion:30)
framework-tethering(minSdkVersion:current)
@@ -239,6 +242,7 @@
libbacktrace_sys.rust_sysroot(minSdkVersion:29)
libbase(minSdkVersion:29)
libbase_headers(minSdkVersion:29)
+libbase_ndk(minSdkVersion:29)
libbinder_headers(minSdkVersion:29)
libbinder_headers_platform_shared(minSdkVersion:29)
libbinderthreadstateutils(minSdkVersion:29)
@@ -314,6 +318,8 @@
libfmq(minSdkVersion:29)
libfmq-base(minSdkVersion:29)
libFraunhoferAAC(minSdkVersion:29)
+libfuse(minSdkVersion:30)
+libfuse_jni(minSdkVersion:30)
libgav1(minSdkVersion:29)
libgcc(minSdkVersion:(no version))
libgcc_stripped(minSdkVersion:(no version))
@@ -425,11 +431,15 @@
libstagefright_mpeg2extractor(minSdkVersion:29)
libstagefright_mpeg2support_nocrypto(minSdkVersion:29)
libstats_jni(minSdkVersion:(no version))
+libstats_jni(minSdkVersion:30)
libstatslog_resolv(minSdkVersion:29)
libstatslog_statsd(minSdkVersion:(no version))
+libstatslog_statsd(minSdkVersion:30)
libstatspull(minSdkVersion:(no version))
+libstatspull(minSdkVersion:30)
libstatspush_compat(minSdkVersion:29)
libstatssocket(minSdkVersion:(no version))
+libstatssocket(minSdkVersion:30)
libstatssocket_headers(minSdkVersion:29)
libstd(minSdkVersion:29)
libsystem_headers(minSdkVersion:apex_inherit)
@@ -463,6 +473,7 @@
libzstd(minSdkVersion:(no version))
media_ndk_headers(minSdkVersion:29)
media_plugin_headers(minSdkVersion:29)
+MediaProvider(minSdkVersion:30)
mediaswcodec(minSdkVersion:29)
metrics-constants-protos(minSdkVersion:29)
modules-utils-build(minSdkVersion:29)
@@ -592,6 +603,7 @@
service-permission(minSdkVersion:30)
service-permission(minSdkVersion:current)
service-permission-shared(minSdkVersion:30)
+service-statsd(minSdkVersion:30)
service-statsd(minSdkVersion:current)
SettingsLibActionBarShadow(minSdkVersion:21)
SettingsLibAppPreference(minSdkVersion:21)
@@ -605,7 +617,9 @@
SettingsLibUtils(minSdkVersion:21)
stats_proto(minSdkVersion:29)
statsd(minSdkVersion:(no version))
+statsd(minSdkVersion:30)
statsd-aidl-ndk_platform(minSdkVersion:(no version))
+statsd-aidl-ndk_platform(minSdkVersion:30)
statsprotos(minSdkVersion:29)
tensorflow_headers(minSdkVersion:(no version))
Tethering(minSdkVersion:30)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 181946b..bbc4b93 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2039,7 +2039,7 @@
},
{
name: "Updatable apex with non-stable transitive dep",
- expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against non-public Android API.",
+ expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.",
bp: `
apex {
name: "myapex",
diff --git a/bloaty/Android.bp b/bloaty/Android.bp
new file mode 100644
index 0000000..b1f1e39
--- /dev/null
+++ b/bloaty/Android.bp
@@ -0,0 +1,40 @@
+bootstrap_go_package {
+ name: "soong-bloaty",
+ pkgPath: "android/soong/bloaty",
+ deps: [
+ "blueprint",
+ "soong-android",
+ ],
+ srcs: [
+ "bloaty.go",
+ ],
+ pluginFor: ["soong_build"],
+}
+
+python_test_host {
+ name: "bloaty_merger_test",
+ srcs: [
+ "bloaty_merger_test.py",
+ "bloaty_merger.py",
+ "file_sections.proto",
+ ],
+ proto: {
+ canonical_path_from_root: false,
+ },
+ libs: [
+ "pyfakefs",
+ "ninja_rsp",
+ ],
+}
+
+python_binary_host {
+ name: "bloaty_merger",
+ srcs: [
+ "bloaty_merger.py",
+ "file_sections.proto",
+ ],
+ proto: {
+ canonical_path_from_root: false,
+ },
+ libs: ["ninja_rsp"],
+}
diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go
new file mode 100644
index 0000000..0bff8aa
--- /dev/null
+++ b/bloaty/bloaty.go
@@ -0,0 +1,92 @@
+// Copyright 2021 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 bloaty implements a singleton that measures binary (e.g. ELF
+// executable, shared library or Rust rlib) section sizes at build time.
+package bloaty
+
+import (
+ "android/soong/android"
+
+ "github.com/google/blueprint"
+)
+
+const bloatyDescriptorExt = "bloaty.csv"
+
+var (
+ fileSizeMeasurerKey blueprint.ProviderKey
+ pctx = android.NewPackageContext("android/soong/bloaty")
+
+ // bloaty is used to measure a binary section sizes.
+ bloaty = pctx.AndroidStaticRule("bloaty",
+ blueprint.RuleParams{
+ Command: "${bloaty} -n 0 --csv ${in} > ${out}",
+ CommandDeps: []string{"${bloaty}"},
+ })
+
+ // The bloaty merger script is used to combine the outputs from bloaty
+ // into a single protobuf.
+ bloatyMerger = pctx.AndroidStaticRule("bloatyMerger",
+ blueprint.RuleParams{
+ Command: "${bloatyMerger} ${out}.lst ${out}",
+ CommandDeps: []string{"${bloatyMerger}"},
+ Rspfile: "${out}.lst",
+ RspfileContent: "${in}",
+ })
+)
+
+func init() {
+ pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
+ pctx.SourcePathVariable("bloaty", "prebuilts/build-tools/${hostPrebuiltTag}/bin/bloaty")
+ pctx.HostBinToolVariable("bloatyMerger", "bloaty_merger")
+ android.RegisterSingletonType("file_metrics", fileSizesSingleton)
+ fileSizeMeasurerKey = blueprint.NewProvider(android.ModuleOutPath{})
+}
+
+// MeasureSizeForPath should be called by binary producers (e.g. in builder.go).
+func MeasureSizeForPath(ctx android.ModuleContext, filePath android.WritablePath) {
+ ctx.SetProvider(fileSizeMeasurerKey, filePath)
+}
+
+type sizesSingleton struct{}
+
+func fileSizesSingleton() android.Singleton {
+ return &sizesSingleton{}
+}
+
+func (singleton *sizesSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var deps android.Paths
+ // Visit all modules. If the size provider give us a binary path to measure,
+ // create the rule to measure it.
+ ctx.VisitAllModules(func(m android.Module) {
+ if !ctx.ModuleHasProvider(m, fileSizeMeasurerKey) {
+ return
+ }
+ filePath := ctx.ModuleProvider(m, fileSizeMeasurerKey).(android.ModuleOutPath)
+ sizeFile := filePath.ReplaceExtension(ctx, bloatyDescriptorExt)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: bloaty,
+ Description: "bloaty " + filePath.Rel(),
+ Input: filePath,
+ Output: sizeFile,
+ })
+ deps = append(deps, sizeFile)
+ })
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: bloatyMerger,
+ Inputs: android.SortedUniquePaths(deps),
+ Output: android.PathForOutput(ctx, "binary_sizes.pb"),
+ })
+}
diff --git a/bloaty/bloaty_merger.py b/bloaty/bloaty_merger.py
new file mode 100644
index 0000000..c873fb8
--- /dev/null
+++ b/bloaty/bloaty_merger.py
@@ -0,0 +1,79 @@
+# Copyright 2021 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.
+"""Bloaty CSV Merger
+
+Merges a list of .csv files from Bloaty into a protobuf. It takes the list as
+a first argument and the output as second. For instance:
+
+ $ bloaty_merger binary_sizes.lst binary_sizes.pb
+
+"""
+
+import argparse
+import csv
+
+import ninja_rsp
+
+import file_sections_pb2
+
+BLOATY_EXTENSION = ".bloaty.csv"
+
+def parse_csv(path):
+ """Parses a Bloaty-generated CSV file into a protobuf.
+
+ Args:
+ path: The filepath to the CSV file, relative to $ANDROID_TOP.
+
+ Returns:
+ A file_sections_pb2.File if the file was found; None otherwise.
+ """
+ file_proto = None
+ with open(path, newline='') as csv_file:
+ file_proto = file_sections_pb2.File()
+ if path.endswith(BLOATY_EXTENSION):
+ file_proto.path = path[:-len(BLOATY_EXTENSION)]
+ section_reader = csv.DictReader(csv_file)
+ for row in section_reader:
+ section = file_proto.sections.add()
+ section.name = row["sections"]
+ section.vm_size = int(row["vmsize"])
+ section.file_size = int(row["filesize"])
+ return file_proto
+
+def create_file_size_metrics(input_list, output_proto):
+ """Creates a FileSizeMetrics proto from a list of CSV files.
+
+ Args:
+ input_list: The path to the file which contains the list of CSV files. Each
+ filepath is separated by a space.
+ output_proto: The path for the output protobuf.
+ """
+ metrics = file_sections_pb2.FileSizeMetrics()
+ reader = ninja_rsp.NinjaRspFileReader(input_list)
+ for csv_path in reader:
+ file_proto = parse_csv(csv_path)
+ if file_proto:
+ metrics.files.append(file_proto)
+ with open(output_proto, "wb") as output:
+ output.write(metrics.SerializeToString())
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("input_list_file", help="List of bloaty csv files.")
+ parser.add_argument("output_proto", help="Output proto.")
+ args = parser.parse_args()
+ create_file_size_metrics(args.input_list_file, args.output_proto)
+
+if __name__ == '__main__':
+ main()
diff --git a/bloaty/bloaty_merger_test.py b/bloaty/bloaty_merger_test.py
new file mode 100644
index 0000000..0e3641d
--- /dev/null
+++ b/bloaty/bloaty_merger_test.py
@@ -0,0 +1,65 @@
+# Copyright 2021 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.
+import unittest
+
+from pyfakefs import fake_filesystem_unittest
+
+import bloaty_merger
+import file_sections_pb2
+
+
+class BloatyMergerTestCase(fake_filesystem_unittest.TestCase):
+ def setUp(self):
+ self.setUpPyfakefs()
+
+ def test_parse_csv(self):
+ csv_content = "sections,vmsize,filesize\nsection1,2,3\n"
+ self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+ pb = bloaty_merger.parse_csv("file1.bloaty.csv")
+ self.assertEqual(pb.path, "file1")
+ self.assertEqual(len(pb.sections), 1)
+ s = pb.sections[0]
+ self.assertEqual(s.name, "section1")
+ self.assertEqual(s.vm_size, 2)
+ self.assertEqual(s.file_size, 3)
+
+ def test_missing_file(self):
+ with self.assertRaises(FileNotFoundError):
+ bloaty_merger.parse_csv("missing.bloaty.csv")
+
+ def test_malformed_csv(self):
+ csv_content = "header1,heaVder2,header3\n4,5,6\n"
+ self.fs.create_file("file1.bloaty.csv", contents=csv_content)
+ with self.assertRaises(KeyError):
+ bloaty_merger.parse_csv("file1.bloaty.csv")
+
+ def test_create_file_metrics(self):
+ file_list = "file1.bloaty.csv file2.bloaty.csv"
+ file1_content = "sections,vmsize,filesize\nsection1,2,3\nsection2,7,8"
+ file2_content = "sections,vmsize,filesize\nsection1,4,5\n"
+
+ self.fs.create_file("files.lst", contents=file_list)
+ self.fs.create_file("file1.bloaty.csv", contents=file1_content)
+ self.fs.create_file("file2.bloaty.csv", contents=file2_content)
+
+ bloaty_merger.create_file_size_metrics("files.lst", "output.pb")
+
+ metrics = file_sections_pb2.FileSizeMetrics()
+ with open("output.pb", "rb") as output:
+ metrics.ParseFromString(output.read())
+
+
+if __name__ == '__main__':
+ suite = unittest.TestLoader().loadTestsFromTestCase(BloatyMergerTestCase)
+ unittest.TextTestRunner(verbosity=2).run(suite)
diff --git a/bloaty/file_sections.proto b/bloaty/file_sections.proto
new file mode 100644
index 0000000..34a32db
--- /dev/null
+++ b/bloaty/file_sections.proto
@@ -0,0 +1,39 @@
+// Copyright 2021 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.
+syntax = "proto2";
+
+package file_sections;
+
+message SectionDescriptior {
+ // Name of the section (e.g. .rodata)
+ optional string name = 1;
+
+ // Size of that section as part of the file.
+ optional uint64 file_size = 2;
+
+ // Size of that section when loaded in memory.
+ optional uint64 vm_size = 3;
+}
+
+message File {
+ // Relative path from $OUT_DIR.
+ optional string path = 1;
+
+ // File sections.
+ repeated SectionDescriptior sections = 2;
+}
+
+message FileSizeMetrics {
+ repeated File files = 1;
+}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index ddde1b7..521bb06 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -22,7 +22,8 @@
testSrcs: [
"build_conversion_test.go",
"bzl_conversion_test.go",
- "cc_conversion_test.go",
+ "cc_library_headers_conversion_test.go",
+ "cc_object_conversion_test.go",
"conversion_test.go",
"sh_conversion_test.go",
"testing.go",
diff --git a/bp2build/cc_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
similarity index 100%
rename from bp2build/cc_conversion_test.go
rename to bp2build/cc_library_headers_conversion_test.go
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
new file mode 100644
index 0000000..e4ffe16
--- /dev/null
+++ b/bp2build/cc_object_conversion_test.go
@@ -0,0 +1,186 @@
+// Copyright 2021 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "fmt"
+ "strings"
+ "testing"
+)
+
+func TestCcObjectBp2Build(t *testing.T) {
+ testCases := []struct {
+ description string
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ blueprint string
+ expectedBazelTargets []string
+ filesystem map[string]string
+ }{
+ {
+ description: "simple cc_object generates cc_object with include header dep",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ filesystem: map[string]string{
+ "a/b/foo.h": "",
+ "a/b/bar.h": "",
+ "a/b/c.c": "",
+ },
+ blueprint: `cc_object {
+ name: "foo",
+ local_include_dirs: ["include"],
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+ srcs: [
+ "a/b/*.h",
+ "a/b/c.c"
+ ],
+
+ bazel_module: { bp2build_available: true },
+}
+`,
+ expectedBazelTargets: []string{`cc_object(
+ name = "foo",
+ copts = [
+ "-fno-addrsig",
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+ local_include_dirs = [
+ "include",
+ ],
+ srcs = [
+ "a/b/bar.h",
+ "a/b/foo.h",
+ "a/b/c.c",
+ ],
+)`,
+ },
+ },
+ {
+ description: "simple cc_object with defaults",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
+ name: "foo",
+ local_include_dirs: ["include"],
+ srcs: [
+ "a/b/*.h",
+ "a/b/c.c"
+ ],
+
+ defaults: ["foo_defaults"],
+ bazel_module: { bp2build_available: true },
+}
+
+cc_defaults {
+ name: "foo_defaults",
+ defaults: ["foo_bar_defaults"],
+ // TODO(b/178130668): handle configurable attributes that depend on the platform
+ arch: {
+ x86: {
+ cflags: ["-fPIC"],
+ },
+ x86_64: {
+ cflags: ["-fPIC"],
+ },
+ },
+}
+
+cc_defaults {
+ name: "foo_bar_defaults",
+ cflags: [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ ],
+}
+`,
+ expectedBazelTargets: []string{`cc_object(
+ name = "foo",
+ copts = [
+ "-Wno-gcc-compat",
+ "-Wall",
+ "-Werror",
+ "-fno-addrsig",
+ ],
+ local_include_dirs = [
+ "include",
+ ],
+ srcs = [
+ "a/b/c.c",
+ ],
+)`,
+ },
+ },
+ }
+
+ dir := "."
+ for _, testCase := range testCases {
+ filesystem := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
+ }
+ for f, content := range testCase.filesystem {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ filesystem[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, testCase.blueprint, filesystem)
+ ctx := android.NewTestContext(config)
+ // Always register cc_defaults module factory
+ ctx.RegisterModuleType("cc_defaults", func() android.Module { return cc.DefaultsFactory() })
+
+ ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
+
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if Errored(t, testCase.description, errs) {
+ continue
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if Errored(t, testCase.description, errs) {
+ continue
+ }
+
+ bazelTargets := GenerateBazelTargets(ctx.Context.Context, Bp2Build)[dir]
+ if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
+ fmt.Println(bazelTargets)
+ t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
+ } else {
+ for i, target := range bazelTargets {
+ if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
+ t.Errorf(
+ "%s: Expected generated Bazel target to be '%s', got '%s'",
+ testCase.description,
+ w,
+ g,
+ )
+ }
+ }
+ }
+ }
+}
diff --git a/cc/cc.go b/cc/cc.go
index 7f59158..6c1469f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -28,6 +28,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc/config"
"android/soong/genrule"
)
@@ -364,6 +365,8 @@
// can depend on libraries that are not exported by the APEXes and use private symbols
// from the exported libraries.
Test_for []string
+
+ bazel.Properties
}
type VendorProperties struct {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index e6024aa..d083d2a 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -31,6 +31,10 @@
"armv8-a": []string{
"-march=armv8-a",
},
+ "armv8-a-branchprot": []string{
+ "-march=armv8-a",
+ "-mbranch-protection=standard",
+ },
"armv8-2a": []string{
"-march=armv8.2-a",
},
@@ -102,6 +106,7 @@
pctx.StaticVariable("Arm64ClangCppflags", strings.Join(ClangFilterUnknownCflags(arm64Cppflags), " "))
pctx.StaticVariable("Arm64ClangArmv8ACflags", strings.Join(arm64ArchVariantCflags["armv8-a"], " "))
+ pctx.StaticVariable("Arm64ClangArmv8ABranchProtCflags", strings.Join(arm64ArchVariantCflags["armv8-a-branchprot"], " "))
pctx.StaticVariable("Arm64ClangArmv82ACflags", strings.Join(arm64ArchVariantCflags["armv8-2a"], " "))
pctx.StaticVariable("Arm64ClangArmv82ADotprodCflags", strings.Join(arm64ArchVariantCflags["armv8-2a-dotprod"], " "))
@@ -124,6 +129,7 @@
var (
arm64ClangArchVariantCflagsVar = map[string]string{
"armv8-a": "${config.Arm64ClangArmv8ACflags}",
+ "armv8-a-branchprot": "${config.Arm64ClangArmv8ABranchProtCflags}",
"armv8-2a": "${config.Arm64ClangArmv82ACflags}",
"armv8-2a-dotprod": "${config.Arm64ClangArmv82ADotprodCflags}",
}
@@ -202,6 +208,7 @@
func arm64ToolchainFactory(arch android.Arch) Toolchain {
switch arch.ArchVariant {
case "armv8-a":
+ case "armv8-a-branchprot":
case "armv8-2a":
case "armv8-2a-dotprod":
// Nothing extra for armv8-a/armv8-2a
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 76186be..5e46d5a 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -151,8 +151,6 @@
// This macro allows the bionic versioning.h to indirectly determine whether the
// option -Wunguarded-availability is on or not.
"-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
- // TODO: remove this once prebuilt SDKs are only using the above macro instead.
- "-D__ANDROID_UNGUARDED_AVAILABILITY__",
}, " "))
pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
diff --git a/cc/fuzz.go b/cc/fuzz.go
index d7da5ab..9fe5b17 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -20,6 +20,8 @@
"sort"
"strings"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/cc/config"
)
@@ -172,7 +174,7 @@
// This function takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
-// - The module is not a shared library, or
+// - The module is not an installable shared library, or
// - The module is a header, stub, or vendor-linked library, or
// - The module is a prebuilt and its source is available, or
// - The module is a versioned member of an SDK snapshot.
@@ -209,6 +211,11 @@
if _, isLLndkStubLibrary := ccLibrary.linker.(*stubDecorator); isLLndkStubLibrary {
return false
}
+ // Discard installable:false libraries because they are expected to be absent
+ // in runtime.
+ if !proptools.BoolDefault(ccLibrary.Properties.Installable, true) {
+ return false
+ }
}
// If the same library is present both as source and a prebuilt we must pick
diff --git a/cc/library.go b/cc/library.go
index bdcb8ae..65533bc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -27,7 +27,6 @@
"github.com/google/blueprint/pathtools"
"android/soong/android"
- "android/soong/bazel"
"android/soong/cc/config"
)
@@ -121,9 +120,6 @@
// If this is an LLNDK library, properties to describe the LLNDK stubs. Will be copied from
// the module pointed to by llndk_stubs if it is set.
Llndk llndkLibraryProperties
-
- // Properties for Bazel migration purposes.
- bazel.Properties
}
// StaticProperties is a properties stanza to affect only attributes of the "static" variants of a
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 448e144..e5a5557 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -86,6 +86,10 @@
return
}
+ if !module.Properties.Bazel_module.Bp2build_available {
+ return
+ }
+
lib, ok := module.linker.(*libraryDecorator)
if !ok {
// Not a cc_library module
@@ -96,10 +100,6 @@
return
}
- if !lib.Properties.Bazel_module.Bp2build_available {
- return
- }
-
// list of directories that will be added to the include path (using -I) for this
// module and any module that links against this module.
includeDirs := lib.flagExporter.Properties.Export_system_include_dirs
diff --git a/cc/object.go b/cc/object.go
index 3ce7676..d92e110 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -18,6 +18,7 @@
"fmt"
"android/soong/android"
+ "android/soong/bazel"
)
//
@@ -27,6 +28,8 @@
func init() {
android.RegisterModuleType("cc_object", ObjectFactory)
android.RegisterSdkMemberType(ccObjectSdkMemberType)
+
+ android.RegisterBp2BuildMutator("cc_object", ObjectBp2Build)
}
var ccObjectSdkMemberType = &librarySdkMemberType{
@@ -82,9 +85,80 @@
module.compiler.appendCflags([]string{"-fno-addrsig"})
module.sdkMemberTypes = []android.SdkMemberType{ccObjectSdkMemberType}
+
return module.Init()
}
+// For bp2build conversion.
+type bazelObjectAttributes struct {
+ Srcs bazel.LabelList
+ Copts []string
+ Local_include_dirs []string
+}
+
+type bazelObject struct {
+ android.BazelTargetModuleBase
+ bazelObjectAttributes
+}
+
+func (m *bazelObject) Name() string {
+ return m.BaseModuleName()
+}
+
+func (m *bazelObject) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
+
+func BazelObjectFactory() android.Module {
+ module := &bazelObject{}
+ module.AddProperties(&module.bazelObjectAttributes)
+ android.InitBazelTargetModule(module)
+ return module
+}
+
+// ObjectBp2Build is the bp2build converter from cc_object modules to the
+// Bazel equivalent target, plus any necessary include deps for the cc_object.
+func ObjectBp2Build(ctx android.TopDownMutatorContext) {
+ m, ok := ctx.Module().(*Module)
+ if !ok || !m.Properties.Bazel_module.Bp2build_available {
+ return
+ }
+
+ // a Module can be something other than a cc_object.
+ if ctx.ModuleType() != "cc_object" {
+ return
+ }
+
+ if m.compiler == nil {
+ // a cc_object must have access to the compiler decorator for its props.
+ ctx.ModuleErrorf("compiler must not be nil for a cc_object module")
+ }
+
+ var copts []string
+ var srcs []string
+ var localIncludeDirs []string
+ for _, props := range m.compiler.compilerProps() {
+ if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
+ copts = baseCompilerProps.Cflags
+ srcs = baseCompilerProps.Srcs
+ localIncludeDirs = baseCompilerProps.Local_include_dirs
+ break
+ }
+ }
+
+ attrs := &bazelObjectAttributes{
+ Srcs: android.BazelLabelForModuleSrc(ctx, srcs),
+ Copts: copts,
+ Local_include_dirs: localIncludeDirs,
+ }
+
+ props := bazel.NewBazelTargetModuleProperties(
+ m.Name(),
+ "cc_object",
+ "//build/bazel/rules:cc_object.bzl",
+ )
+
+ ctx.CreateBazelTargetModule(BazelObjectFactory, props, attrs)
+}
+
func (object *objectLinker) appendLdflags(flags []string) {
panic(fmt.Errorf("appendLdflags on objectLinker not supported"))
}
diff --git a/cc/test.go b/cc/test.go
index 17ac534..68e05ba 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -232,7 +232,6 @@
type testDecorator struct {
Properties TestProperties
linker *baseLinker
- hod android.HostOrDeviceSupported
}
func (test *testDecorator) gtest() bool {
@@ -432,8 +431,7 @@
ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
}
- // TODO(179092189): Clean up to use Ctx.Host() when generalizing to cc_test
- if test.testDecorator.hod == android.HostSupported && test.gtest() && test.Properties.Test_options.Unit_test == nil {
+ if ctx.Host() && test.gtest() && test.Properties.Test_options.Unit_test == nil {
test.Properties.Test_options.Unit_test = proptools.BoolPtr(true)
}
test.binaryDecorator.baseInstaller.install(ctx, file)
@@ -447,7 +445,6 @@
test := &testBinary{
testDecorator: testDecorator{
linker: binary.baseLinker,
- hod: hod,
},
binaryDecorator: binary,
baseCompiler: NewBaseCompiler(),
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 57563eb..e15324b 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -282,11 +282,14 @@
Input: p.sourceFilePath,
})
- if p.Installable() {
- installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
- for _, sl := range p.properties.Symlinks {
- ctx.InstallSymlink(p.installDirPath, sl, installPath)
- }
+ if !p.Installable() {
+ p.SkipInstall()
+ }
+
+ // Call InstallFile even when uninstallable to make the module included in the package
+ installPath := ctx.InstallFile(p.installDirPath, p.outputFilePath.Base(), p.outputFilePath)
+ for _, sl := range p.properties.Symlinks {
+ ctx.InstallSymlink(p.installDirPath, sl, installPath)
}
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 7658154..3bccde9 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -16,6 +16,8 @@
import (
"fmt"
+ "path/filepath"
+ "strings"
"android/soong/android"
@@ -37,6 +39,11 @@
installDir android.InstallPath
}
+type symlinkDefinition struct {
+ Target *string
+ Name *string
+}
+
type filesystemProperties struct {
// When set to true, sign the image with avbtool. Default is false.
Use_avb *bool
@@ -54,6 +61,16 @@
// file_contexts file to make image. Currently, only ext4 is supported.
File_contexts *string `android:"path"`
+
+ // Base directory relative to root, to which deps are installed, e.g. "system". Default is "."
+ // (root).
+ Base_dir *string
+
+ // Directories to be created under root. e.g. /dev, /proc, etc.
+ Dirs []string
+
+ // Symbolic links to be created under root with "ln -sf <target> <name>".
+ Symlinks []symlinkDefinition
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -124,16 +141,75 @@
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
}
+// root zip will contain stuffs like dirs or symlinks.
+func (f *filesystem) buildRootZip(ctx android.ModuleContext) android.OutputPath {
+ rootDir := android.PathForModuleGen(ctx, "root").OutputPath
+ builder := android.NewRuleBuilder(pctx, ctx)
+ builder.Command().Text("rm -rf").Text(rootDir.String())
+ builder.Command().Text("mkdir -p").Text(rootDir.String())
+
+ // create dirs and symlinks
+ for _, dir := range f.properties.Dirs {
+ // OutputPath.Join verifies dir
+ builder.Command().Text("mkdir -p").Text(rootDir.Join(ctx, dir).String())
+ }
+
+ for _, symlink := range f.properties.Symlinks {
+ name := strings.TrimSpace(proptools.String(symlink.Name))
+ target := strings.TrimSpace(proptools.String(symlink.Target))
+
+ if name == "" {
+ ctx.PropertyErrorf("symlinks", "Name can't be empty")
+ continue
+ }
+
+ if target == "" {
+ ctx.PropertyErrorf("symlinks", "Target can't be empty")
+ continue
+ }
+
+ // OutputPath.Join verifies name. don't need to verify target.
+ dst := rootDir.Join(ctx, name)
+
+ builder.Command().Text("mkdir -p").Text(filepath.Dir(dst.String()))
+ builder.Command().Text("ln -sf").Text(proptools.ShellEscape(target)).Text(dst.String())
+ }
+
+ zipOut := android.PathForModuleGen(ctx, "root.zip").OutputPath
+
+ builder.Command().
+ BuiltTool("soong_zip").
+ FlagWithOutput("-o ", zipOut).
+ FlagWithArg("-C ", rootDir.String()).
+ Flag("-L 0"). // no compression because this will be unzipped soon
+ FlagWithArg("-D ", rootDir.String()).
+ Flag("-d") // include empty directories
+ builder.Command().Text("rm -rf").Text(rootDir.String())
+
+ builder.Build("zip_root", fmt.Sprintf("zipping root contents for %s", ctx.ModuleName()))
+ return zipOut
+}
+
func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.OutputPath {
- zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
- f.CopyDepsToZip(ctx, zipFile)
+ depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
+ f.CopyDepsToZip(ctx, depsZipFile)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
+ rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
+ builder.Command().
+ BuiltTool("zip2zip").
+ FlagWithInput("-i ", depsZipFile).
+ FlagWithOutput("-o ", rebasedDepsZip).
+ Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
+ rootZip := f.buildRootZip(ctx)
builder.Command().
BuiltTool("zipsync").
FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(zipFile)
+ Input(rootZip).
+ Input(rebasedDepsZip)
propFile, toolDeps := f.buildPropFile(ctx)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
@@ -187,7 +263,7 @@
}
addStr("fs_type", fsTypeStr(f.fsType(ctx)))
- addStr("mount_point", "system")
+ addStr("mount_point", "/")
addStr("use_dynamic_partition_size", "true")
addPath("ext_mkuserimg", ctx.Config().HostToolPath(ctx, "mkuserimg_mke2fs"))
// b/177813163 deps of the host tools have to be added. Remove this.
@@ -233,15 +309,25 @@
ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
}
- zipFile := android.PathForModuleOut(ctx, "temp.zip").OutputPath
- f.CopyDepsToZip(ctx, zipFile)
+ depsZipFile := android.PathForModuleOut(ctx, "deps.zip").OutputPath
+ f.CopyDepsToZip(ctx, depsZipFile)
+
+ builder := android.NewRuleBuilder(pctx, ctx)
+ depsBase := proptools.StringDefault(f.properties.Base_dir, ".")
+ rebasedDepsZip := android.PathForModuleOut(ctx, "rebased_deps.zip").OutputPath
+ builder.Command().
+ BuiltTool("zip2zip").
+ FlagWithInput("-i ", depsZipFile).
+ FlagWithOutput("-o ", rebasedDepsZip).
+ Text("**/*:" + proptools.ShellEscape(depsBase)) // zip2zip verifies depsBase
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
- builder := android.NewRuleBuilder(pctx, ctx)
+ rootZip := f.buildRootZip(ctx)
builder.Command().
BuiltTool("zipsync").
FlagWithArg("-d ", rootDir.String()). // zipsync wipes this. No need to clear.
- Input(zipFile)
+ Input(rootZip).
+ Input(rebasedDepsZip)
output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
cmd := builder.Command().
diff --git a/java/aar.go b/java/aar.go
index ac7ae25..602d2c4 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -160,8 +160,8 @@
func (a *aapt) IsRROEnforced(ctx android.BaseModuleContext) bool {
// True if RRO is enforced for this module or...
return ctx.Config().EnforceRROForModule(ctx.ModuleName()) ||
- // if RRO is enforced for any of its dependents, and this module is not exempted.
- (a.aaptProperties.RROEnforcedForDependent && !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()))
+ // if RRO is enforced for any of its dependents.
+ a.aaptProperties.RROEnforcedForDependent
}
func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
@@ -443,16 +443,14 @@
assets = append(assets, aarDep.ExportedAssets().Path())
}
- if !ctx.Config().EnforceRROExemptedForModule(ctx.ModuleName()) {
- outer:
- for _, d := range aarDep.ExportedRRODirs() {
- for _, e := range staticRRODirs {
- if d.path == e.path {
- continue outer
- }
+ outer:
+ for _, d := range aarDep.ExportedRRODirs() {
+ for _, e := range staticRRODirs {
+ if d.path == e.path {
+ continue outer
}
- staticRRODirs = append(staticRRODirs, d)
}
+ staticRRODirs = append(staticRRODirs, d)
}
}
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index c315124..282e936 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -82,10 +82,6 @@
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
artModules := global.ArtApexJars
- // With EMMA_INSTRUMENT_FRAMEWORK=true the Core libraries depend on jacoco.
- if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- artModules = artModules.Append("com.android.art", "jacocoagent")
- }
frameworkModules := global.BootJars.RemoveList(artModules)
artSubdir := "apex/art_boot_images/javalib"
diff --git a/java/java.go b/java/java.go
index 69ec2a4..dbfad02 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1014,6 +1014,7 @@
const (
// TODO(jiyong) rename these for better readability. Make the allowed
// and disallowed link types explicit
+ // order is important here. See rank()
javaCore linkType = iota
javaSdk
javaSystem
@@ -1022,6 +1023,31 @@
javaPlatform
)
+func (lt linkType) String() string {
+ switch lt {
+ case javaCore:
+ return "core Java API"
+ case javaSdk:
+ return "Android API"
+ case javaSystem:
+ return "system API"
+ case javaModule:
+ return "module API"
+ case javaSystemServer:
+ return "system server API"
+ case javaPlatform:
+ return "private API"
+ default:
+ panic(fmt.Errorf("unrecognized linktype: %v", lt))
+ }
+}
+
+// rank determins the total order among linkTypes. A link type of rank A can link to another link
+// type of rank B only when B <= A
+func (lt linkType) rank() int {
+ return int(lt)
+}
+
type linkTypeContext interface {
android.Module
getLinkType(name string) (ret linkType, stubs bool)
@@ -1081,44 +1107,13 @@
return
}
otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to))
- commonMessage := " In order to fix this, consider adjusting sdk_version: OR platform_apis: " +
- "property of the source or target module so that target module is built with the same " +
- "or smaller API set when compared to the source."
- switch myLinkType {
- case javaCore:
- if otherLinkType != javaCore {
- ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSdk:
- if otherLinkType != javaCore && otherLinkType != javaSdk {
- ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSystem:
- if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer {
- ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaModule:
- if otherLinkType == javaPlatform || otherLinkType == javaSystemServer {
- ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaSystemServer:
- if otherLinkType == javaPlatform {
- ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage,
- ctx.OtherModuleName(to))
- }
- break
- case javaPlatform:
- // no restriction on link-type
- break
+ if myLinkType.rank() < otherLinkType.rank() {
+ ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+
+ "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+
+ "property of the source or target module so that target module is built "+
+ "with the same or smaller API set when compared to the source.",
+ myLinkType, ctx.OtherModuleName(to), otherLinkType)
}
}
diff --git a/java/java_test.go b/java/java_test.go
index e7776c3..0ef4db6 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -127,7 +127,6 @@
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
-
return ctx, config
}
@@ -1179,6 +1178,110 @@
}
}
+func TestJavaLint(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{
+ "lint-baseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if !strings.Contains(rule.RuleParams.Command, "--baseline lint-baseline.xml") {
+ t.Error("did not pass --baseline flag")
+ }
+}
+
+func TestJavaLintWithoutBaseline(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ }
+ `, map[string][]byte{})
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if strings.Contains(rule.RuleParams.Command, "--baseline") {
+ t.Error("passed --baseline flag for non existent file")
+ }
+}
+
+func TestJavaLintRequiresCustomLintFileToExist(t *testing.T) {
+ config := testConfig(
+ nil,
+ `
+ java_library {
+ name: "foo",
+ srcs: [
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `, map[string][]byte{
+ "build/soong/java/lint_defaults.txt": nil,
+ "prebuilts/cmdline-tools/tools/bin/lint": nil,
+ "prebuilts/cmdline-tools/tools/lib/lint-classpath.jar": nil,
+ "framework/aidl": nil,
+ "a.java": nil,
+ "AndroidManifest.xml": nil,
+ "build/make/target/product/security": nil,
+ })
+ config.TestAllowNonExistentPaths = false
+ testJavaErrorWithConfig(t,
+ "source path \"mybaseline.xml\" does not exist",
+ config,
+ )
+}
+
+func TestJavaLintUsesCorrectBpConfig(t *testing.T) {
+ ctx, _ := testJavaWithFS(t, `
+ java_library {
+ name: "foo",
+ srcs: [
+ "a.java",
+ "b.java",
+ "c.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "system_current",
+ lint: {
+ error_checks: ["SomeCheck"],
+ baseline_filename: "mybaseline.xml",
+ },
+ }
+ `, map[string][]byte{
+ "mybaseline.xml": nil,
+ })
+
+ foo := ctx.ModuleForTests("foo", "android_common")
+ rule := foo.Rule("lint")
+
+ if !strings.Contains(rule.RuleParams.Command, "--baseline mybaseline.xml") {
+ t.Error("did not use the correct file for baseline")
+ }
+}
+
func TestGeneratedSources(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
java_library {
diff --git a/java/lint.go b/java/lint.go
index c9e0cdd..8272595 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -19,6 +19,8 @@
"sort"
"strings"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
)
@@ -46,6 +48,9 @@
// Modules that provide extra lint checks
Extra_check_modules []string
+
+ // Name of the file that lint uses as the baseline. Defaults to "lint-baseline.xml".
+ Baseline_filename *string
}
}
@@ -344,6 +349,19 @@
cmd.FlagWithArg("--check ", checkOnly)
}
+ if lintFilename := proptools.StringDefault(l.properties.Lint.Baseline_filename, "lint-baseline.xml"); lintFilename != "" {
+ var lintBaseline android.OptionalPath
+ if String(l.properties.Lint.Baseline_filename) != "" {
+ // if manually specified, we require the file to exist
+ lintBaseline = android.OptionalPathForPath(android.PathForModuleSrc(ctx, lintFilename))
+ } else {
+ lintBaseline = android.ExistentPathForSource(ctx, ctx.ModuleDir(), lintFilename)
+ }
+ if lintBaseline.Valid() {
+ cmd.FlagWithInput("--baseline ", lintBaseline.Path())
+ }
+ }
+
cmd.Text("|| (").Text("cat").Input(text).Text("; exit 7)").Text(")")
rule.Command().Text("rm -rf").Flag(cacheDir.String()).Flag(homeDir.String())
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 1e90149..c91b321 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -106,14 +106,18 @@
mctx.CreateModule(ImportFactory, &props)
}
-func createFilegroup(mctx android.LoadHookContext, name string, path string) {
- filegroupProps := struct {
+func createApiModule(mctx android.LoadHookContext, name string, path string) {
+ genruleProps := struct {
Name *string
Srcs []string
+ Out []string
+ Cmd *string
}{}
- filegroupProps.Name = proptools.StringPtr(name)
- filegroupProps.Srcs = []string{path}
- mctx.CreateModule(android.FileGroupFactory, &filegroupProps)
+ genruleProps.Name = proptools.StringPtr(name)
+ genruleProps.Srcs = []string{path}
+ genruleProps.Out = []string{name}
+ genruleProps.Cmd = proptools.StringPtr("cp $(in) $(out)")
+ mctx.CreateModule(genrule.GenRuleFactory, &genruleProps)
}
func createEmptyFile(mctx android.LoadHookContext, name string) {
@@ -205,16 +209,16 @@
path string
}
- // Create filegroups for all (<module>, <scope, <version>) triplets,
- // and a "latest" filegroup variant for each (<module>, <scope>) pair
- moduleName := func(module, scope, version string) string {
+ // Create modules for all (<module>, <scope, <version>) triplets,
+ // and a "latest" module variant for each (<module>, <scope>) pair
+ apiModuleName := func(module, scope, version string) string {
return module + ".api." + scope + "." + version
}
m := make(map[string]latestApiInfo)
for _, f := range files {
localPath := strings.TrimPrefix(f, mydir)
module, apiver, scope := parseApiFilePath(mctx, localPath)
- createFilegroup(mctx, moduleName(module, scope, apiver), localPath)
+ createApiModule(mctx, apiModuleName(module, scope, apiver), localPath)
version, err := strconv.Atoi(apiver)
if err != nil {
@@ -239,8 +243,8 @@
// Sort the keys in order to make build.ninja stable
for _, k := range android.SortedStringKeys(m) {
info := m[k]
- name := moduleName(info.module, info.scope, "latest")
- createFilegroup(mctx, name, info.path)
+ name := apiModuleName(info.module, info.scope, "latest")
+ createApiModule(mctx, name, info.path)
}
// Create incompatibilities tracking files for all modules, if we have a "next" api.
@@ -258,14 +262,14 @@
referencedModule = "android"
}
- createFilegroup(mctx, moduleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
+ createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
incompatibilities[referencedModule+"."+scope] = true
}
// Create empty incompatibilities files for remaining modules
for _, k := range android.SortedStringKeys(m) {
if _, ok := incompatibilities[k]; !ok {
- createEmptyFile(mctx, moduleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
+ createEmptyFile(mctx, apiModuleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
}
}
}
@@ -279,10 +283,10 @@
}
}
-// prebuilt_apis is a meta-module that generates filegroup modules for all
-// API txt files found under the directory where the Android.bp is located.
+// prebuilt_apis is a meta-module that generates modules for all API txt files
+// found under the directory where the Android.bp is located.
// Specifically, an API file located at ./<ver>/<scope>/api/<module>.txt
-// generates a filegroup module named <module>-api.<scope>.<ver>.
+// generates a module named <module>-api.<scope>.<ver>.
//
// It also creates <module>-api.<scope>.latest for the latest <ver>.
//
diff --git a/java/rro_test.go b/java/rro_test.go
index 345f2ee..0a2f848 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -263,47 +263,34 @@
func TestEnforceRRO_propagatesToDependencies(t *testing.T) {
testCases := []struct {
- name string
- enforceRROTargets []string
- enforceRROExemptTargets []string
- rroDirs map[string][]string
+ name string
+ enforceRROTargets []string
+ rroDirs map[string][]string
}{
{
- name: "no RRO",
- enforceRROTargets: nil,
- enforceRROExemptTargets: nil,
+ name: "no RRO",
+ enforceRROTargets: nil,
rroDirs: map[string][]string{
"foo": nil,
"bar": nil,
},
},
{
- name: "enforce RRO on all",
- enforceRROTargets: []string{"*"},
- enforceRROExemptTargets: nil,
+ name: "enforce RRO on all",
+ enforceRROTargets: []string{"*"},
rroDirs: map[string][]string{
"foo": {"product/vendor/blah/overlay/lib2/res"},
"bar": {"product/vendor/blah/overlay/lib2/res"},
},
},
{
- name: "enforce RRO on foo",
- enforceRROTargets: []string{"foo"},
- enforceRROExemptTargets: nil,
+ name: "enforce RRO on foo",
+ enforceRROTargets: []string{"foo"},
rroDirs: map[string][]string{
"foo": {"product/vendor/blah/overlay/lib2/res"},
"bar": {"product/vendor/blah/overlay/lib2/res"},
},
},
- {
- name: "enforce RRO on foo, bar exempted",
- enforceRROTargets: []string{"foo"},
- enforceRROExemptTargets: []string{"bar"},
- rroDirs: map[string][]string{
- "foo": {"product/vendor/blah/overlay/lib2/res"},
- "bar": nil,
- },
- },
}
productResourceOverlays := []string{
@@ -351,9 +338,6 @@
if testCase.enforceRROTargets != nil {
config.TestProductVariables.EnforceRROTargets = testCase.enforceRROTargets
}
- if testCase.enforceRROExemptTargets != nil {
- config.TestProductVariables.EnforceRROExemptedTargets = testCase.enforceRROExemptTargets
- }
ctx := testContext(config)
run(t, ctx, config)
diff --git a/rust/Android.bp b/rust/Android.bp
index 8b2aa30..a29c474 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -8,6 +8,7 @@
deps: [
"soong",
"soong-android",
+ "soong-bloaty",
"soong-cc",
"soong-rust-config",
],
diff --git a/rust/builder.go b/rust/builder.go
index 56fe031..547d705 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -21,6 +21,7 @@
"github.com/google/blueprint"
"android/soong/android"
+ "android/soong/bloaty"
"android/soong/rust/config"
)
@@ -249,6 +250,8 @@
implicits = append(implicits, clippyFile)
}
+ bloaty.MeasureSizeForPath(ctx, outputFile)
+
ctx.Build(pctx, android.BuildParams{
Rule: rustc,
Description: "rustc " + main.Rel(),
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 5066428..186e571 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -26,9 +26,10 @@
Arm64LinkFlags = []string{}
Arm64ArchVariantRustFlags = map[string][]string{
- "armv8-a": []string{},
- "armv8-2a": []string{},
- "armv8-2a-dotprod": []string{},
+ "armv8-a": []string{},
+ "armv8-a-branchprot": []string{},
+ "armv8-2a": []string{},
+ "armv8-2a-dotprod": []string{},
}
)
diff --git a/scripts/Android.bp b/scripts/Android.bp
index b9163cc..310c959 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -209,13 +209,18 @@
test_suites: ["general-tests"],
}
+python_library_host {
+ name: "ninja_rsp",
+ srcs: ["ninja_rsp.py"],
+}
+
python_binary_host {
name: "lint-project-xml",
main: "lint-project-xml.py",
srcs: [
"lint-project-xml.py",
- "ninja_rsp.py",
],
+ libs: ["ninja_rsp"],
}
python_binary_host {
@@ -223,8 +228,8 @@
main: "gen-kotlin-build-file.py",
srcs: [
"gen-kotlin-build-file.py",
- "ninja_rsp.py",
],
+ libs: ["ninja_rsp"],
}
python_binary_host {
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index ac67438..b93c883 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -8,6 +8,7 @@
com.android.art.testing
com.android.conscrypt
com.android.i18n
+ com.android.os.statsd
com.android.runtime
com.android.tzdata
)
diff --git a/scripts/check_do_not_merge.sh b/scripts/check_do_not_merge.sh
new file mode 100755
index 0000000..ad6a0a9
--- /dev/null
+++ b/scripts/check_do_not_merge.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+
+# Copyright (C) 2021 The Android Open Source Project
+#
+# 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.
+
+if git show -s --format=%s $1 | grep -qE '(DO NOT MERGE)|(RESTRICT AUTOMERGE)'; then
+ cat >&2 <<EOF
+DO NOT MERGE and RESTRICT AUTOMERGE very often lead to unintended results
+and are not allowed to be used in this project.
+Please use the Merged-In tag to be more explicit about where this change
+should merge to. Google-internal documentation exists at go/merged-in
+
+If this check is mis-triggering or you know Merged-In is incorrect in this
+situation you can bypass this check with \`repo upload --no-verify\`.
+EOF
+ exit 1
+fi