Merge "Run the dcla comparison test for both pure soong build and mixed build."
diff --git a/OWNERS b/OWNERS
index e18eea1..964e27a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,7 +4,6 @@
# AMER
agespino@google.com
alexmarquez@google.com
-asmundak@google.com
ccross@android.com
colefaust@google.com
cparsons@google.com
@@ -27,6 +26,4 @@
jingwen@google.com
# EMEA
-hansson@google.com #{LAST_RESORT_SUGGESTION}
lberki@google.com
-paulduffin@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 89c2d19..63495bc 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -198,6 +198,7 @@
"frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/aapt2": Bp2BuildDefaultTrue,
+ "frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively,
"frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
@@ -383,7 +384,6 @@
// this BUILD file is globbed by //external/icu/icu4c/source:icu4c_test_data's "data/**/*".
"external/icu/icu4c/source/data/unidata/norm2":/* recursive = */ false,
- "frameworks/base/tools/codegen":/* recursive = */ true,
"frameworks/ex/common":/* recursive = */ true,
// Building manually due to b/179889880: resource files cross package boundary
@@ -689,11 +689,21 @@
//kotlin srcs in android_binary
"MusicKotlin",
+
+ // checked in current.txt for merged_txts
+ "non-updatable-current.txt",
+ "non-updatable-system-current.txt",
+ "non-updatable-module-lib-current.txt",
+ "non-updatable-system-server-current.txt",
+
+ // for api_fingerprint.txt generation
+ "api_fingerprint",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
"aidl_interface_headers",
"bpf",
+ "combined_apis",
"license",
"linker_config",
"java_import",
@@ -1429,7 +1439,9 @@
// which will soon be added to the prod allowlist.
// It is implicit that all modules in ProdMixedBuildsEnabledList will
// also be built - do not add them to this list.
- StagingMixedBuildsEnabledList = []string{}
+ StagingMixedBuildsEnabledList = []string{
+ "api_fingerprint",
+ }
// These should be the libs that are included by the apexes in the ProdMixedBuildsEnabledList
ProdDclaMixedBuildsEnabledList = []string{}
diff --git a/android/androidmk.go b/android/androidmk.go
index 14b2e82..aa411d1 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -548,6 +548,7 @@
a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+ a.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
// If the install rule was generated by Soong tell Make about it.
if len(base.katiInstalls) > 0 {
diff --git a/android/apex.go b/android/apex.go
index 3c945ae..358818f 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -817,7 +817,7 @@
var flatContent strings.Builder
fmt.Fprintf(&fullContent, "%s(minSdkVersion:%s):\n", ctx.ModuleName(), minSdkVersion)
- for _, key := range FirstUniqueStrings(SortedStringKeys(depInfos)) {
+ for _, key := range FirstUniqueStrings(SortedKeys(depInfos)) {
info := depInfos[key]
toName := fmt.Sprintf("%s(minSdkVersion:%s)", info.To, info.MinSdkVersion)
if info.IsExternal {
diff --git a/android/api_levels.go b/android/api_levels.go
index 6d7552f..9440ee9 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -225,6 +225,8 @@
// ApiLevelFromUserWithConfig implements ApiLevelFromUser, see comments for
// ApiLevelFromUser for more details.
func ApiLevelFromUserWithConfig(config Config, raw string) (ApiLevel, error) {
+ // This logic is replicated in starlark, if changing logic here update starlark code too
+ // https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=42;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
if raw == "" {
panic("API level string must be non-empty")
}
@@ -329,6 +331,8 @@
var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")
func getFinalCodenamesMap(config Config) map[string]int {
+ // This logic is replicated in starlark, if changing logic here update starlark code too
+ // https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=30;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
return config.Once(finalCodenamesMapKey, func() interface{} {
apiLevelsMap := getApiLevelsMapReleasedVersions()
@@ -355,6 +359,8 @@
// ApiLevelsMap has entries for preview API levels
func GetApiLevelsMap(config Config) map[string]int {
+ // This logic is replicated in starlark, if changing logic here update starlark code too
+ // https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=23;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
return config.Once(apiLevelsMapKey, func() interface{} {
apiLevelsMap := getApiLevelsMapReleasedVersions()
for i, codename := range config.PlatformVersionActiveCodenames() {
diff --git a/android/arch_list.go b/android/arch_list.go
index 578904c..ab644a4 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -26,6 +26,7 @@
"armv8-a-branchprot",
"armv8-2a",
"armv8-2a-dotprod",
+ "armv9-a",
},
X86: {
"amberlake",
@@ -71,6 +72,7 @@
"cortex-a8",
"cortex-a9",
"cortex-a15",
+ "cortex-a32",
"cortex-a53",
"cortex-a53.a57",
"cortex-a55",
@@ -148,6 +150,9 @@
"armv8-2a-dotprod": {
"dotprod",
},
+ "armv9-a": {
+ "dotprod",
+ },
},
X86: {
"amberlake": {
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index e7ff08f..e7b84e3 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -607,7 +607,7 @@
dclaEnabledModules := map[string]bool{}
addToStringSet(dclaEnabledModules, dclaMixedBuildsEnabledList)
return &mixedBuildBazelContext{
- bazelRunner: &builtinBazelRunner{},
+ bazelRunner: &builtinBazelRunner{c.UseBazelProxy, absolutePath(c.outDir)},
paths: &paths,
modulesDefaultToBazel: c.BuildMode == BazelDevMode,
bazelEnabledModules: enabledModules,
@@ -684,23 +684,46 @@
return "", "", nil
}
-type builtinBazelRunner struct{}
+type builtinBazelRunner struct {
+ useBazelProxy bool
+ outDir string
+}
// Issues the given bazel command with given build label and additional flags.
// Returns (stdout, stderr, error). The first and second return values are strings
// containing the stdout and stderr of the run command, and an error is returned if
// the invocation returned an error code.
func (r *builtinBazelRunner) issueBazelCommand(bazelCmd *exec.Cmd, eventHandler *metrics.EventHandler) (string, string, error) {
- eventHandler.Begin("bazel command")
- defer eventHandler.End("bazel command")
- stderr := &bytes.Buffer{}
- bazelCmd.Stderr = stderr
- if output, err := bazelCmd.Output(); err != nil {
- return "", string(stderr.Bytes()),
- fmt.Errorf("bazel command failed: %s\n---command---\n%s\n---env---\n%s\n---stderr---\n%s---",
- err, bazelCmd, strings.Join(bazelCmd.Env, "\n"), stderr)
+ if r.useBazelProxy {
+ eventHandler.Begin("client_proxy")
+ defer eventHandler.End("client_proxy")
+ proxyClient := bazel.NewProxyClient(r.outDir)
+ // Omit the arg containing the Bazel binary, as that is handled by the proxy
+ // server.
+ bazelFlags := bazelCmd.Args[1:]
+ // TODO(b/270989498): Refactor these functions to not take exec.Cmd, as its
+ // not actually executed for client proxying.
+ resp, err := proxyClient.IssueCommand(bazel.CmdRequest{bazelFlags, bazelCmd.Env})
+
+ if err != nil {
+ return "", "", err
+ }
+ if len(resp.ErrorString) > 0 {
+ return "", "", fmt.Errorf(resp.ErrorString)
+ }
+ return resp.Stdout, resp.Stderr, nil
} else {
- return string(output), string(stderr.Bytes()), nil
+ eventHandler.Begin("bazel command")
+ defer eventHandler.End("bazel command")
+ stderr := &bytes.Buffer{}
+ bazelCmd.Stderr = stderr
+ if output, err := bazelCmd.Output(); err != nil {
+ return "", string(stderr.Bytes()),
+ fmt.Errorf("bazel command failed: %s\n---command---\n%s\n---env---\n%s\n---stderr---\n%s---",
+ err, bazelCmd, strings.Join(bazelCmd.Env, "\n"), stderr)
+ } else {
+ return string(output), string(stderr.Bytes()), nil
+ }
}
}
diff --git a/android/config.go b/android/config.go
index c0f84c8..b37d5c8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -87,6 +87,8 @@
BazelModeDev bool
BazelModeStaging bool
BazelForceEnabledModules string
+
+ UseBazelProxy bool
}
// Build modes that soong_build can run as.
@@ -251,6 +253,10 @@
// specified modules. They are passed via the command-line flag
// "--bazel-force-enabled-modules"
bazelForceEnabledModules map[string]struct{}
+
+ // If true, for any requests to Bazel, communicate with a Bazel proxy using
+ // unix sockets, instead of spawning Bazel as a subprocess.
+ UseBazelProxy bool
}
type deviceConfig struct {
@@ -442,6 +448,8 @@
mixedBuildDisabledModules: make(map[string]struct{}),
mixedBuildEnabledModules: make(map[string]struct{}),
bazelForceEnabledModules: make(map[string]struct{}),
+
+ UseBazelProxy: cmdArgs.UseBazelProxy,
}
config.deviceConfig = &deviceConfig{
@@ -727,10 +735,6 @@
return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
}
-func (c *config) TargetsJava17() bool {
- return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_17")
-}
-
// EnvDeps returns the environment variables this build depends on. The first
// call to this function blocks future reads from the environment.
func (c *config) EnvDeps() map[string]string {
@@ -879,6 +883,8 @@
// DefaultAppTargetSdk returns the API level that platform apps are targeting.
// This converts a codename to the exact ApiLevel it represents.
func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel {
+ // This logic is replicated in starlark, if changing logic here update starlark code too
+ // https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/common/api.bzl;l=72;drc=231c7e8c8038fd478a79eb68aa5b9f5c64e0e061
if Bool(c.productVariables.Platform_sdk_final) {
return c.PlatformSdkVersion()
}
diff --git a/android/defaults.go b/android/defaults.go
index 925eafc..a821b28 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -302,7 +302,7 @@
delete(propertiesSet, "visibility")
// Replace the "*" with the names of all the properties that have been set.
- protectedProperties = SortedStringKeys(propertiesSet)
+ protectedProperties = SortedKeys(propertiesSet)
module.setProtectedProperties(protectedProperties)
} else {
for _, property := range protectedProperties {
diff --git a/android/module.go b/android/module.go
index 97c9706..58c5464 100644
--- a/android/module.go
+++ b/android/module.go
@@ -3675,7 +3675,7 @@
// Ensure ancestor directories are in dirMap
// Make directories build their direct subdirectories
// Returns a slice of all directories and a slice of top-level directories.
- dirs := SortedStringKeys(dirMap)
+ dirs := SortedKeys(dirMap)
for _, dir := range dirs {
dir := parentDir(dir)
for dir != "." && dir != "/" {
@@ -3686,7 +3686,7 @@
dir = parentDir(dir)
}
}
- dirs = SortedStringKeys(dirMap)
+ dirs = SortedKeys(dirMap)
var topDirs []string
for _, dir := range dirs {
p := parentDir(dir)
@@ -3696,7 +3696,7 @@
topDirs = append(topDirs, dir)
}
}
- return SortedStringKeys(dirMap), topDirs
+ return SortedKeys(dirMap), topDirs
}
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
@@ -3782,7 +3782,7 @@
}
// Wrap those into host|host-cross|target phony rules
- for _, class := range SortedStringKeys(osClass) {
+ for _, class := range SortedKeys(osClass) {
ctx.Phony(class, osClass[class]...)
}
}
diff --git a/android/neverallow.go b/android/neverallow.go
index ad9880a..ba5385c 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -542,7 +542,7 @@
s = append(s, fmt.Sprintf("properties matching: %s", r.props))
}
if len(r.directDeps) > 0 {
- s = append(s, fmt.Sprintf("dep(s): %q", SortedStringKeys(r.directDeps)))
+ s = append(s, fmt.Sprintf("dep(s): %q", SortedKeys(r.directDeps)))
}
if len(r.osClasses) > 0 {
s = append(s, fmt.Sprintf("os class(es): %q", r.osClasses))
diff --git a/android/packaging.go b/android/packaging.go
index ecd84a2..4a9b591 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -240,7 +240,7 @@
// entries into the specified directory.
func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir ModuleOutPath) (entries []string) {
seenDir := make(map[string]bool)
- for _, k := range SortedStringKeys(specs) {
+ for _, k := range SortedKeys(specs) {
ps := specs[k]
destPath := dir.Join(ctx, ps.relPathInPackage).String()
destDir := filepath.Dir(destPath)
diff --git a/android/phony.go b/android/phony.go
index 0adbb55..814a9e3 100644
--- a/android/phony.go
+++ b/android/phony.go
@@ -48,7 +48,7 @@
func (p *phonySingleton) GenerateBuildActions(ctx SingletonContext) {
p.phonyMap = getPhonyMap(ctx.Config())
- p.phonyList = SortedStringKeys(p.phonyMap)
+ p.phonyList = SortedKeys(p.phonyMap)
for _, phony := range p.phonyList {
p.phonyMap[phony] = SortedUniquePaths(p.phonyMap[phony])
}
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 8953eae..a7e03dc 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -211,7 +211,29 @@
if !s.ApiLevel.IsPreview() {
return s.ApiLevel.String(), nil
}
- return ctx.Config().DefaultAppTargetSdk(ctx).String(), nil
+ // Determine the default sdk
+ ret := ctx.Config().DefaultAppTargetSdk(ctx)
+ if !ret.IsPreview() {
+ // If the default sdk has been finalized, return that
+ return ret.String(), nil
+ }
+ // There can be more than one active in-development sdks
+ // If an app is targeting an active sdk, but not the default one, return the requested active sdk.
+ // e.g.
+ // SETUP
+ // In-development: UpsideDownCake, VanillaIceCream
+ // Default: VanillaIceCream
+ // Android.bp
+ // min_sdk_version: `UpsideDownCake`
+ // RETURN
+ // UpsideDownCake and not VanillaIceCream
+ for _, preview := range ctx.Config().PreviewApiLevels() {
+ if s.ApiLevel.String() == preview.String() {
+ return preview.String(), nil
+ }
+ }
+ // Otherwise return the default one
+ return ret.String(), nil
}
var (
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 9f5440d..5fa6012 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -396,7 +396,7 @@
}
if ctx.Config().BuildMode == Bp2build {
- ctx.Config().Bp2buildSoongConfigDefinitions.AddVars(*mtDef)
+ ctx.Config().Bp2buildSoongConfigDefinitions.AddVars(mtDef)
}
globalModuleTypes := ctx.moduleFactories()
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index ed4888d..23c8afa 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -240,12 +240,7 @@
// string vars, bool vars and value vars created by every
// soong_config_module_type in this build.
type Bp2BuildSoongConfigDefinitions struct {
- // varCache contains a cache of string variables namespace + property
- // The same variable may be used in multiple module types (for example, if need support
- // for cc_default and java_default), only need to process once
- varCache map[string]bool
-
- StringVars map[string][]string
+ StringVars map[string]map[string]bool
BoolVars map[string]bool
ValueVars map[string]bool
}
@@ -255,7 +250,7 @@
// SoongConfigVariablesForBp2build extracts information from a
// SoongConfigDefinition that bp2build needs to generate constraint settings and
// values for, in order to migrate soong_config_module_type usages to Bazel.
-func (defs *Bp2BuildSoongConfigDefinitions) AddVars(mtDef SoongConfigDefinition) {
+func (defs *Bp2BuildSoongConfigDefinitions) AddVars(mtDef *SoongConfigDefinition) {
// In bp2build mode, this method is called concurrently in goroutines from
// loadhooks while parsing soong_config_module_type, so add a mutex to
// prevent concurrent map writes. See b/207572723
@@ -263,7 +258,7 @@
defer bp2buildSoongConfigVarsLock.Unlock()
if defs.StringVars == nil {
- defs.StringVars = make(map[string][]string)
+ defs.StringVars = make(map[string]map[string]bool)
}
if defs.BoolVars == nil {
defs.BoolVars = make(map[string]bool)
@@ -271,24 +266,29 @@
if defs.ValueVars == nil {
defs.ValueVars = make(map[string]bool)
}
- if defs.varCache == nil {
- defs.varCache = make(map[string]bool)
- }
+ // varCache contains a cache of string variables namespace + property
+ // The same variable may be used in multiple module types (for example, if need support
+ // for cc_default and java_default), only need to process once
+ varCache := map[string]bool{}
+
for _, moduleType := range mtDef.ModuleTypes {
for _, v := range moduleType.Variables {
key := strings.Join([]string{moduleType.ConfigNamespace, v.variableProperty()}, "__")
// The same variable may be used in multiple module types (for example, if need support
// for cc_default and java_default), only need to process once
- if _, keyInCache := defs.varCache[key]; keyInCache {
+ if _, keyInCache := varCache[key]; keyInCache {
continue
} else {
- defs.varCache[key] = true
+ varCache[key] = true
}
if strVar, ok := v.(*stringVariable); ok {
+ if _, ok := defs.StringVars[key]; !ok {
+ defs.StringVars[key] = make(map[string]bool, len(strVar.values))
+ }
for _, value := range strVar.values {
- defs.StringVars[key] = append(defs.StringVars[key], value)
+ defs.StringVars[key][value] = true
}
} else if _, ok := v.(*boolVariable); ok {
defs.BoolVars[key] = true
@@ -329,8 +329,13 @@
ret += starlark_fmt.PrintBoolDict(defs.ValueVars, 0)
ret += "\n\n"
+ stringVars := make(map[string][]string, len(defs.StringVars))
+ for k, v := range defs.StringVars {
+ stringVars[k] = sortedStringKeys(v)
+ }
+
ret += "soong_config_string_variables = "
- ret += starlark_fmt.PrintStringListDict(defs.StringVars, 0)
+ ret += starlark_fmt.PrintStringListDict(stringVars, 0)
return ret
}
diff --git a/android/soongconfig/modules_test.go b/android/soongconfig/modules_test.go
index d5d87ef..a5fa349 100644
--- a/android/soongconfig/modules_test.go
+++ b/android/soongconfig/modules_test.go
@@ -414,6 +414,110 @@
}
}
+func Test_Bp2BuildSoongConfigDefinitionsAddVars(t *testing.T) {
+ testCases := []struct {
+ desc string
+ defs []*SoongConfigDefinition
+ expected Bp2BuildSoongConfigDefinitions
+ }{
+ {
+ desc: "non-overlapping",
+ defs: []*SoongConfigDefinition{
+ &SoongConfigDefinition{
+ ModuleTypes: map[string]*ModuleType{
+ "a": &ModuleType{
+ ConfigNamespace: "foo",
+ Variables: []soongConfigVariable{
+ &stringVariable{
+ baseVariable: baseVariable{"string_var"},
+ values: []string{"a", "b", "c"},
+ },
+ },
+ },
+ },
+ },
+ &SoongConfigDefinition{
+ ModuleTypes: map[string]*ModuleType{
+ "b": &ModuleType{
+ ConfigNamespace: "foo",
+ Variables: []soongConfigVariable{
+ &stringVariable{
+ baseVariable: baseVariable{"string_var"},
+ values: []string{"a", "b", "c"},
+ },
+ &boolVariable{baseVariable: baseVariable{"bool_var"}},
+ &valueVariable{baseVariable: baseVariable{"variable_var"}},
+ },
+ },
+ },
+ },
+ },
+ expected: Bp2BuildSoongConfigDefinitions{
+ StringVars: map[string]map[string]bool{
+ "foo__string_var": map[string]bool{"a": true, "b": true, "c": true},
+ },
+ BoolVars: map[string]bool{"foo__bool_var": true},
+ ValueVars: map[string]bool{"foo__variable_var": true},
+ },
+ },
+ {
+ desc: "overlapping",
+ defs: []*SoongConfigDefinition{
+ &SoongConfigDefinition{
+ ModuleTypes: map[string]*ModuleType{
+ "a": &ModuleType{
+ ConfigNamespace: "foo",
+ Variables: []soongConfigVariable{
+ &stringVariable{
+ baseVariable: baseVariable{"string_var"},
+ values: []string{"a", "b", "c"},
+ },
+ },
+ },
+ },
+ },
+ &SoongConfigDefinition{
+ ModuleTypes: map[string]*ModuleType{
+ "b": &ModuleType{
+ ConfigNamespace: "foo",
+ Variables: []soongConfigVariable{
+ &stringVariable{
+ baseVariable: baseVariable{"string_var"},
+ values: []string{"b", "c", "d"},
+ },
+ &boolVariable{baseVariable: baseVariable{"bool_var"}},
+ &valueVariable{baseVariable: baseVariable{"variable_var"}},
+ },
+ },
+ },
+ },
+ },
+ expected: Bp2BuildSoongConfigDefinitions{
+ StringVars: map[string]map[string]bool{
+ "foo__string_var": map[string]bool{"a": true, "b": true, "c": true, "d": true},
+ },
+ BoolVars: map[string]bool{"foo__bool_var": true},
+ ValueVars: map[string]bool{"foo__variable_var": true},
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ actual := &Bp2BuildSoongConfigDefinitions{}
+ for _, d := range tc.defs {
+ func(def *SoongConfigDefinition) {
+ actual.AddVars(def)
+ }(d)
+ }
+ if !reflect.DeepEqual(*actual, tc.expected) {
+ t.Errorf("Expected %#v, got %#v", tc.expected, *actual)
+ }
+ })
+ }
+
+}
+
func Test_Bp2BuildSoongConfigDefinitions(t *testing.T) {
testCases := []struct {
desc string
@@ -456,11 +560,11 @@
soong_config_string_variables = {}`}, {
desc: "only string vars",
defs: Bp2BuildSoongConfigDefinitions{
- StringVars: map[string][]string{
- "string_var": []string{
- "choice1",
- "choice2",
- "choice3",
+ StringVars: map[string]map[string]bool{
+ "string_var": map[string]bool{
+ "choice1": true,
+ "choice2": true,
+ "choice3": true,
},
},
},
@@ -484,15 +588,15 @@
"value_var_one": true,
"value_var_two": true,
},
- StringVars: map[string][]string{
- "string_var_one": []string{
- "choice1",
- "choice2",
- "choice3",
+ StringVars: map[string]map[string]bool{
+ "string_var_one": map[string]bool{
+ "choice1": true,
+ "choice2": true,
+ "choice3": true,
},
- "string_var_two": []string{
- "foo",
- "bar",
+ "string_var_two": map[string]bool{
+ "foo": true,
+ "bar": true,
},
},
},
@@ -512,8 +616,8 @@
"choice3",
],
"string_var_two": [
- "foo",
"bar",
+ "foo",
],
}`},
}
diff --git a/android/test_suites.go b/android/test_suites.go
index 55e1da7..b570b23 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -57,7 +57,7 @@
func robolectricTestSuite(ctx SingletonContext, files map[string]InstallPaths) WritablePath {
var installedPaths InstallPaths
- for _, module := range SortedStringKeys(files) {
+ for _, module := range SortedKeys(files) {
installedPaths = append(installedPaths, files[module]...)
}
testCasesDir := pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases", false)
diff --git a/android/util.go b/android/util.go
index 8f4c17d..38e0a4d 100644
--- a/android/util.go
+++ b/android/util.go
@@ -62,40 +62,33 @@
return buf.String()
}
-// JoinWithSuffix appends the suffix to each string in the list and
-// returns them joined together with given separator.
-func JoinWithSuffix(strs []string, suffix string, separator string) string {
- if len(strs) == 0 {
- return ""
- }
-
- var buf strings.Builder
- buf.WriteString(strs[0])
- buf.WriteString(suffix)
- for i := 1; i < len(strs); i++ {
- buf.WriteString(separator)
- buf.WriteString(strs[i])
- buf.WriteString(suffix)
- }
- return buf.String()
+// SortedStringKeys returns the keys of the given map in the ascending order.
+//
+// Deprecated: Use SortedKeys instead.
+func SortedStringKeys[V any](m map[string]V) []string {
+ return SortedKeys(m)
}
-// 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))
- }
- if v.Len() == 0 {
+type Ordered interface {
+ ~string |
+ ~float32 | ~float64 |
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
+}
+
+// SortedKeys returns the keys of the given map in the ascending order.
+func SortedKeys[T Ordered, V any](m map[T]V) []T {
+ if len(m) == 0 {
return nil
}
- iter := v.MapRange()
- s := make([]string, 0, v.Len())
- for iter.Next() {
- s = append(s, iter.Key().String())
+ ret := make([]T, 0, len(m))
+ for k := range m {
+ ret = append(ret, k)
}
- sort.Strings(s)
- return s
+ sort.Slice(ret, func(i, j int) bool {
+ return ret[i] < ret[j]
+ })
+ return ret
}
// stringValues returns the values of the given string-valued map in randomized map order.
diff --git a/android/util_test.go b/android/util_test.go
index 9b9253b..5584b38 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -641,42 +641,34 @@
}
}
-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"},
- },
- }
+func testSortedKeysHelper[K Ordered, V any](t *testing.T, name string, input map[K]V, expected []K) {
+ t.Helper()
+ t.Run(name, func(t *testing.T) {
+ actual := SortedKeys(input)
+ if !reflect.DeepEqual(actual, expected) {
+ t.Errorf("expected %v, got %v", expected, actual)
+ }
+ })
+}
- 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 TestSortedKeys(t *testing.T) {
+ testSortedKeysHelper(t, "simple", map[string]string{
+ "b": "bar",
+ "a": "foo",
+ }, []string{
+ "a",
+ "b",
+ })
+ testSortedKeysHelper(t, "ints", map[int]interface{}{
+ 10: nil,
+ 5: nil,
+ }, []int{
+ 5,
+ 10,
+ })
+
+ testSortedKeysHelper(t, "nil", map[string]string(nil), nil)
+ testSortedKeysHelper(t, "empty", map[string]string{}, nil)
}
func TestSortedStringValues(t *testing.T) {
diff --git a/apex/Android.bp b/apex/Android.bp
index 018d030..7ffca0e 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -29,6 +29,7 @@
"bp2build.go",
"deapexer.go",
"key.go",
+ "metadata.go",
"prebuilt.go",
"testing.go",
"vndk.go",
@@ -37,6 +38,7 @@
"apex_test.go",
"bootclasspath_fragment_test.go",
"classpath_element_test.go",
+ "metadata_test.go",
"platform_bootclasspath_test.go",
"systemserver_classpath_fragment_test.go",
"vndk_test.go",
diff --git a/apex/OWNERS b/apex/OWNERS
deleted file mode 100644
index 8e4ba5c..0000000
--- a/apex/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-per-file * = jiyong@google.com
diff --git a/apex/apex.go b/apex/apex.go
index d7d76d1..88eb72f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -99,6 +99,10 @@
// /system/sepolicy/apex/<module_name>_file_contexts.
File_contexts *string `android:"path"`
+ // By default, file_contexts is amended by force-labelling / and /apex_manifest.pb as system_file
+ // to avoid mistakes. When set as true, no force-labelling.
+ Use_file_contexts_as_is *bool
+
// Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
// format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
// path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 9cfce68..1f33eca 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -784,6 +784,43 @@
}
}
+func TestFileContexts(t *testing.T) {
+ for _, useFileContextsAsIs := range []bool{true, false} {
+ prop := ""
+ if useFileContextsAsIs {
+ prop = "use_file_contexts_as_is: true,\n"
+ }
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ file_contexts: "file_contexts",
+ updatable: false,
+ vendor: true,
+ `+prop+`
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+ `, withFiles(map[string][]byte{
+ "file_contexts": nil,
+ }))
+
+ rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("file_contexts")
+ forceLabellingCommand := "apex_manifest\\\\.pb u:object_r:system_file:s0"
+ if useFileContextsAsIs {
+ android.AssertStringDoesNotContain(t, "should force-label",
+ rule.RuleParams.Command, forceLabellingCommand)
+ } else {
+ android.AssertStringDoesContain(t, "shouldn't force-label",
+ rule.RuleParams.Command, forceLabellingCommand)
+ }
+ }
+}
+
func TestBasicZipApex(t *testing.T) {
ctx := testApex(t, `
apex {
@@ -4772,6 +4809,9 @@
android.AssertStringEquals(t, "Invalid output", "out/soong/.intermediates/provenance_metadata/myapex/provenance_metadata.textproto", rule.Output.String())
android.AssertStringEquals(t, "Invalid args", "myapex", rule.Args["module_name"])
android.AssertStringEquals(t, "Invalid args", "/system/apex/myapex.apex", rule.Args["install_path"])
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, testingModule.Module())[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "prebuilt_apex", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestPrebuiltMissingSrc(t *testing.T) {
@@ -9500,187 +9540,188 @@
}
}
-func TestApexStrictUpdtabilityLint(t *testing.T) {
- bpTemplate := `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjavalib"],
- updatable: %v,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- }
- java_library {
- name: "myjavalib",
- srcs: ["MyClass.java"],
- apex_available: [ "myapex" ],
- lint: {
- strict_updatability_linting: %v,
- },
- sdk_version: "current",
- min_sdk_version: "29",
- }
- `
- fs := android.MockFS{
- "lint-baseline.xml": nil,
- }
-
- testCases := []struct {
- testCaseName string
- apexUpdatable bool
- javaStrictUpdtabilityLint bool
- lintFileExists bool
- disallowedFlagExpected bool
- }{
- {
- testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
- apexUpdatable: true,
- javaStrictUpdtabilityLint: true,
- lintFileExists: false,
- disallowedFlagExpected: false,
- },
- {
- testCaseName: "non-updatable apex respects strict_updatability of javalib",
- apexUpdatable: false,
- javaStrictUpdtabilityLint: false,
- lintFileExists: true,
- disallowedFlagExpected: false,
- },
- {
- testCaseName: "non-updatable apex respects strict updatability of javalib",
- apexUpdatable: false,
- javaStrictUpdtabilityLint: true,
- lintFileExists: true,
- disallowedFlagExpected: true,
- },
- {
- testCaseName: "updatable apex sets strict updatability of javalib to true",
- apexUpdatable: true,
- javaStrictUpdtabilityLint: false, // will be set to true by mutator
- lintFileExists: true,
- disallowedFlagExpected: true,
- },
- }
-
- for _, testCase := range testCases {
- bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint)
- fixtures := []android.FixturePreparer{}
- if testCase.lintFileExists {
- fixtures = append(fixtures, fs.AddToFixture())
- }
-
- result := testApex(t, bp, fixtures...)
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
- disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi")
-
- if disallowedFlagActual != testCase.disallowedFlagExpected {
- t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
- }
- }
-}
-
-func TestUpdatabilityLintSkipLibcore(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjavalib"],
- updatable: true,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- }
- java_library {
- name: "myjavalib",
- srcs: ["MyClass.java"],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- min_sdk_version: "29",
- }
- `
-
- testCases := []struct {
- testCaseName string
- moduleDirectory string
- disallowedFlagExpected bool
- }{
- {
- testCaseName: "lintable module defined outside libcore",
- moduleDirectory: "",
- disallowedFlagExpected: true,
- },
- {
- testCaseName: "lintable module defined in libcore root directory",
- moduleDirectory: "libcore/",
- disallowedFlagExpected: false,
- },
- {
- testCaseName: "lintable module defined in libcore child directory",
- moduleDirectory: "libcore/childdir/",
- disallowedFlagExpected: true,
- },
- }
-
- for _, testCase := range testCases {
- lintFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"lint-baseline.xml", "")
- bpFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"Android.bp", bp)
- result := testApex(t, "", lintFileCreator, bpFileCreator)
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
- cmdFlags := fmt.Sprintf("--baseline %vlint-baseline.xml --disallowed_issues NewApi", testCase.moduleDirectory)
- disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, cmdFlags)
-
- if disallowedFlagActual != testCase.disallowedFlagExpected {
- t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
- }
- }
-}
-
-// checks transtive deps of an apex coming from bootclasspath_fragment
-func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- bootclasspath_fragments: ["mybootclasspathfragment"],
- updatable: true,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- }
- bootclasspath_fragment {
- name: "mybootclasspathfragment",
- contents: ["myjavalib"],
- apex_available: ["myapex"],
- hidden_api: {
- split_packages: ["*"],
- },
- }
- java_library {
- name: "myjavalib",
- srcs: ["MyClass.java"],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- min_sdk_version: "29",
- compile_dex: true,
- }
- `
- fs := android.MockFS{
- "lint-baseline.xml": nil,
- }
-
- result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture())
- myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") {
- t.Errorf("Strict updabality lint missing in myjavalib coming from bootclasspath_fragment mybootclasspath-fragment\nActual lint cmd: %v", *sboxProto.Commands[0].Command)
- }
-}
+// TODO(b/193460475): Re-enable this test
+//func TestApexStrictUpdtabilityLint(t *testing.T) {
+// bpTemplate := `
+// apex {
+// name: "myapex",
+// key: "myapex.key",
+// java_libs: ["myjavalib"],
+// updatable: %v,
+// min_sdk_version: "29",
+// }
+// apex_key {
+// name: "myapex.key",
+// }
+// java_library {
+// name: "myjavalib",
+// srcs: ["MyClass.java"],
+// apex_available: [ "myapex" ],
+// lint: {
+// strict_updatability_linting: %v,
+// },
+// sdk_version: "current",
+// min_sdk_version: "29",
+// }
+// `
+// fs := android.MockFS{
+// "lint-baseline.xml": nil,
+// }
+//
+// testCases := []struct {
+// testCaseName string
+// apexUpdatable bool
+// javaStrictUpdtabilityLint bool
+// lintFileExists bool
+// disallowedFlagExpected bool
+// }{
+// {
+// testCaseName: "lint-baseline.xml does not exist, no disallowed flag necessary in lint cmd",
+// apexUpdatable: true,
+// javaStrictUpdtabilityLint: true,
+// lintFileExists: false,
+// disallowedFlagExpected: false,
+// },
+// {
+// testCaseName: "non-updatable apex respects strict_updatability of javalib",
+// apexUpdatable: false,
+// javaStrictUpdtabilityLint: false,
+// lintFileExists: true,
+// disallowedFlagExpected: false,
+// },
+// {
+// testCaseName: "non-updatable apex respects strict updatability of javalib",
+// apexUpdatable: false,
+// javaStrictUpdtabilityLint: true,
+// lintFileExists: true,
+// disallowedFlagExpected: true,
+// },
+// {
+// testCaseName: "updatable apex sets strict updatability of javalib to true",
+// apexUpdatable: true,
+// javaStrictUpdtabilityLint: false, // will be set to true by mutator
+// lintFileExists: true,
+// disallowedFlagExpected: true,
+// },
+// }
+//
+// for _, testCase := range testCases {
+// bp := fmt.Sprintf(bpTemplate, testCase.apexUpdatable, testCase.javaStrictUpdtabilityLint)
+// fixtures := []android.FixturePreparer{}
+// if testCase.lintFileExists {
+// fixtures = append(fixtures, fs.AddToFixture())
+// }
+//
+// result := testApex(t, bp, fixtures...)
+// myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
+// sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
+// disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi")
+//
+// if disallowedFlagActual != testCase.disallowedFlagExpected {
+// t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
+// }
+// }
+//}
+//
+//func TestUpdatabilityLintSkipLibcore(t *testing.T) {
+// bp := `
+// apex {
+// name: "myapex",
+// key: "myapex.key",
+// java_libs: ["myjavalib"],
+// updatable: true,
+// min_sdk_version: "29",
+// }
+// apex_key {
+// name: "myapex.key",
+// }
+// java_library {
+// name: "myjavalib",
+// srcs: ["MyClass.java"],
+// apex_available: [ "myapex" ],
+// sdk_version: "current",
+// min_sdk_version: "29",
+// }
+// `
+//
+// testCases := []struct {
+// testCaseName string
+// moduleDirectory string
+// disallowedFlagExpected bool
+// }{
+// {
+// testCaseName: "lintable module defined outside libcore",
+// moduleDirectory: "",
+// disallowedFlagExpected: true,
+// },
+// {
+// testCaseName: "lintable module defined in libcore root directory",
+// moduleDirectory: "libcore/",
+// disallowedFlagExpected: false,
+// },
+// {
+// testCaseName: "lintable module defined in libcore child directory",
+// moduleDirectory: "libcore/childdir/",
+// disallowedFlagExpected: true,
+// },
+// }
+//
+// for _, testCase := range testCases {
+// lintFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"lint-baseline.xml", "")
+// bpFileCreator := android.FixtureAddTextFile(testCase.moduleDirectory+"Android.bp", bp)
+// result := testApex(t, "", lintFileCreator, bpFileCreator)
+// myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
+// sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
+// cmdFlags := fmt.Sprintf("--baseline %vlint-baseline.xml --disallowed_issues NewApi", testCase.moduleDirectory)
+// disallowedFlagActual := strings.Contains(*sboxProto.Commands[0].Command, cmdFlags)
+//
+// if disallowedFlagActual != testCase.disallowedFlagExpected {
+// t.Errorf("Failed testcase: %v \nActual lint cmd: %v", testCase.testCaseName, *sboxProto.Commands[0].Command)
+// }
+// }
+//}
+//
+//// checks transtive deps of an apex coming from bootclasspath_fragment
+//func TestApexStrictUpdtabilityLintBcpFragmentDeps(t *testing.T) {
+// bp := `
+// apex {
+// name: "myapex",
+// key: "myapex.key",
+// bootclasspath_fragments: ["mybootclasspathfragment"],
+// updatable: true,
+// min_sdk_version: "29",
+// }
+// apex_key {
+// name: "myapex.key",
+// }
+// bootclasspath_fragment {
+// name: "mybootclasspathfragment",
+// contents: ["myjavalib"],
+// apex_available: ["myapex"],
+// hidden_api: {
+// split_packages: ["*"],
+// },
+// }
+// java_library {
+// name: "myjavalib",
+// srcs: ["MyClass.java"],
+// apex_available: [ "myapex" ],
+// sdk_version: "current",
+// min_sdk_version: "29",
+// compile_dex: true,
+// }
+// `
+// fs := android.MockFS{
+// "lint-baseline.xml": nil,
+// }
+//
+// result := testApex(t, bp, dexpreopt.FixtureSetApexBootJars("myapex:myjavalib"), fs.AddToFixture())
+// myjavalib := result.ModuleForTests("myjavalib", "android_common_apex29")
+// sboxProto := android.RuleBuilderSboxProtoForTests(t, myjavalib.Output("lint.sbox.textproto"))
+// if !strings.Contains(*sboxProto.Commands[0].Command, "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+// t.Errorf("Strict updabality lint missing in myjavalib coming from bootclasspath_fragment mybootclasspath-fragment\nActual lint cmd: %v", *sboxProto.Commands[0].Command)
+// }
+//}
// updatable apexes should propagate updatable=true to its apps
func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
@@ -9750,30 +9791,85 @@
apex {
name: "myapex",
key: "myapex.key",
- native_shared_libs: ["libfoo"],
+ native_shared_libs: ["libbaz"],
+ binaries: ["binfoo"],
min_sdk_version: "29",
}
apex_key {
name: "myapex.key",
}
- cc_library {
- name: "libfoo",
- shared_libs: ["libc"],
+ cc_binary {
+ name: "binfoo",
+ shared_libs: ["libbar", "libbaz", "libqux",],
apex_available: ["myapex"],
min_sdk_version: "29",
+ recovery_available: false,
+ }
+ cc_library {
+ name: "libbar",
+ srcs: ["libbar.cc"],
+ stubs: {
+ symbol_file: "libbar.map.txt",
+ versions: [
+ "29",
+ ],
+ },
+ }
+ cc_library {
+ name: "libbaz",
+ srcs: ["libbaz.cc"],
+ apex_available: ["myapex"],
+ min_sdk_version: "29",
+ stubs: {
+ symbol_file: "libbaz.map.txt",
+ versions: [
+ "29",
+ ],
+ },
}
cc_api_library {
- name: "libc",
- src: "libc.so",
+ name: "libbar",
+ src: "libbar_stub.so",
min_sdk_version: "29",
- recovery_available: true,
+ variants: ["apex.29"],
+ }
+ cc_api_variant {
+ name: "libbar",
+ variant: "apex",
+ version: "29",
+ src: "libbar_apex_29.so",
+ }
+ cc_api_library {
+ name: "libbaz",
+ src: "libbaz_stub.so",
+ min_sdk_version: "29",
+ variants: ["apex.29"],
+ }
+ cc_api_variant {
+ name: "libbaz",
+ variant: "apex",
+ version: "29",
+ src: "libbaz_apex_29.so",
+ }
+ cc_api_library {
+ name: "libqux",
+ src: "libqux_stub.so",
+ min_sdk_version: "29",
+ variants: ["apex.29"],
+ }
+ cc_api_variant {
+ name: "libqux",
+ variant: "apex",
+ version: "29",
+ src: "libqux_apex_29.so",
}
api_imports {
name: "api_imports",
- shared_libs: [
- "libc",
+ apex_shared_libs: [
+ "libbar",
+ "libbaz",
+ "libqux",
],
- header_libs: [],
}
`
result := testApex(t, bp)
@@ -9789,17 +9885,107 @@
return found
}
- libfooApexVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex29").Module()
- libcApexVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared_apex29").Module()
+ // Library defines stubs and cc_api_library should be used with cc_api_library
+ binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Module()
+ libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+ libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
- android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(libfooApexVariant, libcApexVariant))
+ android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
+ android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
- // libfoo core variant should be buildable in the same inner tree since
- // certain mcombo files might build system and apexes in the same inner tree
- // libfoo core variant should link against source libc
- libfooCoreVariant := result.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libcCoreVariant := result.ModuleForTests("libc.apiimport", "android_arm64_armv8-a_shared").Module()
- android.AssertBoolEquals(t, "core variant should link against source libc", true, hasDep(libfooCoreVariant, libcCoreVariant))
+ binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Rule("ld").Args["libFlags"]
+ android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
+
+ // Library defined in the same APEX should be linked with original definition instead of cc_api_library
+ libbazApexVariant := result.ModuleForTests("libbaz", "android_arm64_armv8-a_shared_apex29").Module()
+ libbazApiImportCoreVariant := result.ModuleForTests("libbaz.apiimport", "android_arm64_armv8-a_shared").Module()
+ android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even from same APEX", true, hasDep(binfooApexVariant, libbazApiImportCoreVariant))
+ android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbazApexVariant))
+
+ android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbaz.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbaz.apiimport.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbaz.apex.29.apiimport.so")
+
+ // cc_api_library defined without original library should be linked with cc_api_library
+ libquxApiImportApexVariant := result.ModuleForTests("libqux.apiimport", "android_arm64_armv8-a_shared").Module()
+ android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even original library definition does not exist", true, hasDep(binfooApexVariant, libquxApiImportApexVariant))
+ android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libqux.apex.29.apiimport.so")
+}
+
+func TestPlatformBinaryBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
+ bp := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["libbar"],
+ min_sdk_version: "29",
+ }
+ apex_key {
+ name: "myapex.key",
+ }
+ cc_binary {
+ name: "binfoo",
+ shared_libs: ["libbar"],
+ recovery_available: false,
+ }
+ cc_library {
+ name: "libbar",
+ srcs: ["libbar.cc"],
+ apex_available: ["myapex"],
+ min_sdk_version: "29",
+ stubs: {
+ symbol_file: "libbar.map.txt",
+ versions: [
+ "29",
+ ],
+ },
+ }
+ cc_api_library {
+ name: "libbar",
+ src: "libbar_stub.so",
+ variants: ["apex.29"],
+ }
+ cc_api_variant {
+ name: "libbar",
+ variant: "apex",
+ version: "29",
+ src: "libbar_apex_29.so",
+ }
+ api_imports {
+ name: "api_imports",
+ apex_shared_libs: [
+ "libbar",
+ ],
+ }
+ `
+
+ result := testApex(t, bp)
+
+ hasDep := func(m android.Module, wantDep android.Module) bool {
+ t.Helper()
+ var found bool
+ result.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+ }
+
+ // Library defines stubs and cc_api_library should be used with cc_api_library
+ binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Module()
+ libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
+ libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+
+ android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
+ android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
+
+ binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
+ android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
+ android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
}
func TestTrimmedApex(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index a62f63c..ee6c473 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -333,6 +333,8 @@
ctx.PropertyErrorf("file_contexts", "cannot find file_contexts file: %q", fileContexts.String())
}
+ useFileContextsAsIs := proptools.Bool(a.properties.Use_file_contexts_as_is)
+
output := android.PathForModuleOut(ctx, "file_contexts")
rule := android.NewRuleBuilder(pctx, ctx)
@@ -344,9 +346,11 @@
rule.Command().Text("cat").Input(fileContexts).Text(">>").Output(output)
// new line
rule.Command().Text("echo").Text(">>").Output(output)
- // force-label /apex_manifest.pb and / as system_file so that apexd can read them
- rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
- rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
+ if !useFileContextsAsIs {
+ // force-label /apex_manifest.pb and / as system_file so that apexd can read them
+ rule.Command().Text("echo").Flag("/apex_manifest\\\\.pb u:object_r:system_file:s0").Text(">>").Output(output)
+ rule.Command().Text("echo").Flag("/ u:object_r:system_file:s0").Text(">>").Output(output)
+ }
case flattenedApex:
// For flattened apexes, install path should be prepended.
// File_contexts file should be emiited to make via LOCAL_FILE_CONTEXTS
@@ -359,9 +363,11 @@
rule.Command().Text("awk").Text(`'/object_r/{printf("` + apexPath + `%s\n", $0)}'`).Input(fileContexts).Text(">").Output(output)
// new line
rule.Command().Text("echo").Text(">>").Output(output)
- // force-label /apex_manifest.pb and / as system_file so that apexd can read them
- rule.Command().Text("echo").Flag(apexPath + `/apex_manifest\\.pb u:object_r:system_file:s0`).Text(">>").Output(output)
- rule.Command().Text("echo").Flag(apexPath + "/ u:object_r:system_file:s0").Text(">>").Output(output)
+ if !useFileContextsAsIs {
+ // force-label /apex_manifest.pb and / as system_file so that apexd can read them
+ rule.Command().Text("echo").Flag(apexPath + `/apex_manifest\\.pb u:object_r:system_file:s0`).Text(">>").Output(output)
+ rule.Command().Text("echo").Flag(apexPath + "/ u:object_r:system_file:s0").Text(">>").Output(output)
+ }
default:
panic(fmt.Errorf("unsupported type %v", a.properties.ApexType))
}
@@ -543,7 +549,7 @@
if len(installMapSet) > 0 {
var installs []string
- installs = append(installs, android.SortedStringKeys(installMapSet)...)
+ installs = append(installs, android.SortedKeys(installMapSet)...)
a.SetLicenseInstallMap(installs)
}
diff --git a/apex/metadata.go b/apex/metadata.go
new file mode 100644
index 0000000..b1dff3e
--- /dev/null
+++ b/apex/metadata.go
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package apex
+
+import (
+ "encoding/json"
+
+ "github.com/google/blueprint"
+
+ "android/soong/android"
+)
+
+var (
+ mtctx = android.NewPackageContext("android/soong/multitree_apex")
+)
+
+func init() {
+ RegisterModulesSingleton(android.InitRegistrationContext)
+}
+
+func RegisterModulesSingleton(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("apex_multitree_singleton", multitreeAnalysisSingletonFactory)
+}
+
+var PrepareForTestWithApexMultitreeSingleton = android.FixtureRegisterWithContext(RegisterModulesSingleton)
+
+func multitreeAnalysisSingletonFactory() android.Singleton {
+ return &multitreeAnalysisSingleton{}
+}
+
+type multitreeAnalysisSingleton struct {
+ multitreeApexMetadataPath android.OutputPath
+}
+
+type ApexMultitreeMetadataEntry struct {
+ // The name of the apex.
+ Name string
+
+ // TODO: Add other properties as needed.
+}
+
+type ApexMultitreeMetadata struct {
+ // Information about the installable apexes.
+ Apexes map[string]ApexMultitreeMetadataEntry
+}
+
+func (p *multitreeAnalysisSingleton) GenerateBuildActions(context android.SingletonContext) {
+ data := ApexMultitreeMetadata{
+ Apexes: make(map[string]ApexMultitreeMetadataEntry, 0),
+ }
+ context.VisitAllModules(func(module android.Module) {
+ // If this module is not being installed, ignore it.
+ if !module.Enabled() || module.IsSkipInstall() {
+ return
+ }
+ // Actual apexes provide ApexBundleInfoProvider.
+ if _, ok := context.ModuleProvider(module, ApexBundleInfoProvider).(ApexBundleInfo); !ok {
+ return
+ }
+ bundle, ok := module.(*apexBundle)
+ if ok && !bundle.testApex && !bundle.vndkApex && bundle.primaryApexType {
+ name := module.Name()
+ entry := ApexMultitreeMetadataEntry{
+ Name: name,
+ }
+ data.Apexes[name] = entry
+ }
+ })
+ p.multitreeApexMetadataPath = android.PathForOutput(context, "multitree_apex_metadata.json")
+
+ jsonStr, err := json.Marshal(data)
+ if err != nil {
+ context.Errorf(err.Error())
+ }
+ android.WriteFileRule(context, p.multitreeApexMetadataPath, string(jsonStr))
+ // This seems cleaner, but doesn't emit the phony rule in testing.
+ // context.Phony("multitree_apex_metadata", p.multitreeApexMetadataPath)
+
+ context.Build(mtctx, android.BuildParams{
+ Rule: blueprint.Phony,
+ Description: "phony rule for multitree_apex_metadata",
+ Inputs: []android.Path{p.multitreeApexMetadataPath},
+ Output: android.PathForPhony(context, "multitree_apex_metadata"),
+ })
+}
diff --git a/apex/metadata_test.go b/apex/metadata_test.go
new file mode 100644
index 0000000..f6ead42
--- /dev/null
+++ b/apex/metadata_test.go
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+package apex
+
+import (
+ "strings"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func TestModulesSingleton(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithApexMultitreeSingleton,
+ java.PrepareForTestWithDexpreopt,
+ PrepareForTestWithApexBuildComponents,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ ).RunTestWithBp(t, `
+ prebuilt_apex {
+ name: "myapex",
+ src: "myapex.apex",
+ exported_bootclasspath_fragments: ["mybootclasspath-fragment"],
+ }
+
+ // A prebuilt java_sdk_library_import that is not preferred by default but will be preferred
+ // because AlwaysUsePrebuiltSdks() is true.
+ java_sdk_library_import {
+ name: "foo",
+ prefer: false,
+ shared_library: false,
+ permitted_packages: ["foo"],
+ public: {
+ jars: ["sdk_library/public/foo-stubs.jar"],
+ stub_srcs: ["sdk_library/public/foo_stub_sources"],
+ current_api: "sdk_library/public/foo.txt",
+ removed_api: "sdk_library/public/foo-removed.txt",
+ sdk_version: "current",
+ },
+ apex_available: ["myapex"],
+ }
+
+ prebuilt_bootclasspath_fragment {
+ name: "mybootclasspath-fragment",
+ apex_available: [
+ "myapex",
+ ],
+ contents: [
+ "foo",
+ ],
+ hidden_api: {
+ stub_flags: "prebuilt-stub-flags.csv",
+ annotation_flags: "prebuilt-annotation-flags.csv",
+ metadata: "prebuilt-metadata.csv",
+ index: "prebuilt-index.csv",
+ all_flags: "prebuilt-all-flags.csv",
+ },
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ fragments: [
+ {
+ apex: "myapex",
+ module:"mybootclasspath-fragment",
+ },
+ ],
+ }
+`,
+ )
+
+ outputs := result.SingletonForTests("apex_multitree_singleton").AllOutputs()
+ for _, output := range outputs {
+ testingBuildParam := result.SingletonForTests("apex_multitree_singleton").Output(output)
+ switch {
+ case strings.Contains(output, "soong/multitree_apex_metadata.json"):
+ android.AssertStringEquals(t, "Invalid build rule", "android/soong/android.writeFile", testingBuildParam.Rule.String())
+ android.AssertIntEquals(t, "Invalid input", len(testingBuildParam.Inputs), 0)
+ android.AssertStringDoesContain(t, "Invalid output path", output, "soong/multitree_apex_metadata.json")
+
+ case strings.HasSuffix(output, "multitree_apex_metadata"):
+ android.AssertStringEquals(t, "Invalid build rule", "<builtin>:phony", testingBuildParam.Rule.String())
+ android.AssertStringEquals(t, "Invalid input", testingBuildParam.Inputs[0].String(), "out/soong/multitree_apex_metadata.json")
+ android.AssertStringEquals(t, "Invalid output path", output, "multitree_apex_metadata")
+ android.AssertIntEquals(t, "Invalid args", len(testingBuildParam.Args), 0)
+ }
+ }
+}
diff --git a/bazel/Android.bp b/bazel/Android.bp
index d11c78b..4709f5c 100644
--- a/bazel/Android.bp
+++ b/bazel/Android.bp
@@ -7,6 +7,7 @@
pkgPath: "android/soong/bazel",
srcs: [
"aquery.go",
+ "bazel_proxy.go",
"configurability.go",
"constants.go",
"properties.go",
diff --git a/bazel/bazel_proxy.go b/bazel/bazel_proxy.go
new file mode 100644
index 0000000..d7f5e64
--- /dev/null
+++ b/bazel/bazel_proxy.go
@@ -0,0 +1,219 @@
+// Copyright 2023 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 bazel
+
+import (
+ "bytes"
+ "encoding/gob"
+ "fmt"
+ "net"
+ os_lib "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "time"
+)
+
+// Logs fatal events of ProxyServer.
+type ServerLogger interface {
+ Fatal(v ...interface{})
+ Fatalf(format string, v ...interface{})
+}
+
+// CmdRequest is a request to the Bazel Proxy server.
+type CmdRequest struct {
+ // Args to the Bazel command.
+ Argv []string
+ // Environment variables to pass to the Bazel invocation. Strings should be of
+ // the form "KEY=VALUE".
+ Env []string
+}
+
+// CmdResponse is a response from the Bazel Proxy server.
+type CmdResponse struct {
+ Stdout string
+ Stderr string
+ ErrorString string
+}
+
+// ProxyClient is a client which can issue Bazel commands to the Bazel
+// proxy server. Requests are issued (and responses received) via a unix socket.
+// See ProxyServer for more details.
+type ProxyClient struct {
+ outDir string
+}
+
+// ProxyServer is a server which runs as a background goroutine. Each
+// request to the server describes a Bazel command which the server should run.
+// The server then issues the Bazel command, and returns a response describing
+// the stdout/stderr of the command.
+// Client-server communication is done via a unix socket under the output
+// directory.
+// The server is intended to circumvent sandboxing for subprocesses of the
+// build. The build orchestrator (soong_ui) can launch a server to exist outside
+// of sandboxing, and sandboxed processes (such as soong_build) can issue
+// bazel commands through this socket tunnel. This allows a sandboxed process
+// to issue bazel requests to a bazel that resides outside of sandbox. This
+// is particularly useful to maintain a persistent Bazel server which lives
+// past the duration of a single build.
+// The ProxyServer will only live as long as soong_ui does; the
+// underlying Bazel server will live past the duration of the build.
+type ProxyServer struct {
+ logger ServerLogger
+ outDir string
+ workspaceDir string
+ // The server goroutine will listen on this channel and stop handling requests
+ // once it is written to.
+ done chan struct{}
+}
+
+// NewProxyClient is a constructor for a ProxyClient.
+func NewProxyClient(outDir string) *ProxyClient {
+ return &ProxyClient{
+ outDir: outDir,
+ }
+}
+
+func unixSocketPath(outDir string) string {
+ return filepath.Join(outDir, "bazelsocket.sock")
+}
+
+// IssueCommand issues a request to the Bazel Proxy Server to issue a Bazel
+// request. Returns a response describing the output from the Bazel process
+// (if the Bazel process had an error, then the response will include an error).
+// Returns an error if there was an issue with the connection to the Bazel Proxy
+// server.
+func (b *ProxyClient) IssueCommand(req CmdRequest) (CmdResponse, error) {
+ var resp CmdResponse
+ var err error
+ // Check for connections every 1 second. This is chosen to be a relatively
+ // short timeout, because the proxy server should accept requests quite
+ // quickly.
+ d := net.Dialer{Timeout: 1 * time.Second}
+ var conn net.Conn
+ conn, err = d.Dial("unix", unixSocketPath(b.outDir))
+ if err != nil {
+ return resp, err
+ }
+ defer conn.Close()
+
+ enc := gob.NewEncoder(conn)
+ if err = enc.Encode(req); err != nil {
+ return resp, err
+ }
+ dec := gob.NewDecoder(conn)
+ err = dec.Decode(&resp)
+ return resp, err
+}
+
+// NewProxyServer is a constructor for a ProxyServer.
+func NewProxyServer(logger ServerLogger, outDir string, workspaceDir string) *ProxyServer {
+ return &ProxyServer{
+ logger: logger,
+ outDir: outDir,
+ workspaceDir: workspaceDir,
+ done: make(chan struct{}),
+ }
+}
+
+func (b *ProxyServer) handleRequest(conn net.Conn) error {
+ defer conn.Close()
+
+ dec := gob.NewDecoder(conn)
+ var req CmdRequest
+ if err := dec.Decode(&req); err != nil {
+ return fmt.Errorf("Error decoding request: %s", err)
+ }
+
+ bazelCmd := exec.Command("./build/bazel/bin/bazel", req.Argv...)
+ bazelCmd.Dir = b.workspaceDir
+ bazelCmd.Env = req.Env
+
+ stderr := &bytes.Buffer{}
+ bazelCmd.Stderr = stderr
+ var stdout string
+ var bazelErrString string
+
+ if output, err := bazelCmd.Output(); err != nil {
+ bazelErrString = fmt.Sprintf("bazel command failed: %s\n---command---\n%s\n---env---\n%s\n---stderr---\n%s---",
+ err, bazelCmd, strings.Join(bazelCmd.Env, "\n"), stderr)
+ } else {
+ stdout = string(output)
+ }
+
+ resp := CmdResponse{stdout, string(stderr.Bytes()), bazelErrString}
+ enc := gob.NewEncoder(conn)
+ if err := enc.Encode(&resp); err != nil {
+ return fmt.Errorf("Error encoding response: %s", err)
+ }
+ return nil
+}
+
+func (b *ProxyServer) listenUntilClosed(listener net.Listener) error {
+ for {
+ // Check for connections every 1 second. This is a blocking operation, so
+ // if the server is closed, the goroutine will not fully close until this
+ // deadline is reached. Thus, this deadline is short (but not too short
+ // so that the routine churns).
+ listener.(*net.UnixListener).SetDeadline(time.Now().Add(time.Second))
+ conn, err := listener.Accept()
+
+ select {
+ case <-b.done:
+ return nil
+ default:
+ }
+
+ if err != nil {
+ if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
+ // Timeout is normal and expected while waiting for client to establish
+ // a connection.
+ continue
+ } else {
+ b.logger.Fatalf("Listener error: %s", err)
+ }
+ }
+
+ err = b.handleRequest(conn)
+ if err != nil {
+ b.logger.Fatal(err)
+ }
+ }
+}
+
+// Start initializes the server unix socket and (in a separate goroutine)
+// handles requests on the socket until the server is closed. Returns an error
+// if a failure occurs during initialization. Will log any post-initialization
+// errors to the server's logger.
+func (b *ProxyServer) Start() error {
+ unixSocketAddr := unixSocketPath(b.outDir)
+ if err := os_lib.RemoveAll(unixSocketAddr); err != nil {
+ return fmt.Errorf("couldn't remove socket '%s': %s", unixSocketAddr, err)
+ }
+ listener, err := net.Listen("unix", unixSocketAddr)
+
+ if err != nil {
+ return fmt.Errorf("error listening on socket '%s': %s", unixSocketAddr, err)
+ }
+
+ go b.listenUntilClosed(listener)
+ return nil
+}
+
+// Close shuts down the server. This will stop the server from listening for
+// additional requests.
+func (b *ProxyServer) Close() {
+ b.done <- struct{}{}
+}
diff --git a/bazel/properties.go b/bazel/properties.go
index f4acd26..40d0ba3 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "reflect"
"regexp"
"sort"
"strings"
@@ -533,6 +534,37 @@
return result, nil
}
+// ToStringListAttribute creates a StringListAttribute from this BoolAttribute,
+// where each bool corresponds to a string list value generated by the provided
+// function.
+// TODO(b/271425661): Generalize this
+func (ba *BoolAttribute) ToStringListAttribute(valueFunc func(boolPtr *bool, axis ConfigurationAxis, config string) []string) (StringListAttribute, error) {
+ mainVal := valueFunc(ba.Value, NoConfigAxis, "")
+ if !ba.HasConfigurableValues() {
+ return MakeStringListAttribute(mainVal), nil
+ }
+
+ result := StringListAttribute{}
+ if err := ba.Collapse(); err != nil {
+ return result, err
+ }
+
+ for axis, configToBools := range ba.ConfigurableValues {
+ if len(configToBools) < 1 {
+ continue
+ }
+ for config, boolPtr := range configToBools {
+ val := valueFunc(&boolPtr, axis, config)
+ if !reflect.DeepEqual(val, mainVal) {
+ result.SetSelectValue(axis, config, val)
+ }
+ }
+ result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal)
+ }
+
+ return result, nil
+}
+
// Collapse reduces the configurable axes of the boolean attribute to a single axis.
// This is necessary for final writing to bp2build, as a configurable boolean
// attribute can only be comprised by a single select.
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 062eba8..d1dfb9d 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -17,21 +17,57 @@
import (
"fmt"
"os"
+ "path/filepath"
"strings"
"android/soong/android"
"android/soong/bazel"
+ "android/soong/shared"
)
+func deleteFilesExcept(ctx *CodegenContext, rootOutputPath android.OutputPath, except []BazelFile) {
+ // Delete files that should no longer be present.
+ bp2buildDirAbs := shared.JoinPath(ctx.topDir, rootOutputPath.String())
+
+ filesToDelete := make(map[string]struct{})
+ err := filepath.Walk(bp2buildDirAbs,
+ func(path string, info os.FileInfo, err error) error {
+ if err != nil {
+ return err
+ }
+ if !info.IsDir() {
+ relPath, err := filepath.Rel(bp2buildDirAbs, path)
+ if err != nil {
+ return err
+ }
+ filesToDelete[relPath] = struct{}{}
+ }
+ return nil
+ })
+ if err != nil {
+ fmt.Printf("ERROR reading %s: %s", bp2buildDirAbs, err)
+ os.Exit(1)
+ }
+
+ for _, bazelFile := range except {
+ filePath := filepath.Join(bazelFile.Dir, bazelFile.Basename)
+ delete(filesToDelete, filePath)
+ }
+ for f, _ := range filesToDelete {
+ absPath := shared.JoinPath(bp2buildDirAbs, f)
+ if err := os.RemoveAll(absPath); err != nil {
+ fmt.Printf("ERROR deleting %s: %s", absPath, err)
+ os.Exit(1)
+ }
+ }
+}
+
// Codegen is the backend of bp2build. The code generator is responsible for
// writing .bzl files that are equivalent to Android.bp files that are capable
// of being built with Bazel.
func Codegen(ctx *CodegenContext) *CodegenMetrics {
// This directory stores BUILD files that could be eventually checked-in.
bp2buildDir := android.PathForOutput(ctx, "bp2build")
- if err := android.RemoveAllOutputDir(bp2buildDir); err != nil {
- fmt.Printf("ERROR: Encountered error while cleaning %s: %s", bp2buildDir, err.Error())
- }
res, errs := GenerateBazelTargets(ctx, true)
if len(errs) > 0 {
@@ -44,6 +80,12 @@
}
bp2buildFiles := CreateBazelFiles(ctx.Config(), nil, res.buildFileToTargets, ctx.mode)
writeFiles(ctx, bp2buildDir, bp2buildFiles)
+ // Delete files under the bp2build root which weren't just written. An
+ // alternative would have been to delete the whole directory and write these
+ // files. However, this would regenerate files which were otherwise unchanged
+ // since the last bp2build run, which would have negative incremental
+ // performance implications.
+ deleteFilesExcept(ctx, bp2buildDir, bp2buildFiles)
injectionFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
if err != nil {
@@ -51,7 +93,6 @@
os.Exit(1)
}
writeFiles(ctx, android.PathForOutput(ctx, bazel.SoongInjectionDirName), injectionFiles)
-
return &res.metrics
}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 6c6631a..ced779c 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -227,7 +227,7 @@
// the generated attributes are sorted to ensure determinism.
func propsToAttributes(props map[string]string) string {
var attributes string
- for _, propName := range android.SortedStringKeys(props) {
+ for _, propName := range android.SortedKeys(props) {
attributes += fmt.Sprintf(" %s = %s,\n", propName, props[propName])
}
return attributes
diff --git a/bp2build/bzl_conversion.go b/bp2build/bzl_conversion.go
index 992cc1c..e774fdf 100644
--- a/bp2build/bzl_conversion.go
+++ b/bp2build/bzl_conversion.go
@@ -83,7 +83,7 @@
func generateSoongModuleBzl(bzlLoads map[string]RuleShim) string {
var loadStmts string
var moduleRuleMap string
- for _, bzlFileName := range android.SortedStringKeys(bzlLoads) {
+ for _, bzlFileName := range android.SortedKeys(bzlLoads) {
loadStmt := "load(\"//build/bazel/queryview_rules:"
loadStmt += bzlFileName
loadStmt += ".bzl\""
@@ -104,7 +104,7 @@
rules := make(map[string][]rule)
// TODO: allow registration of a bzl rule when registring a factory
- for _, moduleType := range android.SortedStringKeys(moduleTypeFactories) {
+ for _, moduleType := range android.SortedKeys(moduleTypeFactories) {
factory := moduleTypeFactories[moduleType]
factoryName := runtime.FuncForPC(reflect.ValueOf(factory).Pointer()).Name()
pkg := strings.Split(factoryName, ".")[0]
@@ -221,7 +221,7 @@
}
properties := make([]property, 0, len(propertiesByName))
- for _, key := range android.SortedStringKeys(propertiesByName) {
+ for _, key := range android.SortedKeys(propertiesByName) {
properties = append(properties, propertiesByName[key])
}
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index a39ed7d..0315732 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -868,3 +868,131 @@
},
})
}
+
+func TestCcBinaryWithThinLto(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct features when thin LTO is enabled",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `["android_thin_lto"]`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithLtoNever(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct features when LTO is explicitly disabled",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `["-android_thin_lto"]`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithThinLtoArchSpecific(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct features when LTO differs across arch and os variants",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ },
+ },
+ },
+ arch: {
+ riscv64: {
+ lto: {
+ thin: false,
+ },
+ },
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
+ "//conditions:default": [],
+ })`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct features when LTO disabled by default but enabled on a particular variant",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ never: false,
+ },
+ },
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os:android": ["android_thin_lto"],
+ "//conditions:default": ["-android_thin_lto"],
+ })`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithThinLtoAndWholeProgramVtables(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct features when thin LTO is enabled with whole_program_vtables",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+ whole_program_vtables: true,
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `[
+ "android_thin_lto",
+ "android_thin_lto_whole_program_vtables",
+ ]`,
+ }},
+ },
+ })
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index af14f64..e20cffd 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -4137,3 +4137,172 @@
},
})
}
+
+func TestCcLibraryWithThinLto(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when thin LTO is enabled",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `["android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryWithLtoNever(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when LTO is explicitly disabled",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `["-android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["-android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryWithThinLtoArchSpecific(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when LTO differs across arch and os variants",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ },
+ },
+ },
+ arch: {
+ riscv64: {
+ lto: {
+ thin: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
+ "//conditions:default": [],
+ })`}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
+ "//conditions:default": [],
+ })`}),
+ },
+ })
+}
+
+func TestCcLibraryWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when LTO disabled by default but enabled on a particular variant",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ never: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os:android": ["android_thin_lto"],
+ "//conditions:default": ["-android_thin_lto"],
+ })`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os:android": ["android_thin_lto"],
+ "//conditions:default": ["-android_thin_lto"],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryWithThinLtoWholeProgramVtables(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when thin LTO is enabled with whole_program_vtables",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+ whole_program_vtables: true,
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `[
+ "android_thin_lto",
+ "android_thin_lto_whole_program_vtables",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "android_thin_lto",
+ "android_thin_lto_whole_program_vtables",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 6207421..838b297 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -974,3 +974,133 @@
},
})
}
+
+func TestCcLibrarySharedWithThinLto(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when thin lto is enabled",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithLtoNever(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when thin lto is enabled",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["-android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithThinLtoArchSpecific(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when LTO differs across arch and os variants",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ },
+ },
+ },
+ arch: {
+ riscv64: {
+ lto: {
+ thin: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
+ "//conditions:default": [],
+ })`}),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared with thin lto disabled by default but enabled on a particular variant",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ never: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os:android": ["android_thin_lto"],
+ "//conditions:default": ["-android_thin_lto"],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithThinLtoAndWholeProgramVtables(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when thin LTO is enabled with whole_program_vtables",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+ whole_program_vtables: true,
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "android_thin_lto",
+ "android_thin_lto_whole_program_vtables",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index d5256f6..d16c5cc 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1889,3 +1889,133 @@
},
})
}
+
+func TestCcLibraryStaticWithThinLto(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when thin lto is enabled",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `["android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithLtoNever(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when thin lto is enabled",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `["-android_thin_lto"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithThinLtoArchSpecific(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when LTO differs across arch and os variants",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ },
+ },
+ },
+ arch: {
+ riscv64: {
+ lto: {
+ thin: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_arm64": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_riscv64": ["-android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86": ["android_thin_lto"],
+ "//build/bazel/platforms/os_arch:android_x86_64": ["android_thin_lto"],
+ "//conditions:default": [],
+ })`}),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithThinLtoDisabledDefaultEnabledVariant(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when LTO disabled by default but enabled on a particular variant",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ lto: {
+ never: true,
+ },
+ target: {
+ android: {
+ lto: {
+ thin: true,
+ never: false,
+ },
+ },
+ },
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `select({
+ "//build/bazel/platforms/os:android": ["android_thin_lto"],
+ "//conditions:default": ["-android_thin_lto"],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithThinLtoAndWholeProgramVtables(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when thin lto is enabled with whole_program_vtables",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ lto: {
+ thin: true,
+ },
+ whole_program_vtables: true,
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `[
+ "android_thin_lto",
+ "android_thin_lto_whole_program_vtables",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index 2a0a78e..8e17103 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -256,7 +256,7 @@
}
var selects string
- for _, selectKey := range android.SortedStringKeys(selectMap) {
+ for _, selectKey := range android.SortedKeys(selectMap) {
if selectKey == bazel.ConditionsDefaultSelectKey {
// Handle default condition later.
continue
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 47cd2b4..6a39e25 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -105,7 +105,7 @@
func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
files := make([]BazelFile, 0, len(buildToTargets))
- for _, dir := range android.SortedStringKeys(buildToTargets) {
+ for _, dir := range android.SortedKeys(buildToTargets) {
targets := buildToTargets[dir]
targets.sort()
diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go
index 46105c7..6f17e34 100644
--- a/bp2build/java_binary_host_conversion_test.go
+++ b/bp2build/java_binary_host_conversion_test.go
@@ -221,6 +221,11 @@
"a.java",
"b.kt",
]`,
+ "resources": `[
+ "res/a.res",
+ "res/dir1/b.res",
+ ]`,
+ "resource_strip_prefix": `"res"`,
"target_compatible_with": `select({
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
"//conditions:default": [],
@@ -229,11 +234,6 @@
MakeBazelTarget("java_binary", "java-binary-host", AttrNameToString{
"main_class": `"com.android.test.MainClass"`,
"runtime_deps": `[":java-binary-host_kt"]`,
- "resources": `[
- "res/a.res",
- "res/dir1/b.res",
- ]`,
- "resource_strip_prefix": `"res"`,
"target_compatible_with": `select({
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
"//conditions:default": [],
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
index 7e29fac..a020650 100644
--- a/bp2build/metrics.go
+++ b/bp2build/metrics.go
@@ -51,7 +51,7 @@
// Print the codegen metrics to stdout.
func (metrics *CodegenMetrics) Print() {
generatedTargetCount := uint64(0)
- for _, ruleClass := range android.SortedStringKeys(metrics.serialized.RuleClassCount) {
+ for _, ruleClass := range android.SortedKeys(metrics.serialized.RuleClassCount) {
count := metrics.serialized.RuleClassCount[ruleClass]
fmt.Printf("[bp2build] %s: %d targets\n", ruleClass, count)
generatedTargetCount += count
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 92a9bf1..43baf98 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -230,11 +230,11 @@
actualTargets := b.buildFileToTargets
// Generate the sorted set of directories to check.
- dirsToCheck := android.SortedStringKeys(expectedTargets)
+ dirsToCheck := android.SortedKeys(expectedTargets)
if !ignoreUnexpected {
// This needs to perform an exact match so add the directories in which targets were
// produced to the list of directories to check.
- dirsToCheck = append(dirsToCheck, android.SortedStringKeys(actualTargets)...)
+ dirsToCheck = append(dirsToCheck, android.SortedKeys(actualTargets)...)
dirsToCheck = android.SortedUniqueStrings(dirsToCheck)
}
@@ -579,7 +579,7 @@
if name != "" {
attrStrings = append(attrStrings, fmt.Sprintf(` name = "%s",`, name))
}
- for _, k := range android.SortedStringKeys(attrs) {
+ for _, k := range android.SortedKeys(attrs) {
attrStrings = append(attrStrings, fmt.Sprintf(" %s = %s,", k, attrs[k]))
}
return fmt.Sprintf(`%s(
diff --git a/cc/OWNERS b/cc/OWNERS
index ffbf14a..c4d82d2 100644
--- a/cc/OWNERS
+++ b/cc/OWNERS
@@ -1,4 +1 @@
per-file ndk_*.go = danalbert@google.com
-per-file tidy*.go = srhines@google.com, chh@google.com
-per-file afdo.go,afdo_test.go,lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
-per-file coverage.go = pirama@google.com, srhines@google.com, allenhair@google.com
diff --git a/cc/binary_test.go b/cc/binary_test.go
index e0b5b5d..2fac002 100644
--- a/cc/binary_test.go
+++ b/cc/binary_test.go
@@ -15,9 +15,10 @@
package cc
import (
- "android/soong/bazel/cquery"
"testing"
+ "android/soong/bazel/cquery"
+
"android/soong/android"
)
@@ -53,6 +54,9 @@
unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
expectedUnStrippedFile := "outputbase/execroot/__main__/foo.unstripped"
android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, binMod)[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_binary", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestCcBinaryWithBazelValidations(t *testing.T) {
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 808f51c..1ea8bda 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -817,6 +817,7 @@
compilerAttrs.hdrs.Prepend = true
features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module))
+ features = features.Append(bp2buildLtoFeatures(ctx, module))
features.DeduplicateAxesFromBase()
addMuslSystemDynamicDeps(ctx, linkerAttrs)
@@ -1263,7 +1264,7 @@
// result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
// from bionic OSes and the no config case as these libraries only build for bionic OSes.
if la.systemDynamicDeps.IsNil() && len(la.usedSystemDynamicDepAsDynamicDep) > 0 {
- toRemove := bazelLabelForSharedDeps(ctx, android.SortedStringKeys(la.usedSystemDynamicDepAsDynamicDep))
+ toRemove := bazelLabelForSharedDeps(ctx, android.SortedKeys(la.usedSystemDynamicDepAsDynamicDep))
la.dynamicDeps.Exclude(bazel.NoConfigAxis, "", toRemove)
la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "android", toRemove)
la.dynamicDeps.Exclude(bazel.OsConfigurationAxis, "linux_bionic", toRemove)
@@ -1459,3 +1460,49 @@
})
return sanitizerFeatures
}
+
+func bp2buildLtoFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
+ lto_feature_name := "android_thin_lto"
+ ltoBoolFeatures := bazel.BoolAttribute{}
+ bp2BuildPropParseHelper(ctx, m, <OProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ if ltoProps, ok := props.(*LTOProperties); ok {
+ thinProp := ltoProps.Lto.Thin != nil && *ltoProps.Lto.Thin
+ thinPropSetToFalse := ltoProps.Lto.Thin != nil && !*ltoProps.Lto.Thin
+ neverProp := ltoProps.Lto.Never != nil && *ltoProps.Lto.Never
+ if thinProp {
+ ltoBoolFeatures.SetSelectValue(axis, config, BoolPtr(true))
+ return
+ }
+ if neverProp || thinPropSetToFalse {
+ if thinProp {
+ ctx.ModuleErrorf("lto.thin and lto.never are mutually exclusive but were specified together")
+ } else {
+ ltoBoolFeatures.SetSelectValue(axis, config, BoolPtr(false))
+ }
+ return
+ }
+ }
+ ltoBoolFeatures.SetSelectValue(axis, config, nil)
+ })
+
+ props := m.GetArchVariantProperties(ctx, <OProperties{})
+ ltoStringFeatures, err := ltoBoolFeatures.ToStringListAttribute(func(boolPtr *bool, axis bazel.ConfigurationAxis, config string) []string {
+ if boolPtr == nil {
+ return []string{}
+ }
+ if !*boolPtr {
+ return []string{"-" + lto_feature_name}
+ }
+ features := []string{lto_feature_name}
+ if ltoProps, ok := props[axis][config].(*LTOProperties); ok {
+ if ltoProps.Whole_program_vtables != nil && *ltoProps.Whole_program_vtables {
+ features = append(features, "android_thin_lto_whole_program_vtables")
+ }
+ }
+ return features
+ })
+ if err != nil {
+ ctx.ModuleErrorf("Error processing LTO attributes: %s", err)
+ }
+ return ltoStringFeatures
+}
diff --git a/cc/cc.go b/cc/cc.go
index c07d836..0e88c56 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -2416,6 +2416,27 @@
return nonVariantLibs, variantLibs
}
+func (c *Module) shouldUseApiSurface() bool {
+ if c.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+ if GetImageVariantType(c) == vendorImageVariant || GetImageVariantType(c) == productImageVariant {
+ // LLNDK Variant
+ return true
+ }
+
+ if c.Properties.IsSdkVariant {
+ // NDK Variant
+ return true
+ }
+
+ if c.isImportedApiLibrary() {
+ // API Library should depend on API headers
+ return true
+ }
+ }
+
+ return false
+}
+
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
if !c.Enabled() {
return
@@ -2435,7 +2456,7 @@
apiNdkLibs := []string{}
apiLateNdkLibs := []string{}
- if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+ if c.shouldUseApiSurface() {
deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
@@ -2466,7 +2487,7 @@
}
// Check header lib replacement from API surface first, and then check again with VSDK
- if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
+ if c.shouldUseApiSurface() {
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
}
lib = GetReplaceModuleName(lib, GetSnapshot(c, &snapshotInfo, actx).HeaderLibs)
@@ -2550,12 +2571,22 @@
}
name, version := StubsLibNameAndVersion(lib)
+ if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) {
+ name = apiLibraryName
+ }
sharedLibNames = append(sharedLibNames, name)
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
- AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
+
+ if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
+ AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
+ }
+
+ if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
+ AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false)
+ }
}
for _, lib := range deps.LateStaticLibs {
@@ -2898,10 +2929,58 @@
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo)
+ skipModuleList := map[string]bool{}
+
+ var apiImportInfo multitree.ApiImportInfo
+ hasApiImportInfo := false
+
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ if dep.Name() == "api_imports" {
+ apiImportInfo = ctx.OtherModuleProvider(dep, multitree.ApiImportsProvider).(multitree.ApiImportInfo)
+ hasApiImportInfo = true
+ }
+ })
+
+ if hasApiImportInfo {
+ targetStubModuleList := map[string]string{}
+ targetOrigModuleList := map[string]string{}
+
+ // Search for dependency which both original module and API imported library with APEX stub exists
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ depName := ctx.OtherModuleName(dep)
+ if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
+ targetStubModuleList[apiLibrary] = depName
+ }
+ })
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ depName := ctx.OtherModuleName(dep)
+ if origLibrary, ok := targetStubModuleList[depName]; ok {
+ targetOrigModuleList[origLibrary] = depName
+ }
+ })
+
+ // Decide which library should be used between original and API imported library
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ depName := ctx.OtherModuleName(dep)
+ if apiLibrary, ok := targetOrigModuleList[depName]; ok {
+ if shouldUseStubForApex(ctx, dep) {
+ skipModuleList[depName] = true
+ } else {
+ skipModuleList[apiLibrary] = true
+ }
+ }
+ })
+ }
+
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
+ if _, ok := skipModuleList[depName]; ok {
+ // skip this module because original module or API imported module matching with this should be used instead.
+ return
+ }
+
if depTag == android.DarwinUniversalVariantTag {
depPaths.DarwinSecondArchOutput = dep.(*Module).OutputFile()
return
@@ -3237,21 +3316,8 @@
return depPaths
}
-// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
-// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
-// dependency. The stub variant is selected when the dependency crosses a boundary where each side
-// has different level of updatability. For example, if a library foo in an APEX depends on a
-// library bar which provides stable interface and exists in the platform, foo uses the stub variant
-// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
-// same APEX as foo, the non-stub variant of bar is used.
-func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+func shouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
depName := ctx.OtherModuleName(dep)
- depTag := ctx.OtherModuleDependencyTag(dep)
- libDepTag, ok := depTag.(libraryDependencyTag)
- if !ok || !libDepTag.shared() {
- panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
- }
-
thisModule, ok := ctx.Module().(android.ApexModule)
if !ok {
panic(fmt.Errorf("Not an APEX module: %q", ctx.ModuleName()))
@@ -3266,62 +3332,93 @@
bootstrap = linkable.Bootstrap()
}
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+
+ useStubs := false
+
+ if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
+ if !apexInfo.IsForPlatform() {
+ // For platform libraries, use current version of LLNDK
+ // If this is for use_vendor apex we will apply the same rules
+ // of apex sdk enforcement below to choose right version.
+ useStubs = true
+ }
+ } else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
+ // If not building for APEX or the containing APEX allows the use of
+ // platform APIs, use stubs only when it is from an APEX (and not from
+ // platform) However, for host, ramdisk, vendor_ramdisk, recovery or
+ // bootstrap modules, always link to non-stub variant
+ isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
+
+ isApexImportedApiLibrary := false
+
+ if cc, ok := dep.(*Module); ok {
+ if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok {
+ if apiLibrary.hasApexStubs() {
+ isApexImportedApiLibrary = true
+ }
+ }
+ }
+
+ useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap
+
+ if useStubs {
+ // Another exception: if this module is a test for an APEX, then
+ // it is linked with the non-stub variant of a module in the APEX
+ // as if this is part of the APEX.
+ testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
+ for _, apexContents := range testFor.ApexContents {
+ if apexContents.DirectlyInApex(depName) {
+ useStubs = false
+ break
+ }
+ }
+ }
+ if useStubs {
+ // Yet another exception: If this module and the dependency are
+ // available to the same APEXes then skip stubs between their
+ // platform variants. This complements the test_for case above,
+ // which avoids the stubs on a direct APEX library dependency, by
+ // avoiding stubs for indirect test dependencies as well.
+ //
+ // TODO(b/183882457): This doesn't work if the two libraries have
+ // only partially overlapping apex_available. For that test_for
+ // modules would need to be split into APEX variants and resolved
+ // separately for each APEX they have access to.
+ if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
+ useStubs = false
+ }
+ }
+ } else {
+ // If building for APEX, use stubs when the parent is in any APEX that
+ // the child is not in.
+ useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
+ }
+
+ return useStubs
+}
+
+// ChooseStubOrImpl determines whether a given dependency should be redirected to the stub variant
+// of the dependency or not, and returns the SharedLibraryInfo and FlagExporterInfo for the right
+// dependency. The stub variant is selected when the dependency crosses a boundary where each side
+// has different level of updatability. For example, if a library foo in an APEX depends on a
+// library bar which provides stable interface and exists in the platform, foo uses the stub variant
+// of bar. If bar doesn't provide a stable interface (i.e. buildStubs() == false) or is in the
+// same APEX as foo, the non-stub variant of bar is used.
+func ChooseStubOrImpl(ctx android.ModuleContext, dep android.Module) (SharedLibraryInfo, FlagExporterInfo) {
+ depTag := ctx.OtherModuleDependencyTag(dep)
+ libDepTag, ok := depTag.(libraryDependencyTag)
+ if !ok || !libDepTag.shared() {
+ panic(fmt.Errorf("Unexpected dependency tag: %T", depTag))
+ }
+
sharedLibraryInfo := ctx.OtherModuleProvider(dep, SharedLibraryInfoProvider).(SharedLibraryInfo)
depExporterInfo := ctx.OtherModuleProvider(dep, FlagExporterInfoProvider).(FlagExporterInfo)
sharedLibraryStubsInfo := ctx.OtherModuleProvider(dep, SharedLibraryStubsProvider).(SharedLibraryStubsInfo)
- apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if !libDepTag.explicitlyVersioned && len(sharedLibraryStubsInfo.SharedStubLibraries) > 0 {
- useStubs := false
-
- if lib := moduleLibraryInterface(dep); lib.buildStubs() && useVndk { // LLNDK
- if !apexInfo.IsForPlatform() {
- // For platform libraries, use current version of LLNDK
- // If this is for use_vendor apex we will apply the same rules
- // of apex sdk enforcement below to choose right version.
- useStubs = true
- }
- } else if apexInfo.IsForPlatform() || apexInfo.UsePlatformApis {
- // If not building for APEX or the containing APEX allows the use of
- // platform APIs, use stubs only when it is from an APEX (and not from
- // platform) However, for host, ramdisk, vendor_ramdisk, recovery or
- // bootstrap modules, always link to non-stub variant
- useStubs = dep.(android.ApexModule).NotInPlatform() && !bootstrap
- if useStubs {
- // Another exception: if this module is a test for an APEX, then
- // it is linked with the non-stub variant of a module in the APEX
- // as if this is part of the APEX.
- testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo)
- for _, apexContents := range testFor.ApexContents {
- if apexContents.DirectlyInApex(depName) {
- useStubs = false
- break
- }
- }
- }
- if useStubs {
- // Yet another exception: If this module and the dependency are
- // available to the same APEXes then skip stubs between their
- // platform variants. This complements the test_for case above,
- // which avoids the stubs on a direct APEX library dependency, by
- // avoiding stubs for indirect test dependencies as well.
- //
- // TODO(b/183882457): This doesn't work if the two libraries have
- // only partially overlapping apex_available. For that test_for
- // modules would need to be split into APEX variants and resolved
- // separately for each APEX they have access to.
- if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
- useStubs = false
- }
- }
- } else {
- // If building for APEX, use stubs when the parent is in any APEX that
- // the child is not in.
- useStubs = !android.DirectlyInAllApexes(apexInfo, depName)
- }
-
// when to use (unspecified) stubs, use the latest one.
- if useStubs {
+ if shouldUseStubForApex(ctx, dep) {
stubs := sharedLibraryStubsInfo.SharedStubLibraries
toUse := stubs[len(stubs)-1]
sharedLibraryInfo = toUse.SharedLibraryInfo
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 0d03b73..b02e037 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3930,7 +3930,7 @@
func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
t.Helper()
- assertArrayString(t, android.SortedStringKeys(m), expected)
+ assertArrayString(t, android.SortedKeys(m), expected)
}
func TestDefaults(t *testing.T) {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index d7f9618..28f3682 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -41,6 +41,11 @@
"armv8-2a-dotprod": []string{
"-march=armv8.2-a+dotprod",
},
+ "armv9-a": []string{
+ "-march=armv8.2-a+dotprod",
+ "-mbranch-protection=standard",
+ "-fno-stack-protector",
+ },
}
arm64Ldflags = []string{
@@ -101,6 +106,7 @@
exportedVars.ExportStringListStaticVariable("Arm64Armv8ABranchProtCflags", arm64ArchVariantCflags["armv8-a-branchprot"])
exportedVars.ExportStringListStaticVariable("Arm64Armv82ACflags", arm64ArchVariantCflags["armv8-2a"])
exportedVars.ExportStringListStaticVariable("Arm64Armv82ADotprodCflags", arm64ArchVariantCflags["armv8-2a-dotprod"])
+ exportedVars.ExportStringListStaticVariable("Arm64Armv9ACflags", arm64ArchVariantCflags["armv9-a"])
exportedVars.ExportStringListStaticVariable("Arm64CortexA53Cflags", arm64CpuVariantCflags["cortex-a53"])
exportedVars.ExportStringListStaticVariable("Arm64CortexA55Cflags", arm64CpuVariantCflags["cortex-a55"])
@@ -117,6 +123,7 @@
"armv8-a-branchprot": "${config.Arm64Armv8ABranchProtCflags}",
"armv8-2a": "${config.Arm64Armv82ACflags}",
"armv8-2a-dotprod": "${config.Arm64Armv82ADotprodCflags}",
+ "armv9-a": "${config.Arm64Armv9ACflags}",
}
arm64CpuVariantCflagsVar = map[string]string{
@@ -193,6 +200,7 @@
case "armv8-a-branchprot":
case "armv8-2a":
case "armv8-2a-dotprod":
+ case "armv9-a":
// Nothing extra for armv8-a/armv8-2a
default:
panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 981d1ea..0704550 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -97,6 +97,15 @@
// better solution comes around. See Bug 27340895
"-D__ARM_FEATURE_LPAE=1",
},
+ "cortex-a32": []string{
+ "-mcpu=cortex-a32",
+ "-mfpu=neon-vfpv4",
+ // Fake an ARM compiler flag as these processors support LPAE which clang
+ // don't advertise.
+ // TODO This is a hack and we need to add it for each processor that supports LPAE until some
+ // better solution comes around. See Bug 27340895
+ "-D__ARM_FEATURE_LPAE=1",
+ },
"cortex-a53": []string{
"-mcpu=cortex-a53",
"-mfpu=neon-fp-armv8",
@@ -204,6 +213,7 @@
exportedVars.ExportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
exportedVars.ExportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
exportedVars.ExportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA32Cflags", armCpuVariantCflags["cortex-a32"])
exportedVars.ExportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
exportedVars.ExportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
exportedVars.ExportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
@@ -224,6 +234,7 @@
"cortex-a8": "${config.ArmCortexA8Cflags}",
"cortex-a9": "${config.ArmGenericCflags}",
"cortex-a15": "${config.ArmCortexA15Cflags}",
+ "cortex-a32": "${config.ArmCortexA32Cflags}",
"cortex-a53": "${config.ArmCortexA53Cflags}",
"cortex-a53.a57": "${config.ArmCortexA53Cflags}",
"cortex-a55": "${config.ArmCortexA55Cflags}",
diff --git a/cc/library.go b/cc/library.go
index 61e3a93..e73af81 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -2951,12 +2951,6 @@
tags := android.ApexAvailableTags(module)
- // This lib needs some special handling in bazel, so add this tag to the build
- // file.
- if module.Name() == "libprofile-clang-extras" {
- tags.Append(bazel.MakeStringListAttribute([]string{"NO_EXPORTING"}))
- }
-
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name(), Tags: tags}, attrs)
}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 1bcbdc5..e743bb6 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -405,7 +405,7 @@
}
// Add the collated include dir properties to the output.
- for _, property := range android.SortedStringKeys(includeDirs) {
+ for _, property := range android.SortedKeys(includeDirs) {
outputProperties.AddProperty(property, includeDirs[property])
}
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 08a5eb6..18d3f21 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -23,7 +23,8 @@
)
var (
- ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
+ ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
+ stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
)
func init() {
@@ -60,6 +61,12 @@
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
ctx.AddDependency(m, nil, variantName)
}
+ } else if m.IsStubs() {
+ targetVariant := "apex." + m.StubsVersion()
+ if inList(targetVariant, apiLibrary.properties.Variants) {
+ variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
+ ctx.AddDependency(m, nil, variantName)
+ }
}
}
@@ -153,15 +160,15 @@
in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
}
- // LLNDK variant
- if m.UseVndk() && d.hasLLNDKStubs() {
- apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
+ libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
+ load_cc_variant := func(apiVariantModule string) {
var mod android.Module
ctx.VisitDirectDeps(func(depMod android.Module) {
if depMod.Name() == apiVariantModule {
mod = depMod
+ libName = apiVariantModule
}
})
@@ -184,37 +191,17 @@
}
}
}
+ }
+
+ if m.UseVndk() && d.hasLLNDKStubs() {
+ // LLNDK variant
+ load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
} else if m.IsSdkVariant() {
// NDK Variant
- apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())
-
- var mod android.Module
-
- ctx.VisitDirectDeps(func(depMod android.Module) {
- if depMod.Name() == apiVariantModule {
- mod = depMod
- }
- })
-
- if mod != nil {
- variantMod, ok := mod.(*CcApiVariant)
- if ok {
- in = variantMod.Src()
-
- // Copy NDK properties to cc_api_library module
- d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
- d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
- variantMod.exportProperties.Export_include_dirs...)
-
- // Export headers as system include dirs if specified. Mostly for libc
- if Bool(variantMod.exportProperties.Export_headers_as_system) {
- d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
- d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
- d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
- d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil
- }
- }
- }
+ load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
+ } else if m.IsStubs() {
+ // APEX Variant
+ load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
}
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
@@ -237,20 +224,58 @@
d.libraryDecorator.flagExporter.setProvider(ctx)
d.unstrippedOutputFile = in
- libName := d.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
+ libName += flags.Toolchain.ShlibSuffix()
tocFile := android.PathForModuleOut(ctx, libName+".toc")
d.tocFile = android.OptionalPathForPath(tocFile)
TransformSharedObjectToToc(ctx, in, tocFile)
+ outputFile := android.PathForModuleOut(ctx, libName)
+
+ // TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts.
+ // We can just use original input if there is any way to avoid name conflict without copy.
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Description: "API surface imported library",
+ Input: in,
+ Output: outputFile,
+ Args: map[string]string{
+ "cpFlags": "-L",
+ },
+ })
+
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
- SharedLibrary: in,
+ SharedLibrary: outputFile,
Target: ctx.Target(),
TableOfContents: d.tocFile,
})
- return in
+ d.shareStubs(ctx)
+
+ return outputFile
+}
+
+// Share additional information about stub libraries with provider
+func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) {
+ stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
+ if len(stubs) > 0 {
+ var stubsInfo []SharedStubLibrary
+ for _, stub := range stubs {
+ stubInfo := ctx.OtherModuleProvider(stub, SharedLibraryInfoProvider).(SharedLibraryInfo)
+ flagInfo := ctx.OtherModuleProvider(stub, FlagExporterInfoProvider).(FlagExporterInfo)
+ stubsInfo = append(stubsInfo, SharedStubLibrary{
+ Version: moduleLibraryInterface(stub).stubsVersion(),
+ SharedLibraryInfo: stubInfo,
+ FlagExporterInfo: flagInfo,
+ })
+ }
+ ctx.SetProvider(SharedLibraryStubsProvider, SharedLibraryStubsInfo{
+ SharedStubLibraries: stubsInfo,
+
+ IsLLNDK: ctx.IsLlndk(),
+ })
+ }
}
func (d *apiLibraryDecorator) availableFor(what string) bool {
@@ -258,6 +283,19 @@
return true
}
+func (d *apiLibraryDecorator) hasApexStubs() bool {
+ for _, variant := range d.properties.Variants {
+ if strings.HasPrefix(variant, "apex") {
+ return true
+ }
+ }
+ return false
+}
+
+func (d *apiLibraryDecorator) hasStubsVariants() bool {
+ return d.hasApexStubs()
+}
+
func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
m, ok := ctx.Module().(*Module)
@@ -265,14 +303,8 @@
return nil
}
- if d.hasLLNDKStubs() && m.UseVndk() {
- // LLNDK libraries only need a single stubs variant.
- return []string{android.FutureApiLevel.String()}
- }
-
// TODO(b/244244438) Create more version information for NDK and APEX variations
// NDK variants
-
if m.IsSdkVariant() {
// TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
if d.hasNDKStubs() {
@@ -280,6 +312,17 @@
}
}
+ if d.hasLLNDKStubs() && m.UseVndk() {
+ // LLNDK libraries only need a single stubs variant.
+ return []string{android.FutureApiLevel.String()}
+ }
+
+ stubsVersions := d.getStubVersions()
+
+ if len(stubsVersions) != 0 {
+ return stubsVersions
+ }
+
if m.MinSdkVersion() == "" {
return nil
}
@@ -319,6 +362,18 @@
return ndkVersions
}
+func (d *apiLibraryDecorator) getStubVersions() []string {
+ stubVersions := []string{}
+
+ for _, variant := range d.properties.Variants {
+ if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
+ stubVersions = append(stubVersions, match[1])
+ }
+ }
+
+ return stubVersions
+}
+
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
// header libraries. The module will replace any dependencies to existing
// original header libraries.
@@ -433,7 +488,7 @@
// Implement ImageInterface to generate image variants
func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
- return String(v.properties.Variant) == "ndk"
+ return inList(String(v.properties.Variant), []string{"ndk", "apex"})
}
func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index 868447a..528577a 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -41,6 +41,7 @@
cc_library {
name: "libfoo",
shared_libs: ["libbar"],
+ vendor_available: true,
}
cc_library {
@@ -49,6 +50,7 @@
cc_api_library {
name: "libbar",
+ vendor_available: true,
src: "libbar.so",
}
@@ -57,7 +59,6 @@
shared_libs: [
"libbar",
],
- header_libs: [],
}
`
@@ -67,8 +68,14 @@
libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
- android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbar))
- android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+ android.AssertBoolEquals(t, "original library should be linked with non-stub variant", true, hasDirectDependency(t, ctx, libfoo, libbar))
+ android.AssertBoolEquals(t, "Stub library from API surface should be not linked with non-stub variant", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+
+ libfooVendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libbarApiImportVendor := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+
+ android.AssertBoolEquals(t, "original library should not be linked", false, hasDirectDependency(t, ctx, libfooVendor, libbar))
+ android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfooVendor, libbarApiImportVendor))
}
func TestApiLibraryDoNotRequireOriginalModule(t *testing.T) {
@@ -76,11 +83,13 @@
cc_library {
name: "libfoo",
shared_libs: ["libbar"],
+ vendor: true,
}
cc_api_library {
name: "libbar",
src: "libbar.so",
+ vendor_available: true,
}
api_imports {
@@ -88,14 +97,13 @@
shared_libs: [
"libbar",
],
- header_libs: [],
}
`
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
}
@@ -105,143 +113,36 @@
cc_library {
name: "libfoo",
shared_libs: ["libbar"],
+ vendor_available: true,
}
cc_library {
name: "libbar",
+ vendor_available: true,
}
cc_api_library {
name: "libbar",
src: "libbar.so",
+ vendor_available: true,
}
api_imports {
name: "api_imports",
shared_libs: [],
- header_libs: [],
}
`
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libbar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
- libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
+ libfoo := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libbar := ctx.ModuleForTests("libbar", "android_vendor.29_arm64_armv8-a_shared").Module()
+ libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "original library should be linked", true, hasDirectDependency(t, ctx, libfoo, libbar))
android.AssertBoolEquals(t, "Stub library from API surface should not be linked", false, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
}
-func TestApiHeaderReplacesExistingModule(t *testing.T) {
- bp := `
- cc_library {
- name: "libfoo",
- header_libs: ["libfoo_headers"],
- }
-
- cc_api_library {
- name: "libfoo",
- header_libs: ["libfoo_headers"],
- src: "libfoo.so",
- }
-
- cc_library_headers {
- name: "libfoo_headers",
- }
-
- cc_api_headers {
- name: "libfoo_headers",
- }
-
- api_imports {
- name: "api_imports",
- shared_libs: [
- "libfoo",
- ],
- header_libs: [
- "libfoo_headers",
- ],
- }
- `
-
- ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libfooApiImport := ctx.ModuleForTests("libfoo.apiimport", "android_arm64_armv8-a_shared").Module()
- libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
- libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
- android.AssertBoolEquals(t, "original header should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeader))
- android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
- android.AssertBoolEquals(t, "original header should not be used for library imported from API surface", false, hasDirectDependency(t, ctx, libfooApiImport, libfooHeader))
- android.AssertBoolEquals(t, "Header from API surface should be used for library imported from API surface", true, hasDirectDependency(t, ctx, libfooApiImport, libfooHeaderApiImport))
-}
-
-func TestApiHeadersDoNotRequireOriginalModule(t *testing.T) {
- bp := `
- cc_library {
- name: "libfoo",
- header_libs: ["libfoo_headers"],
- }
-
- cc_api_headers {
- name: "libfoo_headers",
- }
-
- api_imports {
- name: "api_imports",
- shared_libs: [
- "libfoo",
- ],
- header_libs: [
- "libfoo_headers",
- ],
- }
- `
-
- ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
- android.AssertBoolEquals(t, "Header from API surface should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
-}
-
-func TestApiHeadersShouldNotReplaceWithoutApiImport(t *testing.T) {
- bp := `
- cc_library {
- name: "libfoo",
- header_libs: ["libfoo_headers"],
- }
-
- cc_library_headers {
- name: "libfoo_headers",
- }
-
- cc_api_headers {
- name: "libfoo_headers",
- }
-
- api_imports {
- name: "api_imports",
- shared_libs: [
- "libfoo",
- ],
- header_libs: [],
- }
- `
-
- ctx := prepareForCcTest.RunTestWithBp(t, bp)
-
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
- libfooHeader := ctx.ModuleForTests("libfoo_headers", "android_arm64_armv8-a").Module()
- libfooHeaderApiImport := ctx.ModuleForTests("libfoo_headers.apiimport", "android_arm64_armv8-a").Module()
-
- android.AssertBoolEquals(t, "original header should be used for original library", true, hasDirectDependency(t, ctx, libfoo, libfooHeader))
- android.AssertBoolEquals(t, "Header from API surface should not be used for original library", false, hasDirectDependency(t, ctx, libfoo, libfooHeaderApiImport))
-}
-
func TestExportDirFromStubLibrary(t *testing.T) {
bp := `
cc_library {
@@ -330,7 +231,7 @@
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
- android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar_llndk.so")
+ android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar.llndk.apiimport.so")
binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
@@ -354,6 +255,17 @@
stl: "c++_shared",
}
+ cc_binary {
+ name: "binqux",
+ srcs: ["binfoo.cc"],
+ shared_libs: ["libbar"],
+ }
+
+ cc_library {
+ name: "libbar",
+ srcs: ["libbar.cc"],
+ }
+
cc_api_library {
name: "libbar",
// TODO(b/244244438) Remove src property once all variants are implemented.
@@ -417,10 +329,14 @@
android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
- android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar_ndk_29.so")
+ android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar.ndk.29.apiimport.so")
binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
+
+ binQux := ctx.ModuleForTests("binqux", "android_arm64_armv8-a").Module()
+ android.AssertBoolEquals(t, "NDK Stub library from API surface should not be linked with nonSdk binary", false,
+ (hasDirectDependency(t, ctx, binQux, libbarApiImportv30) || hasDirectDependency(t, ctx, binQux, libbarApiImportv29)))
}
func TestApiLibraryWithMultipleVariants(t *testing.T) {
@@ -440,6 +356,11 @@
shared_libs: ["libbar"],
}
+ cc_library {
+ name: "libbar",
+ srcs: ["libbar.cc"],
+ }
+
cc_api_library {
name: "libbar",
// TODO(b/244244438) Remove src property once all variants are implemented.
@@ -450,6 +371,9 @@
"ndk.29",
"ndk.30",
"ndk.current",
+ "apex.29",
+ "apex.30",
+ "apex.current",
],
}
@@ -479,6 +403,30 @@
cc_api_variant {
name: "libbar",
+ variant: "apex",
+ version: "29",
+ src: "libbar_apex_29.so",
+ export_include_dirs: ["libbar_apex_29_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "apex",
+ version: "30",
+ src: "libbar_apex_30.so",
+ export_include_dirs: ["libbar_apex_30_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "apex",
+ version: "current",
+ src: "libbar_apex_current.so",
+ export_include_dirs: ["libbar_apex_current_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
variant: "llndk",
src: "libbar_llndk.so",
export_include_dirs: ["libbar_llndk_include"]
@@ -489,7 +437,9 @@
shared_libs: [
"libbar",
],
- header_libs: [],
+ apex_shared_libs: [
+ "libbar",
+ ],
}
`
ctx := prepareForCcTest.RunTestWithBp(t, bp)
diff --git a/cc/library_test.go b/cc/library_test.go
index de3db99..dbe2be8 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -464,6 +464,7 @@
expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestCcLibrarySharedWithBazel(t *testing.T) {
@@ -510,6 +511,7 @@
expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestWholeStaticLibPrebuilts(t *testing.T) {
diff --git a/cc/ndk_api_coverage_parser/OWNERS b/cc/ndk_api_coverage_parser/OWNERS
deleted file mode 100644
index a90c48c..0000000
--- a/cc/ndk_api_coverage_parser/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-sophiez@google.com
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 405680c..e3ec9d5 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -169,6 +169,11 @@
if !hasDep(crtx, prebuiltCrtx) {
t.Errorf("crtx missing dependency on prebuilt_crtx")
}
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, prebuiltLiba)[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_shared", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
+ entries = android.AndroidMkEntriesForTest(t, ctx, prebuiltLibb)[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "cc_prebuilt_library_static", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestPrebuiltLibraryShared(t *testing.T) {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 66f459a..aa61453 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1716,9 +1716,9 @@
// These are to be used by use_soong_sanitized_static_libraries.
// See build/make/core/binary.mk for more details.
func (s *sanitizerStaticLibsMap) exportToMake(ctx android.MakeVarsContext) {
- for _, image := range android.SortedStringKeys(s.libsMap) {
+ for _, image := range android.SortedKeys(s.libsMap) {
archMap := s.libsMap[ImageVariantType(image)]
- for _, arch := range android.SortedStringKeys(archMap) {
+ for _, arch := range android.SortedKeys(archMap) {
libs := archMap[arch]
sort.Strings(libs)
diff --git a/cc/sdk.go b/cc/sdk.go
index 23dd0cb..4f361eb 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -62,21 +62,26 @@
} else if isCcModule && ccModule.isImportedApiLibrary() {
apiLibrary, _ := ccModule.linker.(*apiLibraryDecorator)
if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
+ variations := []string{"sdk"}
+ if apiLibrary.hasApexStubs() {
+ variations = append(variations, "")
+ }
// Handle cc_api_library module with NDK stubs and variants only which can use SDK
- modules := ctx.CreateVariations("", "sdk")
-
+ modules := ctx.CreateVariations(variations...)
// Mark the SDK variant.
- modules[1].(*Module).Properties.IsSdkVariant = true
- // SDK variant is not supposed to be installed
- modules[1].(*Module).Properties.PreventInstall = true
-
+ modules[0].(*Module).Properties.IsSdkVariant = true
if ctx.Config().UnbundledBuildApps() {
- // For an unbundled apps build, hide the platform variant from Make.
- modules[0].(*Module).Properties.HideFromMake = true
+ if apiLibrary.hasApexStubs() {
+ // For an unbundled apps build, hide the platform variant from Make.
+ modules[1].(*Module).Properties.HideFromMake = true
+ modules[1].(*Module).Properties.PreventInstall = true
+ }
} else {
// For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
// exposed to Make.
- modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+ modules[0].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+ // SDK variant is not supposed to be installed
+ modules[0].(*Module).Properties.PreventInstall = true
}
} else {
ccModule.Properties.Sdk_version = nil
diff --git a/cc/stub_library.go b/cc/stub_library.go
index 76da782..f324dcc 100644
--- a/cc/stub_library.go
+++ b/cc/stub_library.go
@@ -73,7 +73,7 @@
func (s *stubLibraries) MakeVars(ctx android.MakeVarsContext) {
// Convert stub library file names into Makefile variable.
- ctx.Strict("STUB_LIBRARIES", strings.Join(android.SortedStringKeys(s.stubLibraryMap), " "))
+ ctx.Strict("STUB_LIBRARIES", strings.Join(android.SortedKeys(s.stubLibraryMap), " "))
// Export the list of API XML files to Make.
sort.Strings(s.apiListCoverageXmlPaths)
diff --git a/cc/util.go b/cc/util.go
index 4e10037..aa0f6b5 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -118,7 +118,7 @@
// ...
func installMapListFileRule(ctx android.SingletonContext, m map[string]string, path string) android.OutputPath {
var txtBuilder strings.Builder
- for idx, k := range android.SortedStringKeys(m) {
+ for idx, k := range android.SortedKeys(m) {
if idx > 0 {
txtBuilder.WriteString("\n")
}
diff --git a/cc/vndk.go b/cc/vndk.go
index 6ab4734..3b7c87d 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -876,7 +876,7 @@
})
ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
- strings.Join(android.SortedStringKeys(movedToApexLlndkLibraries), " "))
+ strings.Join(android.SortedKeys(movedToApexLlndkLibraries), " "))
ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 5f27fa7..5c187f6 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -81,6 +81,7 @@
flag.BoolVar(&cmdlineArgs.BazelMode, "bazel-mode", false, "use bazel for analysis of certain modules")
flag.BoolVar(&cmdlineArgs.BazelModeStaging, "bazel-mode-staging", false, "use bazel for analysis of certain near-ready modules")
flag.BoolVar(&cmdlineArgs.BazelModeDev, "bazel-mode-dev", false, "use bazel for analysis of a large number of modules (less stable)")
+ flag.BoolVar(&cmdlineArgs.UseBazelProxy, "use-bazel-proxy", false, "communicate with bazel using unix socket proxy instead of spawning subprocesses")
// Flags that probably shouldn't be flags of soong_build, but we haven't found
// the time to remove them yet
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index fd718c2..ae026ba 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -200,6 +200,7 @@
rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
bazelMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bazel_metrics.pb")
+ soongBuildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_build_metrics.pb")
//the profile file generated by Bazel"
bazelProfileFile := filepath.Join(logsDir, c.logsPrefix+"analyzed_bazel_profile.txt")
@@ -209,6 +210,7 @@
bp2buildMetricsFile, // high level metrics related to bp2build.
soongMetricsFile, // high level metrics related to this build system.
bazelMetricsFile, // high level metrics related to bazel execution
+ soongBuildMetricsFile, // high level metrics related to soong build(except bp2build)
config.BazelMetricsDir(), // directory that contains a set of bazel metrics.
}
diff --git a/dexpreopt/OWNERS b/dexpreopt/OWNERS
deleted file mode 100644
index 5a2a198..0000000
--- a/dexpreopt/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-per-file * = ngeoffray@google.com,calin@google.com,skvadrik@google.com
diff --git a/docs/OWNERS b/docs/OWNERS
deleted file mode 100644
index 2d71271..0000000
--- a/docs/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-per-file map_files.md = danalbert@google.com, enh@google.com, jiyong@google.com
-per-file native_code_coverage.md = pirama@google.com, srhines@google.com, allenhair@google.com
-per-file tidy.md = chh@google.com, srhines@google.com
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index a6477dd..0d44c31 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -140,6 +140,7 @@
"LOCAL_REQUIRED_MODULES": {"modA", "moduleB"},
"LOCAL_HOST_REQUIRED_MODULES": {"hostModA", "hostModB"},
"LOCAL_TARGET_REQUIRED_MODULES": {"targetModA"},
+ "LOCAL_SOONG_MODULE_TYPE": {"prebuilt_etc"},
}
mod := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
diff --git a/java/OWNERS b/java/OWNERS
deleted file mode 100644
index 5b71b1e..0000000
--- a/java/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-per-file dexpreopt*.go = ngeoffray@google.com,calin@google.com,skvadrik@google.com
-
-# For metalava team to disable lint checks in platform
-per-file droidstubs.go = aurimas@google.com,emberrose@google.com,sjgilbert@google.com
\ No newline at end of file
diff --git a/java/app_import_test.go b/java/app_import_test.go
index a29606f..528fffe 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -363,11 +363,14 @@
a := variant.Module().(*AndroidAppImport)
expectedValues := []string{test.expected}
- actualValues := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
+ entries := android.AndroidMkEntriesForTest(t, ctx, a)[0]
+ actualValues := entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
if !reflect.DeepEqual(actualValues, expectedValues) {
t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
actualValues, expectedValues)
}
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "android_app_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
+
rule := variant.Rule("genProvenanceMetaData")
android.AssertStringEquals(t, "Invalid input", test.expectedArtifactPath, rule.Inputs[0].String())
android.AssertStringEquals(t, "Invalid output", test.expectedMetaDataPath, rule.Output.String())
@@ -560,6 +563,7 @@
} else if actualSoongResourceExportPackage[0] != expectedSoongResourceExportPackage {
t.Errorf("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE mismatch, actual: %s, expected: %s", actualSoongResourceExportPackage[0], expectedSoongResourceExportPackage)
}
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "android_app_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func TestAndroidAppImport_relativeInstallPath(t *testing.T) {
diff --git a/java/app_test.go b/java/app_test.go
index c77f29d..5b16cea 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1005,6 +1005,7 @@
platformSdkInt int
platformSdkCodename string
platformSdkFinal bool
+ minSdkVersionBp string
expectedMinSdkVersion string
platformApis bool
activeCodenames []string
@@ -1052,6 +1053,14 @@
platformSdkCodename: "S",
activeCodenames: []string{"S"},
},
+ {
+ name: "two active SDKs",
+ sdkVersion: "module_current",
+ minSdkVersionBp: "UpsideDownCake",
+ expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream
+ platformSdkCodename: "VanillaIceCream",
+ activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"},
+ },
}
for _, moduleType := range []string{"android_app", "android_library"} {
@@ -1061,12 +1070,17 @@
if test.platformApis {
platformApiProp = "platform_apis: true,"
}
+ minSdkVersionProp := ""
+ if test.minSdkVersionBp != "" {
+ minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp)
+ }
bp := fmt.Sprintf(`%s {
name: "foo",
srcs: ["a.java"],
sdk_version: "%s",
%s
- }`, moduleType, test.sdkVersion, platformApiProp)
+ %s
+ }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp)
result := android.GroupFixturePreparers(
prepareForJavaTest,
diff --git a/java/base.go b/java/base.go
index 2e77c1e..85f4a5e 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1003,7 +1003,7 @@
topLevelDirs[srcFileParts[0]] = true
}
}
- patchPaths = append(patchPaths, android.SortedStringKeys(topLevelDirs)...)
+ patchPaths = append(patchPaths, android.SortedKeys(topLevelDirs)...)
classPath := flags.classpath.FormJavaClassPath("")
if classPath != "" {
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 585f818..c07a94a 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -440,7 +440,7 @@
return dexJar, nil
} else {
return nil, fmt.Errorf("unknown bootclasspath_fragment content module %s, expected one of %s",
- name, strings.Join(android.SortedStringKeys(i.contentModuleDexJarPaths), ", "))
+ name, strings.Join(android.SortedKeys(i.contentModuleDexJarPaths), ", "))
}
}
@@ -709,7 +709,7 @@
imageName := *imageNamePtr
imageConfig := imageConfigs[imageName]
if imageConfig == nil {
- ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
+ ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedKeys(imageConfigs), ", "))
return nil
}
return imageConfig
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 259e977..cf81ddb 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -111,7 +111,7 @@
ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name)
}
}
- return android.SortedStringKeys(set)
+ return android.SortedKeys(set)
}
// Converts android.ConfiguredJarList into a list of classpathJars for each given classpathType.
diff --git a/java/config/config.go b/java/config/config.go
index 293eb92..838d007 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -93,9 +93,11 @@
"-JXmx4096M",
"-JXX:+TieredCompilation",
"-JXX:TieredStopAtLevel=1",
+ "-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
}, dexerJavaVmFlagsList...))
exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{
"-JXmx2048M",
+ "-JDcom.android.tools.r8.emitRecordAnnotationsInDex",
}, dexerJavaVmFlagsList...))
exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0ffedf6..e0a0629 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -293,12 +293,6 @@
isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx))
bootImage := defaultBootImageConfig(ctx)
- // When `global.PreoptWithUpdatableBcp` is true, `bcpForDexpreopt` below includes the mainline
- // boot jars into bootclasspath, so we should include the mainline boot image as well because it's
- // generated from those jars.
- if global.PreoptWithUpdatableBcp {
- bootImage = mainlineBootImageConfig(ctx)
- }
dexFiles, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp)
targets := ctx.MultiTargets()
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 6140e11..373b478 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -538,8 +538,8 @@
func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) {
// Create the super set of module names.
names := []string{}
- names = append(names, android.SortedStringKeys(srcBootDexJarsByModule)...)
- names = append(names, android.SortedStringKeys(dstBootJarsByModule)...)
+ names = append(names, android.SortedKeys(srcBootDexJarsByModule)...)
+ names = append(names, android.SortedKeys(dstBootJarsByModule)...)
names = android.SortedUniqueStrings(names)
for _, name := range names {
src := srcBootDexJarsByModule[name]
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 117b660..76c78cb 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -44,8 +44,6 @@
bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
artBootImageName = "art"
frameworkBootImageName = "boot"
- mainlineBootImageName = "mainline"
- bootImageStem = "boot"
)
func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig {
@@ -54,16 +52,14 @@
artModules := global.ArtApexJars
frameworkModules := global.BootJars.RemoveList(artModules)
- mainlineBcpModules := global.ApexBootJars
- frameworkSubdir := "system/framework"
// ART config for the primary boot image in the ART apex.
// It includes the Core Libraries.
artCfg := bootImageConfig{
name: artBootImageName,
- stem: bootImageStem,
+ stem: "boot",
installDirOnHost: "apex/art_boot_images/javalib",
- installDirOnDevice: frameworkSubdir,
+ installDirOnDevice: "system/framework",
profileInstallPathInApex: "etc/boot-image.prof",
modules: artModules,
preloadedClassesFile: "art/build/boot/preloaded-classes",
@@ -72,10 +68,11 @@
// Framework config for the boot image extension.
// It includes framework libraries and depends on the ART config.
+ frameworkSubdir := "system/framework"
frameworkCfg := bootImageConfig{
extends: &artCfg,
name: frameworkBootImageName,
- stem: bootImageStem,
+ stem: "boot",
installDirOnHost: frameworkSubdir,
installDirOnDevice: frameworkSubdir,
modules: frameworkModules,
@@ -83,20 +80,9 @@
compilerFilter: "speed-profile",
}
- mainlineCfg := bootImageConfig{
- extends: &frameworkCfg,
- name: mainlineBootImageName,
- stem: bootImageStem,
- installDirOnHost: frameworkSubdir,
- installDirOnDevice: frameworkSubdir,
- modules: mainlineBcpModules,
- compilerFilter: "verify",
- }
-
return map[string]*bootImageConfig{
artBootImageName: &artCfg,
frameworkBootImageName: &frameworkCfg,
- mainlineBootImageName: &mainlineCfg,
}
}).(map[string]*bootImageConfig)
}
@@ -188,10 +174,6 @@
return genBootImageConfigs(ctx)[frameworkBootImageName]
}
-func mainlineBootImageConfig(ctx android.PathContext) *bootImageConfig {
- return genBootImageConfigs(ctx)[mainlineBootImageName]
-}
-
// Apex boot config allows to access build/install paths of apex boot jars without going
// through the usual trouble of registering dependencies on those modules and extracting build paths
// from those dependencies.
diff --git a/java/dexpreopt_config_test.go b/java/dexpreopt_config_test.go
index cd7f295..b704d09 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -28,10 +28,8 @@
result := android.GroupFixturePreparers(
PrepareForBootImageConfigTest,
- PrepareApexBootJarConfigs,
).RunTest(t)
CheckArtBootImageConfig(t, result)
CheckFrameworkBootImageConfig(t, result)
- CheckMainlineBootImageConfig(t, result)
}
diff --git a/java/dexpreopt_config_testing.go b/java/dexpreopt_config_testing.go
index c27f4c6..c509c1b 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -39,78 +39,6 @@
FixtureConfigureBootJars("com.android.art:core1", "com.android.art:core2", "platform:framework"),
)
-var PrepareApexBootJarConfigs = FixtureConfigureApexBootJars(
- "com.android.foo:framework-foo", "com.android.bar:framework-bar")
-
-var PrepareApexBootJarConfigsAndModules = android.GroupFixturePreparers(
- PrepareApexBootJarConfigs,
- prepareApexBootJarModule("com.android.foo", "framework-foo"),
- prepareApexBootJarModule("com.android.bar", "framework-bar"),
-)
-
-var ApexBootJarFragmentsForPlatformBootclasspath = fmt.Sprintf(`
- {
- apex: "%[1]s",
- module: "%[1]s-bootclasspathfragment",
- },
- {
- apex: "%[2]s",
- module: "%[2]s-bootclasspathfragment",
- },
-`, "com.android.foo", "com.android.bar")
-
-var ApexBootJarDexJarPaths = []string{
- "out/soong/.intermediates/packages/modules/com.android.bar/framework-bar/android_common_apex10000/aligned/framework-bar.jar",
- "out/soong/.intermediates/packages/modules/com.android.foo/framework-foo/android_common_apex10000/aligned/framework-foo.jar",
-}
-
-func prepareApexBootJarModule(apexName string, moduleName string) android.FixturePreparer {
- moduleSourceDir := fmt.Sprintf("packages/modules/%s", apexName)
- return android.GroupFixturePreparers(
- android.FixtureAddTextFile(moduleSourceDir+"/Android.bp", fmt.Sprintf(`
- apex {
- name: "%[1]s",
- key: "%[1]s.key",
- bootclasspath_fragments: [
- "%[1]s-bootclasspathfragment",
- ],
- updatable: false,
- }
-
- apex_key {
- name: "%[1]s.key",
- public_key: "%[1]s.avbpubkey",
- private_key: "%[1]s.pem",
- }
-
- bootclasspath_fragment {
- name: "%[1]s-bootclasspathfragment",
- contents: ["%[2]s"],
- apex_available: ["%[1]s"],
- hidden_api: {
- split_packages: ["*"],
- },
- }
-
- java_library {
- name: "%[2]s",
- srcs: ["%[2]s.java"],
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- apex_available: ["%[1]s"],
- }
- `, apexName, moduleName)),
- android.FixtureMergeMockFs(android.MockFS{
- fmt.Sprintf("%s/apex_manifest.json", moduleSourceDir): nil,
- fmt.Sprintf("%s/%s.avbpubkey", moduleSourceDir, apexName): nil,
- fmt.Sprintf("%s/%s.pem", moduleSourceDir, apexName): nil,
- fmt.Sprintf("system/sepolicy/apex/%s-file_contexts", apexName): nil,
- fmt.Sprintf("%s/%s.java", moduleSourceDir, moduleName): nil,
- }),
- )
-}
-
// normalizedInstall represents a android.RuleBuilderInstall that has been normalized to remove
// test specific parts of the From path.
type normalizedInstall struct {
@@ -673,366 +601,6 @@
checkBootImageConfig(t, imageConfig, mutated, expected)
}
-// getMainlineImageConfig gets the framework bootImageConfig that was created during the test.
-func getMainlineImageConfig(result *android.TestResult) *bootImageConfig {
- pathCtx := &android.TestPathContext{TestResult: result}
- imageConfig := mainlineBootImageConfig(pathCtx)
- return imageConfig
-}
-
-// CheckMainlineBootImageConfig checks the status of the fields of the bootImageConfig and
-// bootImageVariant structures that are returned from mainlineBootImageConfig.
-//
-// This is before any fields are mutated.
-func CheckMainlineBootImageConfig(t *testing.T, result *android.TestResult) {
- expectedLicenseMetadataFile := ""
- imageConfig := getMainlineImageConfig(result)
-
- expected := &expectedConfig{
- name: "mainline",
- stem: "boot",
- dir: "out/soong/test_device/dex_mainlinejars",
- symbolsDir: "out/soong/test_device/dex_mainlinejars_unstripped",
- installDirOnDevice: "system/framework",
- installDirOnHost: "system/framework",
- profileInstallPathInApex: "",
- modules: android.CreateTestConfiguredJarList([]string{
- "com.android.foo:framework-foo",
- "com.android.bar:framework-bar",
- }),
- dexPaths: []string{
- "out/soong/test_device/dex_mainlinejars_input/framework-foo.jar",
- "out/soong/test_device/dex_mainlinejars_input/framework-bar.jar",
- },
- dexPathsDeps: []string{
- "out/soong/test_device/dex_artjars_input/core1.jar",
- "out/soong/test_device/dex_artjars_input/core2.jar",
- "out/soong/test_device/dex_bootjars_input/framework.jar",
- "out/soong/test_device/dex_mainlinejars_input/framework-foo.jar",
- "out/soong/test_device/dex_mainlinejars_input/framework-bar.jar",
- },
- zip: "out/soong/test_device/dex_mainlinejars/mainline.zip",
- variants: []*expectedVariant{
- {
- archType: android.Arm64,
- dexLocations: []string{
- "/apex/com.android.foo/javalib/framework-foo.jar",
- "/apex/com.android.bar/javalib/framework-bar.jar",
- },
- dexLocationsDeps: []string{
- "/apex/com.android.art/javalib/core1.jar",
- "/apex/com.android.art/javalib/core2.jar",
- "/system/framework/framework.jar",
- "/apex/com.android.foo/javalib/framework-foo.jar",
- "/apex/com.android.bar/javalib/framework-bar.jar",
- },
- imagePathOnHost: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
- imagePathOnDevice: "/system/framework/arm64/boot-framework-foo.art",
- imagesDeps: []string{
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex",
- },
- baseImages: []string{
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
- },
- baseImagesDeps: []string{
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex",
- },
- installs: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art",
- to: "/system/framework/arm64/boot-framework-foo.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat",
- to: "/system/framework/arm64/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art",
- to: "/system/framework/arm64/boot-framework-bar.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat",
- to: "/system/framework/arm64/boot-framework-bar.oat",
- },
- },
- vdexInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex",
- to: "/system/framework/arm64/boot-framework-foo.vdex",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex",
- to: "/system/framework/arm64/boot-framework-bar.vdex",
- },
- },
- unstrippedInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat",
- to: "/system/framework/arm64/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-bar.oat",
- to: "/system/framework/arm64/boot-framework-bar.oat",
- },
- },
- licenseMetadataFile: expectedLicenseMetadataFile,
- },
- {
- archType: android.Arm,
- dexLocations: []string{
- "/apex/com.android.foo/javalib/framework-foo.jar",
- "/apex/com.android.bar/javalib/framework-bar.jar",
- },
- dexLocationsDeps: []string{
- "/apex/com.android.art/javalib/core1.jar",
- "/apex/com.android.art/javalib/core2.jar",
- "/system/framework/framework.jar",
- "/apex/com.android.foo/javalib/framework-foo.jar",
- "/apex/com.android.bar/javalib/framework-bar.jar",
- },
- imagePathOnHost: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
- imagePathOnDevice: "/system/framework/arm/boot-framework-foo.art",
- imagesDeps: []string{
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat",
- "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex",
- },
- baseImages: []string{
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
- },
- baseImagesDeps: []string{
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat",
- "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.art",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.oat",
- "out/soong/test_device/dex_bootjars/android/system/framework/arm/boot-framework.vdex",
- },
- installs: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art",
- to: "/system/framework/arm/boot-framework-foo.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat",
- to: "/system/framework/arm/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art",
- to: "/system/framework/arm/boot-framework-bar.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat",
- to: "/system/framework/arm/boot-framework-bar.oat",
- },
- },
- vdexInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex",
- to: "/system/framework/arm/boot-framework-foo.vdex",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex",
- to: "/system/framework/arm/boot-framework-bar.vdex",
- },
- },
- unstrippedInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-foo.oat",
- to: "/system/framework/arm/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-bar.oat",
- to: "/system/framework/arm/boot-framework-bar.oat",
- },
- },
- licenseMetadataFile: expectedLicenseMetadataFile,
- },
- {
- archType: android.X86_64,
- dexLocations: []string{
- "host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
- "host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
- },
- dexLocationsDeps: []string{
- "host/linux-x86/apex/com.android.art/javalib/core1.jar",
- "host/linux-x86/apex/com.android.art/javalib/core2.jar",
- "host/linux-x86/system/framework/framework.jar",
- "host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
- "host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
- },
- imagePathOnHost: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
- imagePathOnDevice: "/system/framework/x86_64/boot-framework-foo.art",
- imagesDeps: []string{
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex",
- },
- baseImages: []string{
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
- },
- baseImagesDeps: []string{
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.oat",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.vdex",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.art",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.oat",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot-core2.vdex",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex",
- },
- installs: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art",
- to: "/system/framework/x86_64/boot-framework-foo.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
- to: "/system/framework/x86_64/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art",
- to: "/system/framework/x86_64/boot-framework-bar.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
- to: "/system/framework/x86_64/boot-framework-bar.oat",
- },
- },
- vdexInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex",
- to: "/system/framework/x86_64/boot-framework-foo.vdex",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex",
- to: "/system/framework/x86_64/boot-framework-bar.vdex",
- },
- },
- unstrippedInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat",
- to: "/system/framework/x86_64/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-bar.oat",
- to: "/system/framework/x86_64/boot-framework-bar.oat",
- },
- },
- licenseMetadataFile: expectedLicenseMetadataFile,
- },
- {
- archType: android.X86,
- dexLocations: []string{
- "host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
- "host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
- },
- dexLocationsDeps: []string{
- "host/linux-x86/apex/com.android.art/javalib/core1.jar",
- "host/linux-x86/apex/com.android.art/javalib/core2.jar",
- "host/linux-x86/system/framework/framework.jar",
- "host/linux-x86/apex/com.android.foo/javalib/framework-foo.jar",
- "host/linux-x86/apex/com.android.bar/javalib/framework-bar.jar",
- },
- imagePathOnHost: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
- imagePathOnDevice: "/system/framework/x86/boot-framework-foo.art",
- imagesDeps: []string{
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat",
- "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex",
- },
- baseImages: []string{
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
- },
- baseImagesDeps: []string{
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat",
- "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat",
- "out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex",
- },
- installs: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art",
- to: "/system/framework/x86/boot-framework-foo.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat",
- to: "/system/framework/x86/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art",
- to: "/system/framework/x86/boot-framework-bar.art",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat",
- to: "/system/framework/x86/boot-framework-bar.oat",
- },
- },
- vdexInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex",
- to: "/system/framework/x86/boot-framework-foo.vdex",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex",
- to: "/system/framework/x86/boot-framework-bar.vdex",
- },
- },
- unstrippedInstalls: []normalizedInstall{
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat",
- to: "/system/framework/x86/boot-framework-foo.oat",
- },
- {
- from: "out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-bar.oat",
- to: "/system/framework/x86/boot-framework-bar.oat",
- },
- },
- licenseMetadataFile: expectedLicenseMetadataFile,
- },
- },
- profileInstalls: []normalizedInstall{},
- profileLicenseMetadataFile: expectedLicenseMetadataFile,
- }
-
- checkBootImageConfig(t, imageConfig, false, expected)
-}
-
// clearMutatedFields clears fields in the expectedConfig that correspond to fields in the
// bootImageConfig/bootImageVariant structs which are mutated outside the call to
// genBootImageConfigs.
@@ -1144,10 +712,6 @@
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art:/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art:/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
DEXPREOPT_IMAGE_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art:/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art:/system/framework/arm/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat:/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art:/system/framework/arm/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat:/system/framework/arm/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art:/system/framework/arm64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art:/system/framework/arm64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat:/system/framework/arm64/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art:/system/framework/x86/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art:/system/framework/x86/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat:/system/framework/x86/boot-framework-bar.oat
-DEXPREOPT_IMAGE_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art:/system/framework/x86_64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art:/system/framework/x86_64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat:/system/framework/x86_64/boot-framework-bar.oat
DEXPREOPT_IMAGE_DEPS_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex
DEXPREOPT_IMAGE_DEPS_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.art out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.oat out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex
DEXPREOPT_IMAGE_DEPS_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.art out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.oat out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex
@@ -1156,10 +720,6 @@
DEXPREOPT_IMAGE_DEPS_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.oat out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex
DEXPREOPT_IMAGE_DEPS_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex
DEXPREOPT_IMAGE_DEPS_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.oat out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_DEPS_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.art out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.oat out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex
DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm=%[1]s
DEXPREOPT_IMAGE_LICENSE_METADATA_art_arm64=%[1]s
DEXPREOPT_IMAGE_LICENSE_METADATA_art_host_x86=%[1]s
@@ -1168,17 +728,11 @@
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
DEXPREOPT_IMAGE_LICENSE_METADATA_boot_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_arm64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
-DEXPREOPT_IMAGE_LICENSE_METADATA_mainline_host_x86_64=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEart=/system/framework/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEboot=/system/framework/boot.art:/system/framework/boot-framework.art
-DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICEmainline=/system/framework/boot.art:/system/framework/boot-framework.art:/system/framework/boot-framework-foo.art
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTart=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art
DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTboot=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art
-DEXPREOPT_IMAGE_LOCATIONS_ON_HOSTmainline=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/boot.art:out/soong/test_device/dex_bootjars/android/system/framework/boot-framework.art:out/soong/test_device/dex_mainlinejars/android/system/framework/boot-framework-foo.art
-DEXPREOPT_IMAGE_NAMES=art boot mainline
+DEXPREOPT_IMAGE_NAMES=art boot
DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED=out/soong/test_device/dex_bootjars/boot.bprof:/system/etc/boot-image.bprof out/soong/test_device/dex_bootjars/boot.prof:/system/etc/boot-image.prof
DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA=out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot.oat:/apex/art_boot_images/javalib/arm/boot.oat out/soong/test_device/dex_artjars_unstripped/android/apex/art_boot_images/javalib/arm/boot-core2.oat:/apex/art_boot_images/javalib/arm/boot-core2.oat
@@ -1189,10 +743,6 @@
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars_unstripped/android/system/framework/arm64/boot-framework.oat:/system/framework/arm64/boot-framework.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86/boot-framework.oat:/system/framework/x86/boot-framework.oat
DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars_unstripped/linux_glibc/system/framework/x86_64/boot-framework.oat:/system/framework/x86_64/boot-framework.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-foo.oat:/system/framework/arm/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm/boot-framework-bar.oat:/system/framework/arm/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-foo.oat:/system/framework/arm64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/android/system/framework/arm64/boot-framework-bar.oat:/system/framework/arm64/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-foo.oat:/system/framework/x86/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86/boot-framework-bar.oat:/system/framework/x86/boot-framework-bar.oat
-DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-foo.oat:/system/framework/x86_64/boot-framework-foo.oat out/soong/test_device/dex_mainlinejars_unstripped/linux_glibc/system/framework/x86_64/boot-framework-bar.oat:/system/framework/x86_64/boot-framework-bar.oat
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex:/apex/art_boot_images/javalib/arm/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-core2.vdex:/apex/art_boot_images/javalib/arm/boot-core2.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex:/apex/art_boot_images/javalib/arm64/boot.vdex out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-core2.vdex:/apex/art_boot_images/javalib/arm64/boot-core2.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.vdex:/apex/art_boot_images/javalib/x86/boot.vdex out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot-core2.vdex:/apex/art_boot_images/javalib/x86/boot-core2.vdex
@@ -1201,13 +751,8 @@
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.vdex:/system/framework/arm64/boot-framework.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.vdex:/system/framework/x86/boot-framework.vdex
DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.vdex:/system/framework/x86_64/boot-framework.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.vdex:/system/framework/arm/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-bar.vdex:/system/framework/arm/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.vdex:/system/framework/arm64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-bar.vdex:/system/framework/arm64/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.vdex:/system/framework/x86/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-bar.vdex:/system/framework/x86/boot-framework-bar.vdex
-DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.vdex:/system/framework/x86_64/boot-framework-foo.vdex out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-bar.vdex:/system/framework/x86_64/boot-framework-bar.vdex
DEXPREOPT_IMAGE_ZIP_art=out/soong/test_device/dex_artjars/art.zip
DEXPREOPT_IMAGE_ZIP_boot=out/soong/test_device/dex_bootjars/boot.zip
-DEXPREOPT_IMAGE_ZIP_mainline=out/soong/test_device/dex_mainlinejars/mainline.zip
DEXPREOPT_IMAGE_art_arm=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art
DEXPREOPT_IMAGE_art_arm64=out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art
DEXPREOPT_IMAGE_art_host_x86=out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art
@@ -1216,10 +761,6 @@
DEXPREOPT_IMAGE_boot_arm64=out/soong/test_device/dex_bootjars/android/system/framework/arm64/boot-framework.art
DEXPREOPT_IMAGE_boot_host_x86=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86/boot-framework.art
DEXPREOPT_IMAGE_boot_host_x86_64=out/soong/test_device/dex_bootjars/linux_glibc/system/framework/x86_64/boot-framework.art
-DEXPREOPT_IMAGE_mainline_arm=out/soong/test_device/dex_mainlinejars/android/system/framework/arm/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_arm64=out/soong/test_device/dex_mainlinejars/android/system/framework/arm64/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_host_x86=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86/boot-framework-foo.art
-DEXPREOPT_IMAGE_mainline_host_x86_64=out/soong/test_device/dex_mainlinejars/linux_glibc/system/framework/x86_64/boot-framework-foo.art
`
expected := strings.TrimSpace(fmt.Sprintf(format, expectedLicenseMetadataFile))
actual := strings.TrimSpace(out.String())
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 01a2c14..e98b9ea 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -603,12 +603,10 @@
Flag("-J-XX:-OmitStackTraceInFastThrow").
Flag("-XDignore.symbol.file").
Flag("--ignore-source-errors").
- // b/240421555: use a stub doclet until Doclava works with JDK 17
- //FlagWithArg("-doclet ", "com.google.doclava.Doclava").
- FlagWithArg("-doclet ", "com.google.stubdoclet.StubDoclet").
+ FlagWithArg("-doclet ", "com.google.doclava.Doclava").
FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
- FlagWithArg("-Xmaxerrs ", "1").
- FlagWithArg("-Xmaxwarns ", "1").
+ FlagWithArg("-Xmaxerrs ", "10").
+ FlagWithArg("-Xmaxwarns ", "10").
Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED").
Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED").
FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
@@ -780,8 +778,6 @@
jsilver := ctx.Config().HostJavaToolPath(ctx, "jsilver.jar")
doclava := ctx.Config().HostJavaToolPath(ctx, "doclava.jar")
- // b/240421555: use a stub doclet until Doclava works with JDK 17
- stubdoclet := ctx.Config().HostJavaToolPath(ctx, "stubdoclet.jar")
outDir := android.PathForModuleOut(ctx, "out")
srcJarDir := android.PathForModuleOut(ctx, "srcjars")
@@ -809,8 +805,7 @@
if Bool(d.properties.Dokka_enabled) {
desc = "dokka"
} else {
- // b/240421555: use a stub doclet until Doclava works with JDK 17
- d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava, stubdoclet})
+ d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
for _, o := range d.Javadoc.properties.Out {
cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
@@ -828,9 +823,9 @@
FlagWithArg("-C ", outDir.String()).
FlagWithArg("-D ", outDir.String())
- // rule.Restat()
+ rule.Restat()
- // zipSyncCleanupCmd(rule, srcJarDir)
+ zipSyncCleanupCmd(rule, srcJarDir)
rule.Build("javadoc", desc)
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 593d772..be4a48e 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -697,7 +697,7 @@
// The relative width of APIs is determined by their order in hiddenAPIScopes.
func (s StubDexJarsByModule) StubDexJarsForWidestAPIScope() android.Paths {
stubDexJars := android.Paths{}
- modules := android.SortedStringKeys(s)
+ modules := android.SortedKeys(s)
for _, module := range modules {
stubDexJarsByScope := s[module]
@@ -714,7 +714,7 @@
// the returned list.
func (s StubDexJarsByModule) StubDexJarsForScope(scope *HiddenAPIScope) android.Paths {
stubDexJars := android.Paths{}
- modules := android.SortedStringKeys(s)
+ modules := android.SortedKeys(s)
for _, module := range modules {
stubDexJarsByScope := s[module]
// Not every module will have the same set of
@@ -917,7 +917,7 @@
// bootDexJars returns the boot dex jar paths sorted by their keys.
func (b bootDexJarByModule) bootDexJars() android.Paths {
paths := android.Paths{}
- for _, k := range android.SortedStringKeys(b) {
+ for _, k := range android.SortedKeys(b) {
paths = append(paths, b[k])
}
return paths
@@ -927,7 +927,7 @@
// libraries if present.
func (b bootDexJarByModule) bootDexJarsWithoutCoverage() android.Paths {
paths := android.Paths{}
- for _, k := range android.SortedStringKeys(b) {
+ for _, k := range android.SortedKeys(b) {
if k == "jacocoagent" {
continue
}
@@ -1217,7 +1217,7 @@
// Encode the flags into the boot dex files.
encodedBootDexJarsByModule := bootDexJarByModule{}
outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
- for _, name := range android.SortedStringKeys(bootDexInfoByModule) {
+ for _, name := range android.SortedKeys(bootDexInfoByModule) {
bootDexInfo := bootDexInfoByModule[name]
unencodedDex := bootDexInfo.path
encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, bootDexInfo.minSdkVersion, outputDir)
@@ -1288,7 +1288,7 @@
// bootDexJars returns the boot dex jar paths sorted by their keys.
func (b bootDexInfoByModule) bootDexJars() android.Paths {
paths := android.Paths{}
- for _, m := range android.SortedStringKeys(b) {
+ for _, m := range android.SortedKeys(b) {
paths = append(paths, b[m].path)
}
return paths
diff --git a/java/java.go b/java/java.go
index 1df45b8..6a764cf 100644
--- a/java/java.go
+++ b/java/java.go
@@ -517,14 +517,8 @@
return normalizeJavaVersion(ctx, javaVersion)
} else if ctx.Device() {
return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
- } else if ctx.Config().TargetsJava17() {
- // Temporary experimental flag to be able to try and build with
- // java version 17 options. The flag, if used, just sets Java
- // 17 as the default version, leaving any components that
- // target an older version intact.
- return JAVA_VERSION_17
} else {
- return JAVA_VERSION_11
+ return JAVA_VERSION_17
}
}
@@ -1782,7 +1776,7 @@
rule.Build("metalava", "metalava merged")
compiledStubs := android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")
- al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), "android.jar")
+ al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
var flags javaBuilderFlags
flags.javaVersion = getStubsJavaVersion()
@@ -2844,7 +2838,7 @@
props = bazel.BazelTargetModuleProperties{
Rule_class: "kt_jvm_library",
- Bzl_load_location: "@rules_kotlin//kotlin:jvm_library.bzl",
+ Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl",
}
}
@@ -2939,14 +2933,15 @@
ktName := m.Name() + "_kt"
ktProps := bazel.BazelTargetModuleProperties{
Rule_class: "kt_jvm_library",
- Bzl_load_location: "@rules_kotlin//kotlin:jvm_library.bzl",
+ Bzl_load_location: "//build/bazel/rules/kotlin:kt_jvm_library.bzl",
}
ktAttrs := &javaLibraryAttributes{
Deps: deps,
javaCommonAttributes: &javaCommonAttributes{
- Srcs: commonAttrs.Srcs,
- Plugins: commonAttrs.Plugins,
- Javacopts: commonAttrs.Javacopts,
+ Srcs: commonAttrs.Srcs,
+ Plugins: commonAttrs.Plugins,
+ Javacopts: commonAttrs.Javacopts,
+ javaResourcesAttributes: commonAttrs.javaResourcesAttributes,
},
}
@@ -2954,19 +2949,6 @@
ktAttrs.javaCommonAttributes.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Common_srcs))
}
- // kt_jvm_library does not support resource_strip_prefix, if this attribute
- // is set, than javaResourcesAttributes needs to be set in the
- // javaCommonAttributes of the java_binary target
- if commonAttrs.javaResourcesAttributes != nil {
- if commonAttrs.javaResourcesAttributes.Resource_strip_prefix != nil {
- attrs.javaCommonAttributes = &javaCommonAttributes{
- javaResourcesAttributes: commonAttrs.javaResourcesAttributes,
- }
- } else {
- ktAttrs.javaCommonAttributes.javaResourcesAttributes = commonAttrs.javaResourcesAttributes
- }
- }
-
ctx.CreateBazelTargetModule(ktProps, android.CommonAttributes{Name: ktName}, ktAttrs)
attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + ktName}})
}
diff --git a/java/java_test.go b/java/java_test.go
index dc42e9e..68b749b 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -615,6 +615,13 @@
android.AssertPathRelativeToTopEquals(t, "baz dex jar build path", expectedDexJar, bazDexJar)
ctx.ModuleForTests("qux", "android_common").Rule("Cp")
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, fooModule.Module())[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
+ entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
+ entries = android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests("sdklib", "android_common").Module())[0]
+ android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_sdk_library_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0])
}
func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) {
@@ -2037,11 +2044,11 @@
}{
{
moduleName: "bar1",
- outputJarName: "bar1/android.jar",
+ outputJarName: "bar1/bar1.jar",
},
{
moduleName: "bar2",
- outputJarName: "bar2/android.jar",
+ outputJarName: "bar2/bar2.jar",
},
}
for _, c := range testcases {
@@ -2113,7 +2120,7 @@
},
{
moduleName: "bar2",
- classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/android.jar"},
+ classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
},
}
for _, c := range testcases {
@@ -2188,7 +2195,7 @@
},
{
moduleName: "bar2",
- staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/android.jar"},
+ staticLibJarNames: []string{"lib1.jar", "lib2.jar", "bar1/bar1.jar"},
},
}
for _, c := range testcases {
diff --git a/java/lint.go b/java/lint.go
index 07b9629..58b43df 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -96,9 +96,10 @@
}
type lintOutputs struct {
- html android.Path
- text android.Path
- xml android.Path
+ html android.Path
+ text android.Path
+ xml android.Path
+ referenceBaseline android.Path
depSets LintDepSets
}
@@ -159,6 +160,50 @@
}
}
+type lintDatabaseFiles struct {
+ apiVersionsModule string
+ apiVersionsCopiedName string
+ apiVersionsPrebuiltPath string
+ annotationsModule string
+ annotationCopiedName string
+ annotationPrebuiltpath string
+}
+
+var allLintDatabasefiles = map[android.SdkKind]lintDatabaseFiles{
+ android.SdkPublic: {
+ apiVersionsModule: "api_versions_public",
+ apiVersionsCopiedName: "api_versions_public.xml",
+ apiVersionsPrebuiltPath: "prebuilts/sdk/current/public/data/api-versions.xml",
+ annotationsModule: "sdk-annotations.zip",
+ annotationCopiedName: "annotations-public.zip",
+ annotationPrebuiltpath: "prebuilts/sdk/current/public/data/annotations.zip",
+ },
+ android.SdkSystem: {
+ apiVersionsModule: "api_versions_system",
+ apiVersionsCopiedName: "api_versions_system.xml",
+ apiVersionsPrebuiltPath: "prebuilts/sdk/current/system/data/api-versions.xml",
+ annotationsModule: "sdk-annotations-system.zip",
+ annotationCopiedName: "annotations-system.zip",
+ annotationPrebuiltpath: "prebuilts/sdk/current/system/data/annotations.zip",
+ },
+ android.SdkModule: {
+ apiVersionsModule: "api_versions_module_lib",
+ apiVersionsCopiedName: "api_versions_module_lib.xml",
+ apiVersionsPrebuiltPath: "prebuilts/sdk/current/module-lib/data/api-versions.xml",
+ annotationsModule: "sdk-annotations-module-lib.zip",
+ annotationCopiedName: "annotations-module-lib.zip",
+ annotationPrebuiltpath: "prebuilts/sdk/current/module-lib/data/annotations.zip",
+ },
+ android.SdkSystemServer: {
+ apiVersionsModule: "api_versions_system_server",
+ apiVersionsCopiedName: "api_versions_system_server.xml",
+ apiVersionsPrebuiltPath: "prebuilts/sdk/current/system-server/data/api-versions.xml",
+ annotationsModule: "sdk-annotations-system-server.zip",
+ annotationCopiedName: "annotations-system-server.zip",
+ annotationPrebuiltpath: "prebuilts/sdk/current/system-server/data/annotations.zip",
+ },
+}
+
func (l *linter) LintDepSets() LintDepSets {
return l.outputs.depSets
}
@@ -269,19 +314,25 @@
cmd.FlagWithInput("@",
android.PathForSource(ctx, "build/soong/java/lint_defaults.txt"))
- cmd.FlagForEachArg("--error_check ", l.extraMainlineLintErrors)
+ if l.compileSdkKind == android.SdkPublic {
+ cmd.FlagForEachArg("--error_check ", l.extraMainlineLintErrors)
+ } else {
+ // TODO(b/268261262): Remove this branch. We're demoting NewApi to a warning due to pre-existing issues that need to be fixed.
+ cmd.FlagForEachArg("--warning_check ", l.extraMainlineLintErrors)
+ }
cmd.FlagForEachArg("--disable_check ", l.properties.Lint.Disabled_checks)
cmd.FlagForEachArg("--warning_check ", l.properties.Lint.Warning_checks)
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
- if l.GetStrictUpdatabilityLinting() {
- // Verify the module does not baseline issues that endanger safe updatability.
- if baselinePath := l.getBaselineFilepath(ctx); baselinePath.Valid() {
- cmd.FlagWithInput("--baseline ", baselinePath.Path())
- cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks)
- }
- }
+ // TODO(b/193460475): Re-enable strict updatability linting
+ //if l.GetStrictUpdatabilityLinting() {
+ // // Verify the module does not baseline issues that endanger safe updatability.
+ // if baselinePath := l.getBaselineFilepath(ctx); baselinePath.Valid() {
+ // cmd.FlagWithInput("--baseline ", baselinePath.Path())
+ // cmd.FlagForEachArg("--disallowed_issues ", updatabilityChecks)
+ // }
+ //}
return lintPaths{
projectXML: projectXMLPath,
@@ -400,7 +451,7 @@
html := android.PathForModuleOut(ctx, "lint", "lint-report.html")
text := android.PathForModuleOut(ctx, "lint", "lint-report.txt")
xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml")
- baseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml")
+ referenceBaseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml")
depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
@@ -414,26 +465,17 @@
rule.Command().Text("mkdir -p").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
rule.Command().Text("rm -f").Output(html).Output(text).Output(xml)
- var apiVersionsName, apiVersionsPrebuilt string
- if l.compileSdkKind == android.SdkModule || l.compileSdkKind == android.SdkSystemServer {
- // When compiling an SDK module (or system server) we use the filtered
- // database because otherwise lint's
- // NewApi check produces too many false positives; This database excludes information
- // about classes created in mainline modules hence removing those false positives.
- apiVersionsName = "api_versions_public_filtered.xml"
- apiVersionsPrebuilt = "prebuilts/sdk/current/public/data/api-versions-filtered.xml"
- } else {
- apiVersionsName = "api_versions.xml"
- apiVersionsPrebuilt = "prebuilts/sdk/current/public/data/api-versions.xml"
+ files, ok := allLintDatabasefiles[l.compileSdkKind]
+ if !ok {
+ files = allLintDatabasefiles[android.SdkPublic]
}
-
var annotationsZipPath, apiVersionsXMLPath android.Path
if ctx.Config().AlwaysUsePrebuiltSdks() {
- annotationsZipPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/annotations.zip")
- apiVersionsXMLPath = android.PathForSource(ctx, apiVersionsPrebuilt)
+ annotationsZipPath = android.PathForSource(ctx, files.annotationPrebuiltpath)
+ apiVersionsXMLPath = android.PathForSource(ctx, files.apiVersionsPrebuiltPath)
} else {
- annotationsZipPath = copiedAnnotationsZipPath(ctx)
- apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx, apiVersionsName)
+ annotationsZipPath = copiedLintDatabaseFilesPath(ctx, files.annotationCopiedName)
+ apiVersionsXMLPath = copiedLintDatabaseFilesPath(ctx, files.apiVersionsCopiedName)
}
cmd := rule.Command()
@@ -472,7 +514,7 @@
cmd.FlagWithInput("--baseline ", lintBaseline.Path())
}
- cmd.FlagWithOutput("--write-reference-baseline ", baseline)
+ cmd.FlagWithOutput("--write-reference-baseline ", referenceBaseline)
cmd.Text("; EXITCODE=$?; ")
@@ -494,9 +536,10 @@
rule.Build("lint", "lint")
l.outputs = lintOutputs{
- html: html,
- text: text,
- xml: xml,
+ html: html,
+ text: text,
+ xml: xml,
+ referenceBaseline: referenceBaseline,
depSets: depSetsBuilder.Build(),
}
@@ -528,9 +571,10 @@
}
type lintSingleton struct {
- htmlZip android.WritablePath
- textZip android.WritablePath
- xmlZip android.WritablePath
+ htmlZip android.WritablePath
+ textZip android.WritablePath
+ xmlZip android.WritablePath
+ referenceBaselineZip android.WritablePath
}
func (l *lintSingleton) GenerateBuildActions(ctx android.SingletonContext) {
@@ -558,54 +602,39 @@
return
}
- apiVersionsDb := findModuleOrErr(ctx, "api_versions_public")
- if apiVersionsDb == nil {
- if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing module api_versions_public")
+ for _, sdk := range android.SortedKeys(allLintDatabasefiles) {
+ files := allLintDatabasefiles[sdk]
+ apiVersionsDb := findModuleOrErr(ctx, files.apiVersionsModule)
+ if apiVersionsDb == nil {
+ if !ctx.Config().AllowMissingDependencies() {
+ ctx.Errorf("lint: missing module api_versions_public")
+ }
+ return
}
- return
- }
- sdkAnnotations := findModuleOrErr(ctx, "sdk-annotations.zip")
- if sdkAnnotations == nil {
- if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing module sdk-annotations.zip")
+ sdkAnnotations := findModuleOrErr(ctx, files.annotationsModule)
+ if sdkAnnotations == nil {
+ if !ctx.Config().AllowMissingDependencies() {
+ ctx.Errorf("lint: missing module sdk-annotations.zip")
+ }
+ return
}
- return
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpIfChanged,
+ Input: android.OutputFileForModule(ctx, sdkAnnotations, ""),
+ Output: copiedLintDatabaseFilesPath(ctx, files.annotationCopiedName),
+ })
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpIfChanged,
+ Input: android.OutputFileForModule(ctx, apiVersionsDb, ".api_versions.xml"),
+ Output: copiedLintDatabaseFilesPath(ctx, files.apiVersionsCopiedName),
+ })
}
-
- filteredDb := findModuleOrErr(ctx, "api-versions-xml-public-filtered")
- if filteredDb == nil {
- if !ctx.Config().AllowMissingDependencies() {
- ctx.Errorf("lint: missing api-versions-xml-public-filtered")
- }
- return
- }
-
- ctx.Build(pctx, android.BuildParams{
- Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, sdkAnnotations, ""),
- Output: copiedAnnotationsZipPath(ctx),
- })
-
- ctx.Build(pctx, android.BuildParams{
- Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, apiVersionsDb, ".api_versions.xml"),
- Output: copiedAPIVersionsXmlPath(ctx, "api_versions.xml"),
- })
-
- ctx.Build(pctx, android.BuildParams{
- Rule: android.CpIfChanged,
- Input: android.OutputFileForModule(ctx, filteredDb, ""),
- Output: copiedAPIVersionsXmlPath(ctx, "api_versions_public_filtered.xml"),
- })
}
-func copiedAnnotationsZipPath(ctx android.PathContext) android.WritablePath {
- return android.PathForOutput(ctx, "lint", "annotations.zip")
-}
-
-func copiedAPIVersionsXmlPath(ctx android.PathContext, name string) android.WritablePath {
+func copiedLintDatabaseFilesPath(ctx android.PathContext, name string) android.WritablePath {
return android.PathForOutput(ctx, "lint", name)
}
@@ -658,12 +687,15 @@
l.xmlZip = android.PathForOutput(ctx, "lint-report-xml.zip")
zip(l.xmlZip, func(l *lintOutputs) android.Path { return l.xml })
- ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip)
+ l.referenceBaselineZip = android.PathForOutput(ctx, "lint-report-reference-baselines.zip")
+ zip(l.referenceBaselineZip, func(l *lintOutputs) android.Path { return l.referenceBaseline })
+
+ ctx.Phony("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
func (l *lintSingleton) MakeVars(ctx android.MakeVarsContext) {
if !ctx.Config().UnbundledBuild() {
- ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip)
+ ctx.DistForGoal("lint-check", l.htmlZip, l.textZip, l.xmlZip, l.referenceBaselineZip)
}
}
diff --git a/java/lint_test.go b/java/lint_test.go
index 62450d5..ec901aa 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -113,8 +113,9 @@
t.Error("did not use the correct file for baseline")
}
- if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check NewApi") {
- t.Error("should check NewApi errors")
+ if !strings.Contains(*sboxProto.Commands[0].Command, "--warning_check NewApi") {
+ // TODO(b/268261262): Change this to check for --error_check
+ t.Error("should check NewApi warnings")
}
if !strings.Contains(*sboxProto.Commands[0].Command, "--error_check SomeCheck") {
@@ -174,55 +175,83 @@
}
}
-func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
- bp := `
- java_library {
- name: "foo",
- srcs: [
- "a.java",
- ],
- static_libs: ["bar"],
- min_sdk_version: "29",
- sdk_version: "current",
- lint: {
- strict_updatability_linting: true,
- },
- }
-
- java_library {
- name: "bar",
- srcs: [
- "a.java",
- ],
- min_sdk_version: "29",
- sdk_version: "current",
- }
- `
- fs := android.MockFS{
- "lint-baseline.xml": nil,
- }
-
- result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
- RunTestWithBp(t, bp)
-
- foo := result.ModuleForTests("foo", "android_common")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command,
- "--baseline lint-baseline.xml --disallowed_issues NewApi") {
- t.Error("did not restrict baselining NewApi")
- }
-
- bar := result.ModuleForTests("bar", "android_common")
- sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command,
- "--baseline lint-baseline.xml --disallowed_issues NewApi") {
- t.Error("did not restrict baselining NewApi")
- }
-}
+// TODO(b/193460475): Re-enable this test
+//func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
+// bp := `
+// java_library {
+// name: "foo",
+// srcs: [
+// "a.java",
+// ],
+// static_libs: ["bar"],
+// min_sdk_version: "29",
+// sdk_version: "current",
+// lint: {
+// strict_updatability_linting: true,
+// },
+// }
+//
+// java_library {
+// name: "bar",
+// srcs: [
+// "a.java",
+// ],
+// min_sdk_version: "29",
+// sdk_version: "current",
+// }
+// `
+// fs := android.MockFS{
+// "lint-baseline.xml": nil,
+// }
+//
+// result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, fs.AddToFixture()).
+// RunTestWithBp(t, bp)
+//
+// foo := result.ModuleForTests("foo", "android_common")
+// sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
+// if !strings.Contains(*sboxProto.Commands[0].Command,
+// "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+// t.Error("did not restrict baselining NewApi")
+// }
+//
+// bar := result.ModuleForTests("bar", "android_common")
+// sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.Output("lint.sbox.textproto"))
+// if !strings.Contains(*sboxProto.Commands[0].Command,
+// "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+// t.Error("did not restrict baselining NewApi")
+// }
+//}
func TestJavaLintDatabaseSelectionFull(t *testing.T) {
- testCases := []string{
- "current", "core_platform", "system_current", "S", "30", "10000",
+ testCases := []struct {
+ sdk_version string
+ expected_file string
+ }{
+ {
+ "current",
+ "api_versions_public.xml",
+ }, {
+ "core_platform",
+ "api_versions_public.xml",
+ }, {
+ "system_current",
+ "api_versions_system.xml",
+ }, {
+ "module_current",
+ "api_versions_module_lib.xml",
+ }, {
+ "system_server_current",
+ "api_versions_system_server.xml",
+ }, {
+ "S",
+ "api_versions_public.xml",
+ }, {
+ "30",
+ "api_versions_public.xml",
+ }, {
+ "10000",
+ "api_versions_public.xml",
+ },
}
bp := `
java_library {
@@ -238,7 +267,7 @@
}
`
for _, testCase := range testCases {
- thisBp := strings.Replace(bp, "XXX", testCase, 1)
+ thisBp := strings.Replace(bp, "XXX", testCase.sdk_version, 1)
result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{
"30": {"foo"},
@@ -248,49 +277,8 @@
foo := result.ModuleForTests("foo", "android_common")
sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if strings.Contains(*sboxProto.Commands[0].Command,
- "/api_versions_public_filtered.xml") {
- t.Error("used public-filtered lint api database for case", testCase)
- }
- if !strings.Contains(*sboxProto.Commands[0].Command,
- "/api_versions.xml") {
+ if !strings.Contains(*sboxProto.Commands[0].Command, "/"+testCase.expected_file) {
t.Error("did not use full api database for case", testCase)
}
}
-
-}
-
-func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) {
- testCases := []string{
- "module_current", "system_server_current",
- }
- bp := `
- java_library {
- name: "foo",
- srcs: [
- "a.java",
- ],
- min_sdk_version: "29",
- sdk_version: "XXX",
- lint: {
- strict_updatability_linting: true,
- },
- }
-`
- for _, testCase := range testCases {
- thisBp := strings.Replace(bp, "XXX", testCase, 1)
- result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
- RunTestWithBp(t, thisBp)
-
- foo := result.ModuleForTests("foo", "android_common")
- sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
- if !strings.Contains(*sboxProto.Commands[0].Command,
- "/api_versions_public_filtered.xml") {
- t.Error("did not use public-filtered lint api database for case", testCase)
- }
- if strings.Contains(*sboxProto.Commands[0].Command,
- "/api_versions.xml") {
- t.Error("used full api database for case", testCase)
- }
- }
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 0ea3609..5824f08 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -414,7 +414,6 @@
frameworkBootImageConfig := defaultBootImageConfig(ctx)
bootFrameworkProfileRule(ctx, frameworkBootImageConfig)
b.generateBootImage(ctx, frameworkBootImageName, platformModules)
- b.generateBootImage(ctx, mainlineBootImageName, apexModules)
b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules)
dumpOatRules(ctx, frameworkBootImageConfig)
}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index c6acd55..206d995 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -264,7 +264,7 @@
}
// Sort the keys in order to make build.ninja stable
- for _, k := range android.SortedStringKeys(latest) {
+ for _, k := range android.SortedKeys(latest) {
info := latest[k]
name := PrebuiltApiModuleName(info.module, info.scope, "latest")
createApiModule(mctx, name, info.path)
@@ -284,7 +284,7 @@
}
}
// Create empty incompatibilities files for remaining modules
- for _, k := range android.SortedStringKeys(latest) {
+ for _, k := range android.SortedKeys(latest) {
if _, ok := incompatibilities[k]; !ok {
createEmptyFile(mctx, PrebuiltApiModuleName(latest[k].module+"-incompatibilities", latest[k].scope, "latest"))
}
diff --git a/java/sdk.go b/java/sdk.go
index b0da5af..855e559 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -57,14 +57,10 @@
return JAVA_VERSION_8
} else if sdk.FinalOrFutureInt() <= 31 {
return JAVA_VERSION_9
- } else if ctx.Config().TargetsJava17() {
- // Temporary experimental flag to be able to try and build with
- // java version 17 options. The flag, if used, just sets Java
- // 17 as the default version, leaving any components that
- // target an older version intact.
- return JAVA_VERSION_17
- } else {
+ } else if sdk.FinalOrFutureInt() <= 32 {
return JAVA_VERSION_11
+ } else {
+ return JAVA_VERSION_17
}
}
@@ -388,10 +384,7 @@
} else if ctx.Config().FrameworksBaseDirExists(ctx) && !ctx.Config().AlwaysUsePrebuiltSdks() {
cmd.Text("cat")
apiTxtFileModules := []string{
- "frameworks-base-api-current.txt",
- "frameworks-base-api-system-current.txt",
- "frameworks-base-api-module-lib-current.txt",
- "frameworks-base-api-system-server-current.txt",
+ "api_fingerprint",
}
count := 0
ctx.VisitAllModules(func(module android.Module) {
@@ -402,10 +395,10 @@
}
})
if count != len(apiTxtFileModules) {
- ctx.Errorf("Could not find all the expected API modules %v, found %d\n", apiTxtFileModules, count)
+ ctx.Errorf("Could not find expected API module %v, found %d\n", apiTxtFileModules, count)
return
}
- cmd.Text("| md5sum | cut -d' ' -f1 >").
+ cmd.Text(">").
Output(out)
} else {
// Unbundled build
diff --git a/java/sdk_library.go b/java/sdk_library.go
index c168c53..d2fbfd9 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1379,7 +1379,7 @@
})
// Make the set of components exported by this module available for use elsewhere.
- exportedComponentInfo := android.ExportedComponentsInfo{Components: android.SortedStringKeys(exportedComponents)}
+ exportedComponentInfo := android.ExportedComponentsInfo{Components: android.SortedKeys(exportedComponents)}
ctx.SetProvider(android.ExportedComponentsInfoProvider, exportedComponentInfo)
// Provide additional information for inclusion in an sdk's generated .info file.
diff --git a/java/testing.go b/java/testing.go
index e6f76e1..63d7dba 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -198,7 +198,7 @@
imports_sdk_version: "none",
imports_compile_dex: true,
}
- `, strings.Join(android.SortedStringKeys(apiLevel2Modules), `", "`))
+ `, strings.Join(android.SortedKeys(apiLevel2Modules), `", "`))
for release, modules := range apiLevel2Modules {
mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
diff --git a/licenses/OWNERS b/licenses/OWNERS
deleted file mode 100644
index fddfc48..0000000
--- a/licenses/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-per-file * = bbadour@google.com
-
diff --git a/linkerconfig/proto/OWNERS b/linkerconfig/proto/OWNERS
deleted file mode 100644
index 31f0460..0000000
--- a/linkerconfig/proto/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-kiyoungkim@google.com
-jiyong@google.com
-jooyung@google.com
diff --git a/multitree/api_imports.go b/multitree/api_imports.go
index 6674d3e..07ec7bc 100644
--- a/multitree/api_imports.go
+++ b/multitree/api_imports.go
@@ -40,8 +40,9 @@
}
type apiImportsProperties struct {
- Shared_libs []string // List of C shared libraries from API surfaces
- Header_libs []string // List of C header libraries from API surfaces
+ Shared_libs []string // List of C shared libraries from API surfaces
+ Header_libs []string // List of C header libraries from API surfaces
+ Apex_shared_libs []string // List of C shared libraries with APEX stubs
}
// 'api_imports' is a module which describes modules available from API surfaces.
@@ -60,7 +61,7 @@
}
type ApiImportInfo struct {
- SharedLibs, HeaderLibs map[string]string
+ SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
}
var ApiImportsProvider = blueprint.NewMutatorProvider(ApiImportInfo{}, "deps")
@@ -78,10 +79,12 @@
sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
+ apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
ctx.SetProvider(ApiImportsProvider, ApiImportInfo{
- SharedLibs: sharedLibs,
- HeaderLibs: headerLibs,
+ SharedLibs: sharedLibs,
+ HeaderLibs: headerLibs,
+ ApexSharedLibs: apexSharedLibs,
})
}
diff --git a/python/python.go b/python/python.go
index 18e5b68..0ae7b36 100644
--- a/python/python.go
+++ b/python/python.go
@@ -532,7 +532,7 @@
if len(relativeRootMap) > 0 {
// in order to keep stable order of soong_zip params, we sort the keys here.
- roots := android.SortedStringKeys(relativeRootMap)
+ roots := android.SortedKeys(relativeRootMap)
// Use -symlinks=false so that the symlinks in the bazel output directory are followed
parArgs := []string{"-symlinks=false"}
diff --git a/rust/builder.go b/rust/builder.go
index a2f1238..5566451 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -134,6 +134,8 @@
func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
+ flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
+
return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib")
}
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 186e571..ae783e8 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -30,6 +30,7 @@
"armv8-a-branchprot": []string{},
"armv8-2a": []string{},
"armv8-2a-dotprod": []string{},
+ "armv9-a": []string{},
}
)
diff --git a/rust/config/global.go b/rust/config/global.go
index 0dface4..9375022 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -54,6 +54,7 @@
// TODO (b/267698452): Temporary workaround until the "no unstable
// features" policy is enforced.
"-A stable-features",
+ "-Zdylib-lto",
}
deviceGlobalRustFlags = []string{
diff --git a/rust/rust.go b/rust/rust.go
index e4cf671..8a13ba3 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -62,11 +62,11 @@
}
type BaseProperties struct {
- AndroidMkRlibs []string
- AndroidMkDylibs []string
- AndroidMkProcMacroLibs []string
- AndroidMkSharedLibs []string
- AndroidMkStaticLibs []string
+ AndroidMkRlibs []string `blueprint:"mutated"`
+ AndroidMkDylibs []string `blueprint:"mutated"`
+ AndroidMkProcMacroLibs []string `blueprint:"mutated"`
+ AndroidMkSharedLibs []string `blueprint:"mutated"`
+ AndroidMkStaticLibs []string `blueprint:"mutated"`
ImageVariationPrefix string `blueprint:"mutated"`
VndkVersion string `blueprint:"mutated"`
diff --git a/scripts/OWNERS b/scripts/OWNERS
deleted file mode 100644
index 7b003fd..0000000
--- a/scripts/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
-per-file construct_context.py = ngeoffray@google.com,calin@google.com,skvadrik@google.com
-per-file conv_linker_config.py = kiyoungkim@google.com, jiyong@google.com, jooyung@google.com
-per-file gen_ndk*.sh,gen_java*.sh = sophiez@google.com, allenhair@google.com
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index ce461b1..869fd3f 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -12,6 +12,7 @@
java\.lang\.invoke
java\.lang\.ref
java\.lang\.reflect
+java\.lang\.runtime
java\.math
java\.net
java\.nio
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index 3d7c0fa..2ce0ee2 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -28,14 +28,15 @@
def Proto(args):
pb = linker_config_pb2.LinkerConfig()
- for input in args.source.split(':'):
- json_content = ''
- with open(input) as f:
- for line in f:
- if not line.lstrip().startswith('//'):
- json_content += line
- obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
- ParseDict(obj, pb)
+ if args.source:
+ for input in args.source.split(':'):
+ json_content = ''
+ with open(input) as f:
+ for line in f:
+ if not line.lstrip().startswith('//'):
+ json_content += line
+ obj = json.loads(json_content, object_pairs_hook=collections.OrderedDict)
+ ParseDict(obj, pb)
with open(args.output, 'wb') as f:
f.write(pb.SerializeToString())
@@ -104,7 +105,7 @@
parser_proto.add_argument(
'-s',
'--source',
- required=True,
+ nargs='?',
type=str,
help='Colon-separated list of linker configuration files in JSON.')
parser_proto.add_argument(
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index efb97be..d81635e 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -27,11 +27,6 @@
// fixtureAddPlatformBootclasspathForBootclasspathFragment adds a platform_bootclasspath module that
// references the bootclasspath fragment.
func fixtureAddPlatformBootclasspathForBootclasspathFragment(apex, fragment string) android.FixturePreparer {
- return fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(apex, fragment, "")
-}
-
-// fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra is the same as above, but also adds extra fragments.
-func fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(apex, fragment, extraFragments string) android.FixturePreparer {
return android.GroupFixturePreparers(
// Add a platform_bootclasspath module.
android.FixtureAddTextFile("frameworks/base/boot/Android.bp", fmt.Sprintf(`
@@ -42,10 +37,9 @@
apex: "%s",
module: "%s",
},
- %s
],
}
- `, apex, fragment, extraFragments)),
+ `, apex, fragment)),
android.FixtureAddFile("frameworks/base/config/boot-profile.txt", nil),
android.FixtureAddFile("frameworks/base/config/boot-image-profile.txt", nil),
android.FixtureAddFile("build/soong/scripts/check_boot_jars/package_allowed_list.txt", nil),
@@ -85,11 +79,9 @@
}),
// Add a platform_bootclasspath that depends on the fragment.
- fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(
- "com.android.art", "mybootclasspathfragment", java.ApexBootJarFragmentsForPlatformBootclasspath),
+ fixtureAddPlatformBootclasspathForBootclasspathFragment("com.android.art", "mybootclasspathfragment"),
java.PrepareForBootImageConfigTest,
- java.PrepareApexBootJarConfigsAndModules,
android.FixtureWithRootAndroidBp(`
sdk {
name: "mysdk",
@@ -204,15 +196,9 @@
snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) {
// Make sure that the boot jars package check rule includes the dex jars retrieved from the prebuilt apex.
checkBootJarsPackageCheckRule(t, result,
- append(
- []string{
- "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core1.jar",
- "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core2.jar",
- "out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
- },
- java.ApexBootJarDexJarPaths...,
- )...,
- )
+ "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core1.jar",
+ "out/soong/.intermediates/prebuilts/apex/com.android.art.deapexer/android_common/deapexer/javalib/core2.jar",
+ "out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar")
java.CheckMutatedArtBootImageConfig(t, result, "out/soong/.intermediates/snapshot/mybootclasspathfragment/android_common_com.android.art/meta_lic")
java.CheckMutatedFrameworkBootImageConfig(t, result, "out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/meta_lic")
}),
@@ -236,15 +222,9 @@
// Make sure that the boot jars package check rule includes the dex jars created from the source.
checkBootJarsPackageCheckRule(t, result,
- append(
- []string{
- "out/soong/.intermediates/core1/android_common_apex10000/aligned/core1.jar",
- "out/soong/.intermediates/core2/android_common_apex10000/aligned/core2.jar",
- "out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
- },
- java.ApexBootJarDexJarPaths...,
- )...,
- )
+ "out/soong/.intermediates/core1/android_common_apex10000/aligned/core1.jar",
+ "out/soong/.intermediates/core2/android_common_apex10000/aligned/core2.jar",
+ "out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar")
}
// checkBootJarsPackageCheckRule checks that the supplied module is an input to the boot jars
diff --git a/sdk/update.go b/sdk/update.go
index f50439c..0820d62 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -565,7 +565,7 @@
if m.deps != nil {
writeObjectPair("@deps", m.deps)
}
- for _, k := range android.SortedStringKeys(m.memberSpecific) {
+ for _, k := range android.SortedKeys(m.memberSpecific) {
v := m.memberSpecific[k]
writeObjectPair(k, v)
}
@@ -626,7 +626,7 @@
getModuleInfo(memberVariantDep.variant)
}
- for _, memberName := range android.SortedStringKeys(name2Info) {
+ for _, memberName := range android.SortedKeys(name2Info) {
info := name2Info[memberName]
modules = append(modules, info)
}
@@ -1708,7 +1708,7 @@
}
// Create the image variant info in a fixed order.
- for _, imageVariantName := range android.SortedStringKeys(variantsByImage) {
+ for _, imageVariantName := range android.SortedKeys(variantsByImage) {
variants := variantsByImage[imageVariantName]
archInfo.imageVariantInfos = append(archInfo.imageVariantInfos, newImageVariantSpecificInfo(ctx, imageVariantName, variantPropertiesFactory, variants))
}
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 878b4a1..1ff1b5b 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -21,6 +21,68 @@
fi
}
+# Tests that, if bp2build reruns due to a blueprint file changing, that
+# BUILD files whose contents are unchanged are not regenerated.
+function test_bp2build_unchanged {
+ setup
+
+ mkdir -p pkg
+ touch pkg/x.txt
+ cat > pkg/Android.bp <<'EOF'
+filegroup {
+ name: "x",
+ srcs: ["x.txt"],
+ bazel_module: {bp2build_available: true},
+ }
+EOF
+
+ run_soong bp2build
+ local -r buildfile_mtime1=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
+ local -r marker_mtime1=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+
+ # Force bp2build to rerun by updating the timestamp of a blueprint file.
+ touch pkg/Android.bp
+
+ run_soong bp2build
+ local -r buildfile_mtime2=$(stat -c "%y" out/soong/bp2build/pkg/BUILD.bazel)
+ local -r marker_mtime2=$(stat -c "%y" out/soong/bp2build_workspace_marker)
+
+ if [[ "$marker_mtime1" == "$marker_mtime2" ]]; then
+ fail "Expected bp2build marker file to change"
+ fi
+ if [[ "$buildfile_mtime1" != "$buildfile_mtime2" ]]; then
+ fail "BUILD.bazel was updated even though contents are same"
+ fi
+}
+
+# Tests that blueprint files that are deleted are not present when the
+# bp2build tree is regenerated.
+function test_bp2build_deleted_blueprint {
+ setup
+
+ mkdir -p pkg
+ touch pkg/x.txt
+ cat > pkg/Android.bp <<'EOF'
+filegroup {
+ name: "x",
+ srcs: ["x.txt"],
+ bazel_module: {bp2build_available: true},
+ }
+EOF
+
+ run_soong bp2build
+ if [[ ! -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
+ fail "Expected pkg/BUILD.bazel to be generated"
+ fi
+
+ rm pkg/Android.bp
+
+ run_soong bp2build
+ if [[ -e "./out/soong/bp2build/pkg/BUILD.bazel" ]]; then
+ fail "Expected pkg/BUILD.bazel to be deleted"
+ fi
+}
+
function test_bp2build_null_build_with_globs {
setup
diff --git a/tests/persistent_bazel_test.sh b/tests/persistent_bazel_test.sh
new file mode 100755
index 0000000..4e2982a
--- /dev/null
+++ b/tests/persistent_bazel_test.sh
@@ -0,0 +1,83 @@
+#!/bin/bash -eu
+
+# Copyright (C) 2023 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.
+
+set -o pipefail
+
+source "$(dirname "$0")/lib.sh"
+
+# This test verifies that adding USE_PERSISTENT_BAZEL creates a Bazel process
+# that outlasts the build process.
+# This test should only be run in sandboxed environments (because this test
+# verifies a Bazel process using global process list, and may spawn lingering
+# Bazel processes).
+function test_persistent_bazel {
+ setup
+
+ # Ensure no existing Bazel process.
+ if [[ -e out/bazel/output/server/server.pid.txt ]]; then
+ kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
+ if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
+ fail "Error killing pre-setup bazel"
+ fi
+ fi
+
+ USE_PERSISTENT_BAZEL=1 run_soong nothing
+
+ if ! kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
+ fail "Persistent bazel process expected, but not found after first build"
+ fi
+ BAZEL_PID=$(cat out/bazel/output/server/server.pid.txt)
+
+ USE_PERSISTENT_BAZEL=1 run_soong nothing
+
+ if ! kill -0 $BAZEL_PID 2>/dev/null ; then
+ fail "Bazel pid $BAZEL_PID was killed after second build"
+ fi
+
+ kill $BAZEL_PID 2>/dev/null
+ if ! kill -0 $BAZEL_PID 2>/dev/null ; then
+ fail "Error killing bazel on shutdown"
+ fi
+}
+
+# Verifies that USE_PERSISTENT_BAZEL mode operates as expected in the event
+# that there are Bazel failures.
+function test_bazel_failure {
+ setup
+
+ # Ensure no existing Bazel process.
+ if [[ -e out/bazel/output/server/server.pid.txt ]]; then
+ kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
+ if kill -0 $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null ; then
+ fail "Error killing pre-setup bazel"
+ fi
+ fi
+
+ # Introduce a syntax error in a BUILD file which is used in every build
+ # (Note this is a BUILD file which is copied as part of test setup, so this
+ # has no effect on sources outside of this test.
+ rm -rf build/bazel/rules
+
+ USE_PERSISTENT_BAZEL=1 run_soong nothing 1>out/failurelog.txt 2>&1 && fail "Expected build failure" || true
+
+ if ! grep -sq "'build/bazel/rules' is not a package" out/failurelog.txt ; then
+ fail "Expected error to contain 'build/bazel/rules' is not a package, instead got:\n$(cat out/failurelog.txt)"
+ fi
+
+ kill $(cat out/bazel/output/server/server.pid.txt) 2>/dev/null || true
+}
+
+scan_and_run_tests
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index da84049..a762952 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -7,6 +7,7 @@
"$TOP/build/soong/tests/bootstrap_test.sh"
"$TOP/build/soong/tests/mixed_mode_test.sh"
"$TOP/build/soong/tests/bp2build_bazel_test.sh"
+"$TOP/build/soong/tests/persistent_bazel_test.sh"
"$TOP/build/soong/tests/soong_test.sh"
"$TOP/build/bazel/ci/rbc_regression_test.sh" aosp_arm64-userdebug
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index 7a8fca9..b79754c 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -50,6 +50,7 @@
"cleanbuild.go",
"config.go",
"context.go",
+ "staging_snapshot.go",
"dumpvars.go",
"environment.go",
"exec.go",
@@ -70,10 +71,11 @@
"cleanbuild_test.go",
"config_test.go",
"environment_test.go",
+ "proc_sync_test.go",
"rbe_test.go",
+ "staging_snapshot_test.go",
"upload_test.go",
"util_test.go",
- "proc_sync_test.go",
],
darwin: {
srcs: [
diff --git a/ui/build/build.go b/ui/build/build.go
index d49a754..edc595d 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -102,9 +102,9 @@
// Whether to include the kati-generated ninja file in the combined ninja.
RunKatiNinja = 1 << iota
// Whether to run ninja on the combined ninja.
- RunNinja = 1 << iota
- RunBuildTests = 1 << iota
- RunAll = RunProductConfig | RunSoong | RunKati | RunKatiNinja | RunNinja
+ RunNinja = 1 << iota
+ RunDistActions = 1 << iota
+ RunBuildTests = 1 << iota
)
// checkBazelMode fails the build if there are conflicting arguments for which bazel
@@ -322,34 +322,42 @@
runNinjaForBuild(ctx, config)
}
+
+ if what&RunDistActions != 0 {
+ runDistActions(ctx, config)
+ }
}
func evaluateWhatToRun(config Config, verboseln func(v ...interface{})) int {
//evaluate what to run
- what := RunAll
+ what := 0
if config.Checkbuild() {
what |= RunBuildTests
}
- if config.SkipConfig() {
+ if !config.SkipConfig() {
+ what |= RunProductConfig
+ } else {
verboseln("Skipping Config as requested")
- what = what &^ RunProductConfig
}
- if config.SkipKati() {
- verboseln("Skipping Kati as requested")
- what = what &^ RunKati
- }
- if config.SkipKatiNinja() {
- verboseln("Skipping use of Kati ninja as requested")
- what = what &^ RunKatiNinja
- }
- if config.SkipSoong() {
+ if !config.SkipSoong() {
+ what |= RunSoong
+ } else {
verboseln("Skipping use of Soong as requested")
- what = what &^ RunSoong
}
-
- if config.SkipNinja() {
+ if !config.SkipKati() {
+ what |= RunKati
+ } else {
+ verboseln("Skipping Kati as requested")
+ }
+ if !config.SkipKatiNinja() {
+ what |= RunKatiNinja
+ } else {
+ verboseln("Skipping use of Kati ninja as requested")
+ }
+ if !config.SkipNinja() {
+ what |= RunNinja
+ } else {
verboseln("Skipping Ninja as requested")
- what = what &^ RunNinja
}
if !config.SoongBuildInvocationNeeded() {
@@ -361,6 +369,11 @@
what = what &^ RunNinja
what = what &^ RunKati
}
+
+ if config.Dist() {
+ what |= RunDistActions
+ }
+
return what
}
@@ -419,3 +432,9 @@
}
}()
}
+
+// Actions to run on every build where 'dist' is in the actions.
+// Be careful, anything added here slows down EVERY CI build
+func runDistActions(ctx Context, config Config) {
+ runStagingSnapshot(ctx, config)
+}
diff --git a/ui/build/config.go b/ui/build/config.go
index 73e2c45..b5ee440 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -1568,6 +1568,10 @@
return c.Environment().IsEnvTrue("BUILD_BROKEN_DISABLE_BAZEL")
}
+func (c *configImpl) IsPersistentBazelEnabled() bool {
+ return c.Environment().IsEnvTrue("USE_PERSISTENT_BAZEL")
+}
+
func (c *configImpl) BazelModulesForceEnabledByFlag() string {
return c.bazelForceEnabledModules
}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index dab1a9b..28f3c38 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -23,10 +23,16 @@
"strings"
"time"
+ "android/soong/shared"
"android/soong/ui/metrics"
"android/soong/ui/status"
)
+const (
+ // File containing the environment state when ninja is executed
+ ninjaEnvFileName = "ninja.environment"
+)
+
// Constructs and runs the Ninja command line with a restricted set of
// environment variables. It's important to restrict the environment Ninja runs
// for hermeticity reasons, and to avoid spurious rebuilds.
@@ -186,6 +192,21 @@
ctx.Verbosef(" %s", envVar)
}
+ // Write the env vars available during ninja execution to a file
+ ninjaEnvVars := cmd.Environment.AsMap()
+ data, err := shared.EnvFileContents(ninjaEnvVars)
+ if err != nil {
+ ctx.Panicf("Could not parse environment variables for ninja run %s", err)
+ }
+ // Write the file in every single run. This is fine because
+ // 1. It is not a dep of Soong analysis, so will not retrigger Soong analysis.
+ // 2. Is is fairly lightweight (~1Kb)
+ ninjaEnvVarsFile := shared.JoinPath(config.SoongOutDir(), ninjaEnvFileName)
+ err = os.WriteFile(ninjaEnvVarsFile, data, 0666)
+ if err != nil {
+ ctx.Panicf("Could not write ninja environment file %s", err)
+ }
+
// Poll the Ninja log for updates regularly based on the heartbeat
// frequency. If it isn't updated enough, then we want to surface the
// possibility that Ninja is stuck, to the user.
diff --git a/ui/build/soong.go b/ui/build/soong.go
index e6543ec..a5a3263 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -21,6 +21,7 @@
"strconv"
"strings"
+ "android/soong/bazel"
"android/soong/ui/metrics"
"android/soong/ui/status"
@@ -268,6 +269,9 @@
if config.bazelStagingMode {
mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-mode-staging")
}
+ if config.IsPersistentBazelEnabled() {
+ mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--use-bazel-proxy")
+ }
if len(config.bazelForceEnabledModules) > 0 {
mainSoongBuildExtraArgs = append(mainSoongBuildExtraArgs, "--bazel-force-enabled-modules="+config.bazelForceEnabledModules)
}
@@ -497,6 +501,12 @@
ctx.BeginTrace(metrics.RunSoong, name)
defer ctx.EndTrace()
+ if config.IsPersistentBazelEnabled() {
+ bazelProxy := bazel.NewProxyServer(ctx.Logger, config.OutDir(), filepath.Join(config.SoongOutDir(), "workspace"))
+ bazelProxy.Start()
+ defer bazelProxy.Close()
+ }
+
fifo := filepath.Join(config.OutDir(), ".ninja_fifo")
nr := status.NewNinjaReader(ctx, ctx.Status.StartTool(), fifo)
defer nr.Close()
diff --git a/ui/build/staging_snapshot.go b/ui/build/staging_snapshot.go
new file mode 100644
index 0000000..377aa64
--- /dev/null
+++ b/ui/build/staging_snapshot.go
@@ -0,0 +1,246 @@
+// Copyright 2023 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 build
+
+import (
+ "crypto/sha1"
+ "encoding/hex"
+ "encoding/json"
+ "io"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "sort"
+ "strings"
+
+ "android/soong/shared"
+ "android/soong/ui/metrics"
+)
+
+// Metadata about a staged file
+type fileEntry struct {
+ Name string `json:"name"`
+ Mode fs.FileMode `json:"mode"`
+ Size int64 `json:"size"`
+ Sha1 string `json:"sha1"`
+}
+
+func fileEntryEqual(a fileEntry, b fileEntry) bool {
+ return a.Name == b.Name && a.Mode == b.Mode && a.Size == b.Size && a.Sha1 == b.Sha1
+}
+
+func sha1_hash(filename string) (string, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return "", err
+ }
+ defer f.Close()
+
+ h := sha1.New()
+ if _, err := io.Copy(h, f); err != nil {
+ return "", err
+ }
+
+ return hex.EncodeToString(h.Sum(nil)), nil
+}
+
+// Subdirs of PRODUCT_OUT to scan
+var stagingSubdirs = []string{
+ "apex",
+ "cache",
+ "coverage",
+ "data",
+ "debug_ramdisk",
+ "fake_packages",
+ "installer",
+ "oem",
+ "product",
+ "ramdisk",
+ "recovery",
+ "root",
+ "sysloader",
+ "system",
+ "system_dlkm",
+ "system_ext",
+ "system_other",
+ "testcases",
+ "test_harness_ramdisk",
+ "vendor",
+ "vendor_debug_ramdisk",
+ "vendor_kernel_ramdisk",
+ "vendor_ramdisk",
+}
+
+// Return an array of stagedFileEntrys, one for each file in the staging directories inside
+// productOut
+func takeStagingSnapshot(ctx Context, productOut string, subdirs []string) ([]fileEntry, error) {
+ var outer_err error
+ if !strings.HasSuffix(productOut, "/") {
+ productOut += "/"
+ }
+ result := []fileEntry{}
+ for _, subdir := range subdirs {
+ filepath.WalkDir(productOut+subdir,
+ func(filename string, dirent fs.DirEntry, err error) error {
+ // Ignore errors. The most common one is that one of the subdirectories
+ // hasn't been built, in which case we just report it as empty.
+ if err != nil {
+ ctx.Verbosef("scanModifiedStagingOutputs error: %s", err)
+ return nil
+ }
+ if dirent.Type().IsRegular() {
+ fileInfo, _ := dirent.Info()
+ relative := strings.TrimPrefix(filename, productOut)
+ sha, err := sha1_hash(filename)
+ if err != nil {
+ outer_err = err
+ }
+ result = append(result, fileEntry{
+ Name: relative,
+ Mode: fileInfo.Mode(),
+ Size: fileInfo.Size(),
+ Sha1: sha,
+ })
+ }
+ return nil
+ })
+ }
+
+ sort.Slice(result, func(l, r int) bool { return result[l].Name < result[r].Name })
+
+ return result, outer_err
+}
+
+// Read json into an array of fileEntry. On error return empty array.
+func readJson(filename string) ([]fileEntry, error) {
+ buf, err := os.ReadFile(filename)
+ if err != nil {
+ // Not an error, just missing, which is empty.
+ return []fileEntry{}, nil
+ }
+
+ var result []fileEntry
+ err = json.Unmarshal(buf, &result)
+ if err != nil {
+ // Bad formatting. This is an error
+ return []fileEntry{}, err
+ }
+
+ return result, nil
+}
+
+// Write obj to filename.
+func writeJson(filename string, obj interface{}) error {
+ buf, err := json.MarshalIndent(obj, "", " ")
+ if err != nil {
+ return err
+ }
+
+ return os.WriteFile(filename, buf, 0660)
+}
+
+type snapshotDiff struct {
+ Added []string `json:"added"`
+ Changed []string `json:"changed"`
+ Removed []string `json:"removed"`
+}
+
+// Diff the two snapshots, returning a snapshotDiff.
+func diffSnapshots(previous []fileEntry, current []fileEntry) snapshotDiff {
+ result := snapshotDiff{
+ Added: []string{},
+ Changed: []string{},
+ Removed: []string{},
+ }
+
+ found := make(map[string]bool)
+
+ prev := make(map[string]fileEntry)
+ for _, pre := range previous {
+ prev[pre.Name] = pre
+ }
+
+ for _, cur := range current {
+ pre, ok := prev[cur.Name]
+ found[cur.Name] = true
+ // Added
+ if !ok {
+ result.Added = append(result.Added, cur.Name)
+ continue
+ }
+ // Changed
+ if !fileEntryEqual(pre, cur) {
+ result.Changed = append(result.Changed, cur.Name)
+ }
+ }
+
+ // Removed
+ for _, pre := range previous {
+ if !found[pre.Name] {
+ result.Removed = append(result.Removed, pre.Name)
+ }
+ }
+
+ // Sort the results
+ sort.Strings(result.Added)
+ sort.Strings(result.Changed)
+ sort.Strings(result.Removed)
+
+ return result
+}
+
+// Write a json files to dist:
+// - A list of which files have changed in this build.
+//
+// And record in out/soong:
+// - A list of all files in the staging directories, including their hashes.
+func runStagingSnapshot(ctx Context, config Config) {
+ ctx.BeginTrace(metrics.RunSoong, "runStagingSnapshot")
+ defer ctx.EndTrace()
+
+ snapshotFilename := shared.JoinPath(config.SoongOutDir(), "staged_files.json")
+
+ // Read the existing snapshot file. If it doesn't exist, this is a full
+ // build, so all files will be treated as new.
+ previous, err := readJson(snapshotFilename)
+ if err != nil {
+ ctx.Fatal(err)
+ return
+ }
+
+ // Take a snapshot of the current out directory
+ current, err := takeStagingSnapshot(ctx, config.ProductOut(), stagingSubdirs)
+ if err != nil {
+ ctx.Fatal(err)
+ return
+ }
+
+ // Diff the snapshots
+ diff := diffSnapshots(previous, current)
+
+ // Write the diff (use RealDistDir, not one that might have been faked for bazel)
+ err = writeJson(shared.JoinPath(config.RealDistDir(), "modified_files.json"), diff)
+ if err != nil {
+ ctx.Fatal(err)
+ return
+ }
+
+ // Update the snapshot
+ err = writeJson(snapshotFilename, current)
+ if err != nil {
+ ctx.Fatal(err)
+ return
+ }
+}
diff --git a/ui/build/staging_snapshot_test.go b/ui/build/staging_snapshot_test.go
new file mode 100644
index 0000000..7ac5443
--- /dev/null
+++ b/ui/build/staging_snapshot_test.go
@@ -0,0 +1,188 @@
+// Copyright 2023 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 build
+
+import (
+ "os"
+ "path/filepath"
+ "reflect"
+ "testing"
+)
+
+func assertDeepEqual(t *testing.T, expected interface{}, actual interface{}) {
+ if !reflect.DeepEqual(actual, expected) {
+ t.Fatalf("expected:\n %#v\n actual:\n %#v", expected, actual)
+ }
+}
+
+// Make a temp directory containing the supplied contents
+func makeTempDir(files []string, directories []string, symlinks []string) string {
+ temp, _ := os.MkdirTemp("", "soon_staging_snapshot_test_")
+
+ for _, file := range files {
+ os.MkdirAll(temp+"/"+filepath.Dir(file), 0700)
+ os.WriteFile(temp+"/"+file, []byte(file), 0600)
+ }
+
+ for _, dir := range directories {
+ os.MkdirAll(temp+"/"+dir, 0770)
+ }
+
+ for _, symlink := range symlinks {
+ os.MkdirAll(temp+"/"+filepath.Dir(symlink), 0770)
+ os.Symlink(temp, temp+"/"+symlink)
+ }
+
+ return temp
+}
+
+// If this is a clean build, we won't have any preexisting files, make sure we get back an empty
+// list and not errors.
+func TestEmptyOut(t *testing.T) {
+ ctx := testContext()
+
+ temp := makeTempDir(nil, nil, nil)
+ defer os.RemoveAll(temp)
+
+ actual, _ := takeStagingSnapshot(ctx, temp, []string{"a", "e", "g"})
+
+ expected := []fileEntry{}
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure only the listed directories are picked up, and only regular files
+func TestNoExtraSubdirs(t *testing.T) {
+ ctx := testContext()
+
+ temp := makeTempDir([]string{"a/b", "a/c", "d", "e/f"}, []string{"g/h"}, []string{"e/symlink"})
+ defer os.RemoveAll(temp)
+
+ actual, _ := takeStagingSnapshot(ctx, temp, []string{"a", "e", "g"})
+
+ expected := []fileEntry{
+ {"a/b", 0600, 3, "3ec69c85a4ff96830024afeef2d4e512181c8f7b"},
+ {"a/c", 0600, 3, "592d70e4e03ee6f6780c71b0bf3b9608dbf1e201"},
+ {"e/f", 0600, 3, "9e164bef74aceede0974b857170100409efe67f1"},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles empty lists
+func TestDiffEmpty(t *testing.T) {
+ actual := diffSnapshots(nil, []fileEntry{})
+
+ expected := snapshotDiff{
+ Added: []string{},
+ Changed: []string{},
+ Removed: []string{},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles adding
+func TestDiffAdd(t *testing.T) {
+ actual := diffSnapshots([]fileEntry{
+ {"a", 0600, 1, "1234"},
+ }, []fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "5678"},
+ })
+
+ expected := snapshotDiff{
+ Added: []string{"b"},
+ Changed: []string{},
+ Removed: []string{},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles changing mode
+func TestDiffChangeMode(t *testing.T) {
+ actual := diffSnapshots([]fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "5678"},
+ }, []fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0600, 2, "5678"},
+ })
+
+ expected := snapshotDiff{
+ Added: []string{},
+ Changed: []string{"b"},
+ Removed: []string{},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles changing size
+func TestDiffChangeSize(t *testing.T) {
+ actual := diffSnapshots([]fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "5678"},
+ }, []fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 3, "5678"},
+ })
+
+ expected := snapshotDiff{
+ Added: []string{},
+ Changed: []string{"b"},
+ Removed: []string{},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles changing contents
+func TestDiffChangeContents(t *testing.T) {
+ actual := diffSnapshots([]fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "5678"},
+ }, []fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "aaaa"},
+ })
+
+ expected := snapshotDiff{
+ Added: []string{},
+ Changed: []string{"b"},
+ Removed: []string{},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}
+
+// Make sure diff handles removing
+func TestDiffRemove(t *testing.T) {
+ actual := diffSnapshots([]fileEntry{
+ {"a", 0600, 1, "1234"},
+ {"b", 0700, 2, "5678"},
+ }, []fileEntry{
+ {"a", 0600, 1, "1234"},
+ })
+
+ expected := snapshotDiff{
+ Added: []string{},
+ Changed: []string{},
+ Removed: []string{"b"},
+ }
+
+ assertDeepEqual(t, expected, actual)
+}