Merge "spelling/grammar fix"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 7ce0d9b..8cd52cb 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -1427,4 +1427,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/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 0880ad5..3a459f1 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,7 +199,7 @@
// 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
// Returns the bazel output base (the root directory for all bazel intermediate outputs).
OutputBase() string
@@ -235,6 +252,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 +277,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 +297,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,7 +337,7 @@
panic("unimplemented")
}
-func (m MockBazelContext) IsModuleNameAllowed(_ string) bool {
+func (m MockBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return true
}
@@ -324,6 +353,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,7 +479,7 @@
return ""
}
-func (n noopBazelContext) IsModuleNameAllowed(_ string) bool {
+func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return false
}
@@ -442,14 +491,15 @@
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 +587,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,13 +612,17 @@
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.bazelDclaEnabledModules[moduleName] {
+ return true
+ }
+
return context.modulesDefaultToBazel
}
@@ -696,21 +759,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 +799,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 +862,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 +890,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 +1007,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 +1024,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 +1152,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
@@ -1325,7 +1437,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 {
@@ -1336,6 +1457,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/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/apex/apex.go b/apex/apex.go
index b77568d..9a80aa8 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -141,6 +141,9 @@
// Default: true.
Installable *bool
+ // Whether this APEX ignores the apex_available list defined in its dependencies.
+ Override_apex_available *bool
+
// If set true, VNDK libs are considered as stable libs and are not included in this APEX.
// Should be only used in non-system apexes (e.g. vendor: true). Default is false.
Use_vndk_as_stable *bool
@@ -1513,6 +1516,10 @@
return proptools.BoolDefault(a.properties.Platform_apis, false)
}
+func (a *apexBundle) OverrideApexAvailable() bool {
+ return proptools.BoolDefault(a.properties.Override_apex_available, false)
+}
+
// getCertString returns the name of the cert that should be used to sign this APEX. This is
// basically from the "certificate" property, but could be overridden by the device config.
func (a *apexBundle) getCertString(ctx android.BaseModuleContext) string {
@@ -3040,6 +3047,11 @@
return
}
+ // Ignore availability when `override_apex_available` is true.
+ if a.OverrideApexAvailable() {
+ return
+ }
+
a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
// As soon as the dependency graph crosses the APEX boundary, don't go further.
if externalDep {
diff --git a/cc/binary.go b/cc/binary.go
index 532b42a..496c610 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -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
diff --git a/cc/cc.go b/cc/cc.go
index c81160d..5bb13ff 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1905,10 +1905,29 @@
}
// 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() {
+ apexKey := android.ApexConfigKey{
+ WithinApex: true,
+ ApexSdkVersion: findApexSdkVersion(ctx, apexInfo).String(),
+ }
+ return &apexKey
+ }
+
+ return nil
}
func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {
@@ -2841,6 +2860,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 +2892,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..0d03b73 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.
@@ -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 f33f37e..61e3a93 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -910,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
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/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