Merge "Update clang version to clang-r487747"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 7ce0d9b..89c2d19 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -199,6 +199,7 @@
"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/aapt2": Bp2BuildDefaultTrue,
"frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively,
+ "frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/gui": Bp2BuildDefaultTrue,
@@ -257,30 +258,32 @@
"libnativehelper": Bp2BuildDefaultTrueRecursively,
- "packages/apps/DevCamera": Bp2BuildDefaultTrue,
- "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
- "packages/apps/Protips": Bp2BuildDefaultTrue,
- "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
- "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
- "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb": Bp2BuildDefaultTrue,
- "packages/modules/adb/apex": Bp2BuildDefaultTrue,
- "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
- "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
- "packages/screensavers/Basic": Bp2BuildDefaultTrue,
- "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
+ "packages/apps/DevCamera": Bp2BuildDefaultTrue,
+ "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
+ "packages/apps/Protips": Bp2BuildDefaultTrue,
+ "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
+ "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb": Bp2BuildDefaultTrue,
+ "packages/modules/adb/apex": Bp2BuildDefaultTrue,
+ "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
+ "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
+ "packages/screensavers/Basic": Bp2BuildDefaultTrue,
+ "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
"platform_testing/tests/example": Bp2BuildDefaultTrueRecursively,
"prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
"prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively,
"prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively,
+ "prebuilts/sdk/current/androidx": Bp2BuildDefaultTrue,
"prebuilts/sdk/current/extras/app-toolkit": Bp2BuildDefaultTrue,
"prebuilts/sdk/current/support": Bp2BuildDefaultTrue,
"prebuilts/tools": Bp2BuildDefaultTrue,
@@ -1427,4 +1430,20 @@
// It is implicit that all modules in ProdMixedBuildsEnabledList will
// also be built - do not add them to this list.
StagingMixedBuildsEnabledList = []string{}
+
+ // These should be the libs that are included by the apexes in the ProdMixedBuildsEnabledList
+ ProdDclaMixedBuildsEnabledList = []string{}
+
+ // These should be the libs that are included by the apexes in the StagingMixedBuildsEnabledList
+ StagingDclaMixedBuildsEnabledList = []string{
+ "libbase",
+ "libc++",
+ "libcrypto",
+ "libcutils",
+ }
+
+ // TODO(b/269342245): Enable the rest of the DCLA libs
+ // "libssl",
+ // "libstagefright_flacdec",
+ // "libutils",
)
diff --git a/android/androidmk.go b/android/androidmk.go
index 6346401..14b2e82 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -501,6 +501,7 @@
// generate and fill in AndroidMkEntries's in-struct data, ready to be flushed to a file.
type fillInEntriesContext interface {
ModuleDir(module blueprint.Module) string
+ ModuleSubDir(module blueprint.Module) string
Config() Config
ModuleProvider(module blueprint.Module, provider blueprint.ProviderKey) interface{}
ModuleHasProvider(module blueprint.Module, provider blueprint.ProviderKey) bool
@@ -528,7 +529,7 @@
fmt.Fprintf(&a.header, distString)
}
- fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS) # "+ctx.ModuleType(mod))
+ fmt.Fprintf(&a.header, "\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod))
// Collect make variable assignment entries.
a.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
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 bf7b317..6d7552f 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -302,31 +302,35 @@
return PathForOutput(ctx, "api_levels.json")
}
+func getApiLevelsMapReleasedVersions() map[string]int {
+ return map[string]int{
+ "G": 9,
+ "I": 14,
+ "J": 16,
+ "J-MR1": 17,
+ "J-MR2": 18,
+ "K": 19,
+ "L": 21,
+ "L-MR1": 22,
+ "M": 23,
+ "N": 24,
+ "N-MR1": 25,
+ "O": 26,
+ "O-MR1": 27,
+ "P": 28,
+ "Q": 29,
+ "R": 30,
+ "S": 31,
+ "S-V2": 32,
+ "Tiramisu": 33,
+ }
+}
+
var finalCodenamesMapKey = NewOnceKey("FinalCodenamesMap")
func getFinalCodenamesMap(config Config) map[string]int {
return config.Once(finalCodenamesMapKey, func() interface{} {
- apiLevelsMap := map[string]int{
- "G": 9,
- "I": 14,
- "J": 16,
- "J-MR1": 17,
- "J-MR2": 18,
- "K": 19,
- "L": 21,
- "L-MR1": 22,
- "M": 23,
- "N": 24,
- "N-MR1": 25,
- "O": 26,
- "O-MR1": 27,
- "P": 28,
- "Q": 29,
- "R": 30,
- "S": 31,
- "S-V2": 32,
- "Tiramisu": 33,
- }
+ apiLevelsMap := getApiLevelsMapReleasedVersions()
// TODO: Differentiate "current" and "future".
// The code base calls it FutureApiLevel, but the spelling is "current",
@@ -349,29 +353,10 @@
var apiLevelsMapKey = NewOnceKey("ApiLevelsMap")
+// ApiLevelsMap has entries for preview API levels
func GetApiLevelsMap(config Config) map[string]int {
return config.Once(apiLevelsMapKey, func() interface{} {
- apiLevelsMap := map[string]int{
- "G": 9,
- "I": 14,
- "J": 16,
- "J-MR1": 17,
- "J-MR2": 18,
- "K": 19,
- "L": 21,
- "L-MR1": 22,
- "M": 23,
- "N": 24,
- "N-MR1": 25,
- "O": 26,
- "O-MR1": 27,
- "P": 28,
- "Q": 29,
- "R": 30,
- "S": 31,
- "S-V2": 32,
- "Tiramisu": 33,
- }
+ apiLevelsMap := getApiLevelsMapReleasedVersions()
for i, codename := range config.PlatformVersionActiveCodenames() {
apiLevelsMap[codename] = previewAPILevelBase + i
}
@@ -386,20 +371,11 @@
createApiLevelsJson(ctx, apiLevelsJson, apiLevelsMap)
}
-func printApiLevelsStarlarkDict(config Config) string {
- apiLevelsMap := GetApiLevelsMap(config)
- valDict := make(map[string]string, len(apiLevelsMap))
- for k, v := range apiLevelsMap {
- valDict[k] = strconv.Itoa(v)
- }
- return starlark_fmt.PrintDict(valDict, 0)
-}
-
func StarlarkApiLevelConfigs(config Config) string {
return fmt.Sprintf(bazel.GeneratedBazelFileWarning+`
-_api_levels = %s
+_api_levels_released_versions = %s
-api_levels = _api_levels
-`, printApiLevelsStarlarkDict(config),
+api_levels_released_versions = _api_levels_released_versions
+`, starlark_fmt.PrintStringIntDict(getApiLevelsMapReleasedVersions(), 0),
)
}
diff --git a/android/bazel.go b/android/bazel.go
index 52f50c5..b600758 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -352,11 +352,13 @@
// metrics reporting.
func MixedBuildsEnabled(ctx BaseModuleContext) bool {
module := ctx.Module()
+ apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo)
+ withinApex := !apexInfo.IsForPlatform()
mixedBuildEnabled := ctx.Config().IsMixedBuildsEnabled() &&
ctx.Os() != Windows && // Windows toolchains are not currently supported.
module.Enabled() &&
convertedToBazel(ctx, module) &&
- ctx.Config().BazelContext.IsModuleNameAllowed(module.Name())
+ ctx.Config().BazelContext.IsModuleNameAllowed(module.Name(), withinApex)
ctx.Config().LogMixedBuild(ctx, mixedBuildEnabled)
return mixedBuildEnabled
}
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 8c34c92..e7ff08f 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -109,12 +109,29 @@
// Portion of cquery map key to describe target configuration.
type configKey struct {
- arch string
- osType OsType
+ arch string
+ osType OsType
+ apexKey ApexConfigKey
+}
+
+type ApexConfigKey struct {
+ WithinApex bool
+ ApexSdkVersion string
+}
+
+func (c ApexConfigKey) String() string {
+ return fmt.Sprintf("%s_%s", withinApexToString(c.WithinApex), c.ApexSdkVersion)
+}
+
+func withinApexToString(withinApex bool) string {
+ if withinApex {
+ return "within_apex"
+ }
+ return ""
}
func (c configKey) String() string {
- return fmt.Sprintf("%s::%s", c.arch, c.osType)
+ return fmt.Sprintf("%s::%s::%s", c.arch, c.osType, c.apexKey)
}
// Map key to describe bazel cquery requests.
@@ -182,13 +199,15 @@
// Note that this only implies "bazel mixed build" allowlisting. The caller
// should independently verify the module is eligible for Bazel handling
// (for example, that it is MixedBuildBuildable).
- IsModuleNameAllowed(moduleName string) bool
+ IsModuleNameAllowed(moduleName string, withinApex bool) bool
+
+ IsModuleDclaAllowed(moduleName string) bool
// Returns the bazel output base (the root directory for all bazel intermediate outputs).
OutputBase() string
// Returns build statements which should get registered to reflect Bazel's outputs.
- BuildStatementsToRegister() []bazel.BuildStatement
+ BuildStatementsToRegister() []*bazel.BuildStatement
// Returns the depsets defined in Bazel's aquery response.
AqueryDepsets() []bazel.AqueryDepset
@@ -222,7 +241,7 @@
results map[cqueryKey]string // Results of cquery requests after Bazel invocations
// Build statements which should get registered to reflect Bazel's outputs.
- buildStatements []bazel.BuildStatement
+ buildStatements []*bazel.BuildStatement
// Depsets which should be used for Bazel's build statements.
depsets []bazel.AqueryDepset
@@ -235,6 +254,8 @@
bazelDisabledModules map[string]bool
// Per-module allowlist to opt modules in to bazel handling.
bazelEnabledModules map[string]bool
+ // DCLA modules are enabled when used in apex.
+ bazelDclaEnabledModules map[string]bool
// If true, modules are bazel-enabled by default, unless present in bazelDisabledModules.
modulesDefaultToBazel bool
@@ -258,10 +279,16 @@
LabelToPythonBinary map[string]string
LabelToApexInfo map[string]cquery.ApexInfo
LabelToCcBinary map[string]cquery.CcUnstrippedInfo
+
+ BazelRequests map[string]bool
}
-func (m MockBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
- panic("unimplemented")
+func (m MockBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
+ key := BuildMockBazelContextRequestKey(label, requestType, cfgKey.arch, cfgKey.osType, cfgKey.apexKey)
+ if m.BazelRequests == nil {
+ m.BazelRequests = make(map[string]bool)
+ }
+ m.BazelRequests[key] = true
}
func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, error) {
@@ -272,10 +299,14 @@
return result, nil
}
-func (m MockBazelContext) GetCcInfo(label string, _ configKey) (cquery.CcInfo, error) {
+func (m MockBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) {
result, ok := m.LabelToCcInfo[label]
if !ok {
- return cquery.CcInfo{}, fmt.Errorf("no target with label %q in LabelToCcInfo", label)
+ key := BuildMockBazelContextResultKey(label, cfgKey.arch, cfgKey.osType, cfgKey.apexKey)
+ result, ok = m.LabelToCcInfo[key]
+ if !ok {
+ return cquery.CcInfo{}, fmt.Errorf("no target with label %q in LabelToCcInfo", label)
+ }
}
return result, nil
}
@@ -308,14 +339,18 @@
panic("unimplemented")
}
-func (m MockBazelContext) IsModuleNameAllowed(_ string) bool {
+func (m MockBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
+ return true
+}
+
+func (m MockBazelContext) IsModuleDclaAllowed(_ string) bool {
return true
}
func (m MockBazelContext) OutputBase() string { return m.OutputBaseDir }
-func (m MockBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
- return []bazel.BuildStatement{}
+func (m MockBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
+ return []*bazel.BuildStatement{}
}
func (m MockBazelContext) AqueryDepsets() []bazel.AqueryDepset {
@@ -324,6 +359,26 @@
var _ BazelContext = MockBazelContext{}
+func BuildMockBazelContextRequestKey(label string, request cqueryRequest, arch string, osType OsType, apexKey ApexConfigKey) string {
+ cfgKey := configKey{
+ arch: arch,
+ osType: osType,
+ apexKey: apexKey,
+ }
+
+ return strings.Join([]string{label, request.Name(), cfgKey.String()}, "_")
+}
+
+func BuildMockBazelContextResultKey(label string, arch string, osType OsType, apexKey ApexConfigKey) string {
+ cfgKey := configKey{
+ arch: arch,
+ osType: osType,
+ apexKey: apexKey,
+ }
+
+ return strings.Join([]string{label, cfgKey.String()}, "_")
+}
+
func (bazelCtx *mixedBuildBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) {
key := makeCqueryKey(label, requestType, cfgKey)
bazelCtx.requestMutex.Lock()
@@ -430,26 +485,31 @@
return ""
}
-func (n noopBazelContext) IsModuleNameAllowed(_ string) bool {
+func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return false
}
-func (m noopBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
- return []bazel.BuildStatement{}
+func (n noopBazelContext) IsModuleDclaAllowed(_ string) bool {
+ return false
+}
+
+func (m noopBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
+ return []*bazel.BuildStatement{}
}
func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
return []bazel.AqueryDepset{}
}
+func addToStringSet(set map[string]bool, items []string) {
+ for _, item := range items {
+ set[item] = true
+ }
+}
+
func GetBazelEnabledAndDisabledModules(buildMode SoongBuildMode, forceEnabled map[string]struct{}) (map[string]bool, map[string]bool) {
disabledModules := map[string]bool{}
enabledModules := map[string]bool{}
- addToStringSet := func(set map[string]bool, items []string) {
- for _, item := range items {
- set[item] = true
- }
- }
switch buildMode {
case BazelProdMode:
@@ -537,15 +597,24 @@
if c.HasDeviceProduct() {
targetProduct = c.DeviceProduct()
}
-
+ dclaMixedBuildsEnabledList := []string{}
+ if c.BuildMode == BazelProdMode {
+ dclaMixedBuildsEnabledList = allowlists.ProdDclaMixedBuildsEnabledList
+ } else if c.BuildMode == BazelStagingMode {
+ dclaMixedBuildsEnabledList = append(allowlists.ProdDclaMixedBuildsEnabledList,
+ allowlists.StagingDclaMixedBuildsEnabledList...)
+ }
+ dclaEnabledModules := map[string]bool{}
+ addToStringSet(dclaEnabledModules, dclaMixedBuildsEnabledList)
return &mixedBuildBazelContext{
- bazelRunner: &builtinBazelRunner{},
- paths: &paths,
- modulesDefaultToBazel: c.BuildMode == BazelDevMode,
- bazelEnabledModules: enabledModules,
- bazelDisabledModules: disabledModules,
- targetProduct: targetProduct,
- targetBuildVariant: targetBuildVariant,
+ bazelRunner: &builtinBazelRunner{},
+ paths: &paths,
+ modulesDefaultToBazel: c.BuildMode == BazelDevMode,
+ bazelEnabledModules: enabledModules,
+ bazelDisabledModules: disabledModules,
+ bazelDclaEnabledModules: dclaEnabledModules,
+ targetProduct: targetProduct,
+ targetBuildVariant: targetBuildVariant,
}, nil
}
@@ -553,16 +622,24 @@
return p.metricsDir
}
-func (context *mixedBuildBazelContext) IsModuleNameAllowed(moduleName string) bool {
+func (context *mixedBuildBazelContext) IsModuleNameAllowed(moduleName string, withinApex bool) bool {
if context.bazelDisabledModules[moduleName] {
return false
}
if context.bazelEnabledModules[moduleName] {
return true
}
+ if withinApex && context.IsModuleDclaAllowed(moduleName) {
+ return true
+ }
+
return context.modulesDefaultToBazel
}
+func (context *mixedBuildBazelContext) IsModuleDclaAllowed(moduleName string) bool {
+ return context.bazelDclaEnabledModules[moduleName]
+}
+
func pwdPrefix() string {
// Darwin doesn't have /proc
if runtime.GOOS != "darwin" {
@@ -696,21 +773,37 @@
#####################################################
# This file is generated by soong_build. Do not edit.
#####################################################
-
def _config_node_transition_impl(settings, attr):
if attr.os == "android" and attr.arch == "target":
target = "{PRODUCT}-{VARIANT}"
else:
target = "{PRODUCT}-{VARIANT}_%s_%s" % (attr.os, attr.arch)
- return {
+ apex_name = ""
+ if attr.within_apex:
+ # //build/bazel/rules/apex:apex_name has to be set to a non_empty value,
+ # otherwise //build/bazel/rules/apex:non_apex will be true and the
+ # "-D__ANDROID_APEX__" compiler flag will be missing. Apex_name is used
+ # in some validation on bazel side which don't really apply in mixed
+ # build because soong will do the work, so we just set it to a fixed
+ # value here.
+ apex_name = "dcla_apex"
+ outputs = {
"//command_line_option:platforms": "@soong_injection//product_config_platforms/products/{PRODUCT}-{VARIANT}:%s" % target,
+ "@//build/bazel/rules/apex:within_apex": attr.within_apex,
+ "@//build/bazel/rules/apex:min_sdk_version": attr.apex_sdk_version,
+ "@//build/bazel/rules/apex:apex_name": apex_name,
}
+ return outputs
+
_config_node_transition = transition(
implementation = _config_node_transition_impl,
inputs = [],
outputs = [
"//command_line_option:platforms",
+ "@//build/bazel/rules/apex:within_apex",
+ "@//build/bazel/rules/apex:min_sdk_version",
+ "@//build/bazel/rules/apex:apex_name",
],
)
@@ -720,9 +813,11 @@
config_node = rule(
implementation = _passthrough_rule_impl,
attrs = {
- "arch" : attr.string(mandatory = True),
- "os" : attr.string(mandatory = True),
- "deps" : attr.label_list(cfg = _config_node_transition, allow_files = True),
+ "arch" : attr.string(mandatory = True),
+ "os" : attr.string(mandatory = True),
+ "within_apex" : attr.bool(default = False),
+ "apex_sdk_version" : attr.string(mandatory = True),
+ "deps" : attr.label_list(cfg = _config_node_transition, allow_files = True),
"_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
},
)
@@ -781,6 +876,8 @@
config_node(name = "%s",
arch = "%s",
os = "%s",
+ within_apex = %s,
+ apex_sdk_version = "%s",
deps = [%s],
testonly = True, # Unblocks testonly deps.
)
@@ -807,15 +904,28 @@
for _, configString := range sortedConfigs {
labels := labelsByConfig[configString]
configTokens := strings.Split(configString, "|")
- if len(configTokens) != 2 {
+ if len(configTokens) < 2 {
panic(fmt.Errorf("Unexpected config string format: %s", configString))
}
archString := configTokens[0]
osString := configTokens[1]
+ withinApex := "False"
+ apexSdkVerString := ""
targetString := fmt.Sprintf("%s_%s", osString, archString)
+ if len(configTokens) > 2 {
+ targetString += "_" + configTokens[2]
+ if configTokens[2] == withinApexToString(true) {
+ withinApex = "True"
+ }
+ }
+ if len(configTokens) > 3 {
+ targetString += "_" + configTokens[3]
+ apexSdkVerString = configTokens[3]
+ }
allLabels = append(allLabels, fmt.Sprintf("\":%s\"", targetString))
labelsString := strings.Join(labels, ",\n ")
- configNodesSection += fmt.Sprintf(configNodeFormatString, targetString, archString, osString, labelsString)
+ configNodesSection += fmt.Sprintf(configNodeFormatString, targetString, archString, osString, withinApex, apexSdkVerString,
+ labelsString)
}
return []byte(fmt.Sprintf(formatString, configNodesSection, strings.Join(allLabels, ",\n ")))
@@ -911,6 +1021,7 @@
# Soong treats filegroups, but it may not be the case with manually-written
# filegroup BUILD targets.
buildoptions = build_options(target)
+
if buildoptions == None:
# File targets do not have buildoptions. File targets aren't associated with
# any specific platform architecture in mixed builds, so use the host.
@@ -927,15 +1038,26 @@
if not platform_name.startswith("{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}"):
fail("expected platform name of the form '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_android_<arch>' or '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms))
platform_name = platform_name.removeprefix("{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}").removeprefix("_")
+ config_key = ""
if not platform_name:
- return "target|android"
+ config_key = "target|android"
elif platform_name.startswith("android_"):
- return platform_name.removeprefix("android_") + "|android"
+ config_key = platform_name.removeprefix("android_") + "|android"
elif platform_name.startswith("linux_"):
- return platform_name.removeprefix("linux_") + "|linux"
+ config_key = platform_name.removeprefix("linux_") + "|linux"
else:
fail("expected platform name of the form '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_android_<arch>' or '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms))
+ within_apex = buildoptions.get("//build/bazel/rules/apex:within_apex")
+ apex_sdk_version = buildoptions.get("//build/bazel/rules/apex:min_sdk_version")
+
+ if within_apex:
+ config_key += "|within_apex"
+ if apex_sdk_version != None and len(apex_sdk_version) > 0:
+ config_key += "|" + apex_sdk_version
+
+ return config_key
+
def format(target):
id_string = str(target.label) + "|" + get_arch(target)
@@ -1044,8 +1166,12 @@
return err
}
- cqueryCommandWithFlag := context.createBazelCommand(config, context.paths, bazel.CqueryBuildRootRunName, cqueryCmd,
- "--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath))
+ extraFlags := []string{"--output=starlark", "--starlark:file=" + absolutePath(cqueryFileRelpath)}
+ if Bool(config.productVariables.ClangCoverage) {
+ extraFlags = append(extraFlags, "--collect_code_coverage")
+ }
+
+ cqueryCommandWithFlag := context.createBazelCommand(config, context.paths, bazel.CqueryBuildRootRunName, cqueryCmd, extraFlags...)
cqueryOutput, cqueryErrorMessage, cqueryErr := context.issueBazelCommand(cqueryCommandWithFlag, eventHandler)
if cqueryErr != nil {
return cqueryErr
@@ -1128,7 +1254,7 @@
return err
}
-func (context *mixedBuildBazelContext) BuildStatementsToRegister() []bazel.BuildStatement {
+func (context *mixedBuildBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
return context.buildStatements
}
@@ -1196,6 +1322,11 @@
executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__")
bazelOutDir := path.Join(executionRoot, "bazel-out")
for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() {
+ // nil build statements are a valid case where we do not create an action because it is
+ // unnecessary or handled by other processing
+ if buildStatement == nil {
+ continue
+ }
if len(buildStatement.Command) > 0 {
rule := NewRuleBuilder(pctx, ctx)
createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx)
@@ -1240,7 +1371,7 @@
}
// Register bazel-owned build statements (obtained from the aquery invocation).
-func createCommand(cmd *RuleBuilderCommand, buildStatement bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext) {
+func createCommand(cmd *RuleBuilderCommand, buildStatement *bazel.BuildStatement, executionRoot string, bazelOutDir string, ctx BuilderContext) {
// executionRoot is the action cwd.
cmd.Text(fmt.Sprintf("cd '%s' &&", executionRoot))
@@ -1320,7 +1451,16 @@
// Use host OS, which is currently hardcoded to be linux.
osName = "linux"
}
- return arch + "|" + osName
+ keyString := arch + "|" + osName
+ if key.configKey.apexKey.WithinApex {
+ keyString += "|" + withinApexToString(key.configKey.apexKey.WithinApex)
+ }
+
+ if len(key.configKey.apexKey.ApexSdkVersion) > 0 {
+ keyString += "|" + key.configKey.apexKey.ApexSdkVersion
+ }
+
+ return keyString
}
func GetConfigKey(ctx BaseModuleContext) configKey {
@@ -1331,6 +1471,19 @@
}
}
+func GetConfigKeyApexVariant(ctx BaseModuleContext, apexKey *ApexConfigKey) configKey {
+ configKey := GetConfigKey(ctx)
+
+ if apexKey != nil {
+ configKey.apexKey = ApexConfigKey{
+ WithinApex: apexKey.WithinApex,
+ ApexSdkVersion: apexKey.ApexSdkVersion,
+ }
+ }
+
+ return configKey
+}
+
func bazelDepsetName(contentHash string) string {
return fmt.Sprintf("bazel_depset_%s", contentHash)
}
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index 4a4ecb5..c67d7fb 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -24,20 +24,37 @@
}
func TestRequestResultsAfterInvokeBazel(t *testing.T) {
- label := "@//foo:bar"
- cfg := configKey{"arm64_armv8-a", Android}
+ label_foo := "@//foo:foo"
+ label_bar := "@//foo:bar"
+ apexKey := ApexConfigKey{
+ WithinApex: true,
+ ApexSdkVersion: "29",
+ }
+ cfg_foo := configKey{"arm64_armv8-a", Android, apexKey}
+ cfg_bar := configKey{arch: "arm64_armv8-a", osType: Android}
+ cmd_results := []string{
+ `@//foo:foo|arm64_armv8-a|android|within_apex|29>>out/foo/foo.txt`,
+ `@//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
+ }
bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
- bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `@//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
+ bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: strings.Join(cmd_results, "\n"),
})
- bazelContext.QueueBazelRequest(label, cquery.GetOutputFiles, cfg)
+
+ bazelContext.QueueBazelRequest(label_foo, cquery.GetOutputFiles, cfg_foo)
+ bazelContext.QueueBazelRequest(label_bar, cquery.GetOutputFiles, cfg_bar)
err := bazelContext.InvokeBazel(testConfig, &testInvokeBazelContext{})
if err != nil {
t.Fatalf("Did not expect error invoking Bazel, but got %s", err)
}
- g, err := bazelContext.GetOutputFiles(label, cfg)
+ verifyCqueryResult(t, bazelContext, label_foo, cfg_foo, "out/foo/foo.txt")
+ verifyCqueryResult(t, bazelContext, label_bar, cfg_bar, "out/foo/bar.txt")
+}
+
+func verifyCqueryResult(t *testing.T, ctx *mixedBuildBazelContext, label string, cfg configKey, result string) {
+ g, err := ctx.GetOutputFiles(label, cfg)
if err != nil {
t.Errorf("Expected cquery results after running InvokeBazel(), but got err %v", err)
- } else if w := []string{"out/foo/bar.txt"}; !reflect.DeepEqual(w, g) {
+ } else if w := []string{result}; !reflect.DeepEqual(w, g) {
t.Errorf("Expected output %s, got %s", w, g)
}
}
@@ -178,14 +195,18 @@
func TestBazelRequestsSorted(t *testing.T) {
bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
- bazelContext.QueueBazelRequest("zzz", cquery.GetOutputFiles, configKey{"arm64_armv8-a", Android})
- bazelContext.QueueBazelRequest("ccc", cquery.GetApexInfo, configKey{"arm64_armv8-a", Android})
- bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, configKey{"arm64_armv8-a", Android})
- bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, configKey{"arm64_armv8-a", Android})
- bazelContext.QueueBazelRequest("xxx", cquery.GetOutputFiles, configKey{"arm64_armv8-a", Linux})
- bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, configKey{"arm64_armv8-a", Android})
- bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, configKey{"otherarch", Android})
- bazelContext.QueueBazelRequest("bbb", cquery.GetOutputFiles, configKey{"otherarch", Android})
+ cfgKeyArm64Android := configKey{arch: "arm64_armv8-a", osType: Android}
+ cfgKeyArm64Linux := configKey{arch: "arm64_armv8-a", osType: Linux}
+ cfgKeyOtherAndroid := configKey{arch: "otherarch", osType: Android}
+
+ bazelContext.QueueBazelRequest("zzz", cquery.GetOutputFiles, cfgKeyArm64Android)
+ bazelContext.QueueBazelRequest("ccc", cquery.GetApexInfo, cfgKeyArm64Android)
+ bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, cfgKeyArm64Android)
+ bazelContext.QueueBazelRequest("duplicate", cquery.GetOutputFiles, cfgKeyArm64Android)
+ bazelContext.QueueBazelRequest("xxx", cquery.GetOutputFiles, cfgKeyArm64Linux)
+ bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, cfgKeyArm64Android)
+ bazelContext.QueueBazelRequest("aaa", cquery.GetOutputFiles, cfgKeyOtherAndroid)
+ bazelContext.QueueBazelRequest("bbb", cquery.GetOutputFiles, cfgKeyOtherAndroid)
if len(bazelContext.requests) != 7 {
t.Error("Expected 7 request elements, but got", len(bazelContext.requests))
@@ -201,6 +222,52 @@
}
}
+func TestIsModuleNameAllowed(t *testing.T) {
+ libDisabled := "lib_disabled"
+ libEnabled := "lib_enabled"
+ libDclaWithinApex := "lib_dcla_within_apex"
+ libDclaNonApex := "lib_dcla_non_apex"
+ libNotConverted := "lib_not_converted"
+
+ disabledModules := map[string]bool{
+ libDisabled: true,
+ }
+ enabledModules := map[string]bool{
+ libEnabled: true,
+ }
+ dclaEnabledModules := map[string]bool{
+ libDclaWithinApex: true,
+ libDclaNonApex: true,
+ }
+
+ bazelContext := &mixedBuildBazelContext{
+ modulesDefaultToBazel: false,
+ bazelEnabledModules: enabledModules,
+ bazelDisabledModules: disabledModules,
+ bazelDclaEnabledModules: dclaEnabledModules,
+ }
+
+ if bazelContext.IsModuleNameAllowed(libDisabled, true) {
+ t.Fatalf("%s shouldn't be allowed for mixed build", libDisabled)
+ }
+
+ if !bazelContext.IsModuleNameAllowed(libEnabled, true) {
+ t.Fatalf("%s should be allowed for mixed build", libEnabled)
+ }
+
+ if !bazelContext.IsModuleNameAllowed(libDclaWithinApex, true) {
+ t.Fatalf("%s should be allowed for mixed build", libDclaWithinApex)
+ }
+
+ if bazelContext.IsModuleNameAllowed(libDclaNonApex, false) {
+ t.Fatalf("%s shouldn't be allowed for mixed build", libDclaNonApex)
+ }
+
+ if bazelContext.IsModuleNameAllowed(libNotConverted, true) {
+ t.Fatalf("%s shouldn't be allowed for mixed build", libNotConverted)
+ }
+}
+
func verifyExtraFlags(t *testing.T, config Config, expected string) string {
bazelContext, _ := testBazelContext(t, map[bazelCommand]string{})
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/filegroup.go b/android/filegroup.go
index d21d146..7d929bc 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -232,7 +232,7 @@
bazelCtx.QueueBazelRequest(
fg.GetBazelLabel(ctx, fg),
cquery.GetOutputFiles,
- configKey{Common.String(), CommonOS})
+ configKey{arch: Common.String(), osType: CommonOS})
}
func (fg *fileGroup) IsMixedBuildSupported(ctx BaseModuleContext) bool {
@@ -252,7 +252,7 @@
relativeRoot = filepath.Join(relativeRoot, *fg.properties.Path)
}
- filePaths, err := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), configKey{Common.String(), CommonOS})
+ filePaths, err := bazelCtx.GetOutputFiles(fg.GetBazelLabel(ctx, fg), configKey{arch: Common.String(), osType: CommonOS})
if err != nil {
ctx.ModuleErrorf(err.Error())
return
diff --git a/android/module.go b/android/module.go
index 681f724..58c5464 100644
--- a/android/module.go
+++ b/android/module.go
@@ -502,6 +502,7 @@
InstallInRoot() bool
InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
+ PartitionTag(DeviceConfig) string
HideFromMake()
IsHideFromMake() bool
IsSkipInstall() bool
@@ -3674,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 != "/" {
@@ -3685,7 +3686,7 @@
dir = parentDir(dir)
}
}
- dirs = SortedStringKeys(dirMap)
+ dirs = SortedKeys(dirMap)
var topDirs []string
for _, dir := range dirs {
p := parentDir(dir)
@@ -3695,7 +3696,7 @@
topDirs = append(topDirs, dir)
}
}
- return SortedStringKeys(dirMap), topDirs
+ return SortedKeys(dirMap), topDirs
}
func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
@@ -3781,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/soongconfig/modules.go b/android/soongconfig/modules.go
index ed4888d..9239ca9 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -301,23 +301,6 @@
}
}
-// This is a copy of the one available in soong/android/util.go, but depending
-// on the android package causes a cyclic dependency. A refactoring here is to
-// extract common utils out from android/utils.go for other packages like this.
-func sortedStringKeys(m interface{}) []string {
- v := reflect.ValueOf(m)
- if v.Kind() != reflect.Map {
- panic(fmt.Sprintf("%#v is not a map", m))
- }
- keys := v.MapKeys()
- s := make([]string, 0, len(keys))
- for _, key := range keys {
- s = append(s, key.String())
- }
- sort.Strings(s)
- return s
-}
-
// String emits the Soong config variable definitions as Starlark dictionaries.
func (defs Bp2BuildSoongConfigDefinitions) String() string {
ret := ""
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 947af69..6c0ddf4 100644
--- a/android/util.go
+++ b/android/util.go
@@ -29,6 +29,15 @@
return append([]string(nil), s...)
}
+// Concat returns a new slice concatenated from the two input slices. It does not change the input
+// slices.
+func Concat[T any](s1, s2 []T) []T {
+ res := make([]T, 0, len(s1)+len(s2))
+ res = append(res, s1...)
+ res = append(res, s2...)
+ return res
+}
+
// JoinWithPrefix prepends the prefix to each string in the list and
// returns them joined together with " " as separator.
func JoinWithPrefix(strs []string, prefix string) string {
@@ -53,25 +62,9 @@
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()
-}
-
-// SorterStringKeys returns the keys of the given string-keyed map in the ascending order.
+// SortedStringKeys returns the keys of the given map in the ascending order.
+//
+// Deprecated: Use SortedKeys instead.
func SortedStringKeys(m interface{}) []string {
v := reflect.ValueOf(m)
if v.Kind() != reflect.Map {
@@ -89,6 +82,28 @@
return s
}
+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
+ }
+ ret := make([]T, 0, len(m))
+ for k := range m {
+ ret = append(ret, k)
+ }
+ 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.
func stringValues(m interface{}) []string {
v := reflect.ValueOf(m)
diff --git a/android/util_test.go b/android/util_test.go
index 9b9253b..51d8e32 100644
--- a/android/util_test.go
+++ b/android/util_test.go
@@ -641,6 +641,36 @@
}
}
+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 %q, got %q", expected, actual)
+ }
+ })
+}
+
+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 TestSortedStringKeys(t *testing.T) {
testCases := []struct {
name string
diff --git a/apex/apex.go b/apex/apex.go
index 8a8b19d..d7d76d1 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -111,6 +111,18 @@
Multilib apexMultilibProperties
+ // List of runtime resource overlays (RROs) that are embedded inside this APEX.
+ Rros []string
+
+ // List of bootclasspath fragments that are embedded inside this APEX bundle.
+ Bootclasspath_fragments []string
+
+ // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
+ Systemserverclasspath_fragments []string
+
+ // List of java libraries that are embedded inside this APEX bundle.
+ Java_libs []string
+
// List of sh binaries that are embedded inside this APEX bundle.
Sh_binaries []string
@@ -326,21 +338,9 @@
// List of prebuilt files that are embedded inside this APEX bundle.
Prebuilts []string
- // List of runtime resource overlays (RROs) that are embedded inside this APEX.
- Rros []string
-
// List of BPF programs inside this APEX bundle.
Bpfs []string
- // List of bootclasspath fragments that are embedded inside this APEX bundle.
- Bootclasspath_fragments []string
-
- // List of systemserverclasspath fragments that are embedded inside this APEX bundle.
- Systemserverclasspath_fragments []string
-
- // List of java libraries that are embedded inside this APEX bundle.
- Java_libs []string
-
// Names of modules to be overridden. Listed modules can only be other binaries (in Make or
// Soong). This does not completely prevent installation of the overridden binaries, but if
// both binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will
@@ -514,6 +514,7 @@
// buildFile is put in the installDir inside the APEX.
builtFile android.Path
installDir string
+ partition string
customStem string
symlinks []string // additional symlinks
@@ -553,6 +554,7 @@
}
if module != nil {
ret.moduleDir = ctx.OtherModuleDir(module)
+ ret.partition = module.PartitionTag(ctx.DeviceConfig())
ret.requiredModuleNames = module.RequiredModuleNames()
ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
@@ -845,6 +847,10 @@
// Common-arch dependencies come next
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
+ ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
+ ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
+ ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
+ ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
}
@@ -858,10 +864,6 @@
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
- ctx.AddFarVariationDependencies(commonVariation, rroTag, a.overridableProperties.Rros...)
- ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.overridableProperties.Bootclasspath_fragments...)
- ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.overridableProperties.Systemserverclasspath_fragments...)
- ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.overridableProperties.Java_libs...)
if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
// regardless of the TARGET_PREFER_* setting. See b/144532908
@@ -3107,9 +3109,9 @@
// Collect information for opening IDE project files in java/jdeps.go.
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
- dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Java_libs...)
- dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Bootclasspath_fragments...)
- dpInfo.Deps = append(dpInfo.Deps, a.overridableProperties.Systemserverclasspath_fragments...)
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
+ dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
dpInfo.Paths = append(dpInfo.Paths, a.modulePaths...)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index eec24b0..53e922c 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2128,6 +2128,34 @@
min_sdk_version: "30",
}
`)
+
+ // Skip check for modules compiling against core API surface
+ testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["libfoo"],
+ min_sdk_version: "29",
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "libfoo",
+ srcs: ["Foo.java"],
+ apex_available: [
+ "myapex",
+ ],
+ // Compile against core API surface
+ sdk_version: "core_current",
+ min_sdk_version: "30",
+ }
+ `)
+
}
func TestApexMinSdkVersion_Okay(t *testing.T) {
@@ -6294,9 +6322,6 @@
apps: ["app"],
bpfs: ["bpf"],
prebuilts: ["myetc"],
- bootclasspath_fragments: ["mybootclasspath_fragment"],
- systemserverclasspath_fragments: ["mysystemserverclasspath_fragment"],
- java_libs: ["myjava_library"],
overrides: ["oldapex"],
updatable: false,
}
@@ -6307,9 +6332,6 @@
apps: ["override_app"],
bpfs: ["overrideBpf"],
prebuilts: ["override_myetc"],
- bootclasspath_fragments: ["override_bootclasspath_fragment"],
- systemserverclasspath_fragments: ["override_systemserverclasspath_fragment"],
- java_libs: ["override_java_library"],
overrides: ["unknownapex"],
logging_parent: "com.foo.bar",
package_name: "test.overridden.package",
@@ -6368,78 +6390,6 @@
name: "override_myetc",
src: "override_myprebuilt",
}
-
- java_library {
- name: "bcplib",
- srcs: ["a.java"],
- compile_dex: true,
- apex_available: ["myapex"],
- permitted_packages: ["bcp.lib"],
- }
-
- bootclasspath_fragment {
- name: "mybootclasspath_fragment",
- contents: ["bcplib"],
- apex_available: ["myapex"],
- hidden_api: {
- split_packages: ["*"],
- },
- }
-
- java_library {
- name: "override_bcplib",
- srcs: ["a.java"],
- compile_dex: true,
- apex_available: ["myapex"],
- permitted_packages: ["override.bcp.lib"],
- }
-
- bootclasspath_fragment {
- name: "override_bootclasspath_fragment",
- contents: ["override_bcplib"],
- apex_available: ["myapex"],
- hidden_api: {
- split_packages: ["*"],
- },
- }
-
- java_library {
- name: "systemserverlib",
- srcs: ["a.java"],
- apex_available: ["myapex"],
- }
-
- systemserverclasspath_fragment {
- name: "mysystemserverclasspath_fragment",
- standalone_contents: ["systemserverlib"],
- apex_available: ["myapex"],
- }
-
- java_library {
- name: "override_systemserverlib",
- srcs: ["a.java"],
- apex_available: ["myapex"],
- }
-
- systemserverclasspath_fragment {
- name: "override_systemserverclasspath_fragment",
- standalone_contents: ["override_systemserverlib"],
- apex_available: ["myapex"],
- }
-
- java_library {
- name: "myjava_library",
- srcs: ["a.java"],
- compile_dex: true,
- apex_available: ["myapex"],
- }
-
- java_library {
- name: "override_java_library",
- srcs: ["a.java"],
- compile_dex: true,
- apex_available: ["myapex"],
- }
`, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule)
@@ -6474,13 +6424,6 @@
t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent)
}
- android.AssertArrayString(t, "Bootclasspath_fragments does not match",
- []string{"override_bootclasspath_fragment"}, apexBundle.overridableProperties.Bootclasspath_fragments)
- android.AssertArrayString(t, "Systemserverclasspath_fragments does not match",
- []string{"override_systemserverclasspath_fragment"}, apexBundle.overridableProperties.Systemserverclasspath_fragments)
- android.AssertArrayString(t, "Java_libs does not match",
- []string{"override_java_library"}, apexBundle.overridableProperties.Java_libs)
-
optFlags := apexRule.Args["opt_flags"]
ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package")
ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey")
@@ -6495,18 +6438,12 @@
ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := overrideBpf.o.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := override_bcplib.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := override_java_library.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := bpf.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := override_bcplib.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := override_java_library.pb.myapex")
ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
}
@@ -7122,7 +7059,10 @@
cc_library {
name: "mylib",
srcs: ["mylib.cpp"],
- shared_libs: ["myotherlib"],
+ shared_libs: [
+ "myotherlib",
+ "myotherlib_ext",
+ ],
system_shared_libs: [],
stl: "none",
apex_available: [
@@ -7146,6 +7086,20 @@
min_sdk_version: "current",
}
+ cc_library {
+ name: "myotherlib_ext",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ system_ext_specific: true,
+ stl: "none",
+ apex_available: [
+ "myapex",
+ "myapex.updatable",
+ "//apex_available:platform",
+ ],
+ min_sdk_version: "current",
+ }
+
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
@@ -7186,12 +7140,15 @@
t.Errorf("%q is not found", file)
}
- ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) {
+ ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string, target string) {
for _, f := range files {
if f.path == file {
if !f.isLink {
t.Errorf("%q is not a symlink", file)
}
+ if f.src != target {
+ t.Errorf("expected symlink target to be %q, got %q", target, f.src)
+ }
return
}
}
@@ -7205,23 +7162,27 @@
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
ensureRealfileExists(t, files, "lib64/myotherlib.so")
+ ensureRealfileExists(t, files, "lib64/myotherlib_ext.so")
files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
ensureRealfileExists(t, files, "lib64/myotherlib.so")
+ ensureRealfileExists(t, files, "lib64/myotherlib_ext.so")
// For bundled build, symlink to the system for the non-updatable APEXes only
ctx = testApex(t, bp)
files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink
+ ensureSymlinkExists(t, files, "lib64/myotherlib.so", "/system/lib64/myotherlib.so") // this is symlink
+ ensureSymlinkExists(t, files, "lib64/myotherlib_ext.so", "/system_ext/lib64/myotherlib_ext.so") // this is symlink
files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
ensureRealfileExists(t, files, "javalib/myjar.jar")
ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
+ ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
+ ensureRealfileExists(t, files, "lib64/myotherlib_ext.so") // this is a real file
}
func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
@@ -9539,187 +9500,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) {
diff --git a/apex/builder.go b/apex/builder.go
index 93ff80d..7248d97 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -476,8 +476,7 @@
// Copy the built file to the directory. But if the symlink optimization is turned
// on, place a symlink to the corresponding file in /system partition instead.
if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
- // TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
- pathOnDevice := filepath.Join("/system", fi.path())
+ pathOnDevice := filepath.Join("/", fi.partition, fi.path())
copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
} else {
// Copy the file into APEX
@@ -544,7 +543,7 @@
if len(installMapSet) > 0 {
var installs []string
- installs = append(installs, android.SortedStringKeys(installMapSet)...)
+ installs = append(installs, android.SortedKeys(installMapSet)...)
a.SetLicenseInstallMap(installs)
}
@@ -941,8 +940,7 @@
dir := filepath.Join("apex", bundleName, fi.installDir)
installDir := android.PathForModuleInstall(ctx, dir)
if a.linkToSystemLib && fi.transitiveDep && fi.availableToPlatform() {
- // TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
- pathOnDevice := filepath.Join("/system", fi.path())
+ pathOnDevice := filepath.Join("/", fi.partition, fi.path())
installedSymlinks = append(installedSymlinks,
ctx.InstallAbsoluteSymlink(installDir, fi.stem(), pathOnDevice))
} else {
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 6af472a..4d39e8f 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -22,6 +22,7 @@
"reflect"
"sort"
"strings"
+ "sync"
analysis_v2_proto "prebuilts/bazel/common/proto/analysis_v2"
@@ -105,7 +106,7 @@
Depfile *string
OutputPaths []string
SymlinkPaths []string
- Env []KeyValuePair
+ Env []*analysis_v2_proto.KeyValuePair
Mnemonic string
// Inputs of this build statement, either as unexpanded depsets or expanded
@@ -130,7 +131,7 @@
// depsetIdToArtifactIdsCache is a memoization of depset flattening, because flattening
// may be an expensive operation.
- depsetHashToArtifactPathsCache map[string][]string
+ depsetHashToArtifactPathsCache sync.Map
// Maps artifact ids to fully expanded paths.
artifactIdToPath map[artifactId]string
}
@@ -143,8 +144,11 @@
"%python_binary%": "python3",
}
-// The file name of py3wrapper.sh, which is used by py_binary targets.
-const py3wrapperFileName = "/py3wrapper.sh"
+const (
+ middlemanMnemonic = "Middleman"
+ // The file name of py3wrapper.sh, which is used by py_binary targets.
+ py3wrapperFileName = "/py3wrapper.sh"
+)
func indexBy[K comparable, V any](values []V, keyFn func(v V) K) map[K]V {
m := map[K]V{}
@@ -154,18 +158,18 @@
return m
}
-func newAqueryHandler(aqueryResult actionGraphContainer) (*aqueryArtifactHandler, error) {
- pathFragments := indexBy(aqueryResult.PathFragments, func(pf pathFragment) pathFragmentId {
- return pf.Id
+func newAqueryHandler(aqueryResult *analysis_v2_proto.ActionGraphContainer) (*aqueryArtifactHandler, error) {
+ pathFragments := indexBy(aqueryResult.PathFragments, func(pf *analysis_v2_proto.PathFragment) pathFragmentId {
+ return pathFragmentId(pf.Id)
})
- artifactIdToPath := map[artifactId]string{}
+ artifactIdToPath := make(map[artifactId]string, len(aqueryResult.Artifacts))
for _, artifact := range aqueryResult.Artifacts {
- artifactPath, err := expandPathFragment(artifact.PathFragmentId, pathFragments)
+ artifactPath, err := expandPathFragment(pathFragmentId(artifact.PathFragmentId), pathFragments)
if err != nil {
return nil, err
}
- artifactIdToPath[artifact.Id] = artifactPath
+ artifactIdToPath[artifactId(artifact.Id)] = artifactPath
}
// Map middleman artifact ContentHash to input artifact depset ID.
@@ -173,23 +177,23 @@
// if we find a middleman action which has inputs [foo, bar], and output [baz_middleman], then,
// for each other action which has input [baz_middleman], we add [foo, bar] to the inputs for
// that action instead.
- middlemanIdToDepsetIds := map[artifactId][]depsetId{}
+ middlemanIdToDepsetIds := map[artifactId][]uint32{}
for _, actionEntry := range aqueryResult.Actions {
- if actionEntry.Mnemonic == "Middleman" {
+ if actionEntry.Mnemonic == middlemanMnemonic {
for _, outputId := range actionEntry.OutputIds {
- middlemanIdToDepsetIds[outputId] = actionEntry.InputDepSetIds
+ middlemanIdToDepsetIds[artifactId(outputId)] = actionEntry.InputDepSetIds
}
}
}
- depsetIdToDepset := indexBy(aqueryResult.DepSetOfFiles, func(d depSetOfFiles) depsetId {
- return d.Id
+ depsetIdToDepset := indexBy(aqueryResult.DepSetOfFiles, func(d *analysis_v2_proto.DepSetOfFiles) depsetId {
+ return depsetId(d.Id)
})
aqueryHandler := aqueryArtifactHandler{
depsetIdToAqueryDepset: map[depsetId]AqueryDepset{},
depsetHashToAqueryDepset: map[string]AqueryDepset{},
- depsetHashToArtifactPathsCache: map[string][]string{},
+ depsetHashToArtifactPathsCache: sync.Map{},
emptyDepsetIds: make(map[depsetId]struct{}, 0),
artifactIdToPath: artifactIdToPath,
}
@@ -207,20 +211,21 @@
// Ensures that the handler's depsetIdToAqueryDepset map contains an entry for the given
// depset.
-func (a *aqueryArtifactHandler) populateDepsetMaps(depset depSetOfFiles, middlemanIdToDepsetIds map[artifactId][]depsetId, depsetIdToDepset map[depsetId]depSetOfFiles) (*AqueryDepset, error) {
- if aqueryDepset, containsDepset := a.depsetIdToAqueryDepset[depset.Id]; containsDepset {
+func (a *aqueryArtifactHandler) populateDepsetMaps(depset *analysis_v2_proto.DepSetOfFiles, middlemanIdToDepsetIds map[artifactId][]uint32, depsetIdToDepset map[depsetId]*analysis_v2_proto.DepSetOfFiles) (*AqueryDepset, error) {
+ if aqueryDepset, containsDepset := a.depsetIdToAqueryDepset[depsetId(depset.Id)]; containsDepset {
return &aqueryDepset, nil
}
transitiveDepsetIds := depset.TransitiveDepSetIds
- var directArtifactPaths []string
- for _, artifactId := range depset.DirectArtifactIds {
- path, pathExists := a.artifactIdToPath[artifactId]
+ directArtifactPaths := make([]string, 0, len(depset.DirectArtifactIds))
+ for _, id := range depset.DirectArtifactIds {
+ aId := artifactId(id)
+ path, pathExists := a.artifactIdToPath[aId]
if !pathExists {
- return nil, fmt.Errorf("undefined input artifactId %d", artifactId)
+ return nil, fmt.Errorf("undefined input artifactId %d", aId)
}
// Filter out any inputs which are universally dropped, and swap middleman
// artifacts with their corresponding depsets.
- if depsetsToUse, isMiddleman := middlemanIdToDepsetIds[artifactId]; isMiddleman {
+ if depsetsToUse, isMiddleman := middlemanIdToDepsetIds[aId]; isMiddleman {
// Swap middleman artifacts with their corresponding depsets and drop the middleman artifacts.
transitiveDepsetIds = append(transitiveDepsetIds, depsetsToUse...)
} else if strings.HasSuffix(path, py3wrapperFileName) ||
@@ -237,8 +242,9 @@
}
}
- var childDepsetHashes []string
- for _, childDepsetId := range transitiveDepsetIds {
+ childDepsetHashes := make([]string, 0, len(transitiveDepsetIds))
+ for _, id := range transitiveDepsetIds {
+ childDepsetId := depsetId(id)
childDepset, exists := depsetIdToDepset[childDepsetId]
if !exists {
if _, empty := a.emptyDepsetIds[childDepsetId]; empty {
@@ -256,7 +262,7 @@
}
}
if len(directArtifactPaths) == 0 && len(childDepsetHashes) == 0 {
- a.emptyDepsetIds[depset.Id] = struct{}{}
+ a.emptyDepsetIds[depsetId(depset.Id)] = struct{}{}
return nil, nil
}
aqueryDepset := AqueryDepset{
@@ -264,7 +270,7 @@
DirectArtifacts: directArtifactPaths,
TransitiveDepSetHashes: childDepsetHashes,
}
- a.depsetIdToAqueryDepset[depset.Id] = aqueryDepset
+ a.depsetIdToAqueryDepset[depsetId(depset.Id)] = aqueryDepset
a.depsetHashToAqueryDepset[aqueryDepset.ContentHash] = aqueryDepset
return &aqueryDepset, nil
}
@@ -273,10 +279,11 @@
// input paths contained in these depsets.
// This is a potentially expensive operation, and should not be invoked except
// for actions which need specialized input handling.
-func (a *aqueryArtifactHandler) getInputPaths(depsetIds []depsetId) ([]string, error) {
+func (a *aqueryArtifactHandler) getInputPaths(depsetIds []uint32) ([]string, error) {
var inputPaths []string
- for _, inputDepSetId := range depsetIds {
+ for _, id := range depsetIds {
+ inputDepSetId := depsetId(id)
depset := a.depsetIdToAqueryDepset[inputDepSetId]
inputArtifacts, err := a.artifactPathsFromDepsetHash(depset.ContentHash)
if err != nil {
@@ -291,8 +298,8 @@
}
func (a *aqueryArtifactHandler) artifactPathsFromDepsetHash(depsetHash string) ([]string, error) {
- if result, exists := a.depsetHashToArtifactPathsCache[depsetHash]; exists {
- return result, nil
+ if result, exists := a.depsetHashToArtifactPathsCache.Load(depsetHash); exists {
+ return result.([]string), nil
}
if depset, exists := a.depsetHashToAqueryDepset[depsetHash]; exists {
result := depset.DirectArtifacts
@@ -303,7 +310,7 @@
}
result = append(result, childArtifactIds...)
}
- a.depsetHashToArtifactPathsCache[depsetHash] = result
+ a.depsetHashToArtifactPathsCache.Store(depsetHash, result)
return result, nil
} else {
return nil, fmt.Errorf("undefined input depset hash %s", depsetHash)
@@ -315,124 +322,56 @@
// action graph, as described by the given action graph json proto.
// BuildStatements are one-to-one with actions in the given action graph, and AqueryDepsets
// are one-to-one with Bazel's depSetOfFiles objects.
-func AqueryBuildStatements(aqueryJsonProto []byte, eventHandler *metrics.EventHandler) ([]BuildStatement, []AqueryDepset, error) {
+func AqueryBuildStatements(aqueryJsonProto []byte, eventHandler *metrics.EventHandler) ([]*BuildStatement, []AqueryDepset, error) {
aqueryProto := &analysis_v2_proto.ActionGraphContainer{}
err := proto.Unmarshal(aqueryJsonProto, aqueryProto)
if err != nil {
return nil, nil, err
}
- aqueryResult := actionGraphContainer{}
-
- for _, protoArtifact := range aqueryProto.Artifacts {
- aqueryResult.Artifacts = append(aqueryResult.Artifacts, artifact{artifactId(protoArtifact.Id),
- pathFragmentId(protoArtifact.PathFragmentId)})
- }
-
- for _, protoAction := range aqueryProto.Actions {
- var environmentVariable []KeyValuePair
- var inputDepSetIds []depsetId
- var outputIds []artifactId
- var substitutions []KeyValuePair
-
- for _, protoEnvironmentVariable := range protoAction.EnvironmentVariables {
- environmentVariable = append(environmentVariable, KeyValuePair{
- protoEnvironmentVariable.Key, protoEnvironmentVariable.Value,
- })
- }
- for _, protoInputDepSetIds := range protoAction.InputDepSetIds {
- inputDepSetIds = append(inputDepSetIds, depsetId(protoInputDepSetIds))
- }
- for _, protoOutputIds := range protoAction.OutputIds {
- outputIds = append(outputIds, artifactId(protoOutputIds))
- }
- for _, protoSubstitutions := range protoAction.Substitutions {
- substitutions = append(substitutions, KeyValuePair{
- protoSubstitutions.Key, protoSubstitutions.Value,
- })
- }
-
- aqueryResult.Actions = append(aqueryResult.Actions,
- action{
- Arguments: protoAction.Arguments,
- EnvironmentVariables: environmentVariable,
- InputDepSetIds: inputDepSetIds,
- Mnemonic: protoAction.Mnemonic,
- OutputIds: outputIds,
- TemplateContent: protoAction.TemplateContent,
- Substitutions: substitutions,
- FileContents: protoAction.FileContents})
- }
-
- for _, protoDepSetOfFiles := range aqueryProto.DepSetOfFiles {
- var directArtifactIds []artifactId
- var transitiveDepSetIds []depsetId
-
- for _, protoDirectArtifactIds := range protoDepSetOfFiles.DirectArtifactIds {
- directArtifactIds = append(directArtifactIds, artifactId(protoDirectArtifactIds))
- }
- for _, protoTransitiveDepSetIds := range protoDepSetOfFiles.TransitiveDepSetIds {
- transitiveDepSetIds = append(transitiveDepSetIds, depsetId(protoTransitiveDepSetIds))
- }
- aqueryResult.DepSetOfFiles = append(aqueryResult.DepSetOfFiles,
- depSetOfFiles{
- Id: depsetId(protoDepSetOfFiles.Id),
- DirectArtifactIds: directArtifactIds,
- TransitiveDepSetIds: transitiveDepSetIds})
-
- }
-
- for _, protoPathFragments := range aqueryProto.PathFragments {
- aqueryResult.PathFragments = append(aqueryResult.PathFragments,
- pathFragment{
- Id: pathFragmentId(protoPathFragments.Id),
- Label: protoPathFragments.Label,
- ParentId: pathFragmentId(protoPathFragments.ParentId)})
-
- }
var aqueryHandler *aqueryArtifactHandler
{
eventHandler.Begin("init_handler")
defer eventHandler.End("init_handler")
- aqueryHandler, err = newAqueryHandler(aqueryResult)
+ aqueryHandler, err = newAqueryHandler(aqueryProto)
if err != nil {
return nil, nil, err
}
}
- var buildStatements []BuildStatement
+ // allocate both length and capacity so each goroutine can write to an index independently without
+ // any need for synchronization for slice access.
+ buildStatements := make([]*BuildStatement, len(aqueryProto.Actions))
{
eventHandler.Begin("build_statements")
defer eventHandler.End("build_statements")
- for _, actionEntry := range aqueryResult.Actions {
- if shouldSkipAction(actionEntry) {
- continue
- }
+ wg := sync.WaitGroup{}
+ var errOnce sync.Once
- var buildStatement BuildStatement
- if actionEntry.isSymlinkAction() {
- buildStatement, err = aqueryHandler.symlinkActionBuildStatement(actionEntry)
- } else if actionEntry.isTemplateExpandAction() && len(actionEntry.Arguments) < 1 {
- buildStatement, err = aqueryHandler.templateExpandActionBuildStatement(actionEntry)
- } else if actionEntry.isFileWriteAction() {
- buildStatement, err = aqueryHandler.fileWriteActionBuildStatement(actionEntry)
- } else if actionEntry.isSymlinkTreeAction() {
- buildStatement, err = aqueryHandler.symlinkTreeActionBuildStatement(actionEntry)
- } else if len(actionEntry.Arguments) < 1 {
- err = fmt.Errorf("received action with no command: [%s]", actionEntry.Mnemonic)
- } else {
- buildStatement, err = aqueryHandler.normalActionBuildStatement(actionEntry)
- }
-
- if err != nil {
- return nil, nil, err
- }
- buildStatements = append(buildStatements, buildStatement)
+ for i, actionEntry := range aqueryProto.Actions {
+ wg.Add(1)
+ go func(i int, actionEntry *analysis_v2_proto.Action) {
+ buildStatement, aErr := aqueryHandler.actionToBuildStatement(actionEntry)
+ if aErr != nil {
+ errOnce.Do(func() {
+ err = aErr
+ })
+ } else {
+ // set build statement at an index rather than appending such that each goroutine does not
+ // impact other goroutines
+ buildStatements[i] = buildStatement
+ }
+ wg.Done()
+ }(i, actionEntry)
}
+ wg.Wait()
+ }
+ if err != nil {
+ return nil, nil, err
}
depsetsByHash := map[string]AqueryDepset{}
- var depsets []AqueryDepset
+ depsets := make([]AqueryDepset, 0, len(aqueryHandler.depsetIdToAqueryDepset))
{
eventHandler.Begin("depsets")
defer eventHandler.End("depsets")
@@ -455,7 +394,13 @@
// output). Note they are not sorted by their original IDs nor their Bazel ordering,
// as Bazel gives nondeterministic ordering / identifiers in aquery responses.
sort.Slice(buildStatements, func(i, j int) bool {
- // For build statements, compare output lists. In Bazel, each output file
+ // Sort all nil statements to the end of the slice
+ if buildStatements[i] == nil {
+ return false
+ } else if buildStatements[j] == nil {
+ return true
+ }
+ //For build statements, compare output lists. In Bazel, each output file
// may only have one action which generates it, so this will provide
// a deterministic ordering.
outputs_i := buildStatements[i].OutputPaths
@@ -493,12 +438,13 @@
return fullHash
}
-func (a *aqueryArtifactHandler) depsetContentHashes(inputDepsetIds []depsetId) ([]string, error) {
+func (a *aqueryArtifactHandler) depsetContentHashes(inputDepsetIds []uint32) ([]string, error) {
var hashes []string
- for _, depsetId := range inputDepsetIds {
- if aqueryDepset, exists := a.depsetIdToAqueryDepset[depsetId]; !exists {
- if _, empty := a.emptyDepsetIds[depsetId]; !empty {
- return nil, fmt.Errorf("undefined (not even empty) input depsetId %d", depsetId)
+ for _, id := range inputDepsetIds {
+ dId := depsetId(id)
+ if aqueryDepset, exists := a.depsetIdToAqueryDepset[dId]; !exists {
+ if _, empty := a.emptyDepsetIds[dId]; !empty {
+ return nil, fmt.Errorf("undefined (not even empty) input depsetId %d", dId)
}
} else {
hashes = append(hashes, aqueryDepset.ContentHash)
@@ -507,18 +453,18 @@
return hashes, nil
}
-func (a *aqueryArtifactHandler) normalActionBuildStatement(actionEntry action) (BuildStatement, error) {
+func (a *aqueryArtifactHandler) normalActionBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
command := strings.Join(proptools.ShellEscapeListIncludingSpaces(actionEntry.Arguments), " ")
inputDepsetHashes, err := a.depsetContentHashes(actionEntry.InputDepSetIds)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
outputPaths, depfile, err := a.getOutputPaths(actionEntry)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
- buildStatement := BuildStatement{
+ buildStatement := &BuildStatement{
Command: command,
Depfile: depfile,
OutputPaths: outputPaths,
@@ -529,13 +475,13 @@
return buildStatement, nil
}
-func (a *aqueryArtifactHandler) templateExpandActionBuildStatement(actionEntry action) (BuildStatement, error) {
+func (a *aqueryArtifactHandler) templateExpandActionBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
outputPaths, depfile, err := a.getOutputPaths(actionEntry)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
if len(outputPaths) != 1 {
- return BuildStatement{}, fmt.Errorf("Expect 1 output to template expand action, got: output %q", outputPaths)
+ return nil, fmt.Errorf("Expect 1 output to template expand action, got: output %q", outputPaths)
}
expandedTemplateContent := expandTemplateContent(actionEntry)
// The expandedTemplateContent is escaped for being used in double quotes and shell unescape,
@@ -547,10 +493,10 @@
escapeCommandlineArgument(expandedTemplateContent), outputPaths[0])
inputDepsetHashes, err := a.depsetContentHashes(actionEntry.InputDepSetIds)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
- buildStatement := BuildStatement{
+ buildStatement := &BuildStatement{
Command: command,
Depfile: depfile,
OutputPaths: outputPaths,
@@ -561,16 +507,16 @@
return buildStatement, nil
}
-func (a *aqueryArtifactHandler) fileWriteActionBuildStatement(actionEntry action) (BuildStatement, error) {
+func (a *aqueryArtifactHandler) fileWriteActionBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
outputPaths, _, err := a.getOutputPaths(actionEntry)
var depsetHashes []string
if err == nil {
depsetHashes, err = a.depsetContentHashes(actionEntry.InputDepSetIds)
}
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
- return BuildStatement{
+ return &BuildStatement{
Depfile: nil,
OutputPaths: outputPaths,
Env: actionEntry.EnvironmentVariables,
@@ -580,20 +526,20 @@
}, nil
}
-func (a *aqueryArtifactHandler) symlinkTreeActionBuildStatement(actionEntry action) (BuildStatement, error) {
+func (a *aqueryArtifactHandler) symlinkTreeActionBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
outputPaths, _, err := a.getOutputPaths(actionEntry)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
inputPaths, err := a.getInputPaths(actionEntry.InputDepSetIds)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
if len(inputPaths) != 1 || len(outputPaths) != 1 {
- return BuildStatement{}, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths)
+ return nil, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths)
}
// The actual command is generated in bazelSingleton.GenerateBuildActions
- return BuildStatement{
+ return &BuildStatement{
Depfile: nil,
OutputPaths: outputPaths,
Env: actionEntry.EnvironmentVariables,
@@ -602,18 +548,18 @@
}, nil
}
-func (a *aqueryArtifactHandler) symlinkActionBuildStatement(actionEntry action) (BuildStatement, error) {
+func (a *aqueryArtifactHandler) symlinkActionBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
outputPaths, depfile, err := a.getOutputPaths(actionEntry)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
inputPaths, err := a.getInputPaths(actionEntry.InputDepSetIds)
if err != nil {
- return BuildStatement{}, err
+ return nil, err
}
if len(inputPaths) != 1 || len(outputPaths) != 1 {
- return BuildStatement{}, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths)
+ return nil, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths)
}
out := outputPaths[0]
outDir := proptools.ShellEscapeIncludingSpaces(filepath.Dir(out))
@@ -623,7 +569,7 @@
command := fmt.Sprintf("mkdir -p %[1]s && rm -f %[2]s && ln -sf %[3]s %[2]s", outDir, out, in)
symlinkPaths := outputPaths[:]
- buildStatement := BuildStatement{
+ buildStatement := &BuildStatement{
Command: command,
Depfile: depfile,
OutputPaths: outputPaths,
@@ -635,9 +581,9 @@
return buildStatement, nil
}
-func (a *aqueryArtifactHandler) getOutputPaths(actionEntry action) (outputPaths []string, depfile *string, err error) {
+func (a *aqueryArtifactHandler) getOutputPaths(actionEntry *analysis_v2_proto.Action) (outputPaths []string, depfile *string, err error) {
for _, outputId := range actionEntry.OutputIds {
- outputPath, exists := a.artifactIdToPath[outputId]
+ outputPath, exists := a.artifactIdToPath[artifactId(outputId)]
if !exists {
err = fmt.Errorf("undefined outputId %d", outputId)
return
@@ -658,14 +604,15 @@
}
// expandTemplateContent substitutes the tokens in a template.
-func expandTemplateContent(actionEntry action) string {
- var replacerString []string
- for _, pair := range actionEntry.Substitutions {
+func expandTemplateContent(actionEntry *analysis_v2_proto.Action) string {
+ replacerString := make([]string, len(actionEntry.Substitutions)*2)
+ for i, pair := range actionEntry.Substitutions {
value := pair.Value
if val, ok := templateActionOverriddenTokens[pair.Key]; ok {
value = val
}
- replacerString = append(replacerString, pair.Key, value)
+ replacerString[i*2] = pair.Key
+ replacerString[i*2+1] = value
}
replacer := strings.NewReplacer(replacerString...)
return replacer.Replace(actionEntry.TemplateContent)
@@ -685,44 +632,41 @@
return commandLineArgumentReplacer.Replace(str)
}
-func (a action) isSymlinkAction() bool {
- return a.Mnemonic == "Symlink" || a.Mnemonic == "SolibSymlink" || a.Mnemonic == "ExecutableSymlink"
-}
-
-func (a action) isTemplateExpandAction() bool {
- return a.Mnemonic == "TemplateExpand"
-}
-
-func (a action) isFileWriteAction() bool {
- return a.Mnemonic == "FileWrite" || a.Mnemonic == "SourceSymlinkManifest"
-}
-
-func (a action) isSymlinkTreeAction() bool {
- return a.Mnemonic == "SymlinkTree"
-}
-
-func shouldSkipAction(a action) bool {
+func (a *aqueryArtifactHandler) actionToBuildStatement(actionEntry *analysis_v2_proto.Action) (*BuildStatement, error) {
+ switch actionEntry.Mnemonic {
// Middleman actions are not handled like other actions; they are handled separately as a
// preparatory step so that their inputs may be relayed to actions depending on middleman
// artifacts.
- if a.Mnemonic == "Middleman" {
- return true
- }
+ case middlemanMnemonic:
+ return nil, nil
// PythonZipper is bogus action returned by aquery, ignore it (b/236198693)
- if a.Mnemonic == "PythonZipper" {
- return true
- }
+ case "PythonZipper":
+ return nil, nil
// Skip "Fail" actions, which are placeholder actions designed to always fail.
- if a.Mnemonic == "Fail" {
- return true
+ case "Fail":
+ return nil, nil
+ case "BaselineCoverage":
+ return nil, nil
+ case "Symlink", "SolibSymlink", "ExecutableSymlink":
+ return a.symlinkActionBuildStatement(actionEntry)
+ case "TemplateExpand":
+ if len(actionEntry.Arguments) < 1 {
+ return a.templateExpandActionBuildStatement(actionEntry)
+ }
+ case "FileWrite", "SourceSymlinkManifest":
+ return a.fileWriteActionBuildStatement(actionEntry)
+ case "SymlinkTree":
+ return a.symlinkTreeActionBuildStatement(actionEntry)
}
- if a.Mnemonic == "BaselineCoverage" {
- return true
+
+ if len(actionEntry.Arguments) < 1 {
+ return nil, fmt.Errorf("received action with no command: [%s]", actionEntry.Mnemonic)
}
- return false
+ return a.normalActionBuildStatement(actionEntry)
+
}
-func expandPathFragment(id pathFragmentId, pathFragmentsMap map[pathFragmentId]pathFragment) (string, error) {
+func expandPathFragment(id pathFragmentId, pathFragmentsMap map[pathFragmentId]*analysis_v2_proto.PathFragment) (string, error) {
var labels []string
currId := id
// Only positive IDs are valid for path fragments. An ID of zero indicates a terminal node.
@@ -732,10 +676,11 @@
return "", fmt.Errorf("undefined path fragment id %d", currId)
}
labels = append([]string{currFragment.Label}, labels...)
- if currId == currFragment.ParentId {
+ parentId := pathFragmentId(currFragment.ParentId)
+ if currId == parentId {
return "", fmt.Errorf("fragment cannot refer to itself as parent %#v", currFragment)
}
- currId = currFragment.ParentId
+ currId = parentId
}
return filepath.Join(labels...), nil
}
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index c6b139e..19a584f 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -139,17 +139,17 @@
return
}
actualbuildStatements, actualDepsets, _ := AqueryBuildStatements(data, &metrics.EventHandler{})
- var expectedBuildStatements []BuildStatement
+ var expectedBuildStatements []*BuildStatement
for _, arch := range []string{"arm", "arm64", "x86", "x86_64"} {
expectedBuildStatements = append(expectedBuildStatements,
- BuildStatement{
+ &BuildStatement{
Command: fmt.Sprintf(
"/bin/bash -c 'source ../bazel_tools/tools/genrule/genrule-setup.sh; ../sourceroot/bionic/libc/tools/gensyscalls.py %s ../sourceroot/bionic/libc/SYSCALLS.TXT > bazel-out/sourceroot/k8-fastbuild/bin/bionic/libc/syscalls-%s.S'",
arch, arch),
OutputPaths: []string{
fmt.Sprintf("bazel-out/sourceroot/k8-fastbuild/bin/bionic/libc/syscalls-%s.S", arch),
},
- Env: []KeyValuePair{
+ Env: []*analysis_v2_proto.KeyValuePair{
{Key: "PATH", Value: "/bin:/usr/bin:/usr/local/bin"},
},
Mnemonic: "Genrule",
@@ -487,11 +487,12 @@
}
actualbuildStatements, actualDepsets, _ := AqueryBuildStatements(data, &metrics.EventHandler{})
- expectedBuildStatements := []BuildStatement{
- {
- Command: "/bin/bash -c 'touch bazel-out/sourceroot/k8-fastbuild/bin/testpkg/test_out'",
- OutputPaths: []string{"bazel-out/sourceroot/k8-fastbuild/bin/testpkg/test_out"},
- Mnemonic: "Action",
+ expectedBuildStatements := []*BuildStatement{
+ &BuildStatement{
+ Command: "/bin/bash -c 'touch bazel-out/sourceroot/k8-fastbuild/bin/testpkg/test_out'",
+ OutputPaths: []string{"bazel-out/sourceroot/k8-fastbuild/bin/testpkg/test_out"},
+ Mnemonic: "Action",
+ SymlinkPaths: []string{},
},
}
assertBuildStatements(t, expectedBuildStatements, actualbuildStatements)
@@ -544,12 +545,13 @@
if err != nil {
t.Errorf("Unexpected error %q", err)
}
- assertBuildStatements(t, []BuildStatement{
- {
- Command: "",
- OutputPaths: []string{"foo.runfiles/MANIFEST"},
- Mnemonic: "SymlinkTree",
- InputPaths: []string{"foo.manifest"},
+ assertBuildStatements(t, []*BuildStatement{
+ &BuildStatement{
+ Command: "",
+ OutputPaths: []string{"foo.runfiles/MANIFEST"},
+ Mnemonic: "SymlinkTree",
+ InputPaths: []string{"foo.manifest"},
+ SymlinkPaths: []string{},
},
}, actual)
}
@@ -613,10 +615,11 @@
t.Errorf("dependency ../dep2 expected but not found")
}
- expectedBuildStatement := BuildStatement{
- Command: "bogus command",
- OutputPaths: []string{"output"},
- Mnemonic: "x",
+ expectedBuildStatement := &BuildStatement{
+ Command: "bogus command",
+ OutputPaths: []string{"output"},
+ Mnemonic: "x",
+ SymlinkPaths: []string{},
}
buildStatementFound := false
for _, actualBuildStatement := range actualBuildStatements {
@@ -689,7 +692,7 @@
return
}
- expectedBuildStatement := BuildStatement{
+ expectedBuildStatement := &BuildStatement{
Command: "bogus command",
OutputPaths: []string{"output"},
Mnemonic: "x",
@@ -754,8 +757,8 @@
if err != nil {
t.Errorf("Unexpected error %q", err)
}
- if expected := 1; len(actualBuildStatements) != expected {
- t.Fatalf("Expected %d build statements, got %d", expected, len(actualBuildStatements))
+ if expected := 2; len(actualBuildStatements) != expected {
+ t.Fatalf("Expected %d build statements, got %d %#v", expected, len(actualBuildStatements), actualBuildStatements)
}
expectedDepsetFiles := [][]string{
@@ -780,6 +783,11 @@
if !reflect.DeepEqual(actualFlattenedInputs, expectedFlattenedInputs) {
t.Errorf("Expected flattened inputs %v, but got %v", expectedFlattenedInputs, actualFlattenedInputs)
}
+
+ bs = actualBuildStatements[1]
+ if bs != nil {
+ t.Errorf("Expected nil action for skipped")
+ }
}
// Returns the contents of given depsets in concatenated post order.
@@ -853,8 +861,8 @@
t.Errorf("Unexpected error %q", err)
}
- expectedBuildStatements := []BuildStatement{
- {
+ expectedBuildStatements := []*BuildStatement{
+ &BuildStatement{
Command: "mkdir -p one/symlink_subdir && " +
"rm -f one/symlink_subdir/symlink && " +
"ln -sf $PWD/one/file_subdir/file one/symlink_subdir/symlink",
@@ -901,8 +909,8 @@
t.Errorf("Unexpected error %q", err)
}
- expectedBuildStatements := []BuildStatement{
- {
+ expectedBuildStatements := []*BuildStatement{
+ &BuildStatement{
Command: "mkdir -p 'one/symlink subdir' && " +
"rm -f 'one/symlink subdir/symlink' && " +
"ln -sf $PWD/'one/file subdir/file' 'one/symlink subdir/symlink'",
@@ -1011,12 +1019,13 @@
t.Errorf("Unexpected error %q", err)
}
- expectedBuildStatements := []BuildStatement{
- {
+ expectedBuildStatements := []*BuildStatement{
+ &BuildStatement{
Command: "/bin/bash -c 'echo \"Test template substitutions: abcd, python3\" | sed \"s/\\\\\\\\n/\\\\n/g\" > template_file && " +
"chmod a+x template_file'",
- OutputPaths: []string{"template_file"},
- Mnemonic: "TemplateExpand",
+ OutputPaths: []string{"template_file"},
+ Mnemonic: "TemplateExpand",
+ SymlinkPaths: []string{},
},
}
assertBuildStatements(t, expectedBuildStatements, actual)
@@ -1080,11 +1089,12 @@
if err != nil {
t.Errorf("Unexpected error %q", err)
}
- assertBuildStatements(t, []BuildStatement{
- {
+ assertBuildStatements(t, []*BuildStatement{
+ &BuildStatement{
OutputPaths: []string{"foo.manifest"},
Mnemonic: "FileWrite",
FileContents: "file data\n",
+ SymlinkPaths: []string{},
},
}, actual)
}
@@ -1117,10 +1127,11 @@
if err != nil {
t.Errorf("Unexpected error %q", err)
}
- assertBuildStatements(t, []BuildStatement{
- {
- OutputPaths: []string{"foo.manifest"},
- Mnemonic: "SourceSymlinkManifest",
+ assertBuildStatements(t, []*BuildStatement{
+ &BuildStatement{
+ OutputPaths: []string{"foo.manifest"},
+ Mnemonic: "SourceSymlinkManifest",
+ SymlinkPaths: []string{},
},
}, actual)
}
@@ -1136,7 +1147,7 @@
// Asserts that the given actual build statements match the given expected build statements.
// Build statement equivalence is determined using buildStatementEquals.
-func assertBuildStatements(t *testing.T, expected []BuildStatement, actual []BuildStatement) {
+func assertBuildStatements(t *testing.T, expected []*BuildStatement, actual []*BuildStatement) {
t.Helper()
if len(expected) != len(actual) {
t.Errorf("expected %d build statements, but got %d,\n expected: %#v,\n actual: %#v",
@@ -1144,8 +1155,13 @@
return
}
type compareFn = func(i int, j int) bool
- byCommand := func(slice []BuildStatement) compareFn {
+ byCommand := func(slice []*BuildStatement) compareFn {
return func(i int, j int) bool {
+ if slice[i] == nil {
+ return false
+ } else if slice[j] == nil {
+ return false
+ }
return slice[i].Command < slice[j].Command
}
}
@@ -1161,7 +1177,10 @@
}
}
-func buildStatementEquals(first BuildStatement, second BuildStatement) string {
+func buildStatementEquals(first *BuildStatement, second *BuildStatement) string {
+ if (first == nil) != (second == nil) {
+ return "Nil"
+ }
if first.Mnemonic != second.Mnemonic {
return "Mnemonic"
}
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 fe156df..a39ed7d 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -365,7 +365,7 @@
{
description: "nocrt: true",
soongProperty: `nocrt: true,`,
- bazelAttr: AttrNameToString{"link_crt": `False`},
+ bazelAttr: AttrNameToString{"features": `["-link_crt"]`},
},
{
description: "nocrt: false",
@@ -408,12 +408,12 @@
{
description: "no_libcrt: true",
soongProperty: `no_libcrt: true,`,
- bazelAttr: AttrNameToString{"use_libcrt": `False`},
+ bazelAttr: AttrNameToString{"features": `["-use_libcrt"]`},
},
{
description: "no_libcrt: false",
soongProperty: `no_libcrt: false,`,
- bazelAttr: AttrNameToString{"use_libcrt": `True`},
+ bazelAttr: AttrNameToString{},
},
{
description: "no_libcrt: not set",
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c11a50d..af14f64 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1308,7 +1308,7 @@
func TestCCLibraryNoCrtTrue(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
- Description: "cc_library - nocrt: true emits attribute",
+ Description: "cc_library - nocrt: true disables feature",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Filesystem: map[string]string{
@@ -1323,7 +1323,7 @@
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
- "link_crt": `False`,
+ "features": `["-link_crt"]`,
"srcs": `["impl.cpp"]`,
}),
},
@@ -1375,7 +1375,13 @@
include_build_directory: false,
}
`,
- ExpectedErr: fmt.Errorf("module \"foo-lib\": nocrt is not supported for arch variants"),
+ ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
+ "features": `select({
+ "//build/bazel/platforms/arch:arm": ["-link_crt"],
+ "//conditions:default": [],
+ })`,
+ "srcs": `["impl.cpp"]`,
+ }),
})
}
@@ -1395,8 +1401,8 @@
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `False`,
+ "features": `["-use_libcrt"]`,
+ "srcs": `["impl.cpp"]`,
}),
})
}
@@ -1445,8 +1451,7 @@
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `True`,
+ "srcs": `["impl.cpp"]`,
}),
})
}
@@ -1475,10 +1480,10 @@
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
"srcs": `["impl.cpp"]`,
- "use_libcrt": `select({
- "//build/bazel/platforms/arch:arm": False,
- "//build/bazel/platforms/arch:x86": False,
- "//conditions:default": None,
+ "features": `select({
+ "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
+ "//build/bazel/platforms/arch:x86": ["-use_libcrt"],
+ "//conditions:default": [],
})`,
}),
})
@@ -1512,17 +1517,15 @@
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
- "srcs": `["impl.cpp"]`,
- "use_libcrt": `select({
- "//build/bazel/platforms/os_arch:android_arm": False,
- "//build/bazel/platforms/os_arch:android_x86": False,
- "//build/bazel/platforms/os_arch:darwin_arm64": False,
- "//build/bazel/platforms/os_arch:darwin_x86_64": False,
- "//build/bazel/platforms/os_arch:linux_glibc_x86": False,
- "//build/bazel/platforms/os_arch:linux_musl_x86": False,
- "//build/bazel/platforms/os_arch:windows_x86": False,
- "//conditions:default": None,
+ "features": `select({
+ "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
+ "//build/bazel/platforms/arch:x86": ["-use_libcrt"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:darwin": ["-use_libcrt"],
+ "//conditions:default": [],
})`,
+ "srcs": `["impl.cpp"]`,
}),
})
}
@@ -1557,16 +1560,10 @@
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo-lib", AttrNameToString{
"srcs": `["impl.cpp"]`,
- "use_libcrt": `select({
- "//build/bazel/platforms/os_arch:android_arm": False,
- "//build/bazel/platforms/os_arch:android_x86_64": False,
- "//build/bazel/platforms/os_arch:darwin_arm64": True,
- "//build/bazel/platforms/os_arch:darwin_x86_64": False,
- "//build/bazel/platforms/os_arch:linux_bionic_x86_64": False,
- "//build/bazel/platforms/os_arch:linux_glibc_x86_64": False,
- "//build/bazel/platforms/os_arch:linux_musl_x86_64": False,
- "//build/bazel/platforms/os_arch:windows_x86_64": False,
- "//conditions:default": None,
+ "features": `select({
+ "//build/bazel/platforms/arch:arm": ["-use_libcrt"],
+ "//build/bazel/platforms/arch:x86_64": ["-use_libcrt"],
+ "//conditions:default": [],
})`,
}),
})
@@ -4087,3 +4084,56 @@
},
})
}
+
+func TestCcLibraryInApexWithStubSharedLibs(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library with in apex with stub shared_libs and export_shared_lib_headers",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "barlib",
+ stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "bazlib",
+ stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "foo",
+ shared_libs: ["barlib", "bazlib"],
+ export_shared_lib_headers: ["bazlib"],
+ apex_available: [
+ "apex_available:platform",
+ ],
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "implementation_dynamic_deps": `select({
+ "//build/bazel/rules/apex:android-in_apex": [":barlib_stub_libs_current"],
+ "//conditions:default": [":barlib"],
+ })`,
+ "dynamic_deps": `select({
+ "//build/bazel/rules/apex:android-in_apex": [":bazlib_stub_libs_current"],
+ "//conditions:default": [":bazlib"],
+ })`,
+ "local_includes": `["."]`,
+ "tags": `["apex_available=apex_available:platform"]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "implementation_dynamic_deps": `select({
+ "//build/bazel/rules/apex:android-in_apex": [":barlib_stub_libs_current"],
+ "//conditions:default": [":barlib"],
+ })`,
+ "dynamic_deps": `select({
+ "//build/bazel/rules/apex:android-in_apex": [":bazlib_stub_libs_current"],
+ "//conditions:default": [":bazlib"],
+ })`,
+ "local_includes": `["."]`,
+ "tags": `["apex_available=apex_available:platform"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 017df6f..6207421 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -15,7 +15,6 @@
package bp2build
import (
- "fmt"
"testing"
"android/soong/android"
@@ -405,7 +404,7 @@
func TestCcLibrarySharedNoCrtTrue(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared - nocrt: true emits attribute",
+ Description: "cc_library_shared - nocrt: true disables feature",
Filesystem: map[string]string{
"impl.cpp": "",
},
@@ -419,7 +418,7 @@
`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
- "link_crt": `False`,
+ "features": `["-link_crt"]`,
"srcs": `["impl.cpp"]`,
}),
},
@@ -428,7 +427,7 @@
func TestCcLibrarySharedNoCrtFalse(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared - nocrt: false doesn't emit attribute",
+ Description: "cc_library_shared - nocrt: false doesn't disable feature",
Filesystem: map[string]string{
"impl.cpp": "",
},
@@ -469,7 +468,15 @@
include_build_directory: false,
}
`,
- ExpectedErr: fmt.Errorf("module \"foo_shared\": nocrt is not supported for arch variants"),
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo_shared", AttrNameToString{
+ "features": `select({
+ "//build/bazel/platforms/arch:arm": ["-link_crt"],
+ "//conditions:default": [],
+ })`,
+ "srcs": `["impl.cpp"]`,
+ }),
+ },
})
}
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 73df675..6a39e25 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -59,6 +59,7 @@
return nil, err
}
files = append(files, newFile("api_levels", GeneratedBuildFileName, `exports_files(["api_levels.json"])`))
+ // TODO(b/269691302) value of apiLevelsContent is product variable dependent and should be avoided for soong injection
files = append(files, newFile("api_levels", "api_levels.json", string(apiLevelsContent)))
files = append(files, newFile("api_levels", "api_levels.bzl", android.StarlarkApiLevelConfigs(cfg)))
@@ -104,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/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/androidmk.go b/cc/androidmk.go
index ce35b5c..980dd07 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -124,14 +124,17 @@
}
}
}
- if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake {
+ if c.Properties.IsSdkVariant {
// Make the SDK variant uninstallable so that there are not two rules to install
// to the same location.
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
- // Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
- // dependencies to the .sdk suffix when building a module that uses the SDK.
- entries.SetString("SOONG_SDK_VARIANT_MODULES",
- "$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
+
+ if c.Properties.SdkAndPlatformVariantVisibleToMake {
+ // Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
+ // dependencies to the .sdk suffix when building a module that uses the SDK.
+ entries.SetString("SOONG_SDK_VARIANT_MODULES",
+ "$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
+ }
}
},
},
diff --git a/cc/binary.go b/cc/binary.go
index a04b174..496c610 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -151,7 +151,7 @@
// modules common to most binaries, such as bionic libraries.
func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
deps = binary.baseLinker.linkerDeps(ctx, deps)
- if !Bool(binary.baseLinker.Properties.Nocrt) {
+ if binary.baseLinker.Properties.crt() {
if binary.static() {
deps.CrtBegin = ctx.toolchain().CrtBeginStaticBinary()
deps.CrtEnd = ctx.toolchain().CrtEndStaticBinary()
@@ -577,12 +577,12 @@
func (handler *ccBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
}
func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKey(ctx))
+ info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
if err != nil {
ctx.ModuleErrorf(err.Error())
return
@@ -630,8 +630,6 @@
Local_includes: baseAttrs.localIncludes,
Absolute_includes: baseAttrs.absoluteIncludes,
Linkopts: baseAttrs.linkopts,
- Link_crt: baseAttrs.linkCrt,
- Use_libcrt: baseAttrs.useLibcrt,
Use_version_lib: baseAttrs.useVersionLib,
Rtti: baseAttrs.rtti,
Stl: baseAttrs.stl,
@@ -695,10 +693,7 @@
Linkopts bazel.StringListAttribute
Additional_linker_inputs bazel.LabelListAttribute
-
- Link_crt bazel.BoolAttribute
- Use_libcrt bazel.BoolAttribute
- Use_version_lib bazel.BoolAttribute
+ Use_version_lib bazel.BoolAttribute
Rtti bazel.BoolAttribute
Stl *string
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 6c5505a..9751a2e 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -965,8 +965,6 @@
systemDynamicDeps bazel.LabelListAttribute
usedSystemDynamicDepAsDynamicDep map[string]bool
- linkCrt bazel.BoolAttribute
- useLibcrt bazel.BoolAttribute
useVersionLib bazel.BoolAttribute
linkopts bazel.StringListAttribute
additionalLinkerInputs bazel.LabelListAttribute
@@ -1082,43 +1080,13 @@
la.resolveTargetApexProp(ctx, props)
if axis == bazel.NoConfigAxis || (axis == bazel.OsConfigurationAxis && config == bazel.OsAndroid) {
- // If a dependency in la.implementationDynamicDeps has stubs, its stub variant should be
- // used when the dependency is linked in a APEX. The dependencies in NoConfigAxis and
- // OsConfigurationAxis/OsAndroid are grouped by having stubs or not, so Bazel select()
- // statement can be used to choose source/stub variants of them.
- depsWithStubs := []bazel.Label{}
- for _, l := range sharedDeps.implementation.Includes {
- dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
- if m, ok := dep.(*Module); ok && m.HasStubsVariants() {
- depsWithStubs = append(depsWithStubs, l)
- }
- }
- if len(depsWithStubs) > 0 {
- implDynamicDeps := bazel.SubtractBazelLabelList(sharedDeps.implementation, bazel.MakeLabelList(depsWithStubs))
- la.implementationDynamicDeps.SetSelectValue(axis, config, implDynamicDeps)
-
- stubLibLabels := []bazel.Label{}
- for _, l := range depsWithStubs {
- l.Label = l.Label + stubsSuffix
- stubLibLabels = append(stubLibLabels, l)
- }
- inApexSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex)
- nonApexSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex)
- defaultSelectValue := la.implementationDynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey)
- if axis == bazel.NoConfigAxis {
- (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
- (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
- (&defaultSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
- la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
- la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
- la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, bazel.FirstUniqueBazelLabelList(defaultSelectValue))
- } else if config == bazel.OsAndroid {
- (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
- (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
- la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
- la.implementationDynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
- }
- }
+ // If a dependency in la.implementationDynamicDeps or la.dynamicDeps has stubs, its
+ // stub variant should be used when the dependency is linked in a APEX. The
+ // dependencies in NoConfigAxis and OsConfigurationAxis/OsAndroid are grouped by
+ // having stubs or not, so Bazel select() statement can be used to choose
+ // source/stub variants of them.
+ setStubsForDynamicDeps(ctx, axis, config, sharedDeps.export, &la.dynamicDeps, 0)
+ setStubsForDynamicDeps(ctx, axis, config, sharedDeps.implementation, &la.implementationDynamicDeps, 1)
}
if !BoolDefault(props.Pack_relocations, packRelocationsDefault) {
@@ -1138,6 +1106,13 @@
}
}
+ if !props.libCrt() {
+ axisFeatures = append(axisFeatures, "-use_libcrt")
+ }
+ if !props.crt() {
+ axisFeatures = append(axisFeatures, "-link_crt")
+ }
+
// This must happen before the addition of flags for Version Script and
// Dynamic List, as these flags must be split on spaces and those must not
linkerFlags = parseCommandLineFlags(linkerFlags, filterOutClangUnknownCflags)
@@ -1157,16 +1132,6 @@
la.additionalLinkerInputs.SetSelectValue(axis, config, additionalLinkerInputs)
la.linkopts.SetSelectValue(axis, config, linkerFlags)
- la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
-
- // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it.
- if props.crt() != nil {
- if axis == bazel.NoConfigAxis {
- la.linkCrt.SetSelectValue(axis, config, props.crt())
- } else if axis == bazel.ArchConfigurationAxis {
- ctx.ModuleErrorf("nocrt is not supported for arch variants")
- }
- }
if axisFeatures != nil {
la.features.SetSelectValue(axis, config, axisFeatures)
@@ -1178,6 +1143,43 @@
}
}
+func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
+ config string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int) {
+ depsWithStubs := []bazel.Label{}
+ for _, l := range dynamicLibs.Includes {
+ dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
+ if m, ok := dep.(*Module); ok && m.HasStubsVariants() {
+ depsWithStubs = append(depsWithStubs, l)
+ }
+ }
+ if len(depsWithStubs) > 0 {
+ implDynamicDeps := bazel.SubtractBazelLabelList(dynamicLibs, bazel.MakeLabelList(depsWithStubs))
+ dynamicDeps.SetSelectValue(axis, config, implDynamicDeps)
+
+ stubLibLabels := []bazel.Label{}
+ for _, l := range depsWithStubs {
+ l.Label = l.Label + stubsSuffix
+ stubLibLabels = append(stubLibLabels, l)
+ }
+ inApexSelectValue := dynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex)
+ nonApexSelectValue := dynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex)
+ defaultSelectValue := dynamicDeps.SelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey)
+ if axis == bazel.NoConfigAxis {
+ (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
+ (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
+ (&defaultSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.ConditionsDefaultConfigKey, bazel.FirstUniqueBazelLabelList(defaultSelectValue))
+ } else if config == bazel.OsAndroid {
+ (&inApexSelectValue).Append(bazel.MakeLabelList(stubLibLabels))
+ (&nonApexSelectValue).Append(bazel.MakeLabelList(depsWithStubs))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndInApex, bazel.FirstUniqueBazelLabelList(inApexSelectValue))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, bazel.AndroidAndNonApex, bazel.FirstUniqueBazelLabelList(nonApexSelectValue))
+ }
+ }
+}
+
func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
bp2BuildPropParseHelper(ctx, module, &StripProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if stripProperties, ok := props.(*StripProperties); ok {
@@ -1261,7 +1263,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)
diff --git a/cc/cc.go b/cc/cc.go
index c81160d..c07d836 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1905,10 +1905,32 @@
}
// TODO(b/261058727): Remove this (enable mixed builds for modules with UBSan)
- ubsanEnabled := c.sanitize != nil &&
- ((c.sanitize.Properties.Sanitize.Integer_overflow != nil && *c.sanitize.Properties.Sanitize.Integer_overflow) ||
- c.sanitize.Properties.Sanitize.Misc_undefined != nil)
- return c.bazelHandler != nil && !ubsanEnabled
+ // Currently we can only support ubsan when minimum runtime is used.
+ return c.bazelHandler != nil && (!isUbsanEnabled(c) || c.MinimalRuntimeNeeded())
+}
+
+func isUbsanEnabled(c *Module) bool {
+ if c.sanitize == nil {
+ return false
+ }
+ sanitizeProps := &c.sanitize.Properties.SanitizeMutated
+ return Bool(sanitizeProps.Integer_overflow) || len(sanitizeProps.Misc_undefined) > 0
+}
+
+func GetApexConfigKey(ctx android.BaseModuleContext) *android.ApexConfigKey {
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ if !apexInfo.IsForPlatform() {
+ if !ctx.Config().BazelContext.IsModuleDclaAllowed(ctx.Module().Name()) {
+ return nil
+ }
+ apexKey := android.ApexConfigKey{
+ WithinApex: true,
+ ApexSdkVersion: findApexSdkVersion(ctx, apexInfo).String(),
+ }
+ return &apexKey
+ }
+
+ return nil
}
func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {
@@ -2841,6 +2863,23 @@
}
}
+func findApexSdkVersion(ctx android.BaseModuleContext, apexInfo android.ApexInfo) android.ApiLevel {
+ // For the dependency from platform to apex, use the latest stubs
+ apexSdkVersion := android.FutureApiLevel
+ if !apexInfo.IsForPlatform() {
+ apexSdkVersion = apexInfo.MinSdkVersion
+ }
+
+ if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
+ // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
+ // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
+ // (b/144430859)
+ apexSdkVersion = android.FutureApiLevel
+ }
+
+ return apexSdkVersion
+}
+
// Convert dependencies to paths. Returns a PathDeps containing paths
func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
@@ -2856,19 +2895,8 @@
depPaths.ReexportedGeneratedHeaders = append(depPaths.ReexportedGeneratedHeaders, exporter.GeneratedHeaders...)
}
- // For the dependency from platform to apex, use the latest stubs
- c.apexSdkVersion = android.FutureApiLevel
apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- if !apexInfo.IsForPlatform() {
- c.apexSdkVersion = apexInfo.MinSdkVersion
- }
-
- if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
- // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
- // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
- // (b/144430859)
- c.apexSdkVersion = android.FutureApiLevel
- }
+ c.apexSdkVersion = findApexSdkVersion(ctx, apexInfo)
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 62adfd3..b02e037 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -28,6 +28,10 @@
"android/soong/bazel/cquery"
)
+func init() {
+ registerTestMutators(android.InitRegistrationContext)
+}
+
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
@@ -41,6 +45,36 @@
}),
)
+var ccLibInApex = "cc_lib_in_apex"
+var apexVariationName = "apex28"
+var apexVersion = "28"
+
+func registerTestMutators(ctx android.RegistrationContext) {
+ ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("apex", testApexMutator).Parallel()
+ ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
+ })
+}
+
+func mixedBuildsPrepareMutator(ctx android.BottomUpMutatorContext) {
+ if m := ctx.Module(); m.Enabled() {
+ if mixedBuildMod, ok := m.(android.MixedBuildBuildable); ok {
+ if mixedBuildMod.IsMixedBuildSupported(ctx) && android.MixedBuildsEnabled(ctx) {
+ mixedBuildMod.QueueBazelCall(ctx)
+ }
+ }
+ }
+}
+
+func testApexMutator(mctx android.BottomUpMutatorContext) {
+ modules := mctx.CreateVariations(apexVariationName)
+ apexInfo := android.ApexInfo{
+ ApexVariationName: apexVariationName,
+ MinSdkVersion: android.ApiLevelForTest(apexVersion),
+ }
+ mctx.SetVariationProvider(modules[0], android.ApexInfoProvider, apexInfo)
+}
+
// testCcWithConfig runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
@@ -3896,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) {
@@ -4906,3 +4940,56 @@
})
}
}
+
+func TestDclaLibraryInApex(t *testing.T) {
+ t.Parallel()
+ bp := `
+ cc_library_shared {
+ name: "cc_lib_in_apex",
+ srcs: ["foo.cc"],
+ apex_available: ["myapex"],
+ bazel_module: { label: "//foo/bar:bar" },
+ }`
+ label := "//foo/bar:bar"
+ arch64 := "arm64_armv8-a"
+ arch32 := "arm_armv7-a-neon"
+ apexCfgKey := android.ApexConfigKey{
+ WithinApex: true,
+ ApexSdkVersion: "28",
+ }
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ android.FixtureRegisterWithContext(registerTestMutators),
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.BazelContext = android.MockBazelContext{
+ OutputBaseDir: "outputbase",
+ LabelToCcInfo: map[string]cquery.CcInfo{
+ android.BuildMockBazelContextResultKey(label, arch32, android.Android, apexCfgKey): cquery.CcInfo{
+ RootDynamicLibraries: []string{"foo.so"},
+ },
+ android.BuildMockBazelContextResultKey(label, arch64, android.Android, apexCfgKey): cquery.CcInfo{
+ RootDynamicLibraries: []string{"foo.so"},
+ },
+ },
+ BazelRequests: make(map[string]bool),
+ }
+ }),
+ ).RunTestWithBp(t, bp)
+ ctx := result.TestContext
+
+ // Test if the bazel request is queued correctly
+ key := android.BuildMockBazelContextRequestKey(label, cquery.GetCcInfo, arch32, android.Android, apexCfgKey)
+ if !ctx.Config().BazelContext.(android.MockBazelContext).BazelRequests[key] {
+ t.Errorf("Bazel request was not queued: %s", key)
+ }
+
+ sharedFoo := ctx.ModuleForTests(ccLibInApex, "android_arm_armv7-a-neon_shared_"+apexVariationName).Module()
+ producer := sharedFoo.(android.OutputFileProducer)
+ outputFiles, err := producer.OutputFiles("")
+ if err != nil {
+ t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
+ }
+ expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
+ android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
+}
diff --git a/cc/library.go b/cc/library.go
index 9421007..61e3a93 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -243,7 +243,6 @@
Local_includes bazel.StringListAttribute
Absolute_includes bazel.StringListAttribute
Linkopts bazel.StringListAttribute
- Use_libcrt bazel.BoolAttribute
Rtti bazel.BoolAttribute
Stl *string
@@ -251,7 +250,6 @@
C_std *string
// This is shared only.
- Link_crt bazel.BoolAttribute
Additional_linker_inputs bazel.LabelListAttribute
// Common properties shared between both shared and static variants.
@@ -360,7 +358,6 @@
Export_system_includes: exportedIncludes.SystemIncludes,
Local_includes: compilerAttrs.localIncludes,
Absolute_includes: compilerAttrs.absoluteIncludes,
- Use_libcrt: linkerAttrs.useLibcrt,
Rtti: compilerAttrs.rtti,
Stl: compilerAttrs.stl,
Cpp_std: compilerAttrs.cppStd,
@@ -381,8 +378,6 @@
Local_includes: compilerAttrs.localIncludes,
Absolute_includes: compilerAttrs.absoluteIncludes,
Linkopts: linkerAttrs.linkopts,
- Link_crt: linkerAttrs.linkCrt,
- Use_libcrt: linkerAttrs.useLibcrt,
Rtti: compilerAttrs.rtti,
Stl: compilerAttrs.stl,
Cpp_std: compilerAttrs.cppStd,
@@ -915,12 +910,12 @@
func (handler *ccLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
}
func (handler *ccLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
+ ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
if err != nil {
ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
return
@@ -1500,7 +1495,7 @@
deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...)
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...)
} else if library.shared() {
- if !Bool(library.baseLinker.Properties.Nocrt) {
+ if library.baseLinker.Properties.crt() {
deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...)
deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...)
}
@@ -2884,13 +2879,10 @@
commonAttrs.Deps.Add(baseAttributes.protoDependency)
attrs = &bazelCcLibraryStaticAttributes{
staticOrSharedAttributes: commonAttrs,
-
- Use_libcrt: linkerAttrs.useLibcrt,
-
- Rtti: compilerAttrs.rtti,
- Stl: compilerAttrs.stl,
- Cpp_std: compilerAttrs.cppStd,
- C_std: compilerAttrs.cStd,
+ Rtti: compilerAttrs.rtti,
+ Stl: compilerAttrs.stl,
+ Cpp_std: compilerAttrs.cppStd,
+ C_std: compilerAttrs.cStd,
Export_includes: exportedIncludes.Includes,
Export_absolute_includes: exportedIncludes.AbsoluteIncludes,
@@ -2915,8 +2907,6 @@
Asflags: asFlags,
Linkopts: linkerAttrs.linkopts,
- Link_crt: linkerAttrs.linkCrt,
- Use_libcrt: linkerAttrs.useLibcrt,
Use_version_lib: linkerAttrs.useVersionLib,
Rtti: compilerAttrs.rtti,
@@ -2974,13 +2964,11 @@
type bazelCcLibraryStaticAttributes struct {
staticOrSharedAttributes
- Use_libcrt bazel.BoolAttribute
Use_version_lib bazel.BoolAttribute
-
- Rtti bazel.BoolAttribute
- Stl *string
- Cpp_std *string
- C_std *string
+ Rtti bazel.BoolAttribute
+ Stl *string
+ Cpp_std *string
+ C_std *string
Export_includes bazel.StringListAttribute
Export_absolute_includes bazel.StringListAttribute
@@ -3000,10 +2988,7 @@
type bazelCcLibrarySharedAttributes struct {
staticOrSharedAttributes
- Linkopts bazel.StringListAttribute
- Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary)
-
- Use_libcrt bazel.BoolAttribute
+ Linkopts bazel.StringListAttribute
Use_version_lib bazel.BoolAttribute
Rtti bazel.BoolAttribute
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 32ea1d4..1dee726 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -59,12 +59,12 @@
func (handler *libraryHeaderBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
}
func (h *libraryHeaderBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
+ ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
if err != nil {
ctx.ModuleErrorf(err.Error())
return
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/linker.go b/cc/linker.go
index 371d78d..e49b97d 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -237,29 +237,14 @@
Exclude_shared_libs []string `android:"arch_variant"`
}
-func invertBoolPtr(value *bool) *bool {
- if value == nil {
- return nil
- }
- ret := !(*value)
- return &ret
+func (blp *BaseLinkerProperties) crt() bool {
+ // Since crt is enabled for almost every module compiling against the Bionic runtime,
+ // we interpret `nil` as enabled.
+ return blp.Nocrt == nil || !*blp.Nocrt
}
-func (blp *BaseLinkerProperties) crt() *bool {
- val := invertBoolPtr(blp.Nocrt)
- if val != nil && *val {
- // == True
- //
- // Since crt is enabled for almost every module compiling against the Bionic runtime,
- // use `nil` when it's enabled, and rely on the Starlark macro to set it to True by default.
- // This keeps the BUILD files clean.
- return nil
- }
- return val // can be False or nil
-}
-
-func (blp *BaseLinkerProperties) libCrt() *bool {
- return invertBoolPtr(blp.No_libcrt)
+func (blp *BaseLinkerProperties) libCrt() bool {
+ return blp.No_libcrt == nil || !*blp.No_libcrt
}
func NewBaseLinker(sanitize *sanitize) *baseLinker {
@@ -392,7 +377,7 @@
if ctx.toolchain().Bionic() {
// libclang_rt.builtins has to be last on the command line
- if !Bool(linker.Properties.No_libcrt) && !ctx.header() {
+ if linker.Properties.libCrt() && !ctx.header() {
deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
}
@@ -415,7 +400,7 @@
ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc")
}
} else if ctx.toolchain().Musl() {
- if !Bool(linker.Properties.No_libcrt) && !ctx.header() {
+ if linker.Properties.libCrt() && !ctx.header() {
deps.UnexportedStaticLibs = append(deps.UnexportedStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
}
}
diff --git a/cc/object.go b/cc/object.go
index 11ce793..ef44467 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -54,12 +54,12 @@
func (handler *objectBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
}
func (handler *objectBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- objPaths, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+ objPaths, err := bazelCtx.GetOutputFiles(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
if err != nil {
ctx.ModuleErrorf(err.Error())
return
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 03a600a..bb517ea 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -761,12 +761,12 @@
func (h *prebuiltBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
+ bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
}
func (h *prebuiltBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
bazelCtx := ctx.Config().BazelContext
- outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+ outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
if err != nil {
ctx.ModuleErrorf(err.Error())
return
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 3e50c9f..23dd0cb 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -47,16 +47,16 @@
// Mark the SDK variant.
modules[1].(*Module).Properties.IsSdkVariant = true
+ // SDK variant is not supposed to be installed
+ modules[1].(*Module).Properties.PreventInstall = true
if ctx.Config().UnbundledBuildApps() {
// For an unbundled apps build, hide the platform variant from Make.
modules[0].(*Module).Properties.HideFromMake = true
- modules[0].(*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[1].(*Module).Properties.PreventInstall = true
}
ctx.AliasVariation("")
} else if isCcModule && ccModule.isImportedApiLibrary() {
@@ -64,16 +64,19 @@
if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
// Handle cc_api_library module with NDK stubs and variants only which can use SDK
modules := ctx.CreateVariations("", "sdk")
+
+ // Mark the SDK variant.
modules[1].(*Module).Properties.IsSdkVariant = true
+ // SDK variant is not supposed to be installed
+ modules[1].(*Module).Properties.PreventInstall = true
+
if ctx.Config().UnbundledBuildApps() {
// For an unbundled apps build, hide the platform variant from Make.
modules[0].(*Module).Properties.HideFromMake = true
- modules[0].(*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[1].(*Module).Properties.PreventInstall = true
}
} else {
ccModule.Properties.Sdk_version = nil
diff --git a/cc/sdk_test.go b/cc/sdk_test.go
index 61925e3..790440c 100644
--- a/cc/sdk_test.go
+++ b/cc/sdk_test.go
@@ -101,3 +101,95 @@
assertDep(t, libsdkNDK, libcxxNDK)
assertDep(t, libsdkPlatform, libcxxPlatform)
}
+
+func TestMakeModuleNameForSdkVariant(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libfoo",
+ srcs: ["main_test.cpp"],
+ sdk_version: "current",
+ stl: "none",
+ }
+ `
+ platformVariant := "android_arm64_armv8-a_shared"
+ sdkVariant := "android_arm64_armv8-a_sdk_shared"
+ testCases := []struct {
+ name string
+ unbundledApps []string
+ variant string
+ skipInstall bool // soong skips install
+ hideFromMake bool // no make entry
+ makeUninstallable bool // make skips install
+ makeModuleName string
+ }{
+ {
+ name: "platform variant in normal builds",
+ unbundledApps: nil,
+ variant: platformVariant,
+ // installable in soong
+ skipInstall: false,
+ // visiable in Make as "libfoo"
+ hideFromMake: false,
+ makeModuleName: "libfoo",
+ // installable in Make
+ makeUninstallable: false,
+ },
+ {
+ name: "sdk variant in normal builds",
+ unbundledApps: nil,
+ variant: sdkVariant,
+ // soong doesn't install
+ skipInstall: true,
+ // visible in Make as "libfoo.sdk"
+ hideFromMake: false,
+ makeModuleName: "libfoo.sdk",
+ // but not installed
+ makeUninstallable: true,
+ },
+ {
+ name: "platform variant in unbunded builds",
+ unbundledApps: []string{"bar"},
+ variant: platformVariant,
+ // installable in soong
+ skipInstall: false,
+ // hidden from make
+ hideFromMake: true,
+ },
+ {
+ name: "sdk variant in unbunded builds",
+ unbundledApps: []string{"bar"},
+ variant: sdkVariant,
+ // soong doesn't install
+ skipInstall: true,
+ // visible in Make as "libfoo"
+ hideFromMake: false,
+ makeModuleName: "libfoo",
+ // but not installed
+ makeUninstallable: true,
+ },
+ }
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ fixture := android.GroupFixturePreparers(prepareForCcTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Unbundled_build_apps = tc.unbundledApps
+ }),
+ )
+ ctx := fixture.RunTestWithBp(t, bp).TestContext
+ module := ctx.ModuleForTests("libfoo", tc.variant).Module().(*Module)
+ android.AssertBoolEquals(t, "IsSkipInstall", tc.skipInstall, module.IsSkipInstall())
+ android.AssertBoolEquals(t, "HideFromMake", tc.hideFromMake, module.HiddenFromMake())
+ if !tc.hideFromMake {
+ entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
+ android.AssertStringEquals(t, "LOCAL_MODULE",
+ tc.makeModuleName, entries.EntryMap["LOCAL_MODULE"][0])
+ actualUninstallable := false
+ if actual, ok := entries.EntryMap["LOCAL_UNINSTALLABLE_MODULE"]; ok {
+ actualUninstallable = "true" == actual[0]
+ }
+ android.AssertBoolEquals(t, "LOCAL_UNINSTALLABLE_MODULE",
+ tc.makeUninstallable, actualUninstallable)
+ }
+ })
+ }
+}
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/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 444ffd0..a65d9dd 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -188,3 +188,40 @@
android.AssertStringDoesContain(t, "Can't find --include_descriptors_from_image",
cmd, "--include_descriptors_from_image ")
}
+
+func TestFileSystemShouldInstallCoreVariantIfTargetBuildAppsIsSet(t *testing.T) {
+ context := android.GroupFixturePreparers(
+ fixture,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Unbundled_build_apps = []string{"bar"}
+ }),
+ )
+ result := context.RunTestWithBp(t, `
+ android_system_image {
+ name: "myfilesystem",
+ deps: [
+ "libfoo",
+ ],
+ linker_config_src: "linker.config.json",
+ }
+
+ cc_library {
+ name: "libfoo",
+ shared_libs: [
+ "libbar",
+ ],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libbar",
+ sdk_version: "9",
+ stl: "none",
+ }
+ `)
+
+ inputs := result.ModuleForTests("myfilesystem", "android_common").Output("deps.zip").Implicits
+ android.AssertStringListContains(t, "filesystem should have libbar even for unbundled build",
+ inputs.Strings(),
+ "out/soong/.intermediates/libbar/android_arm64_armv8-a_shared/libbar.so")
+}
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 5e5769b..8175a37 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -69,42 +69,222 @@
Dir string
}
-type PrivilegedLevel string
+type Vector string
const (
- // Environment with the most minimal permissions.
- Constrained PrivilegedLevel = "Constrained"
- // Typical execution environment running unprivileged code.
- Unprivileged = "Unprivileged"
- // May have access to elevated permissions.
- Privileged = "Privileged"
- // Trusted computing base.
- Tcb = "TCB"
- // Bootloader chain.
- Bootloader = "Bootloader"
- // Tusted execution environment.
- Tee = "Tee"
- // Secure enclave.
- Se = "Se"
- // Other.
- Other = "Other"
+ unknown_access_vector Vector = "unknown_access_vector"
+ // The code being fuzzed is reachable from a remote source, or using data
+ // provided by a remote source. For example: media codecs process media files
+ // from the internet, SMS processing handles remote message data.
+ // See
+ // https://source.android.com/docs/security/overview/updates-resources#local-vs-remote
+ // for an explanation of what's considered "remote."
+ remote = "remote"
+ // The code being fuzzed can only be reached locally, such as from an
+ // installed app. As an example, if it's fuzzing a Binder interface, it's
+ // assumed that you'd need a local app to make arbitrary Binder calls.
+ // And the app that's calling the fuzzed code does not require any privileges;
+ // any 3rd party app could make these calls.
+ local_no_privileges_required = "local_no_privileges_required"
+ // The code being fuzzed can only be called locally, and the calling process
+ // requires additional permissions that prevent arbitrary 3rd party apps from
+ // calling the code. For instance: this requires a privileged or signature
+ // permission to reach, or SELinux restrictions prevent the untrusted_app
+ // domain from calling it.
+ local_privileges_required = "local_privileges_required"
+ // The code is only callable on a PC host, not on a production Android device.
+ // For instance, this is fuzzing code used during the build process, or
+ // tooling that does not exist on a user's actual Android device.
+ host_access = "host_access"
+ // The code being fuzzed is only reachable if the user has enabled Developer
+ // Options, or has enabled a persistent Developer Options setting.
+ local_with_developer_options = "local_with_developer_options"
)
+func (vector Vector) isValidVector() bool {
+ switch vector {
+ case "",
+ unknown_access_vector,
+ remote,
+ local_no_privileges_required,
+ local_privileges_required,
+ host_access,
+ local_with_developer_options:
+ return true
+ }
+ return false
+}
+
+type ServicePrivilege string
+
+const (
+ unknown_service_privilege ServicePrivilege = "unknown_service_privilege"
+ // The code being fuzzed runs on a Secure Element. This has access to some
+ // of the most privileged data on the device, such as authentication keys.
+ // Not all devices have a Secure Element.
+ secure_element = "secure_element"
+ // The code being fuzzed runs in the TEE. The TEE is designed to be resistant
+ // to a compromised kernel, and stores sensitive data.
+ trusted_execution = "trusted_execution"
+ // The code being fuzzed has privileges beyond what arbitrary 3rd party apps
+ // have. For instance, it's running as the System UID, or it's in an SELinux
+ // domain that's able to perform calls that can't be made by 3rd party apps.
+ privileged = "privileged"
+ // The code being fuzzed is equivalent to a 3rd party app. It runs in the
+ // untrusted_app SELinux domain, or it only has privileges that are equivalent
+ // to what a 3rd party app could have.
+ unprivileged = "unprivileged"
+ // The code being fuzzed is significantly constrained, and even if it's
+ // compromised, it has significant restrictions that prevent it from
+ // performing most actions. This is significantly more restricted than
+ // UNPRIVILEGED. An example is the isolatedProcess=true setting in a 3rd
+ // party app. Or a process that's very restricted by SELinux, such as
+ // anything in the mediacodec SELinux domain.
+ constrained = "constrained"
+ // The code being fuzzed always has Negligible Security Impact. Even
+ // arbitrary out of bounds writes and full code execution would not be
+ // considered a security vulnerability. This typically only makes sense if
+ // FuzzedCodeUsage is set to FUTURE_VERSION or EXPERIMENTAL, and if
+ // AutomaticallyRouteTo is set to ALWAYS_NSI.
+ nsi = "nsi"
+ // The code being fuzzed only runs on a PC host, not on a production Android
+ // device. For instance, the fuzzer is fuzzing code used during the build
+ // process, or tooling that does not exist on a user's actual Android device.
+ host_only = "host_only"
+)
+
+func (service_privilege ServicePrivilege) isValidServicePrivilege() bool {
+ switch service_privilege {
+ case "",
+ unknown_service_privilege,
+ secure_element,
+ trusted_execution,
+ privileged,
+ unprivileged,
+ constrained,
+ nsi,
+ host_only:
+ return true
+ }
+ return false
+}
+
+type UserData string
+
+const (
+ unknown_user_data UserData = "unknown_user_data"
+ // The process being fuzzed only handles data from a single user, or from a
+ // single process or app. It's possible the process shuts down before
+ // handling data from another user/process/app, or it's possible the process
+ // only ever handles one user's/process's/app's data. As an example, some
+ // print spooler processes are started for a single document and terminate
+ // when done, so each instance only handles data from a single user/app.
+ single_user = "single_user"
+ // The process handles data from multiple users, or from multiple other apps
+ // or processes. Media processes, for instance, can handle media requests
+ // from multiple different apps without restarting. Wi-Fi and network
+ // processes handle data from multiple users, and processes, and apps.
+ multi_user = "multi_user"
+)
+
+func (user_data UserData) isValidUserData() bool {
+ switch user_data {
+ case "",
+ unknown_user_data,
+ single_user,
+ multi_user:
+ return true
+ }
+ return false
+}
+
+type FuzzedCodeUsage string
+
+const (
+ undefined FuzzedCodeUsage = "undefined"
+ unknown = "unknown"
+ // The code being fuzzed exists in a shipped version of Android and runs on
+ // devices in production.
+ shipped = "shipped"
+ // The code being fuzzed is not yet in a shipping version of Android, but it
+ // will be at some point in the future.
+ future_version = "future_version"
+ // The code being fuzzed is not in a shipping version of Android, and there
+ // are no plans to ship it in the future.
+ experimental = "experimental"
+)
+
+func (fuzzed_code_usage FuzzedCodeUsage) isValidFuzzedCodeUsage() bool {
+ switch fuzzed_code_usage {
+ case "",
+ undefined,
+ unknown,
+ shipped,
+ future_version,
+ experimental:
+ return true
+ }
+ return false
+}
+
+type AutomaticallyRouteTo string
+
+const (
+ undefined_routing AutomaticallyRouteTo = "undefined_routing"
+ // Automatically route this to the Android Automotive security team for
+ // assessment.
+ android_automotive = "android_automotive"
+ // This should not be used in fuzzer configurations. It is used internally
+ // by Severity Assigner to flag memory leak reports.
+ memory_leak = "memory_leak"
+ // Route this vulnerability to our Ittiam vendor team for assessment.
+ ittiam = "ittiam"
+ // Reports from this fuzzer are always NSI (see the NSI ServicePrivilegeEnum
+ // value for additional context). It is not possible for this code to ever
+ // have a security vulnerability.
+ always_nsi = "always_nsi"
+ // Route this vulnerability to AIDL team for assessment.
+ aidl = "aidl"
+)
+
+func (automatically_route_to AutomaticallyRouteTo) isValidAutomaticallyRouteTo() bool {
+ switch automatically_route_to {
+ case "",
+ undefined_routing,
+ android_automotive,
+ memory_leak,
+ ittiam,
+ always_nsi,
+ aidl:
+ return true
+ }
+ return false
+}
+
func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool {
var config = fuzzModule.FuzzProperties.Fuzz_config
if config != nil {
- var level = PrivilegedLevel(config.Privilege_level)
- if level != "" {
- switch level {
- case Constrained, Unprivileged, Privileged, Tcb, Bootloader, Tee, Se, Other:
- return true
- }
- panic(fmt.Errorf("Invalid privileged level in fuzz config in %s", moduleName))
+ if !config.Vector.isValidVector() {
+ panic(fmt.Errorf("Invalid vector in fuzz config in %s", moduleName))
}
- return true
- } else {
- return false
+
+ if !config.Service_privilege.isValidServicePrivilege() {
+ panic(fmt.Errorf("Invalid service_privilege in fuzz config in %s", moduleName))
+ }
+
+ if !config.Users.isValidUserData() {
+ panic(fmt.Errorf("Invalid users (user_data) in fuzz config in %s", moduleName))
+ }
+
+ if !config.Fuzzed_code_usage.isValidFuzzedCodeUsage() {
+ panic(fmt.Errorf("Invalid fuzzed_code_usage in fuzz config in %s", moduleName))
+ }
+
+ if !config.Automatically_route_to.isValidAutomaticallyRouteTo() {
+ panic(fmt.Errorf("Invalid automatically_route_to in fuzz config in %s", moduleName))
+ }
}
+ return true
}
type FuzzConfig struct {
@@ -112,19 +292,24 @@
Cc []string `json:"cc,omitempty"`
// A brief description of what the fuzzed code does.
Description string `json:"description,omitempty"`
- // Can this code be triggered remotely or only locally.
- Remotely_accessible *bool `json:"remotely_accessible,omitempty"`
- // Is the fuzzed code host only, i.e. test frameworks or support utilities.
- Host_only *bool `json:"host_only,omitempty"`
+ // Whether the code being fuzzed is remotely accessible or requires privileges
+ // to access locally.
+ Vector Vector `json:"vector,omitempty"`
+ // How privileged the service being fuzzed is.
+ Service_privilege ServicePrivilege `json:"service_privilege,omitempty"`
+ // Whether the service being fuzzed handles data from multiple users or only
+ // a single one.
+ Users UserData `json:"users,omitempty"`
+ // Specifies the use state of the code being fuzzed. This state factors into
+ // how an issue is handled.
+ Fuzzed_code_usage FuzzedCodeUsage `json:"fuzzed_code_usage,omitempty"`
+ // Comment describing how we came to these settings for this fuzzer.
+ Config_comment string
+ // Which team to route this to, if it should be routed automatically.
+ Automatically_route_to AutomaticallyRouteTo `json:"automatically_route_to,omitempty"`
// Can third party/untrusted apps supply data to fuzzed code.
Untrusted_data *bool `json:"untrusted_data,omitempty"`
- // Is the code being fuzzed in a privileged, constrained or any other
- // context from:
- // https://source.android.com/security/overview/updates-resources#context_types.
- Privilege_level PrivilegedLevel `json:"privilege_level,omitempty"`
- // Can the fuzzed code isolated or can be called by multiple users/processes.
- Isolated *bool `json:"users_isolation,omitempty"`
- // When code was relaeased or will be released.
+ // When code was released or will be released.
Production_date string `json:"production_date,omitempty"`
// Prevents critical service functionality like phone calls, bluetooth, etc.
Critical *bool `json:"critical,omitempty"`
@@ -134,7 +319,7 @@
Fuzz_on_haiku_host *bool `json:"fuzz_on_haiku_host,omitempty"`
// Component in Google's bug tracking system that bugs should be filed to.
Componentid *int64 `json:"componentid,omitempty"`
- // Hotlists in Google's bug tracking system that bugs should be marked with.
+ // Hotlist(s) in Google's bug tracking system that bugs should be marked with.
Hotlists []string `json:"hotlists,omitempty"`
// Specify whether this fuzz target was submitted by a researcher. Defaults
// to false.
diff --git a/java/aar.go b/java/aar.go
index a483e13..7cdcbae 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -219,13 +219,32 @@
linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirStrings, "-A "))
linkDeps = append(linkDeps, assetDeps...)
- // SDK version flags
- minSdkVersion, err := sdkContext.MinSdkVersion(ctx).EffectiveVersionString(ctx)
- if err != nil {
- ctx.ModuleErrorf("invalid minSdkVersion: %s", err)
+ // Returns the effective version for {min|target}_sdk_version
+ effectiveVersionString := func(sdkVersion android.SdkSpec, minSdkVersion android.SdkSpec) string {
+ // If {min|target}_sdk_version is current, use sdk_version to determine the effective level
+ // This is necessary for vendor modules.
+ // The effective version does not _only_ depend on {min|target}_sdk_version(level),
+ // but also on the sdk_version (kind+level)
+ if minSdkVersion.ApiLevel.IsCurrent() {
+ ret, err := sdkVersion.EffectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid sdk_version: %s", err)
+ }
+ return ret
+ }
+ ret, err := minSdkVersion.EffectiveVersionString(ctx)
+ if err != nil {
+ ctx.ModuleErrorf("invalid min_sdk_version: %s", err)
+ }
+ return ret
}
+ // SDK version flags
+ sdkVersion := sdkContext.SdkVersion(ctx)
+ minSdkVersion := effectiveVersionString(sdkVersion, sdkContext.MinSdkVersion(ctx))
linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion)
+ // Use minSdkVersion for target-sdk-version, even if `target_sdk_version` is set
+ // This behavior has been copied from Make.
linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion)
// Version code
diff --git a/java/base.go b/java/base.go
index cce06a4..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 != "" {
@@ -1487,7 +1487,14 @@
}
// Dex compilation
var dexOutputFile android.OutputPath
- dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), implementationAndResourcesJar, jarName)
+ params := &compileDexParams{
+ flags: flags,
+ sdkVersion: j.SdkVersion(ctx),
+ minSdkVersion: j.MinSdkVersion(ctx),
+ classesJar: implementationAndResourcesJar,
+ jarName: jarName,
+ }
+ dexOutputFile = j.dexer.compileDex(ctx, params)
if ctx.Failed() {
return
}
@@ -1838,15 +1845,18 @@
// Implements android.ApexModule
func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
- sdkSpec := j.MinSdkVersion(ctx)
- if !sdkSpec.Specified() {
+ sdkVersionSpec := j.SdkVersion(ctx)
+ minSdkVersionSpec := j.MinSdkVersion(ctx)
+ if !minSdkVersionSpec.Specified() {
return fmt.Errorf("min_sdk_version is not specified")
}
- if sdkSpec.Kind == android.SdkCore {
+ // If the module is compiling against core (via sdk_version), skip comparison check.
+ if sdkVersionSpec.Kind == android.SdkCore {
return nil
}
- if sdkSpec.ApiLevel.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel)
+ minSdkVersion := minSdkVersionSpec.ApiLevel
+ if minSdkVersion.GreaterThan(sdkVersion) {
+ return fmt.Errorf("newer SDK(%v)", minSdkVersion)
}
return nil
}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 101d3ca..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
@@ -1291,7 +1291,7 @@
}
return bootImageFiles
} else {
- if profile == nil {
+ if profile == nil && imageConfig.isProfileGuided() {
ctx.ModuleErrorf("Unable to produce boot image files: neither boot image files nor profiles exists in the prebuilt apex")
return bootImageOutputs{}
}
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/dex.go b/java/dex.go
index a8dd375..7b6a99a 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -184,7 +184,7 @@
"r8Flags", "zipFlags", "tmpJar", "mergeZipsFlags"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
- minSdkVersion android.SdkSpec) (flags []string, deps android.Paths) {
+ dexParams *compileDexParams) (flags []string, deps android.Paths) {
flags = d.dexProperties.Dxflags
// Translate all the DX flags to D8 ones until all the build files have been migrated
@@ -213,11 +213,11 @@
// Note: Targets with a min SDK kind of core_platform (e.g., framework.jar) or unspecified (e.g.,
// services.jar), are not classified as stable, which is WAI.
// TODO(b/232073181): Expand to additional min SDK cases after validation.
- if !minSdkVersion.Stable() {
+ if !dexParams.sdkVersion.Stable() {
flags = append(flags, "--android-platform-build")
}
- effectiveVersion, err := minSdkVersion.EffectiveVersion(ctx)
+ effectiveVersion, err := dexParams.minSdkVersion.EffectiveVersion(ctx)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
@@ -340,20 +340,27 @@
return r8Flags, r8Deps
}
-func (d *dexer) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, minSdkVersion android.SdkSpec,
- classesJar android.Path, jarName string) android.OutputPath {
+type compileDexParams struct {
+ flags javaBuilderFlags
+ sdkVersion android.SdkSpec
+ minSdkVersion android.SdkSpec
+ classesJar android.Path
+ jarName string
+}
+
+func (d *dexer) compileDex(ctx android.ModuleContext, dexParams *compileDexParams) android.OutputPath {
// Compile classes.jar into classes.dex and then javalib.jar
- javalibJar := android.PathForModuleOut(ctx, "dex", jarName).OutputPath
+ javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", jarName)
+ tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
zipFlags := "--ignore_missing_files"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
- commonFlags, commonDeps := d.dexCommonFlags(ctx, minSdkVersion)
+ commonFlags, commonDeps := d.dexCommonFlags(ctx, dexParams)
// Exclude kotlinc generated files when "exclude_kotlinc_generated_files" is set to true.
mergeZipsFlags := ""
@@ -372,7 +379,7 @@
android.ModuleNameWithPossibleOverride(ctx), "unused.txt")
proguardUsageZip := android.PathForModuleOut(ctx, "proguard_usage.zip")
d.proguardUsageZip = android.OptionalPathForPath(proguardUsageZip)
- r8Flags, r8Deps := d.r8Flags(ctx, flags)
+ r8Flags, r8Deps := d.r8Flags(ctx, dexParams.flags)
r8Deps = append(r8Deps, commonDeps...)
rule := r8
args := map[string]string{
@@ -396,12 +403,12 @@
Description: "r8",
Output: javalibJar,
ImplicitOutputs: android.WritablePaths{proguardDictionary, proguardUsageZip},
- Input: classesJar,
+ Input: dexParams.classesJar,
Implicits: r8Deps,
Args: args,
})
} else {
- d8Flags, d8Deps := d8Flags(flags)
+ d8Flags, d8Deps := d8Flags(dexParams.flags)
d8Deps = append(d8Deps, commonDeps...)
rule := d8
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_D8") {
@@ -411,7 +418,7 @@
Rule: rule,
Description: "d8",
Output: javalibJar,
- Input: classesJar,
+ Input: dexParams.classesJar,
Implicits: d8Deps,
Args: map[string]string{
"d8Flags": strings.Join(append(commonFlags, d8Flags...), " "),
@@ -423,7 +430,7 @@
})
}
if proptools.Bool(d.dexProperties.Uncompress_dex) {
- alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName).OutputPath
+ alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
javalibJar = alignedJavalibJar
}
diff --git a/java/dex_test.go b/java/dex_test.go
index dc85f9e..97fc3d0 100644
--- a/java/dex_test.go
+++ b/java/dex_test.go
@@ -43,6 +43,7 @@
name: "core_platform_app",
srcs: ["foo.java"],
sdk_version: "core_platform",
+ min_sdk_version: "31",
}
java_library {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index e0a0629..0ffedf6 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -293,6 +293,12 @@
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 3effff6..373b478 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "sort"
"strings"
"android/soong/android"
@@ -287,6 +288,9 @@
// Path of the preloaded classes file.
preloadedClassesFile string
+
+ // The "--compiler-filter" argument.
+ compilerFilter string
}
// Target-dependent description of a boot image.
@@ -309,17 +313,17 @@
// All the files that constitute this image variant, i.e. .art, .oat and .vdex files.
imagesDeps android.OutputPaths
- // The path to the primary image variant's imagePathOnHost field, where primary image variant
+ // The path to the base image variant's imagePathOnHost field, where base image variant
// means the image variant that this extends.
//
// This is only set for a variant of an image that extends another image.
- primaryImages android.OutputPath
+ baseImages android.OutputPaths
- // The paths to the primary image variant's imagesDeps field, where primary image variant
+ // The paths to the base image variant's imagesDeps field, where base image variant
// means the image variant that this extends.
//
// This is only set for a variant of an image that extends another image.
- primaryImagesDeps android.Paths
+ baseImagesDeps android.Paths
// Rules which should be used in make to install the outputs on host.
//
@@ -443,6 +447,10 @@
append(imageLocationsOnDevice, dexpreopt.PathStringToLocation(image.imagePathOnDevice, image.target.Arch.ArchType))
}
+func (image *bootImageConfig) isProfileGuided() bool {
+ return image.compilerFilter == "speed-profile"
+}
+
func dexpreoptBootJarsFactory() android.SingletonModule {
m := &dexpreoptBootJars{}
android.InitAndroidModule(m)
@@ -504,8 +512,13 @@
defaultImageConfig := defaultBootImageConfig(ctx)
d.defaultBootImage = defaultImageConfig
- artBootImageConfig := artBootImageConfig(ctx)
- d.otherImages = []*bootImageConfig{artBootImageConfig}
+ imageConfigs := genBootImageConfigs(ctx)
+ d.otherImages = make([]*bootImageConfig, 0, len(imageConfigs)-1)
+ for _, config := range imageConfigs {
+ if config != defaultImageConfig {
+ d.otherImages = append(d.otherImages, config)
+ }
+ }
}
// shouldBuildBootImages determines whether boot images should be built.
@@ -525,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]
@@ -701,9 +714,11 @@
}
if image.extends != nil {
- // It is a boot image extension, so it needs the boot image it depends on (in this case the
- // primary ART APEX image).
- artImage := image.primaryImages
+ // It is a boot image extension, so it needs the boot images that it depends on.
+ baseImageLocations := make([]string, 0, len(image.baseImages))
+ for _, image := range image.baseImages {
+ baseImageLocations = append(baseImageLocations, dexpreopt.PathToLocation(image, arch))
+ }
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
@@ -711,21 +726,23 @@
// dex2oat will reconstruct the path to the actual file when it needs it. As the actual path
// to the file cannot be passed to the command make sure to add the actual path as an Implicit
// dependency to ensure that it is built before the command runs.
- FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage).
+ FlagWithList("--boot-image=", baseImageLocations, ":").Implicits(image.baseImages.Paths()).
// Similarly, the dex2oat tool will automatically find the paths to other files in the base
// boot image so make sure to add them as implicit dependencies to ensure that they are built
// before this command is run.
- Implicits(image.primaryImagesDeps)
+ Implicits(image.baseImagesDeps)
} else {
// It is a primary image, so it needs a base address.
cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress())
}
- // We always expect a preloaded classes file to be available. However, if we cannot find it, it's
- // OK to not pass the flag to dex2oat.
- preloadedClassesPath := android.ExistentPathForSource(ctx, image.preloadedClassesFile)
- if preloadedClassesPath.Valid() {
- cmd.FlagWithInput("--preloaded-classes=", preloadedClassesPath.Path())
+ if len(image.preloadedClassesFile) > 0 {
+ // We always expect a preloaded classes file to be available. However, if we cannot find it, it's
+ // OK to not pass the flag to dex2oat.
+ preloadedClassesPath := android.ExistentPathForSource(ctx, image.preloadedClassesFile)
+ if preloadedClassesPath.Valid() {
+ cmd.FlagWithInput("--preloaded-classes=", preloadedClassesPath.Path())
+ }
}
cmd.
@@ -745,6 +762,12 @@
Flag("--force-determinism").
Flag("--abort-on-hard-verifier-error")
+ // If the image is profile-guided but the profile is disabled, we omit "--compiler-filter" to
+ // leave the decision to dex2oat to pick the compiler filter.
+ if !(image.isProfileGuided() && global.DisableGenerateProfile) {
+ cmd.FlagWithArg("--compiler-filter=", image.compilerFilter)
+ }
+
// Use the default variant/features for host builds.
// The map below contains only device CPU info (which might be x86 on some devices).
if image.target.Os == android.Android {
@@ -828,6 +851,10 @@
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath {
+ if !image.isProfileGuided() {
+ return nil
+ }
+
globalSoong := dexpreopt.GetGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -1007,6 +1034,8 @@
ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE"+current.name, strings.Join(imageLocationsOnDevice, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
}
+ // Ensure determinism.
+ sort.Strings(imageNames)
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
}
}
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 4d0bd09..117b660 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -44,6 +44,8 @@
bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw")
artBootImageName = "art"
frameworkBootImageName = "boot"
+ mainlineBootImageName = "mainline"
+ bootImageStem = "boot"
)
func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig {
@@ -52,35 +54,49 @@
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: "boot",
+ stem: bootImageStem,
installDirOnHost: "apex/art_boot_images/javalib",
- installDirOnDevice: "system/framework",
+ installDirOnDevice: frameworkSubdir,
profileInstallPathInApex: "etc/boot-image.prof",
modules: artModules,
preloadedClassesFile: "art/build/boot/preloaded-classes",
+ compilerFilter: "speed-profile",
}
// 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: "boot",
+ stem: bootImageStem,
installDirOnHost: frameworkSubdir,
installDirOnDevice: frameworkSubdir,
modules: frameworkModules,
preloadedClassesFile: "frameworks/base/config/preloaded-classes",
+ 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)
}
@@ -92,10 +108,7 @@
deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName())
configs := genBootImageConfigRaw(ctx)
- artCfg := configs[artBootImageName]
- frameworkCfg := configs[frameworkBootImageName]
- // common to all configs
for _, c := range configs {
c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars")
c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
@@ -131,18 +144,42 @@
c.zip = c.dir.Join(ctx, c.name+".zip")
}
- // specific to the framework config
- frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
- for i := range targets {
- frameworkCfg.variants[i].primaryImages = artCfg.variants[i].imagePathOnHost
- frameworkCfg.variants[i].primaryImagesDeps = artCfg.variants[i].imagesDeps.Paths()
- frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...)
+ visited := make(map[string]bool)
+ for _, c := range configs {
+ calculateDepsRecursive(c, targets, visited)
}
return configs
}).(map[string]*bootImageConfig)
}
+// calculateDepsRecursive calculates the dependencies of the given boot image config and all its
+// ancestors, if they are not visited.
+// The boot images are supposed to form a tree, where the root is the primary boot image. We do not
+// expect loops (e.g., A extends B, B extends C, C extends A), and we let them crash soong with a
+// stack overflow.
+// Note that a boot image config only has a pointer to the parent, not to children. Therefore, we
+// first go up through the parent chain, and then go back down to visit every code along the path.
+// `visited` is a map where a key is a boot image name and the value indicates whether the boot
+// image config is visited. The boot image names are guaranteed to be unique because they come from
+// `genBootImageConfigRaw` above, which also returns a map and would fail in the first place if the
+// names were not unique.
+func calculateDepsRecursive(c *bootImageConfig, targets []android.Target, visited map[string]bool) {
+ if c.extends == nil || visited[c.name] {
+ return
+ }
+ if c.extends.extends != nil {
+ calculateDepsRecursive(c.extends, targets, visited)
+ }
+ visited[c.name] = true
+ c.dexPathsDeps = android.Concat(c.extends.dexPathsDeps, c.dexPathsDeps)
+ for i := range targets {
+ c.variants[i].baseImages = android.Concat(c.extends.variants[i].baseImages, android.OutputPaths{c.extends.variants[i].imagePathOnHost})
+ c.variants[i].baseImagesDeps = android.Concat(c.extends.variants[i].baseImagesDeps, c.extends.variants[i].imagesDeps.Paths())
+ c.variants[i].dexLocationsDeps = android.Concat(c.extends.variants[i].dexLocationsDeps, c.variants[i].dexLocationsDeps)
+ }
+}
+
func artBootImageConfig(ctx android.PathContext) *bootImageConfig {
return genBootImageConfigs(ctx)[artBootImageName]
}
@@ -151,6 +188,10 @@
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 b704d09..cd7f295 100644
--- a/java/dexpreopt_config_test.go
+++ b/java/dexpreopt_config_test.go
@@ -28,8 +28,10 @@
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 1c236d8..c27f4c6 100644
--- a/java/dexpreopt_config_testing.go
+++ b/java/dexpreopt_config_testing.go
@@ -39,6 +39,78 @@
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 {
@@ -100,8 +172,8 @@
imagePathOnHost string
imagePathOnDevice string
imagesDeps []string
- primaryImages string
- primaryImagesDeps []string
+ baseImages []string
+ baseImagesDeps []string
// Mutated fields
installs []normalizedInstall
@@ -413,8 +485,8 @@
"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",
},
- primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art",
- primaryImagesDeps: []string{
+ baseImages: []string{"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.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",
@@ -461,8 +533,8 @@
"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",
},
- primaryImages: "out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art",
- primaryImagesDeps: []string{
+ baseImages: []string{"out/soong/test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.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",
@@ -509,8 +581,8 @@
"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",
},
- primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.art",
- primaryImagesDeps: []string{
+ baseImages: []string{"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86_64/boot.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",
@@ -557,8 +629,8 @@
"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",
},
- primaryImages: "out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.art",
- primaryImagesDeps: []string{
+ baseImages: []string{"out/soong/test_device/dex_artjars/linux_glibc/apex/art_boot_images/javalib/x86/boot.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",
@@ -601,6 +673,366 @@
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.
@@ -664,8 +1096,8 @@
android.AssertPathRelativeToTopEquals(t, "imagePathOnHost", expectedVariant.imagePathOnHost, variant.imagePathOnHost)
android.AssertStringEquals(t, "imagePathOnDevice", expectedVariant.imagePathOnDevice, variant.imagePathOnDevice)
android.AssertPathsRelativeToTopEquals(t, "imagesDeps", expectedVariant.imagesDeps, variant.imagesDeps.Paths())
- android.AssertPathRelativeToTopEquals(t, "primaryImages", expectedVariant.primaryImages, variant.primaryImages)
- android.AssertPathsRelativeToTopEquals(t, "primaryImagesDeps", expectedVariant.primaryImagesDeps, variant.primaryImagesDeps)
+ android.AssertPathsRelativeToTopEquals(t, "baseImages", expectedVariant.baseImages, variant.baseImages.Paths())
+ android.AssertPathsRelativeToTopEquals(t, "baseImagesDeps", expectedVariant.baseImagesDeps, variant.baseImagesDeps)
assertInstallsEqual(t, "installs", expectedVariant.installs, variant.installs)
assertInstallsEqual(t, "vdexInstalls", expectedVariant.vdexInstalls, variant.vdexInstalls)
assertInstallsEqual(t, "unstrippedInstalls", expectedVariant.unstrippedInstalls, variant.unstrippedInstalls)
@@ -712,6 +1144,10 @@
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
@@ -720,6 +1156,10 @@
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
@@ -728,11 +1168,17 @@
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_NAMES=art boot
+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_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
@@ -743,6 +1189,10 @@
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
@@ -751,8 +1201,13 @@
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
@@ -761,6 +1216,10 @@
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/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 c2fcccf..1df45b8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2067,7 +2067,15 @@
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
var dexOutputFile android.OutputPath
- dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName)
+ dexParams := &compileDexParams{
+ flags: flags,
+ sdkVersion: j.SdkVersion(ctx),
+ minSdkVersion: j.MinSdkVersion(ctx),
+ classesJar: outputFile,
+ jarName: jarName,
+ }
+
+ dexOutputFile = j.dexer.compileDex(ctx, dexParams)
if ctx.Failed() {
return
}
@@ -2158,15 +2166,18 @@
// Implements android.ApexModule
func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
sdkVersion android.ApiLevel) error {
- sdkSpec := j.MinSdkVersion(ctx)
- if !sdkSpec.Specified() {
+ sdkVersionSpec := j.SdkVersion(ctx)
+ minSdkVersionSpec := j.MinSdkVersion(ctx)
+ if !minSdkVersionSpec.Specified() {
return fmt.Errorf("min_sdk_version is not specified")
}
- if sdkSpec.Kind == android.SdkCore {
+ // If the module is compiling against core (via sdk_version), skip comparison check.
+ if sdkVersionSpec.Kind == android.SdkCore {
return nil
}
- if sdkSpec.ApiLevel.GreaterThan(sdkVersion) {
- return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel)
+ minSdkVersion := minSdkVersionSpec.ApiLevel
+ if minSdkVersion.GreaterThan(sdkVersion) {
+ return fmt.Errorf("newer SDK(%v)", minSdkVersion)
}
return nil
}
@@ -2807,6 +2818,9 @@
if sdkVersion.Kind == android.SdkPublic && sdkVersion.ApiLevel == android.FutureApiLevel {
// TODO(b/220869005) remove forced dependency on current public android.jar
deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import"))
+ } else if sdkVersion.Kind == android.SdkSystem && sdkVersion.ApiLevel == android.FutureApiLevel {
+ // TODO(b/215230098) remove forced dependency on current public android.jar
+ deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:system_current_android_sdk_java_import"))
}
} else if !deps.IsEmpty() {
ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
diff --git a/java/lint.go b/java/lint.go
index 07b9629..81666bf 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -275,13 +275,14 @@
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,
diff --git a/java/lint_test.go b/java/lint_test.go
index 62450d5..1ab416c 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -174,51 +174,52 @@
}
}
-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{
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index f0de7a4..0ea3609 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -129,7 +129,7 @@
// Add dependencies on all the non-updatable module configured in the "boot" boot image. That does
// not include modules configured in the "art" boot image.
- bootImageConfig := b.getImageConfig(ctx)
+ bootImageConfig := defaultBootImageConfig(ctx)
addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules, platformBootclasspathBootJarDepTag)
// Add dependencies on all the apex jars.
@@ -205,7 +205,7 @@
func (b *platformBootclasspathModule) configuredJars(ctx android.ModuleContext) android.ConfiguredJarList {
// Include all non APEX jars
- jars := b.getImageConfig(ctx).modules
+ jars := defaultBootImageConfig(ctx).modules
// Include jars from APEXes that don't populate their classpath proto config.
remainingJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars
@@ -266,10 +266,6 @@
}
}
-func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
- return defaultBootImageConfig(ctx)
-}
-
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) bootDexJarByModule {
@@ -410,27 +406,25 @@
// GenerateSingletonBuildActions method as it cannot create it for itself.
dexpreopt.GetGlobalSoongConfig(ctx)
- imageConfig := b.getImageConfig(ctx)
- if imageConfig == nil {
- return
- }
-
global := dexpreopt.GetGlobalConfig(ctx)
if !shouldBuildBootImages(ctx.Config(), global) {
return
}
- // Generate the framework profile rule
- bootFrameworkProfileRule(ctx, imageConfig)
+ frameworkBootImageConfig := defaultBootImageConfig(ctx)
+ bootFrameworkProfileRule(ctx, frameworkBootImageConfig)
+ b.generateBootImage(ctx, frameworkBootImageName, platformModules)
+ b.generateBootImage(ctx, mainlineBootImageName, apexModules)
+ b.copyApexBootJarsForAppsDexpreopt(ctx, apexModules)
+ dumpOatRules(ctx, frameworkBootImageConfig)
+}
- // Copy platform module dex jars to their predefined locations.
- platformBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, platformModules)
- copyBootJarsToPredefinedLocations(ctx, platformBootDexJarsByModule, imageConfig.dexPathsByModule)
+func (b *platformBootclasspathModule) generateBootImage(ctx android.ModuleContext, imageName string, modules []android.Module) {
+ imageConfig := genBootImageConfigs(ctx)[imageName]
- // Copy apex module dex jars to their predefined locations.
- config := GetApexBootConfig(ctx)
- apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules)
- copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule)
+ // Copy module dex jars to their predefined locations.
+ bootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, modules)
+ copyBootJarsToPredefinedLocations(ctx, bootDexJarsByModule, imageConfig.dexPathsByModule)
// Build a profile for the image config and then use that to build the boot image.
profile := bootImageProfileRule(ctx, imageConfig)
@@ -443,6 +437,11 @@
// Build boot image files for the host variants. There are use directly by ART host side tests.
buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
+}
- dumpOatRules(ctx, imageConfig)
+// Copy apex module dex jars to their predefined locations. They will be used for dexpreopt for apps.
+func (b *platformBootclasspathModule) copyApexBootJarsForAppsDexpreopt(ctx android.ModuleContext, apexModules []android.Module) {
+ config := GetApexBootConfig(ctx)
+ apexBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, apexModules)
+ copyBootJarsToPredefinedLocations(ctx, apexBootDexJarsByModule, config.dexPathsByModule)
}
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_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/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/bindgen.go b/rust/bindgen.go
index 878f896..8cec918 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -313,7 +313,7 @@
func (b *bindgenDecorator) SourceProviderDeps(ctx DepsContext, deps Deps) Deps {
deps = b.BaseSourceProvider.SourceProviderDeps(ctx, deps)
- if ctx.toolchain().Bionic() {
+ if ctx.toolchain().Bionic() && !ctx.RustModule().compiler.noStdlibs() {
deps = bionicDeps(ctx, deps, false)
} else if ctx.Os() == android.LinuxMusl {
deps = muslDeps(ctx, deps, false)
diff --git a/rust/builder.go b/rust/builder.go
index 5b5c993..a2f1238 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -247,7 +247,13 @@
if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
incrementalPath := android.PathForOutput(ctx, "rustc").String()
- rustcFlags = append(rustcFlags, "-C incremental="+incrementalPath)
+ rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath)
+ }
+
+ // Disallow experimental features
+ modulePath := android.PathForModuleSrc(ctx).String()
+ if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
+ rustcFlags = append(rustcFlags, "-Zallow-features=\"default_alloc_error_handler,custom_inner_attributes,mixed_integer_ops,slice_internals\"")
}
// Collect linker flags
diff --git a/rust/compiler.go b/rust/compiler.go
index 31acd49..06ae12f 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -269,6 +269,11 @@
func (compiler *baseCompiler) cfgFlags(ctx ModuleContext, flags Flags) Flags {
if ctx.RustModule().UseVndk() {
compiler.Properties.Cfgs = append(compiler.Properties.Cfgs, "android_vndk")
+ if ctx.RustModule().InVendor() {
+ compiler.Properties.Cfgs = append(compiler.Properties.Cfgs, "android_vendor")
+ } else if ctx.RustModule().InProduct() {
+ compiler.Properties.Cfgs = append(compiler.Properties.Cfgs, "android_product")
+ }
}
flags.RustFlags = append(flags.RustFlags, compiler.cfgsToFlags()...)
diff --git a/rust/config/global.go b/rust/config/global.go
index ef428b8..0dface4 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.66.1"
+ RustDefaultVersion = "1.67.1"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/image_test.go b/rust/image_test.go
index 8185872..fb4d9c1 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -53,6 +53,7 @@
crate_name: "foo",
srcs: ["foo.rs"],
vendor_available: true,
+ product_available: true,
}
`)
@@ -61,6 +62,35 @@
if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
}
+ if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") {
+ t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ }
+ if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") {
+ t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ }
+
+ product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc")
+ if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
+ t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ }
+ if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") {
+ t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ }
+ if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") {
+ t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ }
+
+ system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc")
+ if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
+ t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
+ }
+ if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") {
+ t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
+ }
+ if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") {
+ t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ }
+
}
// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries.
diff --git a/scripts/check_boot_jars/package_allowed_list.txt b/scripts/check_boot_jars/package_allowed_list.txt
index 08bd80c..ce461b1 100644
--- a/scripts/check_boot_jars/package_allowed_list.txt
+++ b/scripts/check_boot_jars/package_allowed_list.txt
@@ -8,6 +8,7 @@
java\.io
java\.lang
java\.lang\.annotation
+java\.lang\.constant
java\.lang\.invoke
java\.lang\.ref
java\.lang\.reflect
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index d81635e..efb97be 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -27,6 +27,11 @@
// 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(`
@@ -37,9 +42,10 @@
apex: "%s",
module: "%s",
},
+ %s
],
}
- `, apex, fragment)),
+ `, apex, fragment, extraFragments)),
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),
@@ -79,9 +85,11 @@
}),
// Add a platform_bootclasspath that depends on the fragment.
- fixtureAddPlatformBootclasspathForBootclasspathFragment("com.android.art", "mybootclasspathfragment"),
+ fixtureAddPlatformBootclasspathForBootclasspathFragmentWithExtra(
+ "com.android.art", "mybootclasspathfragment", java.ApexBootJarFragmentsForPlatformBootclasspath),
java.PrepareForBootImageConfigTest,
+ java.PrepareApexBootJarConfigsAndModules,
android.FixtureWithRootAndroidBp(`
sdk {
name: "mysdk",
@@ -196,9 +204,15 @@
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,
- "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")
+ 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...,
+ )...,
+ )
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")
}),
@@ -222,9 +236,15 @@
// Make sure that the boot jars package check rule includes the dex jars created from the source.
checkBootJarsPackageCheckRule(t, result,
- "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")
+ 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...,
+ )...,
+ )
}
// 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/starlark_fmt/format.go b/starlark_fmt/format.go
index 3e51fa1..064fc21 100644
--- a/starlark_fmt/format.go
+++ b/starlark_fmt/format.go
@@ -17,6 +17,7 @@
import (
"fmt"
"sort"
+ "strconv"
"strings"
)
@@ -84,6 +85,16 @@
return PrintDict(formattedValueDict, indentLevel)
}
+// PrintStringIntDict returns a Starlark-compatible string formatted as dictionary with
+// string keys and int values.
+func PrintStringIntDict(dict map[string]int, indentLevel int) string {
+ valDict := make(map[string]string, len(dict))
+ for k, v := range dict {
+ valDict[k] = strconv.Itoa(v)
+ }
+ return PrintDict(valDict, indentLevel)
+}
+
// PrintDict returns a starlark-compatible string containing a dictionary with string keys and
// values printed with no additional formatting.
func PrintDict(dict map[string]string, indentLevel int) string {
diff --git a/tests/dcla_apex_comparison_test.sh b/tests/dcla_apex_comparison_test.sh
new file mode 100755
index 0000000..2ecb876
--- /dev/null
+++ b/tests/dcla_apex_comparison_test.sh
@@ -0,0 +1,138 @@
+#!/bin/bash
+
+# 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 -euo pipefail
+
+# Soong/Bazel integration test to build the mainline modules in mixed build and
+# compare the DCLA libs extracted from those modules to ensure they are identical.
+
+if [ ! -e "build/make/core/Makefile" ]; then
+ echo "$0 must be run from the top of the Android source tree."
+ exit 1
+fi
+
+TARGET_PRODUCTS=(
+ module_arm64
+ module_x86_64
+)
+
+MODULES=(
+ # These modules depend on the DCLA libs
+ com.android.adbd
+ com.android.art
+ com.android.art.debug
+ com.android.art.testing
+ com.android.btservices
+ com.android.conscrypt
+ com.android.i18n
+ com.android.media
+ com.android.media.swcodec
+ com.android.resolv
+ com.android.runtime
+ com.android.tethering
+)
+
+DCLA_LIBS=(
+ libbase.so
+ libc++.so
+ libcrypto.so
+ libcutils.so
+)
+
+if [[ -z ${OUT_DIR+x} ]]; then
+ OUT_DIR="out"
+fi
+
+if [[ -z ${ANDROID_HOST_OUT+x} ]]; then
+ export ANDROID_HOST_OUT="out/host/linux-x86"
+fi
+
+######################
+# Build deapexer and debugfs
+######################
+DEAPEXER="${ANDROID_HOST_OUT}/bin/deapexer"
+DEBUGFS="${ANDROID_HOST_OUT}/bin/debugfs"
+if [[ ! -f "${DEAPEXER}" ]] || [[ ! -f "${DEBUGFS}" ]]; then
+ build/soong/soong_ui.bash --make-mode --skip-soong-tests deapexer debugfs
+fi
+
+DEAPEXER="${DEAPEXER} --debugfs_path=${DEBUGFS}"
+
+############
+# Test Setup
+############
+OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
+
+function cleanup {
+ rm -rf "${OUTPUT_DIR}"
+}
+trap cleanup EXIT
+
+#######
+# Tests
+#######
+
+function extract_dcla_libs() {
+ local product=$1; shift
+ for module in "${MODULES[@]}"; do
+ local apex="${OUTPUT_DIR}/${product}/${module}.apex"
+ local extract_dir="${OUTPUT_DIR}/${product}/${module}/extract"
+
+ $DEAPEXER extract "${apex}" "${extract_dir}"
+ done
+}
+
+function compare_dcla_libs() {
+ local product=$1; shift
+
+ for lib in "${DCLA_LIBS[@]}"; do
+ for arch in lib lib64; do
+ local prev_sha=""
+ for module in "${MODULES[@]}"; do
+ local file="${OUTPUT_DIR}/${product}/${module}/extract/${arch}/${lib}"
+ if [[ ! -f "${file}" ]]; then
+ # not all libs are present in a module
+ echo "file doesn't exist: ${file}"
+ continue
+ fi
+ sha=$(sha1sum ${file})
+ sha="${sha% *}"
+ if [ "${prev_sha}" == "" ]; then
+ prev_sha="${sha}"
+ elif [ "${sha}" != "${prev_sha}" ]; then
+ echo "Test failed, ${lib} has different hash value"
+ exit 1
+ fi
+ done
+ done
+ done
+}
+
+export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
+export TARGET_BUILD_APPS="${MODULES[@]}"
+for product in "${TARGET_PRODUCTS[@]}"; do
+ ###########
+ # Build the mainline modules
+ ###########
+ packages/modules/common/build/build_unbundled_mainline_module.sh \
+ --product "${product}" \
+ --dist_dir "${OUTPUT_DIR}/${product}"
+
+ extract_dcla_libs "${product}"
+ compare_dcla_libs "${product}"
+done
+
+echo "Test passed"
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index eb76a46..8ba2984 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -14,7 +14,7 @@
# mock client.
"$TOP/build/soong/tests/apex_comparison_tests.sh"
"$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
-
+"$TOP/build/soong/tests/dcla_apex_comparison_test.sh"
"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh"
"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_arm" "armv7-a"
-"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
\ No newline at end of file
+"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
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/path.go b/ui/build/path.go
index 86e61c0..29128d8 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -109,6 +109,15 @@
prebuiltsPath, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86")
myPath = prebuiltsPath + string(os.PathListSeparator) + myPath
+ if value, _ := config.Environment().Get("BUILD_BROKEN_PYTHON_IS_PYTHON2"); value == "true" {
+ py2Path, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86/py2")
+ if info, err := os.Stat(py2Path); err == nil && info.IsDir() {
+ myPath = py2Path + string(os.PathListSeparator) + myPath
+ }
+ } else if value != "" {
+ ctx.Fatalf("BUILD_BROKEN_PYTHON_IS_PYTHON2 can only be set to 'true' or an empty string, but got %s\n", value)
+ }
+
// Set $PATH to be the directories containing the host tool symlinks, and
// the prebuilts directory for the current host OS.
config.Environment().Set("PATH", myPath)
@@ -244,6 +253,15 @@
prebuiltsPath, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86")
myPath = prebuiltsPath + string(os.PathListSeparator) + myPath
+ if value, _ := config.Environment().Get("BUILD_BROKEN_PYTHON_IS_PYTHON2"); value == "true" {
+ py2Path, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86/py2")
+ if info, err := os.Stat(py2Path); err == nil && info.IsDir() {
+ myPath = py2Path + string(os.PathListSeparator) + myPath
+ }
+ } else if value != "" {
+ ctx.Fatalf("BUILD_BROKEN_PYTHON_IS_PYTHON2 can only be set to 'true' or an empty string, but got %s\n", value)
+ }
+
// Replace the $PATH variable with the path_interposer symlinks, and
// checked-in prebuilts.
config.Environment().Set("PATH", myPath)