diff --git a/android/bazel.go b/android/bazel.go index 8341e5725..9cebc800e 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -259,7 +259,6 @@ var ( // Per-module denylist of cc_library modules to only generate the static // variant if their shared variant isn't ready or buildable by Bazel. bp2buildCcLibraryStaticOnlyList = []string{ - "libstdc++", // http://b/186822597, cc_library, ld.lld: error: undefined symbol: __errno "libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets. } @@ -294,8 +293,8 @@ func init() { } } -func GenerateCcLibraryStaticOnly(ctx BazelConversionPathContext) bool { - return bp2buildCcLibraryStaticOnly[ctx.Module().Name()] +func GenerateCcLibraryStaticOnly(moduleName string) bool { + return bp2buildCcLibraryStaticOnly[moduleName] } func ShouldKeepExistingBuildFileForDir(dir string) bool { @@ -325,7 +324,7 @@ func (b *BazelModuleBase) MixedBuildsEnabled(ctx BazelConversionPathContext) boo return false } - if GenerateCcLibraryStaticOnly(ctx) { + if GenerateCcLibraryStaticOnly(ctx.Module().Name()) { // Don't use partially-converted cc_library targets in mixed builds, // since mixed builds would generally rely on both static and shared // variants of a cc_library. diff --git a/android/bazel_paths.go b/android/bazel_paths.go index ccbc156bc..b5746f750 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -15,11 +15,12 @@ package android import ( - "android/soong/bazel" "fmt" "path/filepath" "strings" + "android/soong/bazel" + "github.com/google/blueprint" "github.com/google/blueprint/pathtools" ) @@ -84,24 +85,8 @@ type BazelConversionPathContext interface { // BazelLabelForModuleDeps expects a list of reference to other modules, ("" // or ":") and returns a Bazel-compatible label which corresponds to dependencies on the // module within the given ctx. -func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList { - return bazelLabelForModuleDeps(ctx, modules, false) -} - -// BazelLabelForModuleWholeDeps expects a list of references to other modules, ("" -// or ":") and returns a Bazel-compatible label which corresponds to dependencies on the -// module within the given ctx, where prebuilt dependencies will be appended with _alwayslink so -// they can be handled as whole static libraries. -func BazelLabelForModuleWholeDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList { - return bazelLabelForModuleDeps(ctx, modules, true) -} - -// BazelLabelForModuleDepsExcludes expects two lists: modules (containing modules to include in the -// list), and excludes (modules to exclude from the list). Both of these should contain references -// to other modules, ("" or ":"). It returns a Bazel-compatible label list which -// corresponds to dependencies on the module within the given ctx, and the excluded dependencies. -func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList { - return bazelLabelForModuleDepsExcludes(ctx, modules, excludes, false) +func BazelLabelForModuleDeps(ctx TopDownMutatorContext, modules []string) bazel.LabelList { + return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel) } // BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in @@ -110,11 +95,15 @@ func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, ex // list which corresponds to dependencies on the module within the given ctx, and the excluded // dependencies. Prebuilt dependencies will be appended with _alwayslink so they can be handled as // whole static libraries. -func BazelLabelForModuleWholeDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList { - return bazelLabelForModuleDepsExcludes(ctx, modules, excludes, true) +func BazelLabelForModuleDepsExcludes(ctx TopDownMutatorContext, modules, excludes []string) bazel.LabelList { + return BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, BazelModuleLabel) } -func bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, isWholeLibs bool) bazel.LabelList { +// BazelLabelForModuleDepsWithFn expects a list of reference to other modules, ("" +// or ":") and applies moduleToLabelFn to determine and return a Bazel-compatible label +// which corresponds to dependencies on the module within the given ctx. +func BazelLabelForModuleDepsWithFn(ctx TopDownMutatorContext, modules []string, + moduleToLabelFn func(TopDownMutatorContext, blueprint.Module) string) bazel.LabelList { var labels bazel.LabelList // In some cases, a nil string list is different than an explicitly empty list. if len(modules) == 0 && modules != nil { @@ -127,7 +116,7 @@ func bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, i module = ":" + module } if m, t := SrcIsModuleWithTag(module); m != "" { - l := getOtherModuleLabel(ctx, m, t, isWholeLibs) + l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn) l.OriginalModuleName = bpText labels.Includes = append(labels.Includes, l) } else { @@ -137,23 +126,29 @@ func bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, i return labels } -func bazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string, isWholeLibs bool) bazel.LabelList { - moduleLabels := bazelLabelForModuleDeps(ctx, RemoveListFromList(modules, excludes), isWholeLibs) +// BazelLabelForModuleDepsExcludesWithFn expects two lists: modules (containing modules to include in the +// list), and excludes (modules to exclude from the list). Both of these should contain references +// to other modules, ("" or ":"). It applies moduleToLabelFn to determine and return a +// Bazel-compatible label list which corresponds to dependencies on the module within the given ctx, and +// the excluded dependencies. +func BazelLabelForModuleDepsExcludesWithFn(ctx TopDownMutatorContext, modules, excludes []string, + moduleToLabelFn func(TopDownMutatorContext, blueprint.Module) string) bazel.LabelList { + moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn) if len(excludes) == 0 { return moduleLabels } - excludeLabels := bazelLabelForModuleDeps(ctx, excludes, isWholeLibs) + excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn) return bazel.LabelList{ Includes: moduleLabels.Includes, Excludes: excludeLabels.Includes, } } -func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label { +func BazelLabelForModuleSrcSingle(ctx TopDownMutatorContext, path string) bazel.Label { return BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes[0] } -func BazelLabelForModuleDepSingle(ctx BazelConversionPathContext, path string) bazel.Label { +func BazelLabelForModuleDepSingle(ctx TopDownMutatorContext, path string) bazel.Label { return BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes[0] } @@ -163,7 +158,7 @@ func BazelLabelForModuleDepSingle(ctx BazelConversionPathContext, path string) b // relative if within the same package). // Properties must have been annotated with struct tag `android:"path"` so that dependencies modules // will have already been handled by the path_deps mutator. -func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList { +func BazelLabelForModuleSrc(ctx TopDownMutatorContext, paths []string) bazel.LabelList { return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil)) } @@ -173,7 +168,7 @@ func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) baze // (absolute if in a different package or relative if within the same package). // Properties must have been annotated with struct tag `android:"path"` so that dependencies modules // will have already been handled by the path_deps mutator. -func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList { +func BazelLabelForModuleSrcExcludes(ctx TopDownMutatorContext, paths, excludes []string) bazel.LabelList { excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil)) excluded := make([]string, 0, len(excludeLabels.Includes)) for _, e := range excludeLabels.Includes { @@ -293,7 +288,7 @@ func transformSubpackagePaths(ctx BazelConversionPathContext, paths bazel.LabelL // Properties passed as the paths or excludes argument must have been annotated with struct tag // `android:"path"` so that dependencies on other modules will have already been handled by the // path_deps mutator. -func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList { +func expandSrcsForBazel(ctx TopDownMutatorContext, paths, expandedExcludes []string) bazel.LabelList { if paths == nil { return bazel.LabelList{} } @@ -310,7 +305,7 @@ func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes for _, p := range paths { if m, tag := SrcIsModuleWithTag(p); m != "" { - l := getOtherModuleLabel(ctx, m, tag, false) + l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel) if !InList(l.Label, expandedExcludes) { l.OriginalModuleName = fmt.Sprintf(":%s", m) labels.Includes = append(labels.Includes, l) @@ -341,7 +336,8 @@ func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes // getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the // module. The label will be relative to the current directory if appropriate. The dependency must // already be resolved by either deps mutator or path deps mutator. -func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, isWholeLibs bool) bazel.Label { +func getOtherModuleLabel(ctx TopDownMutatorContext, dep, tag string, + labelFromModule func(TopDownMutatorContext, blueprint.Module) string) bazel.Label { m, _ := ctx.ModuleFromName(dep) if m == nil { panic(fmt.Errorf("No module named %q found, but was a direct dep of %q", dep, ctx.Module().Name())) @@ -349,13 +345,11 @@ func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, isWhol if !convertedToBazel(ctx, m) { ctx.AddUnconvertedBp2buildDep(dep) } - otherLabel := bazelModuleLabel(ctx, m, tag) - label := bazelModuleLabel(ctx, ctx.Module(), "") - if isWholeLibs { - if m, ok := m.(Module); ok && IsModulePrebuilt(m) { - otherLabel += "_alwayslink" - } - } + label := BazelModuleLabel(ctx, ctx.Module()) + otherLabel := labelFromModule(ctx, m) + + // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets. + if samePackage(label, otherLabel) { otherLabel = bazelShortLabel(otherLabel) } @@ -365,7 +359,7 @@ func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, isWhol } } -func bazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module, tag string) string { +func BazelModuleLabel(ctx TopDownMutatorContext, module blueprint.Module) string { // TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets. if !convertedToBazel(ctx, module) { return bp2buildModuleLabel(ctx, module) diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 371593b5e..b3a10531e 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -1022,18 +1022,18 @@ cc_library { }), implementation_deps = select({ "//build/bazel/platforms/arch:arm": [], - "//conditions:default": [":arm_static_lib_excludes"], + "//conditions:default": [":arm_static_lib_excludes_bp2build_cc_library_static"], }) + select({ "//build/bazel/product_variables:malloc_not_svelte": [], - "//conditions:default": [":malloc_not_svelte_static_lib_excludes"], + "//conditions:default": [":malloc_not_svelte_static_lib_excludes_bp2build_cc_library_static"], }), srcs_c = ["common.c"], whole_archive_deps = select({ "//build/bazel/platforms/arch:arm": [], - "//conditions:default": [":arm_whole_static_lib_excludes"], + "//conditions:default": [":arm_whole_static_lib_excludes_bp2build_cc_library_static"], }) + select({ - "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib"], - "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes"], + "//build/bazel/product_variables:malloc_not_svelte": [":malloc_not_svelte_whole_static_lib_bp2build_cc_library_static"], + "//conditions:default": [":malloc_not_svelte_whole_static_lib_excludes_bp2build_cc_library_static"], }), )`, }, diff --git a/cc/bp2build.go b/cc/bp2build.go index 67ea70e2c..e48f757dc 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -20,6 +20,7 @@ import ( "android/soong/android" "android/soong/bazel" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -136,10 +137,10 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { attrs.Copts.SetSelectValue(axis, config, props.Cflags) attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) - attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) - attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) - attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)) - attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs)) + attrs.Static_deps.SetSelectValue(axis, config, bazelLabelForStaticDeps(ctx, props.Static_libs)) + attrs.Dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.Shared_libs)) + attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs)) + attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs)) } // system_dynamic_deps distinguishes between nil/empty list behavior: // nil -> use default values @@ -388,9 +389,9 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) // Excludes to parallel Soong: // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs) - staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)) + staticDeps.SetSelectValue(axis, config, bazelLabelForStaticDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) - wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) + wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) systemSharedLibs := baseLinkerProps.System_shared_libs // systemSharedLibs distinguishes between nil/empty list behavior: @@ -399,15 +400,15 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) if len(systemSharedLibs) > 0 { systemSharedLibs = android.FirstUniqueStrings(systemSharedLibs) } - systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs)) + systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) - dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) + dynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) - headerDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, headerLibs)) + headerDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, headerLibs)) exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers) - exportedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, exportedLibs)) + exportedDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, exportedLibs)) linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps)) if baseLinkerProps.Version_script != nil { @@ -424,14 +425,14 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) // reference to the bazel attribute that should be set for the given product variable config attribute *bazel.LabelListAttribute - depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList + depResolutionFunc func(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList } productVarToDepFields := map[string]productVarDep{ // product variables do not support exclude_shared_libs - "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: android.BazelLabelForModuleDepsExcludes}, - "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, android.BazelLabelForModuleDepsExcludes}, - "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, android.BazelLabelForModuleWholeDepsExcludes}, + "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes}, + "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, bazelLabelForStaticDepsExcludes}, + "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes}, } productVariableProps := android.ProductVariableProperties(ctx) @@ -559,3 +560,59 @@ func bp2BuildParseExportedIncludesHelper(ctx android.TopDownMutatorContext, modu return exported } + +func bazelLabelForStaticModule(ctx android.TopDownMutatorContext, m blueprint.Module) string { + label := android.BazelModuleLabel(ctx, m) + if aModule, ok := m.(android.Module); ok { + if ctx.OtherModuleType(aModule) == "cc_library" && !android.GenerateCcLibraryStaticOnly(m.Name()) { + label += "_bp2build_cc_library_static" + } + } + return label +} + +func bazelLabelForSharedModule(ctx android.TopDownMutatorContext, m blueprint.Module) string { + // cc_library, at it's root name, propagates the shared library, which depends on the static + // library. + return android.BazelModuleLabel(ctx, m) +} + +func bazelLabelForStaticWholeModuleDeps(ctx android.TopDownMutatorContext, m blueprint.Module) string { + label := bazelLabelForStaticModule(ctx, m) + if aModule, ok := m.(android.Module); ok { + if android.IsModulePrebuilt(aModule) { + label += "_alwayslink" + } + } + return label +} + +func bazelLabelForWholeDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList { + return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps) +} + +func bazelLabelForWholeDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList { + return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps) +} + +func bazelLabelForStaticDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList { + return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule) +} + +func bazelLabelForStaticDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList { + return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule) +} + +func bazelLabelForSharedDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList { + return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule) +} + +func bazelLabelForHeaderDeps(ctx android.TopDownMutatorContext, modules []string) bazel.LabelList { + // This is not elegant, but bp2build's shared library targets only propagate + // their header information as part of the normal C++ provider. + return bazelLabelForSharedDeps(ctx, modules) +} + +func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList { + return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule) +} diff --git a/cc/library.go b/cc/library.go index f5a82c282..8a572f994 100644 --- a/cc/library.go +++ b/cc/library.go @@ -277,7 +277,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { // For some cc_library modules, their static variants are ready to be // converted, but not their shared variants. For these modules, delegate to // the cc_library_static bp2build converter temporarily instead. - if android.GenerateCcLibraryStaticOnly(ctx) { + if android.GenerateCcLibraryStaticOnly(ctx.Module().Name()) { ccSharedOrStaticBp2BuildMutatorInternal(ctx, m, "cc_library_static") return }