From 2d7bbe3883690020667ac3e480cb3452fcaab9e4 Mon Sep 17 00:00:00 2001 From: Liz Kammer Date: Thu, 10 Jun 2021 18:20:06 -0400 Subject: [PATCH] Append _alwayslink to prebuilt whole static deps This allows us to support prebuilt archives that are part of whole static deps. Test: build/bazel/ci/bp2build.sh Bug: 190716727 Change-Id: I913dbd8f85a1974fbd53c0cbaa49211db18ea45f --- android/bazel_paths.go | 51 +++++++++++++++++++++----- bp2build/cc_library_conversion_test.go | 43 ++++++++++++++++++++++ cc/bp2build.go | 19 ++++++---- 3 files changed, 95 insertions(+), 18 deletions(-) diff --git a/android/bazel_paths.go b/android/bazel_paths.go index f93fe2b5e..f74fed13f 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -83,6 +83,36 @@ type BazelConversionPathContext interface { // 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) +} + +// BazelLabelForModuleWholeDepsExcludes 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. 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 bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, isWholeLibs bool) bazel.LabelList { var labels bazel.LabelList for _, module := range modules { bpText := module @@ -90,7 +120,7 @@ func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) b module = ":" + module } if m, t := SrcIsModuleWithTag(module); m != "" { - l := getOtherModuleLabel(ctx, m, t) + l := getOtherModuleLabel(ctx, m, t, isWholeLibs) l.OriginalModuleName = bpText labels.Includes = append(labels.Includes, l) } else { @@ -100,16 +130,12 @@ func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) b return labels } -// BazelLabelForModuleDeps 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 { - moduleLabels := BazelLabelForModuleDeps(ctx, RemoveListFromList(modules, excludes)) +func bazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string, isWholeLibs bool) bazel.LabelList { + moduleLabels := bazelLabelForModuleDeps(ctx, RemoveListFromList(modules, excludes), isWholeLibs) if len(excludes) == 0 { return moduleLabels } - excludeLabels := BazelLabelForModuleDeps(ctx, excludes) + excludeLabels := bazelLabelForModuleDeps(ctx, excludes, isWholeLibs) return bazel.LabelList{ Includes: moduleLabels.Includes, Excludes: excludeLabels.Includes, @@ -273,7 +299,7 @@ func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes for _, p := range paths { if m, tag := SrcIsModuleWithTag(p); m != "" { - l := getOtherModuleLabel(ctx, m, tag) + l := getOtherModuleLabel(ctx, m, tag, false) if !InList(l.Label, expandedExcludes) { l.OriginalModuleName = fmt.Sprintf(":%s", m) labels.Includes = append(labels.Includes, l) @@ -304,7 +330,7 @@ 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) bazel.Label { +func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string, isWholeLibs bool) bazel.Label { m, _ := ctx.GetDirectDep(dep) if m == nil { panic(fmt.Errorf(`Cannot get direct dep %q of %q. @@ -313,6 +339,11 @@ func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string) bazel. } otherLabel := bazelModuleLabel(ctx, m, tag) label := bazelModuleLabel(ctx, ctx.Module(), "") + if isWholeLibs { + if m, ok := m.(Module); ok && IsModulePrebuilt(m) { + otherLabel += "_alwayslink" + } + } if samePackage(label, otherLabel) { otherLabel = bazelShortLabel(otherLabel) } diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index f18825193..7f6982cc3 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -49,6 +49,7 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) + ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory) ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) } @@ -401,6 +402,48 @@ cc_library { name: "shared_dep_for_both" } }) } +func TestCcLibraryWholeStaticLibsAlwaysLink(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build}, + dir: "foo/bar", + filesystem: map[string]string{ + "foo/bar/Android.bp": ` +cc_library { + name: "a", + whole_static_libs: ["whole_static_lib_for_both"], + static: { + whole_static_libs: ["whole_static_lib_for_static"], + }, + shared: { + whole_static_libs: ["whole_static_lib_for_shared"], + }, + bazel_module: { bp2build_available: true }, +} + +cc_prebuilt_library_static { name: "whole_static_lib_for_shared" } + +cc_prebuilt_library_static { name: "whole_static_lib_for_static" } + +cc_prebuilt_library_static { name: "whole_static_lib_for_both" } +`, + }, + blueprint: soongCcLibraryPreamble, + expectedBazelTargets: []string{`cc_library( + name = "a", + copts = [ + "-Ifoo/bar", + "-I$(BINDIR)/foo/bar", + ], + whole_archive_deps = [":whole_static_lib_for_both_alwayslink"], + whole_archive_deps_for_shared = [":whole_static_lib_for_shared_alwayslink"], + whole_archive_deps_for_static = [":whole_static_lib_for_static_alwayslink"], +)`}, + }) +} + func TestCcLibrarySharedStaticPropsInArch(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ description: "cc_library shared/static props in arch", diff --git a/cc/bp2build.go b/cc/bp2build.go index 5357668e5..7c6ee0a68 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -255,7 +255,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)), staticDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)), dynamicDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)), - wholeArchiveDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)), + wholeArchiveDeps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)), } setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { @@ -263,7 +263,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module attrs.srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) attrs.staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) attrs.dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) - attrs.wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Whole_static_libs)) + attrs.wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)) } if isStatic { @@ -554,7 +554,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs) staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) - wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) + wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) @@ -581,7 +581,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs) staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) - wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) + wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) @@ -604,13 +604,15 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) excludesField string // 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 } productVarToDepFields := map[string]productVarDep{ // product variables do not support exclude_shared_libs - "Shared_libs": productVarDep{attribute: &dynamicDeps}, - "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps}, - "Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps}, + "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}, } productVariableProps := android.ProductVariableProperties(ctx) @@ -644,7 +646,8 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) if excludes, ok = excludesProp.Property.([]string); excludesExists && !ok { ctx.ModuleErrorf("Could not convert product variable %s property", dep.excludesField) } - dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, android.BazelLabelForModuleDepsExcludes(ctx, android.FirstUniqueStrings(includes), excludes)) + + dep.attribute.SetSelectValue(bazel.ProductVariableConfigurationAxis(config), config, dep.depResolutionFunc(ctx, android.FirstUniqueStrings(includes), excludes)) } }