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:
@@ -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",
|
||||
)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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{})
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
57
cc/cc.go
57
cc/cc.go
@@ -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)
|
||||
|
@@ -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())
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user