Merge "convert java proto libraries with bp2build"
diff --git a/android/arch.go b/android/arch.go
index a719cf3..69d66e9 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -829,7 +829,7 @@
const maxArchTypeNameSize = 500
// Convert the type to a new set of types that contains only the arch-specific properties
- // (those that are tagged with `android:"arch_specific"`), and sharded into multiple types
+ // (those that are tagged with `android:"arch_variant"`), and sharded into multiple types
// to keep the runtime-generated names under the limit.
propShards, _ := proptools.FilterPropertyStructSharded(props, maxArchTypeNameSize, filterArchStruct)
diff --git a/android/bazel.go b/android/bazel.go
index 7e5736f..f4fc038 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -198,6 +198,7 @@
// build/bazel is not recursive. Instead list each subdirectory under
// build/bazel explicitly.
"build/bazel":/* recursive = */ false,
+ "build/bazel/ci/dist":/* recursive = */ false,
"build/bazel/examples/android_app":/* recursive = */ true,
"build/bazel/examples/java":/* recursive = */ true,
"build/bazel/bazel_skylib":/* recursive = */ true,
@@ -515,6 +516,8 @@
"art-script", // depends on unconverted modules: dalvikvm, dex2oat
"dex2oat-script", // depends on unconverted modules: dex2oat
+
+ "error_prone_checkerframework_dataflow_nullaway", // TODO(b/219908977): "Error in fail: deps not allowed without srcs; move to runtime_deps?"
}
// Per-module denylist of cc_library modules to only generate the static
@@ -537,6 +540,31 @@
"libadb_pairing_connection",
"libadb_pairing_connection_static",
"libadb_pairing_server", "libadb_pairing_server_static",
+
+ // TODO(b/204811222) support suffix in cc_binary
+ "acvp_modulewrapper",
+ "android.hardware.media.c2@1.0-service-v4l2",
+ "app_process",
+ "bar_test",
+ "bench_cxa_atexit",
+ "bench_noop",
+ "bench_noop_nostl",
+ "bench_noop_static",
+ "boringssl_self_test",
+ "boringssl_self_test_vendor",
+ "bssl",
+ "cavp",
+ "crash_dump",
+ "crasher",
+ "libcxx_test_template",
+ "linker",
+ "memory_replay",
+ "native_bridge_guest_linker",
+ "native_bridge_stub_library_defaults",
+ "noop",
+ "simpleperf_ndk",
+ "toybox-static",
+ "zlib_bench",
}
// Used for quicker lookups
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 0052551..804a5fb 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -73,7 +73,7 @@
}
type BazelContext interface {
- // The below methods involve queuing cquery requests to be later invoked
+ // The methods below involve queuing cquery requests to be later invoked
// by bazel. If any of these methods return (_, false), then the request
// has been queued to be run later.
@@ -561,7 +561,7 @@
return id_string + ">>" + %s(target)
`
- for requestType, _ := range requestTypeToCqueryIdEntries {
+ for requestType := range requestTypeToCqueryIdEntries {
labelMapName := requestType.Name() + "_Labels"
functionName := requestType.Name() + "_Fn"
labelRegistrationMapSection += fmt.Sprintf(mapDeclarationFormatString,
diff --git a/android/config.go b/android/config.go
index 877800a..4a7e0d9 100644
--- a/android/config.go
+++ b/android/config.go
@@ -350,18 +350,19 @@
config := &config{
productVariables: productVariables{
- DeviceName: stringPtr("test_device"),
- Platform_sdk_version: intPtr(30),
- Platform_sdk_codename: stringPtr("S"),
- Platform_version_active_codenames: []string{"S", "Tiramisu"},
- DeviceSystemSdkVersions: []string{"14", "15"},
- Platform_systemsdk_versions: []string{"29", "30"},
- AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
- AAPTPreferredConfig: stringPtr("xhdpi"),
- AAPTCharacteristics: stringPtr("nosdcard"),
- AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
- UncompressPrivAppDex: boolPtr(true),
- ShippingApiLevel: stringPtr("30"),
+ DeviceName: stringPtr("test_device"),
+ Platform_sdk_version: intPtr(30),
+ Platform_sdk_codename: stringPtr("S"),
+ Platform_base_sdk_extension_version: intPtr(1),
+ Platform_version_active_codenames: []string{"S", "Tiramisu"},
+ DeviceSystemSdkVersions: []string{"14", "15"},
+ Platform_systemsdk_versions: []string{"29", "30"},
+ AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
+ AAPTPreferredConfig: stringPtr("xhdpi"),
+ AAPTCharacteristics: stringPtr("nosdcard"),
+ AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
+ UncompressPrivAppDex: boolPtr(true),
+ ShippingApiLevel: stringPtr("30"),
},
outDir: buildDir,
@@ -742,6 +743,14 @@
return String(c.productVariables.Platform_sdk_codename)
}
+func (c *config) PlatformSdkExtensionVersion() int {
+ return *c.productVariables.Platform_sdk_extension_version
+}
+
+func (c *config) PlatformBaseSdkExtensionVersion() int {
+ return *c.productVariables.Platform_base_sdk_extension_version
+}
+
func (c *config) PlatformSecurityPatch() string {
return String(c.productVariables.Platform_security_patch)
}
@@ -1530,6 +1539,18 @@
return c.config.productVariables.BoardProductPrivatePrebuiltDirs
}
+func (c *deviceConfig) SystemExtSepolicyPrebuiltApiDir() string {
+ return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir)
+}
+
+func (c *deviceConfig) ProductSepolicyPrebuiltApiDir() string {
+ return String(c.config.productVariables.ProductSepolicyPrebuiltApiDir)
+}
+
+func (c *deviceConfig) IsPartnerTrebleSepolicyTestEnabled() bool {
+ return c.SystemExtSepolicyPrebuiltApiDir() != "" || c.ProductSepolicyPrebuiltApiDir() != ""
+}
+
func (c *deviceConfig) DirectedVendorSnapshot() bool {
return c.config.productVariables.DirectedVendorSnapshot
}
diff --git a/android/module_test.go b/android/module_test.go
index a1bab6d..1dcddf7 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -15,12 +15,9 @@
package android
import (
- "bytes"
"path/filepath"
"runtime"
"testing"
-
- mkparser "android/soong/androidmk/parser"
)
func TestSrcIsModule(t *testing.T) {
@@ -475,21 +472,10 @@
prepareForModuleTests,
PrepareForTestWithArchMutator,
FixtureModifyConfig(SetKatiEnabledForTests),
- FixtureRegisterWithContext(func(ctx RegistrationContext) {
- ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
- }),
+ PrepareForTestWithMakevars,
).RunTestWithBp(t, bp)
- installs := result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
- buf := bytes.NewBuffer(append([]byte(nil), installs...))
- parser := mkparser.NewParser("makevars", buf)
-
- nodes, errs := parser.Parse()
- if len(errs) > 0 {
- t.Fatalf("error parsing install rules: %s", errs[0])
- }
-
- rules := parseMkRules(t, result.Config, nodes)
+ rules := result.InstallMakeRulesForTesting(t)
module := func(name string, host bool) TestingModule {
variant := "android_common"
@@ -501,121 +487,78 @@
outputRule := func(name string) TestingBuildParams { return module(name, false).Output(name) }
- ruleForOutput := func(output string) installMakeRule {
+ ruleForOutput := func(output string) InstallMakeRule {
for _, rule := range rules {
- if rule.target == output {
+ if rule.Target == output {
return rule
}
}
t.Fatalf("no make install rule for %s", output)
- return installMakeRule{}
+ return InstallMakeRule{}
}
- installRule := func(name string) installMakeRule {
+ installRule := func(name string) InstallMakeRule {
return ruleForOutput(filepath.Join("out/target/product/test_device/system", name))
}
- symlinkRule := func(name string) installMakeRule {
+ symlinkRule := func(name string) InstallMakeRule {
return ruleForOutput(filepath.Join("out/target/product/test_device/system/symlinks", name))
}
hostOutputRule := func(name string) TestingBuildParams { return module(name, true).Output(name) }
- hostInstallRule := func(name string) installMakeRule {
+ hostInstallRule := func(name string) InstallMakeRule {
return ruleForOutput(filepath.Join("out/host/linux-x86", name))
}
- hostSymlinkRule := func(name string) installMakeRule {
+ hostSymlinkRule := func(name string) InstallMakeRule {
return ruleForOutput(filepath.Join("out/host/linux-x86/symlinks", name))
}
- assertDeps := func(rule installMakeRule, deps ...string) {
+ assertDeps := func(rule InstallMakeRule, deps ...string) {
t.Helper()
- AssertArrayString(t, "expected inputs", deps, rule.deps)
+ AssertArrayString(t, "expected inputs", deps, rule.Deps)
}
- assertOrderOnlys := func(rule installMakeRule, orderonlys ...string) {
+ assertOrderOnlys := func(rule InstallMakeRule, orderonlys ...string) {
t.Helper()
- AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.orderOnlyDeps)
+ AssertArrayString(t, "expected orderonly dependencies", orderonlys, rule.OrderOnlyDeps)
}
// Check host install rule dependencies
assertDeps(hostInstallRule("foo"),
hostOutputRule("foo").Output.String(),
- hostInstallRule("bar").target,
- hostSymlinkRule("bar").target,
- hostInstallRule("baz").target,
- hostSymlinkRule("baz").target,
- hostInstallRule("qux").target,
- hostSymlinkRule("qux").target,
+ hostInstallRule("bar").Target,
+ hostSymlinkRule("bar").Target,
+ hostInstallRule("baz").Target,
+ hostSymlinkRule("baz").Target,
+ hostInstallRule("qux").Target,
+ hostSymlinkRule("qux").Target,
)
assertOrderOnlys(hostInstallRule("foo"))
// Check host symlink rule dependencies. Host symlinks must use a normal dependency, not an
// order-only dependency, so that the tool gets updated when the symlink is depended on.
- assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").target)
+ assertDeps(hostSymlinkRule("foo"), hostInstallRule("foo").Target)
assertOrderOnlys(hostSymlinkRule("foo"))
// Check device install rule dependencies
assertDeps(installRule("foo"), outputRule("foo").Output.String())
assertOrderOnlys(installRule("foo"),
- installRule("bar").target,
- symlinkRule("bar").target,
- installRule("baz").target,
- symlinkRule("baz").target,
- installRule("qux").target,
- symlinkRule("qux").target,
+ installRule("bar").Target,
+ symlinkRule("bar").Target,
+ installRule("baz").Target,
+ symlinkRule("baz").Target,
+ installRule("qux").Target,
+ symlinkRule("qux").Target,
)
// Check device symlink rule dependencies. Device symlinks could use an order-only dependency,
// but the current implementation uses a normal dependency.
- assertDeps(symlinkRule("foo"), installRule("foo").target)
+ assertDeps(symlinkRule("foo"), installRule("foo").Target)
assertOrderOnlys(symlinkRule("foo"))
}
-type installMakeRule struct {
- target string
- deps []string
- orderOnlyDeps []string
-}
-
-func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installMakeRule {
- var rules []installMakeRule
- for _, node := range nodes {
- if mkParserRule, ok := node.(*mkparser.Rule); ok {
- var rule installMakeRule
-
- if targets := mkParserRule.Target.Words(); len(targets) == 0 {
- t.Fatalf("no targets for rule %s", mkParserRule.Dump())
- } else if len(targets) > 1 {
- t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
- } else if !targets[0].Const() {
- t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
- } else {
- rule.target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
- }
-
- prereqList := &rule.deps
- for _, prereq := range mkParserRule.Prerequisites.Words() {
- if !prereq.Const() {
- t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
- }
-
- if prereq.Value(nil) == "|" {
- prereqList = &rule.orderOnlyDeps
- continue
- }
-
- *prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
- }
-
- rules = append(rules, rule)
- }
- }
-
- return rules
-}
-
type PropsTestModuleEmbedded struct {
Embedded_prop *string
}
diff --git a/android/singleton_module_test.go b/android/singleton_module_test.go
index eb5554c..9d98478 100644
--- a/android/singleton_module_test.go
+++ b/android/singleton_module_test.go
@@ -46,8 +46,8 @@
PrepareForTestWithAndroidMk,
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterSingletonModuleType("test_singleton_module", testSingletonModuleFactory)
- ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
}),
+ PrepareForTestWithMakevars,
)
func TestSingletonModule(t *testing.T) {
diff --git a/android/testing.go b/android/testing.go
index 39864e1..a9632e9 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -15,6 +15,7 @@
package android
import (
+ "bytes"
"fmt"
"path/filepath"
"regexp"
@@ -23,6 +24,8 @@
"sync"
"testing"
+ mkparser "android/soong/androidmk/parser"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -115,6 +118,10 @@
ctx.PreArchMutators(RegisterNamespaceMutator)
})
+var PrepareForTestWithMakevars = FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterSingletonType("makevars", makeVarsSingletonFunc)
+})
+
// Test fixture preparer that will register most java build components.
//
// Singletons and mutators should only be added here if they are needed for a majority of java
@@ -602,6 +609,62 @@
"\nall singletons: %v", name, allSingletonNames))
}
+type InstallMakeRule struct {
+ Target string
+ Deps []string
+ OrderOnlyDeps []string
+}
+
+func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []InstallMakeRule {
+ var rules []InstallMakeRule
+ for _, node := range nodes {
+ if mkParserRule, ok := node.(*mkparser.Rule); ok {
+ var rule InstallMakeRule
+
+ if targets := mkParserRule.Target.Words(); len(targets) == 0 {
+ t.Fatalf("no targets for rule %s", mkParserRule.Dump())
+ } else if len(targets) > 1 {
+ t.Fatalf("unsupported multiple targets for rule %s", mkParserRule.Dump())
+ } else if !targets[0].Const() {
+ t.Fatalf("unsupported non-const target for rule %s", mkParserRule.Dump())
+ } else {
+ rule.Target = normalizeStringRelativeToTop(config, targets[0].Value(nil))
+ }
+
+ prereqList := &rule.Deps
+ for _, prereq := range mkParserRule.Prerequisites.Words() {
+ if !prereq.Const() {
+ t.Fatalf("unsupported non-const prerequisite for rule %s", mkParserRule.Dump())
+ }
+
+ if prereq.Value(nil) == "|" {
+ prereqList = &rule.OrderOnlyDeps
+ continue
+ }
+
+ *prereqList = append(*prereqList, normalizeStringRelativeToTop(config, prereq.Value(nil)))
+ }
+
+ rules = append(rules, rule)
+ }
+ }
+
+ return rules
+}
+
+func (ctx *TestContext) InstallMakeRulesForTesting(t *testing.T) []InstallMakeRule {
+ installs := ctx.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).installsForTesting
+ buf := bytes.NewBuffer(append([]byte(nil), installs...))
+ parser := mkparser.NewParser("makevars", buf)
+
+ nodes, errs := parser.Parse()
+ if len(errs) > 0 {
+ t.Fatalf("error parsing install rules: %s", errs[0])
+ }
+
+ return parseMkRules(t, ctx.config, nodes)
+}
+
func (ctx *TestContext) Config() Config {
return ctx.config
}
diff --git a/android/util.go b/android/util.go
index 0ee253e..47c4583 100644
--- a/android/util.go
+++ b/android/util.go
@@ -65,21 +65,55 @@
return buf.String()
}
-// SorterStringKeys returns the keys of the given string-keyed map in the ascending order
+// SorterStringKeys returns the keys of the given string-keyed map in the ascending order.
func SortedStringKeys(m interface{}) []string {
v := reflect.ValueOf(m)
if v.Kind() != reflect.Map {
panic(fmt.Sprintf("%#v is not a map", m))
}
- keys := v.MapKeys()
- s := make([]string, 0, len(keys))
- for _, key := range keys {
- s = append(s, key.String())
+ if v.Len() == 0 {
+ return nil
+ }
+ iter := v.MapRange()
+ s := make([]string, 0, v.Len())
+ for iter.Next() {
+ s = append(s, iter.Key().String())
}
sort.Strings(s)
return s
}
+// stringValues returns the values of the given string-valued map in randomized map order.
+func stringValues(m interface{}) []string {
+ v := reflect.ValueOf(m)
+ if v.Kind() != reflect.Map {
+ panic(fmt.Sprintf("%#v is not a map", m))
+ }
+ if v.Len() == 0 {
+ return nil
+ }
+ iter := v.MapRange()
+ s := make([]string, 0, v.Len())
+ for iter.Next() {
+ s = append(s, iter.Value().String())
+ }
+ return s
+}
+
+// SortedStringValues returns the values of the given string-valued map in the ascending order.
+func SortedStringValues(m interface{}) []string {
+ s := stringValues(m)
+ sort.Strings(s)
+ return s
+}
+
+// SortedUniqueStringValues returns the values of the given string-valued map in the ascending order
+// with duplicates removed.
+func SortedUniqueStringValues(m interface{}) []string {
+ s := stringValues(m)
+ return SortedUniqueStrings(s)
+}
+
// IndexList returns the index of the first occurrence of the given string in the list or -1
func IndexList(s string, list []string) int {
for i, l := range list {
diff --git a/android/util_test.go b/android/util_test.go
index 09bec01..9b9253b 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -640,3 +640,117 @@
})
}
}
+
+func TestSortedStringKeys(t *testing.T) {
+ testCases := []struct {
+ name string
+ in interface{}
+ expected []string
+ }{
+ {
+ name: "nil",
+ in: map[string]string(nil),
+ expected: nil,
+ },
+ {
+ name: "empty",
+ in: map[string]string{},
+ expected: nil,
+ },
+ {
+ name: "simple",
+ in: map[string]string{"a": "foo", "b": "bar"},
+ expected: []string{"a", "b"},
+ },
+ {
+ name: "interface values",
+ in: map[string]interface{}{"a": nil, "b": nil},
+ expected: []string{"a", "b"},
+ },
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ got := SortedStringKeys(tt.in)
+ if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted %q, got %q", w, g)
+ }
+ })
+ }
+}
+
+func TestSortedStringValues(t *testing.T) {
+ testCases := []struct {
+ name string
+ in interface{}
+ expected []string
+ }{
+ {
+ name: "nil",
+ in: map[string]string(nil),
+ expected: nil,
+ },
+ {
+ name: "empty",
+ in: map[string]string{},
+ expected: nil,
+ },
+ {
+ name: "simple",
+ in: map[string]string{"foo": "a", "bar": "b"},
+ expected: []string{"a", "b"},
+ },
+ {
+ name: "duplicates",
+ in: map[string]string{"foo": "a", "bar": "b", "baz": "b"},
+ expected: []string{"a", "b", "b"},
+ },
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ got := SortedStringValues(tt.in)
+ if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted %q, got %q", w, g)
+ }
+ })
+ }
+}
+
+func TestSortedUniqueStringValues(t *testing.T) {
+ testCases := []struct {
+ name string
+ in interface{}
+ expected []string
+ }{
+ {
+ name: "nil",
+ in: map[string]string(nil),
+ expected: nil,
+ },
+ {
+ name: "empty",
+ in: map[string]string{},
+ expected: nil,
+ },
+ {
+ name: "simple",
+ in: map[string]string{"foo": "a", "bar": "b"},
+ expected: []string{"a", "b"},
+ },
+ {
+ name: "duplicates",
+ in: map[string]string{"foo": "a", "bar": "b", "baz": "b"},
+ expected: []string{"a", "b"},
+ },
+ }
+
+ for _, tt := range testCases {
+ t.Run(tt.name, func(t *testing.T) {
+ got := SortedUniqueStringValues(tt.in)
+ if g, w := got, tt.expected; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted %q, got %q", w, g)
+ }
+ })
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index ff77fef..627d9bd 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -191,6 +191,7 @@
Platform_sdk_version_or_codename *string `json:",omitempty"`
Platform_sdk_final *bool `json:",omitempty"`
Platform_sdk_extension_version *int `json:",omitempty"`
+ Platform_base_sdk_extension_version *int `json:",omitempty"`
Platform_version_active_codenames []string `json:",omitempty"`
Platform_vndk_version *string `json:",omitempty"`
Platform_systemsdk_versions []string `json:",omitempty"`
@@ -364,6 +365,9 @@
PlatformSepolicyVersion *string `json:",omitempty"`
TotSepolicyVersion *string `json:",omitempty"`
+ SystemExtSepolicyPrebuiltApiDir *string `json:",omitempty"`
+ ProductSepolicyPrebuiltApiDir *string `json:",omitempty"`
+
PlatformSepolicyCompatVersions []string `json:",omitempty"`
VendorVars map[string]map[string]string `json:",omitempty"`
diff --git a/cc/afdo.go b/cc/afdo.go
index d7cce77..c888213 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -32,7 +32,7 @@
var afdoProfileProjectsConfigKey = android.NewOnceKey("AfdoProfileProjects")
-const afdoCFlagsFormat = "-fprofile-sample-accurate -fprofile-sample-use=%s"
+const afdoCFlagsFormat = "-funique-internal-linkage-names -fprofile-sample-accurate -fprofile-sample-use=%s"
func getAfdoProfileProjects(config android.DeviceConfig) []string {
return config.OnceStringSlice(afdoProfileProjectsConfigKey, func() []string {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 7154905..9290272 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -399,6 +399,9 @@
}
entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory))
+ if len(test.Properties.Data_bins) > 0 {
+ entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...)
+ }
})
AndroidMkWriteTestData(test.data, entries)
diff --git a/cc/binary.go b/cc/binary.go
index 54fd339..6c7d581 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -70,6 +70,7 @@
// cc_binary produces a binary that is runnable on a device.
func BinaryFactory() android.Module {
module, _ := newBinary(android.HostAndDeviceSupported, true)
+ module.bazelHandler = &ccBinaryBazelHandler{module: module}
return module.Init()
}
@@ -556,6 +557,28 @@
})
}
+type ccBinaryBazelHandler struct {
+ android.BazelHandler
+
+ module *Module
+}
+
+func (handler *ccBinaryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
+ bazelCtx := ctx.Config().BazelContext
+ filePaths, ok := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+ if ok {
+ if len(filePaths) != 1 {
+ ctx.ModuleErrorf("expected exactly one output file for '%s', but got %s", label, filePaths)
+ return false
+ }
+ outputFilePath := android.PathForBazelOut(ctx, filePaths[0])
+ handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
+ // TODO(b/220164721): We need to decide if we should return the stripped as the unstripped.
+ handler.module.linker.(*binaryDecorator).unstrippedOutputFile = outputFilePath
+ }
+ return ok
+}
+
func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
baseAttrs := bp2BuildParseBaseProps(ctx, m)
binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
diff --git a/cc/binary_test.go b/cc/binary_test.go
new file mode 100644
index 0000000..8ec3871
--- /dev/null
+++ b/cc/binary_test.go
@@ -0,0 +1,51 @@
+// Copyright 2022 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 cc
+
+import (
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestCcBinaryWithBazel(t *testing.T) {
+ bp := `
+cc_binary {
+ name: "foo",
+ srcs: ["foo.cc"],
+ bazel_module: { label: "//foo/bar:bar" },
+}`
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
+ config.BazelContext = android.MockBazelContext{
+ OutputBaseDir: "outputbase",
+ LabelToOutputFiles: map[string][]string{
+ "//foo/bar:bar": []string{"foo"},
+ },
+ }
+ ctx := testCcWithConfig(t, config)
+
+ binMod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module()
+ producer := binMod.(android.OutputFileProducer)
+ outputFiles, err := producer.OutputFiles("")
+ if err != nil {
+ t.Errorf("Unexpected error getting cc_binary outputfiles %s", err)
+ }
+ expectedOutputFiles := []string{"outputbase/execroot/__main__/foo"}
+ android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+
+ unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
+ expectedUnStrippedFile := "outputbase/execroot/__main__/foo"
+ android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
+}
diff --git a/cc/builder.go b/cc/builder.go
index ee3ea2d..525b1a1 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -459,21 +459,25 @@
}
// Generate rules for compiling multiple .c, .cpp, or .S files to individual .o files
-func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs android.Paths,
+func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs, timeoutTidySrcs android.Paths,
flags builderFlags, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
// Source files are one-to-one with tidy, coverage, or kythe files, if enabled.
objFiles := make(android.Paths, len(srcFiles))
var tidyFiles android.Paths
- noTidySrcsMap := make(map[android.Path]bool)
+ noTidySrcsMap := make(map[string]bool)
var tidyVars string
if flags.tidy {
tidyFiles = make(android.Paths, 0, len(srcFiles))
for _, path := range noTidySrcs {
- noTidySrcsMap[path] = true
+ noTidySrcsMap[path.String()] = true
}
tidyTimeout := ctx.Config().Getenv("TIDY_TIMEOUT")
if len(tidyTimeout) > 0 {
tidyVars += "TIDY_TIMEOUT=" + tidyTimeout + " "
+ // add timeoutTidySrcs into noTidySrcsMap if TIDY_TIMEOUT is set
+ for _, path := range timeoutTidySrcs {
+ noTidySrcsMap[path.String()] = true
+ }
}
}
var coverageFiles android.Paths
@@ -675,7 +679,7 @@
}
// Even with tidy, some src file could be skipped by noTidySrcsMap.
- if tidy && !noTidySrcsMap[srcFile] {
+ if tidy && !noTidySrcsMap[srcFile.String()] {
tidyFile := android.ObjPathWithExt(ctx, subdir, srcFile, "tidy")
tidyDepFile := android.ObjPathWithExt(ctx, subdir, srcFile, "tidy.dep")
tidyFiles = append(tidyFiles, tidyFile)
diff --git a/cc/cc.go b/cc/cc.go
index 019b1f2..a8adb0c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2807,6 +2807,8 @@
// dependency.
depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts, linkFile.Path())
}
+ depPaths.WholeStaticLibsFromPrebuilts = append(depPaths.WholeStaticLibsFromPrebuilts,
+ staticLibraryInfo.WholeStaticLibsFromPrebuilts...)
} else {
switch libDepTag.Order {
case earlyLibraryDependency:
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 31d91b6..51a6a27 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3943,7 +3943,6 @@
"${config.ArmGenericCflags}",
"-target",
"armv7a-linux-androideabi20",
- "-B${config.ArmGccRoot}/arm-linux-androideabi/bin",
}
expectedIncludes := []string{
diff --git a/cc/compiler.go b/cc/compiler.go
index 9dbf2d1..eb5458f 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -42,6 +42,9 @@
// list of source files that should not be compiled with clang-tidy.
Tidy_disabled_srcs []string `android:"path,arch_variant"`
+ // list of source files that should not be compiled by clang-tidy when TIDY_TIMEOUT is set.
+ Tidy_timeout_srcs []string `android:"path,arch_variant"`
+
// list of source files that should not be used to build the C/C++ module.
// This is most useful in the arch/multilib variants to remove non-common files
Exclude_srcs []string `android:"path,arch_variant"`
@@ -403,6 +406,10 @@
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RECOVERY__")
}
+ if ctx.inRecovery() || ctx.inRamdisk() || ctx.inVendorRamdisk() {
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_RAMDISK__")
+ }
+
if ctx.apexVariationName() != "" {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__")
if ctx.Device() {
@@ -450,11 +457,9 @@
}
}
- gccPrefix := "-B" + config.ToolPath(tc)
-
- flags.Global.CFlags = append(flags.Global.CFlags, target, gccPrefix)
- flags.Global.AsFlags = append(flags.Global.AsFlags, target, gccPrefix)
- flags.Global.LdFlags = append(flags.Global.LdFlags, target, gccPrefix)
+ flags.Global.CFlags = append(flags.Global.CFlags, target)
+ flags.Global.AsFlags = append(flags.Global.AsFlags, target)
+ flags.Global.LdFlags = append(flags.Global.LdFlags, target)
hod := "Host"
if ctx.Os().Class == android.Device {
@@ -665,6 +670,7 @@
// Compile files listed in c.Properties.Srcs into objects
objs := compileObjs(ctx, buildFlags, "", srcs,
android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_disabled_srcs),
+ android.PathsForModuleSrc(ctx, compiler.Properties.Tidy_timeout_srcs),
pathDeps, compiler.cFlagsDeps)
if ctx.Failed() {
@@ -676,9 +682,9 @@
// Compile a list of source files into objects a specified subdirectory
func compileObjs(ctx ModuleContext, flags builderFlags, subdir string,
- srcFiles, noTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
+ srcFiles, noTidySrcs, timeoutTidySrcs, pathDeps android.Paths, cFlagsDeps android.Paths) Objects {
- return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, flags, pathDeps, cFlagsDeps)
+ return transformSourceToObj(ctx, subdir, srcFiles, noTidySrcs, timeoutTidySrcs, flags, pathDeps, cFlagsDeps)
}
// Properties for rust_bindgen related to generating rust bindings.
diff --git a/cc/config/darwin_host.go b/cc/config/darwin_host.go
index 206bec1..5e3f7c7 100644
--- a/cc/config/darwin_host.go
+++ b/cc/config/darwin_host.go
@@ -258,8 +258,12 @@
return darwinAvailableLibraries
}
-func (t *toolchainDarwin) ToolPath() string {
- return "${config.MacToolPath}"
+func (t *toolchainDarwin) ToolchainCflags() string {
+ return "-B${config.MacToolPath}"
+}
+
+func (t *toolchainDarwin) ToolchainLdflags() string {
+ return "-B${config.MacToolPath}"
}
var toolchainDarwinArmSingleton Toolchain = &toolchainDarwinArm{}
diff --git a/cc/config/global.go b/cc/config/global.go
index 48a8b48..400be31 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -107,6 +107,9 @@
// 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__",
+
+ // Turn off FMA which got enabled by default in clang-r445002 (http://b/218805949)
+ "-ffp-contract=off",
}
commonGlobalConlyflags = []string{}
@@ -238,6 +241,8 @@
// http://b/197240255
"-Wno-unused-but-set-variable",
"-Wno-unused-but-set-parameter",
+ // http://b/215753485
+ "-Wno-bitwise-instead-of-logical",
}
// Extra cflags for external third-party projects to disable warnings that
@@ -282,8 +287,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r437112b"
- ClangDefaultShortVersion = "14.0.1"
+ ClangDefaultVersion = "clang-r445002"
+ ClangDefaultShortVersion = "14.0.2"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index 6320dbb..6cede11 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "path/filepath"
"android/soong/android"
)
@@ -77,7 +76,6 @@
GccTriple() string
// GccVersion should return a real value, not a ninja reference
GccVersion() string
- ToolPath() string
IncludeFlags() string
@@ -198,10 +196,6 @@
return false
}
-func (t toolchainBase) ToolPath() string {
- return ""
-}
-
type toolchain64Bit struct {
toolchainBase
}
@@ -283,11 +277,4 @@
return LibclangRuntimeLibrary(t, "fuzzer")
}
-func ToolPath(t Toolchain) string {
- if p := t.ToolPath(); p != "" {
- return p
- }
- return filepath.Join(t.GccRoot(), t.GccTriple(), "bin")
-}
-
var inList = android.InList
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index 60f03c2..ce6836b 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -47,6 +47,7 @@
"-D_LIBCPP_HAS_MUSL_LIBC",
"-DANDROID_HOST_MUSL",
"-nostdlibinc",
+ "--sysroot /dev/null",
}
linuxLdflags = []string{
@@ -65,6 +66,7 @@
linuxMuslLdflags = []string{
"-nostdlib",
"-lgcc", "-lgcc_eh",
+ "--sysroot /dev/null",
}
// Extended cflags
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index 9daf40f..2c83211 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -15,6 +15,7 @@
package config
import (
+ "path/filepath"
"strings"
"android/soong/android"
@@ -180,6 +181,14 @@
return "${config.WindowsGccTriple}"
}
+func (t *toolchainWindows) ToolchainCflags() string {
+ return "-B" + filepath.Join(t.GccRoot(), t.GccTriple(), "bin")
+}
+
+func (t *toolchainWindows) ToolchainLdflags() string {
+ return "-B" + filepath.Join(t.GccRoot(), t.GccTriple(), "bin")
+}
+
func (t *toolchainWindows) GccVersion() string {
return windowsGccVersion
}
diff --git a/cc/library.go b/cc/library.go
index 708aa10..5fa3471 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -145,6 +145,8 @@
Tidy_disabled_srcs []string `android:"path,arch_variant"`
+ Tidy_timeout_srcs []string `android:"path,arch_variant"`
+
Sanitized Sanitized `android:"arch_variant"`
Cflags []string `android:"arch_variant"`
@@ -586,7 +588,8 @@
stripper Stripper
// For whole_static_libs
- objects Objects
+ objects Objects
+ wholeStaticLibsFromPrebuilts android.Paths
// Uses the module's name if empty, but can be overridden. Does not include
// shlib suffix.
@@ -1078,11 +1081,13 @@
srcs := android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Srcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceStaticLibrary, srcs,
android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_disabled_srcs),
+ android.PathsForModuleSrc(ctx, library.StaticProperties.Static.Tidy_timeout_srcs),
library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
} else if library.shared() {
srcs := android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Srcs)
objs = objs.Append(compileObjs(ctx, buildFlags, android.DeviceSharedLibrary, srcs,
android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_disabled_srcs),
+ android.PathsForModuleSrc(ctx, library.SharedProperties.Shared.Tidy_timeout_srcs),
library.baseCompiler.pathDeps, library.baseCompiler.cFlagsDeps))
}
@@ -1343,6 +1348,7 @@
library.objects = deps.WholeStaticLibObjs.Copy()
library.objects = library.objects.Append(objs)
+ library.wholeStaticLibsFromPrebuilts = android.CopyOfPaths(deps.WholeStaticLibsFromPrebuilts)
fileName := ctx.ModuleName() + staticLibraryExtension
outputFile := android.PathForModuleOut(ctx, fileName)
@@ -1368,9 +1374,10 @@
if library.static() {
ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
- StaticLibrary: outputFile,
- ReuseObjects: library.reuseObjects,
- Objects: library.objects,
+ StaticLibrary: outputFile,
+ ReuseObjects: library.reuseObjects,
+ Objects: library.objects,
+ WholeStaticLibsFromPrebuilts: library.wholeStaticLibsFromPrebuilts,
TransitiveStaticLibrariesForOrdering: android.NewDepSetBuilder(android.TOPOLOGICAL).
Direct(outputFile).
diff --git a/cc/library_test.go b/cc/library_test.go
index d220e19..6d5eda2 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -379,3 +379,77 @@
gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
}
+
+func TestWholeStaticLibPrebuilts(t *testing.T) {
+ result := PrepareForIntegrationTestWithCc.RunTestWithBp(t, `
+ cc_prebuilt_library_static {
+ name: "libprebuilt",
+ srcs: ["foo.a"],
+ }
+
+ cc_library_static {
+ name: "libdirect",
+ whole_static_libs: ["libprebuilt"],
+ }
+
+ cc_library_static {
+ name: "libtransitive",
+ whole_static_libs: ["libdirect"],
+ }
+
+ cc_library_static {
+ name: "libdirect_with_srcs",
+ srcs: ["bar.c"],
+ whole_static_libs: ["libprebuilt"],
+ }
+
+ cc_library_static {
+ name: "libtransitive_with_srcs",
+ srcs: ["baz.c"],
+ whole_static_libs: ["libdirect_with_srcs"],
+ }
+ `)
+
+ libdirect := result.ModuleForTests("libdirect", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libtransitive := result.ModuleForTests("libtransitive", "android_arm64_armv8-a_static").Rule("arWithLibs")
+
+ libdirectWithSrcs := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
+ libtransitiveWithSrcs := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("arWithLibs")
+
+ barObj := result.ModuleForTests("libdirect_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
+ bazObj := result.ModuleForTests("libtransitive_with_srcs", "android_arm64_armv8-a_static").Rule("cc")
+
+ android.AssertStringListContains(t, "missing dependency on foo.a",
+ libdirect.Inputs.Strings(), "foo.a")
+ android.AssertStringDoesContain(t, "missing flag for foo.a",
+ libdirect.Args["arLibs"], "foo.a")
+
+ android.AssertStringListContains(t, "missing dependency on foo.a",
+ libtransitive.Inputs.Strings(), "foo.a")
+ android.AssertStringDoesContain(t, "missing flag for foo.a",
+ libtransitive.Args["arLibs"], "foo.a")
+
+ android.AssertStringListContains(t, "missing dependency on foo.a",
+ libdirectWithSrcs.Inputs.Strings(), "foo.a")
+ android.AssertStringDoesContain(t, "missing flag for foo.a",
+ libdirectWithSrcs.Args["arLibs"], "foo.a")
+ android.AssertStringListContains(t, "missing dependency on bar.o",
+ libdirectWithSrcs.Inputs.Strings(), barObj.Output.String())
+ android.AssertStringDoesContain(t, "missing flag for bar.o",
+ libdirectWithSrcs.Args["arObjs"], barObj.Output.String())
+
+ android.AssertStringListContains(t, "missing dependency on foo.a",
+ libtransitiveWithSrcs.Inputs.Strings(), "foo.a")
+ android.AssertStringDoesContain(t, "missing flag for foo.a",
+ libtransitiveWithSrcs.Args["arLibs"], "foo.a")
+
+ android.AssertStringListContains(t, "missing dependency on bar.o",
+ libtransitiveWithSrcs.Inputs.Strings(), barObj.Output.String())
+ android.AssertStringDoesContain(t, "missing flag for bar.o",
+ libtransitiveWithSrcs.Args["arObjs"], barObj.Output.String())
+
+ android.AssertStringListContains(t, "missing dependency on baz.o",
+ libtransitiveWithSrcs.Inputs.Strings(), bazObj.Output.String())
+ android.AssertStringDoesContain(t, "missing flag for baz.o",
+ libtransitiveWithSrcs.Args["arObjs"], bazObj.Output.String())
+}
diff --git a/cc/linkable.go b/cc/linkable.go
index 02d7047..d4b4770 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -352,6 +352,11 @@
Objects Objects
ReuseObjects Objects
+ // A static library may contain prebuilt static libraries included with whole_static_libs
+ // that won't appear in Objects. They are transitively available in
+ // WholeStaticLibsFromPrebuilts.
+ WholeStaticLibsFromPrebuilts android.Paths
+
// This isn't the actual transitive DepSet, shared library dependencies have been
// converted into static library analogues. It is only used to order the static
// library dependencies that were specified for the current module.
diff --git a/cc/makevars.go b/cc/makevars.go
index b7aaaad..6752f8c 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -227,7 +227,6 @@
}
clangPrefix := secondPrefix + "CLANG_" + typePrefix
- clangExtras := "-B" + config.ToolPath(toolchain)
ctx.Strict(clangPrefix+"TRIPLE", toolchain.ClangTriple())
ctx.Strict(clangPrefix+"GLOBAL_CFLAGS", strings.Join([]string{
@@ -235,7 +234,6 @@
"${config.CommonGlobalCflags}",
fmt.Sprintf("${config.%sGlobalCflags}", hod),
toolchain.ToolchainCflags(),
- clangExtras,
productExtraCflags,
}, " "))
ctx.Strict(clangPrefix+"GLOBAL_CPPFLAGS", strings.Join([]string{
@@ -248,25 +246,52 @@
toolchain.Ldflags(),
toolchain.ToolchainLdflags(),
productExtraLdflags,
- clangExtras,
}, " "))
ctx.Strict(clangPrefix+"GLOBAL_LLDFLAGS", strings.Join([]string{
fmt.Sprintf("${config.%sGlobalLldflags}", hod),
toolchain.Lldflags(),
toolchain.ToolchainLdflags(),
productExtraLdflags,
- clangExtras,
}, " "))
if target.Os.Class == android.Device {
- ctx.Strict(secondPrefix+"ADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.AddressSanitizerRuntimeLibrary(toolchain), ".so"))
- ctx.Strict(secondPrefix+"HWADDRESS_SANITIZER_RUNTIME_LIBRARY", strings.TrimSuffix(config.HWAddressSanitizerRuntimeLibrary(toolchain), ".so"))
- ctx.Strict(secondPrefix+"HWADDRESS_SANITIZER_STATIC_LIBRARY", strings.TrimSuffix(config.HWAddressSanitizerStaticLibrary(toolchain), ".a"))
- ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
- ctx.Strict(secondPrefix+"UBSAN_MINIMAL_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), ".a"))
- ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
- ctx.Strict(secondPrefix+"SCUDO_RUNTIME_LIBRARY", strings.TrimSuffix(config.ScudoRuntimeLibrary(toolchain), ".so"))
- ctx.Strict(secondPrefix+"SCUDO_MINIMAL_RUNTIME_LIBRARY", strings.TrimSuffix(config.ScudoMinimalRuntimeLibrary(toolchain), ".so"))
+ sanitizerVariables := map[string]string{
+ "ADDRESS_SANITIZER_RUNTIME_LIBRARY": config.AddressSanitizerRuntimeLibrary(toolchain),
+ "HWADDRESS_SANITIZER_RUNTIME_LIBRARY": config.HWAddressSanitizerRuntimeLibrary(toolchain),
+ "HWADDRESS_SANITIZER_STATIC_LIBRARY": config.HWAddressSanitizerStaticLibrary(toolchain),
+ "UBSAN_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain),
+ "UBSAN_MINIMAL_RUNTIME_LIBRARY": config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain),
+ "TSAN_RUNTIME_LIBRARY": config.ThreadSanitizerRuntimeLibrary(toolchain),
+ "SCUDO_RUNTIME_LIBRARY": config.ScudoRuntimeLibrary(toolchain),
+ "SCUDO_MINIMAL_RUNTIME_LIBRARY": config.ScudoMinimalRuntimeLibrary(toolchain),
+ }
+
+ for variable, value := range sanitizerVariables {
+ ctx.Strict(secondPrefix+variable, value)
+ }
+
+ sanitizerLibs := android.SortedStringValues(sanitizerVariables)
+ var sanitizerLibStems []string
+ ctx.VisitAllModules(func(m android.Module) {
+ if !m.Enabled() {
+ return
+ }
+
+ ccModule, _ := m.(*Module)
+ if ccModule == nil || ccModule.library == nil || !ccModule.library.shared() {
+ return
+ }
+
+ if android.InList(strings.TrimPrefix(ctx.ModuleName(m), "prebuilt_"), sanitizerLibs) &&
+ m.Target().Os == target.Os && m.Target().Arch.ArchType == target.Arch.ArchType {
+ outputFile := ccModule.outputFile
+ if outputFile.Valid() {
+ sanitizerLibStems = append(sanitizerLibStems, outputFile.Path().Base())
+ }
+ }
+ })
+ sanitizerLibStems = android.SortedUniqueStrings(sanitizerLibStems)
+ ctx.Strict(secondPrefix+"SANITIZER_STEMS", strings.Join(sanitizerLibStems, " "))
}
// This is used by external/gentoo/...
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 7efe134..fc682ff 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -279,7 +279,7 @@
func compileStubLibrary(ctx ModuleContext, flags Flags, src android.Path) Objects {
return compileObjs(ctx, flagsToBuilderFlags(flags), "",
- android.Paths{src}, nil, nil, nil)
+ android.Paths{src}, nil, nil, nil, nil)
}
func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 339a16d..5980319 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "strings"
"android/soong/android"
"android/soong/bazel"
@@ -188,6 +189,16 @@
TableOfContents: p.tocFile,
})
+ // TODO(b/220898484): Mainline module sdk prebuilts of stub libraries use a stub
+ // library as their source and must not be installed, but libclang_rt.* libraries
+ // have stubs because they are LLNDK libraries, but use an implementation library
+ // as their source and need to be installed. This discrepancy should be resolved
+ // without the prefix hack below.
+ if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() &&
+ !strings.HasPrefix(ctx.baseModuleName(), "libclang_rt.") {
+ ctx.Module().MakeUninstallable()
+ }
+
return outputFile
}
}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 94f75fe..901f458 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/bazel/cquery"
+
"github.com/google/blueprint"
)
@@ -29,6 +30,7 @@
)
func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext {
+ t.Helper()
result := android.GroupFixturePreparers(
prepareForPrebuiltTest,
fs.AddToFixture(),
@@ -449,3 +451,72 @@
expectedOutputFiles := []string{pathPrefix + "foo.so"}
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
}
+
+func TestPrebuiltStubNoinstall(t *testing.T) {
+ testFunc := func(t *testing.T, bp string) {
+ result := android.GroupFixturePreparers(
+ prepareForPrebuiltTest,
+ android.PrepareForTestWithMakevars,
+ ).RunTestWithBp(t, bp)
+
+ installRules := result.InstallMakeRulesForTesting(t)
+ var installedlibRule *android.InstallMakeRule
+ for i, rule := range installRules {
+ if rule.Target == "out/target/product/test_device/system/lib/installedlib.so" {
+ if installedlibRule != nil {
+ t.Errorf("Duplicate install rules for %s", rule.Target)
+ }
+ installedlibRule = &installRules[i]
+ }
+ }
+ if installedlibRule == nil {
+ t.Errorf("No install rule found for installedlib")
+ return
+ }
+
+ android.AssertStringListDoesNotContain(t,
+ "installedlib has install dependency on stub",
+ installedlibRule.Deps,
+ "out/target/product/test_device/system/lib/stublib.so")
+ android.AssertStringListDoesNotContain(t,
+ "installedlib has order-only install dependency on stub",
+ installedlibRule.OrderOnlyDeps,
+ "out/target/product/test_device/system/lib/stublib.so")
+ }
+
+ const prebuiltStublibBp = `
+ cc_prebuilt_library {
+ name: "stublib",
+ prefer: true,
+ srcs: ["foo.so"],
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `
+
+ const installedlibBp = `
+ cc_library {
+ name: "installedlib",
+ shared_libs: ["stublib"],
+ }
+ `
+
+ t.Run("prebuilt without source", func(t *testing.T) {
+ testFunc(t, prebuiltStublibBp+installedlibBp)
+ })
+
+ const disabledSourceStublibBp = `
+ cc_library {
+ name: "stublib",
+ enabled: false,
+ stubs: {
+ versions: ["1"],
+ },
+ }
+ `
+
+ t.Run("prebuilt with disabled source", func(t *testing.T) {
+ testFunc(t, disabledSourceStublibBp+prebuiltStublibBp+installedlibBp)
+ })
+}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index b8e1468..f8661a6 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -42,6 +42,7 @@
"-fno-omit-frame-pointer",
"-Wno-frame-larger-than=",
"-fsanitize-hwaddress-abi=platform",
+ "-mllvm", "-hwasan-use-after-scope=1",
}
// ThinLTO performs codegen during link time, thus these flags need to
@@ -582,20 +583,12 @@
func (sanitize *sanitize) flags(ctx ModuleContext, flags Flags) Flags {
minimalRuntimeLib := config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(ctx.toolchain()) + ".a"
- minimalRuntimePath := "${config.ClangAsanLibDir}/" + minimalRuntimeLib
- builtinsRuntimeLib := config.BuiltinsRuntimeLibrary(ctx.toolchain()) + ".a"
- builtinsRuntimePath := "${config.ClangAsanLibDir}/" + builtinsRuntimeLib
if sanitize.Properties.MinimalRuntimeDep {
flags.Local.LdFlags = append(flags.Local.LdFlags,
- minimalRuntimePath,
"-Wl,--exclude-libs,"+minimalRuntimeLib)
}
- if sanitize.Properties.BuiltinsDep {
- flags.libFlags = append([]string{builtinsRuntimePath}, flags.libFlags...)
- }
-
if !sanitize.Properties.SanitizerEnabled && !sanitize.Properties.UbsanRuntimeDep {
return flags
}
@@ -725,11 +718,7 @@
if enableMinimalRuntime(sanitize) {
flags.Local.CFlags = append(flags.Local.CFlags, strings.Join(minimalRuntimeFlags, " "))
- flags.libFlags = append([]string{minimalRuntimePath}, flags.libFlags...)
flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--exclude-libs,"+minimalRuntimeLib)
- if !ctx.toolchain().Bionic() {
- flags.libFlags = append([]string{builtinsRuntimePath}, flags.libFlags...)
- }
}
if Bool(sanitize.Properties.Sanitize.Fuzzer) {
@@ -1198,6 +1187,36 @@
}
}
+ addStaticDeps := func(deps ...string) {
+ // If we're using snapshots, redirect to snapshot whenever possible
+ snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
+ for idx, dep := range deps {
+ if lib, ok := snapshot.StaticLibs[dep]; ok {
+ deps[idx] = lib
+ }
+ }
+
+ // static executable gets static runtime libs
+ depTag := libraryDependencyTag{Kind: staticLibraryDependency}
+ variations := append(mctx.Target().Variations(),
+ blueprint.Variation{Mutator: "link", Variation: "static"})
+ if c.Device() {
+ variations = append(variations, c.ImageVariation())
+ }
+ if c.UseSdk() {
+ variations = append(variations,
+ blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
+ }
+ mctx.AddFarVariationDependencies(variations, depTag, deps...)
+
+ }
+ if enableMinimalRuntime(c.sanitize) || c.sanitize.Properties.MinimalRuntimeDep {
+ addStaticDeps(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain))
+ }
+ if c.sanitize.Properties.BuiltinsDep {
+ addStaticDeps(config.BuiltinsRuntimeLibrary(toolchain))
+ }
+
if runtimeLibrary != "" && (toolchain.Bionic() || c.sanitize.Properties.UbsanRuntimeDep) {
// UBSan is supported on non-bionic linux host builds as well
@@ -1209,23 +1228,8 @@
// Note that by adding dependency with {static|shared}DepTag, the lib is
// added to libFlags and LOCAL_SHARED_LIBRARIES by cc.Module
if c.staticBinary() {
- deps := append(extraStaticDeps, runtimeLibrary)
- // If we're using snapshots, redirect to snapshot whenever possible
- snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
- for idx, dep := range deps {
- if lib, ok := snapshot.StaticLibs[dep]; ok {
- deps[idx] = lib
- }
- }
-
- // static executable gets static runtime libs
- depTag := libraryDependencyTag{Kind: staticLibraryDependency}
- variations := append(mctx.Target().Variations(),
- blueprint.Variation{Mutator: "link", Variation: "static"})
- if c.Device() {
- variations = append(variations, c.ImageVariation())
- }
- mctx.AddFarVariationDependencies(variations, depTag, deps...)
+ addStaticDeps(runtimeLibrary)
+ addStaticDeps(extraStaticDeps...)
} else if !c.static() && !c.Header() {
// If we're using snapshots, redirect to snapshot whenever possible
snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
@@ -1250,6 +1254,10 @@
if c.Device() {
variations = append(variations, c.ImageVariation())
}
+ if c.UseSdk() {
+ variations = append(variations,
+ blueprint.Variation{Mutator: "sdk", Variation: "sdk"})
+ }
AddSharedLibDependenciesWithVersions(mctx, c, variations, depTag, runtimeLibrary, "", true)
}
// static lib does not have dependency to the runtime library. The
diff --git a/cc/testing.go b/cc/testing.go
index 3d0c10a..a03d147 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -99,6 +99,18 @@
vendor_ramdisk_available: true,
}
+ cc_prebuilt_library_static {
+ name: "libclang_rt.builtins-x86_64",
+ defaults: ["toolchain_libs_defaults"],
+ host_supported: true,
+ }
+
+ cc_prebuilt_library_static {
+ name: "libclang_rt.builtins-i386",
+ defaults: ["toolchain_libs_defaults"],
+ host_supported: true,
+ }
+
cc_prebuilt_library_shared {
name: "libclang_rt.hwasan-aarch64-android",
defaults: ["toolchain_libs_defaults"],
@@ -168,6 +180,16 @@
defaults: ["toolchain_libs_defaults"],
}
+ cc_prebuilt_library_static {
+ name: "libclang_rt.ubsan_minimal-aarch64-android",
+ defaults: ["toolchain_libs_defaults"],
+ }
+
+ cc_prebuilt_library_static {
+ name: "libclang_rt.ubsan_minimal-arm-android",
+ defaults: ["toolchain_libs_defaults"],
+ }
+
cc_library {
name: "libc",
defaults: ["linux_bionic_supported"],
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go
index 1280553..5603b41 100644
--- a/cmd/extract_linker/main.go
+++ b/cmd/extract_linker/main.go
@@ -114,6 +114,10 @@
fmt.Fprintln(asm, `.section .note.android.embedded_linker,"a",%note`)
+ // Discard the PT_INTERP section so that the linker doesn't need to be passed the
+ // --no-dynamic-linker flag.
+ fmt.Println(script, " /DISCARD/ : { *(.interp) }")
+
fmt.Fprintln(script, "}")
fmt.Fprintln(script, "INSERT BEFORE .note.android.embedded_linker;")
diff --git a/docs/tidy.md b/docs/tidy.md
index 3140198..890c3a0 100644
--- a/docs/tidy.md
+++ b/docs/tidy.md
@@ -225,6 +225,16 @@
in several Android continuous builds where `WITH_TIDY=1` and
`CLANG_ANALYZER_CHECKS=1` are set.
+Similar to `tidy_disabled_srcs` a `tidy_timeout_srcs` list
+can be used to include all source files that took too much time to compile
+with clang-tidy. Files listed in `tidy_timeout_srcs` will not
+be compiled by clang-tidy when `TIDY_TIMEOUT` is defined.
+This can save global build time, when it is necessary to set some
+time limit globally to finish in an acceptable time.
+For developers who want to find all clang-tidy warnings and
+are willing to spend more time on all files in a project,
+they should not define `TIDY_TIMEOUT` and build only the wanted project directories.
+
## Capabilities for Android.bp and Android.mk
Some of the previously mentioned features are defined only
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 1679a57..8282426 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -294,7 +294,7 @@
if _, exists := locationLabels[label]; !exists {
locationLabels[label] = loc
} else {
- ctx.ModuleErrorf("multiple labels for %q, %q and %q",
+ ctx.ModuleErrorf("multiple locations for label %q: %q and %q (do you have duplicate srcs entries?)",
label, locationLabels[label], loc)
}
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index df8d8c8..21e1d12 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -59,7 +59,7 @@
name: artBootImageName,
stem: "boot",
installDirOnHost: "apex/art_boot_images/javalib",
- installDirOnDevice: "apex/com.android.art/javalib",
+ installDirOnDevice: "system/framework",
profileInstallPathInApex: "etc/boot-image.prof",
modules: artModules,
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index f9dcfd6..7ad316f 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -334,11 +334,7 @@
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
FlagWithArg("--hide ", "SuperfluousPrefix").
- FlagWithArg("--hide ", "AnnotationExtraction").
- // (b/217545629)
- FlagWithArg("--hide ", "ChangedThrows").
- // (b/217552813)
- FlagWithArg("--hide ", "ChangedAbstract")
+ FlagWithArg("--hide ", "AnnotationExtraction")
}
}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index c67e2bd..44650a6 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path"
"strconv"
"strings"
@@ -37,6 +38,11 @@
// list of api version directories
Api_dirs []string
+ // Directory containing finalized api txt files for extension versions.
+ // Extension versions higher than the base sdk extension version will
+ // be assumed to be finalized later than all Api_dirs.
+ Extensions_dir *string
+
// The next API directory can optionally point to a directory where
// files incompatibility-tracking files are stored for the current
// "in progress" API. Each module present in one of the api_dirs will have
@@ -60,36 +66,45 @@
// no need to implement
}
-func parseJarPath(path string) (module string, apiver string, scope string) {
- elements := strings.Split(path, "/")
+// parsePrebuiltPath parses the relevant variables out of a variety of paths, e.g.
+// <version>/<scope>/<module>.jar
+// <version>/<scope>/api/<module>.txt
+// extensions/<version>/<scope>/<module>.jar
+// extensions/<version>/<scope>/api/<module>.txt
+func parsePrebuiltPath(ctx android.LoadHookContext, p string) (module string, version string, scope string) {
+ elements := strings.Split(p, "/")
- apiver = elements[0]
- scope = elements[1]
-
- module = strings.TrimSuffix(elements[2], ".jar")
- return
-}
-
-func parseApiFilePath(ctx android.LoadHookContext, path string) (module string, apiver string, scope string) {
- elements := strings.Split(path, "/")
- apiver = elements[0]
-
- scope = elements[1]
- if scope != "public" && scope != "system" && scope != "test" && scope != "module-lib" && scope != "system-server" {
- ctx.ModuleErrorf("invalid scope %q found in path: %q", scope, path)
+ scopeIdx := len(elements) - 2
+ if elements[scopeIdx] == "api" {
+ scopeIdx--
+ }
+ scope = elements[scopeIdx]
+ if scope != "core" && scope != "public" && scope != "system" && scope != "test" && scope != "module-lib" && scope != "system-server" {
+ ctx.ModuleErrorf("invalid scope %q found in path: %q", scope, p)
return
}
+ version = elements[scopeIdx-1]
- // elements[2] is string literal "api". skipping.
- module = strings.TrimSuffix(elements[3], ".txt")
+ module = strings.TrimSuffix(path.Base(p), path.Ext(p))
return
}
-func prebuiltApiModuleName(mctx android.LoadHookContext, module string, scope string, apiver string) string {
- return mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module
+// parseFinalizedPrebuiltPath is like parsePrebuiltPath, but verifies the version is numeric (a finalized version).
+func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string) (module string, version int, scope string) {
+ module, v, scope := parsePrebuiltPath(ctx, p)
+ version, err := strconv.Atoi(v)
+ if err != nil {
+ ctx.ModuleErrorf("Found finalized API files in non-numeric dir '%v'", v)
+ return
+ }
+ return
}
-func createImport(mctx android.LoadHookContext, module, scope, apiver, path, sdkVersion string, compileDex bool) {
+func prebuiltApiModuleName(mctx android.LoadHookContext, module, scope, version string) string {
+ return fmt.Sprintf("%s_%s_%s_%s", mctx.ModuleName(), scope, version, module)
+}
+
+func createImport(mctx android.LoadHookContext, module, scope, version, path, sdkVersion string, compileDex bool) {
props := struct {
Name *string
Jars []string
@@ -97,7 +112,7 @@
Installable *bool
Compile_dex *bool
}{}
- props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, apiver))
+ props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, version))
props.Jars = append(props.Jars, path)
props.Sdk_version = proptools.StringPtr(sdkVersion)
props.Installable = proptools.BoolPtr(false)
@@ -132,111 +147,125 @@
mctx.CreateModule(genrule.GenRuleFactory, &props)
}
-func getPrebuiltFiles(mctx android.LoadHookContext, p *prebuiltApis, name string) []string {
+// globApiDirs collects all the files in all api_dirs and all scopes that match the given glob, e.g. '*.jar' or 'api/*.txt'.
+// <api-dir>/<scope>/<glob> for all api-dir and scope.
+func globApiDirs(mctx android.LoadHookContext, p *prebuiltApis, api_dir_glob string) []string {
var files []string
for _, apiver := range p.properties.Api_dirs {
- files = append(files, getPrebuiltFilesInSubdir(mctx, apiver, name)...)
+ files = append(files, globScopeDir(mctx, apiver, api_dir_glob)...)
}
return files
}
-func getPrebuiltFilesInSubdir(mctx android.LoadHookContext, subdir string, name string) []string {
+// globExtensionDirs collects all the files under the extension dir (for all versions and scopes) that match the given glob
+// <extension-dir>/<version>/<scope>/<glob> for all version and scope.
+func globExtensionDirs(mctx android.LoadHookContext, p *prebuiltApis, extension_dir_glob string) []string {
+ // <extensions-dir>/<num>/<extension-dir-glob>
+ return globScopeDir(mctx, *p.properties.Extensions_dir+"/*", extension_dir_glob)
+}
+
+// globScopeDir collects all the files in the given subdir across all scopes that match the given glob, e.g. '*.jar' or 'api/*.txt'.
+// <subdir>/<scope>/<glob> for all scope.
+func globScopeDir(mctx android.LoadHookContext, subdir string, subdir_glob string) []string {
var files []string
dir := mctx.ModuleDir() + "/" + subdir
for _, scope := range []string{"public", "system", "test", "core", "module-lib", "system-server"} {
- glob := fmt.Sprintf("%s/%s/%s", dir, scope, name)
+ glob := fmt.Sprintf("%s/%s/%s", dir, scope, subdir_glob)
vfiles, err := mctx.GlobWithDeps(glob, nil)
if err != nil {
- mctx.ModuleErrorf("failed to glob %s files under %q: %s", name, dir+"/"+scope, err)
+ mctx.ModuleErrorf("failed to glob %s files under %q: %s", subdir_glob, dir+"/"+scope, err)
}
files = append(files, vfiles...)
}
+ for i, f := range files {
+ files[i] = strings.TrimPrefix(f, mctx.ModuleDir()+"/")
+ }
return files
}
func prebuiltSdkStubs(mctx android.LoadHookContext, p *prebuiltApis) {
- mydir := mctx.ModuleDir() + "/"
// <apiver>/<scope>/<module>.jar
- files := getPrebuiltFiles(mctx, p, "*.jar")
+ files := globApiDirs(mctx, p, "*.jar")
sdkVersion := proptools.StringDefault(p.properties.Imports_sdk_version, "current")
compileDex := proptools.BoolDefault(p.properties.Imports_compile_dex, false)
for _, f := range files {
// create a Import module for each jar file
- localPath := strings.TrimPrefix(f, mydir)
- module, apiver, scope := parseJarPath(localPath)
- createImport(mctx, module, scope, apiver, localPath, sdkVersion, compileDex)
+ module, version, scope := parsePrebuiltPath(mctx, f)
+ createImport(mctx, module, scope, version, f, sdkVersion, compileDex)
if module == "core-for-system-modules" {
- createSystemModules(mctx, apiver, scope)
+ createSystemModules(mctx, version, scope)
}
}
}
-func createSystemModules(mctx android.LoadHookContext, apiver string, scope string) {
+func createSystemModules(mctx android.LoadHookContext, version, scope string) {
props := struct {
Name *string
Libs []string
}{}
- props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", scope, apiver))
- props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", scope, apiver))
+ props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", scope, version))
+ props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", scope, version))
mctx.CreateModule(systemModulesImportFactory, &props)
}
func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
- mydir := mctx.ModuleDir() + "/"
// <apiver>/<scope>/api/<module>.txt
- files := getPrebuiltFiles(mctx, p, "api/*.txt")
-
- if len(files) == 0 {
- mctx.ModuleErrorf("no api file found under %q", mydir)
- }
-
- // construct a map to find out the latest api file path
- // for each (<module>, <scope>) pair.
- type latestApiInfo struct {
- module string
- scope string
- version int
- path string
+ apiLevelFiles := globApiDirs(mctx, p, "api/*.txt")
+ if len(apiLevelFiles) == 0 {
+ mctx.ModuleErrorf("no api file found under %q", mctx.ModuleDir())
}
// 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)
- createApiModule(mctx, apiModuleName(module, scope, apiver), localPath)
+ for _, f := range apiLevelFiles {
+ module, version, scope := parseFinalizedPrebuiltPath(mctx, f)
+ createApiModule(mctx, apiModuleName(module, scope, strconv.Itoa(version)), f)
+ }
- version, err := strconv.Atoi(apiver)
- if err != nil {
- mctx.ModuleErrorf("Found finalized API files in non-numeric dir %v", apiver)
- return
- }
+ // Figure out the latest version of each module/scope
+ type latestApiInfo struct {
+ module, scope, path string
+ version int
+ }
- // Track latest version of each module/scope, except for incompatibilities
- if !strings.HasSuffix(module, "incompatibilities") {
+ getLatest := func(files []string) map[string]latestApiInfo {
+ m := make(map[string]latestApiInfo)
+ for _, f := range files {
+ module, version, scope := parseFinalizedPrebuiltPath(mctx, f)
+ if strings.HasSuffix(module, "incompatibilities") {
+ continue
+ }
key := module + "." + scope
- info, ok := m[key]
- if !ok {
- m[key] = latestApiInfo{module, scope, version, localPath}
- } else if version > info.version {
- info.version = version
- info.path = localPath
- m[key] = info
+ info, exists := m[key]
+ if !exists || version > info.version {
+ m[key] = latestApiInfo{module, scope, f, version}
+ }
+ }
+ return m
+ }
+
+ latest := getLatest(apiLevelFiles)
+ if p.properties.Extensions_dir != nil {
+ extensionApiFiles := globExtensionDirs(mctx, p, "api/*.txt")
+ for k, v := range getLatest(extensionApiFiles) {
+ if v.version > mctx.Config().PlatformBaseSdkExtensionVersion() {
+ if _, exists := latest[k]; !exists {
+ mctx.ModuleErrorf("Module %v finalized for extension %d but never during an API level; likely error", v.module, v.version)
+ }
+ latest[k] = v
}
}
}
// Sort the keys in order to make build.ninja stable
- for _, k := range android.SortedStringKeys(m) {
- info := m[k]
+ for _, k := range android.SortedStringKeys(latest) {
+ info := latest[k]
name := apiModuleName(info.module, info.scope, "latest")
createApiModule(mctx, name, info.path)
}
@@ -244,21 +273,20 @@
// Create incompatibilities tracking files for all modules, if we have a "next" api.
incompatibilities := make(map[string]bool)
if nextApiDir := String(p.properties.Next_api_dir); nextApiDir != "" {
- files := getPrebuiltFilesInSubdir(mctx, nextApiDir, "api/*incompatibilities.txt")
+ files := globScopeDir(mctx, nextApiDir, "api/*incompatibilities.txt")
for _, f := range files {
- localPath := strings.TrimPrefix(f, mydir)
- filename, _, scope := parseApiFilePath(mctx, localPath)
+ filename, _, scope := parsePrebuiltPath(mctx, f)
referencedModule := strings.TrimSuffix(filename, "-incompatibilities")
- createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), localPath)
+ createApiModule(mctx, apiModuleName(referencedModule+"-incompatibilities", scope, "latest"), f)
incompatibilities[referencedModule+"."+scope] = true
}
}
// Create empty incompatibilities files for remaining modules
- for _, k := range android.SortedStringKeys(m) {
+ for _, k := range android.SortedStringKeys(latest) {
if _, ok := incompatibilities[k]; !ok {
- createEmptyFile(mctx, apiModuleName(m[k].module+"-incompatibilities", m[k].scope, "latest"))
+ createEmptyFile(mctx, apiModuleName(latest[k].module+"-incompatibilities", latest[k].scope, "latest"))
}
}
}
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index 79f4225..75422ad 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -20,9 +20,14 @@
"testing"
"android/soong/android"
+
"github.com/google/blueprint"
)
+func intPtr(v int) *int {
+ return &v
+}
+
func TestPrebuiltApis_SystemModulesCreation(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
@@ -54,3 +59,34 @@
sort.Strings(expected)
android.AssertArrayString(t, "sdk system modules", expected, sdkSystemModules)
}
+
+func TestPrebuiltApis_WithExtensions(t *testing.T) {
+ runTestWithBaseExtensionLevel := func(v int) (foo_input string, bar_input string) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_base_sdk_extension_version = intPtr(v)
+ }),
+ FixtureWithPrebuiltApisAndExtensions(map[string][]string{
+ "31": {"foo"},
+ "32": {"foo", "bar"},
+ "current": {"foo", "bar"},
+ }, map[string][]string{
+ "1": {"foo"},
+ "2": {"foo", "bar"},
+ }),
+ ).RunTest(t)
+ foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ return
+ }
+ // Here, the base extension level is 1, so extension level 2 is the latest
+ foo_input, bar_input := runTestWithBaseExtensionLevel(1)
+ android.AssertStringEquals(t, "Expected latest = extension level 2", "prebuilts/sdk/extensions/2/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
+
+ // Here, the base extension level is 2, so 2 is not later than 32.
+ foo_input, bar_input = runTestWithBaseExtensionLevel(2)
+ android.AssertStringEquals(t, "Expected latest = api level 32", "prebuilts/sdk/32/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest = api level 32", "prebuilts/sdk/32/public/api/bar.txt", bar_input)
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e794a48..bfdfffc 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1511,15 +1511,15 @@
}
droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
disabledWarnings := []string{
- "MissingPermission",
"BroadcastBehavior",
- "HiddenSuperclass",
"DeprecationMismatch",
- "UnavailableSymbol",
- "SdkConstant",
+ "HiddenSuperclass",
"HiddenTypeParameter",
+ "MissingPermission",
+ "SdkConstant",
"Todo",
"Typo",
+ "UnavailableSymbol",
}
droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
diff --git a/java/testing.go b/java/testing.go
index 6c49bc8..82aa29b 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -146,6 +146,10 @@
// This defines a file in the mock file system in a predefined location (prebuilts/sdk/Android.bp)
// and so only one instance of this can be used in each fixture.
func FixtureWithPrebuiltApis(release2Modules map[string][]string) android.FixturePreparer {
+ return FixtureWithPrebuiltApisAndExtensions(release2Modules, nil)
+}
+
+func FixtureWithPrebuiltApisAndExtensions(apiLevel2Modules map[string][]string, extensionLevel2Modules map[string][]string) android.FixturePreparer {
mockFS := android.MockFS{}
path := "prebuilts/sdk/Android.bp"
@@ -153,14 +157,20 @@
prebuilt_apis {
name: "sdk",
api_dirs: ["%s"],
+ extensions_dir: "extensions",
imports_sdk_version: "none",
imports_compile_dex: true,
}
- `, strings.Join(android.SortedStringKeys(release2Modules), `", "`))
+ `, strings.Join(android.SortedStringKeys(apiLevel2Modules), `", "`))
- for release, modules := range release2Modules {
+ for release, modules := range apiLevel2Modules {
mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
}
+ if extensionLevel2Modules != nil {
+ for release, modules := range extensionLevel2Modules {
+ mockFS.Merge(prebuiltExtensionApiFiles([]string{release}, modules))
+ }
+ }
return android.GroupFixturePreparers(
android.FixtureAddTextFile(path, bp),
android.FixtureMergeMockFs(mockFS),
@@ -198,6 +208,19 @@
return fs
}
+func prebuiltExtensionApiFiles(extensionLevels []string, modules []string) map[string][]byte {
+ fs := make(map[string][]byte)
+ for _, level := range extensionLevels {
+ for _, sdkKind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkModule, android.SdkSystemServer} {
+ for _, lib := range modules {
+ fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s.txt", level, sdkKind, lib)] = nil
+ fs[fmt.Sprintf("prebuilts/sdk/extensions/%s/%s/api/%s-removed.txt", level, sdkKind, lib)] = nil
+ }
+ }
+ }
+ return fs
+}
+
// FixtureConfigureBootJars configures the boot jars in both the dexpreopt.GlobalConfig and
// Config.productVariables structs. As a side effect that enables dexpreopt.
func FixtureConfigureBootJars(bootJars ...string) android.FixturePreparer {
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 4e58632..2361e03 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -106,6 +106,9 @@
}
entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(test.Properties.Auto_gen_config, true))
entries.SetBoolIfTrue("LOCAL_IS_UNIT_TEST", Bool(test.Properties.Test_options.Unit_test))
+ if test.Properties.Data_bins != nil {
+ entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...)
+ }
})
cc.AndroidMkWriteTestData(test.data, ret)
diff --git a/rust/rust.go b/rust/rust.go
index 018d1dd..f40f1a8 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1192,6 +1192,10 @@
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
directStaticLibDeps = append(directStaticLibDeps, ccDep)
+
+ // Record baseLibName for snapshots.
+ mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
+
mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, makeLibName)
case cc.IsSharedDepTag(depTag):
// For the shared lib dependencies, we may link to the stub variant
@@ -1214,7 +1218,6 @@
// Record baseLibName for snapshots.
mod.Properties.SnapshotSharedLibs = append(mod.Properties.SnapshotSharedLibs, cc.BaseLibName(depName))
- mod.Properties.SnapshotStaticLibs = append(mod.Properties.SnapshotStaticLibs, cc.BaseLibName(depName))
mod.Properties.AndroidMkSharedLibs = append(mod.Properties.AndroidMkSharedLibs, makeLibName)
exportDep = true
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 4783037..1574587 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -23,6 +23,7 @@
source build/envsetup.sh
PLATFORM_SDK_VERSION=$(get_build_var PLATFORM_SDK_VERSION)
+PLATFORM_BASE_SDK_EXTENSION_VERSION=$(get_build_var PLATFORM_BASE_SDK_EXTENSION_VERSION)
PLATFORM_VERSION_ALL_CODENAMES=$(get_build_var PLATFORM_VERSION_ALL_CODENAMES)
# PLATFORM_VERSION_ALL_CODENAMES is a comma separated list like O,P. We need to
@@ -46,6 +47,7 @@
cat > ${SOONG_OUT}/soong.variables << EOF
{
"Platform_sdk_version": ${PLATFORM_SDK_VERSION},
+ "Platform_base_sdk_extension_version": ${PLATFORM_BASE_SDK_EXTENSION_VERSION},
"Platform_version_active_codenames": ${PLATFORM_VERSION_ALL_CODENAMES},
"DeviceName": "generic_arm64",
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 2ab784d..d1beaba 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -149,6 +149,9 @@
// Only available for host sh_test modules.
Data_device_libs []string `android:"path,arch_variant"`
+ // Install the test into a folder named for the module in all test suites.
+ Per_testcase_directory *bool
+
// Test options.
Test_options TestOptions
}
@@ -458,9 +461,13 @@
dir := strings.TrimSuffix(s.dataModules[relPath].String(), relPath)
entries.AddStrings("LOCAL_TEST_DATA", dir+":"+relPath)
}
+ if s.testProperties.Data_bins != nil {
+ entries.AddStrings("LOCAL_TEST_DATA_BINS", s.testProperties.Data_bins...)
+ }
if Bool(s.testProperties.Test_options.Unit_test) {
entries.SetBool("LOCAL_IS_UNIT_TEST", true)
}
+ entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(s.testProperties.Per_testcase_directory))
},
},
}}
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 7fe1d85..89b8126 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -37,6 +37,8 @@
//
// deprecated
func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) {
+ bp = bp + cc.GatherRequiredDepsForTest(android.Android)
+
result := prepareForShTest.RunTestWithBp(t, bp)
return result.TestContext, result.Config