Support DCLA am: e43124023c

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/2393572

Change-Id: Iae2d689e9c09838a82d78d44416e1629dcb03eb6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Yu Liu
2023-02-22 01:35:44 +00:00
committed by Automerger Merge Worker
12 changed files with 411 additions and 80 deletions

View File

@@ -1427,4 +1427,20 @@ var (
// 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",
)

View File

@@ -352,11 +352,13 @@ func GetBp2BuildAllowList() Bp2BuildConversionAllowlist {
// 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
}

View File

@@ -109,12 +109,29 @@ type cqueryRequest interface {
// 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 @@ type BazelContext interface {
// 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 @@ type mixedBuildBazelContext struct {
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 @@ type MockBazelContext struct {
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 @@ func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, e
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 @@ func (m MockBazelContext) InvokeBazel(_ Config, _ invokeBazelContext) error {
panic("unimplemented")
}
func (m MockBazelContext) IsModuleNameAllowed(_ string) bool {
func (m MockBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return true
}
@@ -324,6 +353,26 @@ func (m MockBazelContext) AqueryDepsets() []bazel.AqueryDepset {
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 @@ func (m noopBazelContext) OutputBase() string {
return ""
}
func (n noopBazelContext) IsModuleNameAllowed(_ string) bool {
func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return false
}
@@ -442,14 +491,15 @@ 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 +587,24 @@ func NewBazelContext(c *config) (BazelContext, error) {
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 @@ func (p *bazelPaths) BazelMetricsDir() string {
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 @@ func (context *mixedBuildBazelContext) mainBzlFileContents() []byte {
#####################################################
# 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 @@ def _passthrough_rule_impl(ctx):
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 @@ phony_root(name = "phonyroot",
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 @@ config_node(name = "%s",
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 @@ def get_arch(target):
# 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 @@ def get_arch(target):
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 @@ func (context *mixedBuildBazelContext) runCquery(config Config, ctx invokeBazelC
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 @@ func getConfigString(key cqueryKey) string {
// 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 GetConfigKey(ctx BaseModuleContext) configKey {
}
}
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)
}

View File

@@ -24,20 +24,37 @@ func (t *testInvokeBazelContext) GetEventHandler() *metrics.EventHandler {
}
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 TestCoverageFlagsAfterInvokeBazel(t *testing.T) {
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 TestBazelRequestsSorted(t *testing.T) {
}
}
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{})

View File

@@ -232,7 +232,7 @@ func (fg *fileGroup) QueueBazelCall(ctx BaseModuleContext) {
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 @@ func (fg *fileGroup) ProcessBazelQueryResponse(ctx ModuleContext) {
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

View File

@@ -577,12 +577,12 @@ var _ BazelHandler = (*ccBinaryBazelHandler)(nil)
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

View File

@@ -1905,10 +1905,29 @@ func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
}
// 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 checkDoubleLoadableLibraries(ctx android.TopDownMutatorContext) {
}
}
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 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
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)

View File

@@ -28,6 +28,10 @@ import (
"android/soong/bazel/cquery"
)
func init() {
registerTestMutators(android.InitRegistrationContext)
}
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
@@ -41,6 +45,36 @@ var prepareForCcTest = android.GroupFixturePreparers(
}),
)
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 TestCcBuildBrokenClangCFlags(t *testing.T) {
})
}
}
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())
}

View File

@@ -910,12 +910,12 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi
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

View File

@@ -59,12 +59,12 @@ var _ BazelHandler = (*libraryHeaderBazelHandler)(nil)
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

View File

@@ -54,12 +54,12 @@ var _ BazelHandler = (*objectBazelHandler)(nil)
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

View File

@@ -761,12 +761,12 @@ var _ BazelHandler = (*prebuiltBinaryBazelHandler)(nil)
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