diff options
| -rw-r--r-- | android/filegroup.go | 5 | ||||
| -rw-r--r-- | bazel/properties.go | 34 | ||||
| -rw-r--r-- | bp2build/cc_library_conversion_test.go | 134 | ||||
| -rw-r--r-- | cc/bp2build.go | 99 | ||||
| -rw-r--r-- | cc/library.go | 55 |
5 files changed, 289 insertions, 38 deletions
diff --git a/android/filegroup.go b/android/filegroup.go index fc6850eb5..e2074127e 100644 --- a/android/filegroup.go +++ b/android/filegroup.go @@ -63,7 +63,10 @@ func FilegroupBp2Build(ctx TopDownMutatorContext) { Srcs: srcs, } - props := bazel.BazelTargetModuleProperties{Rule_class: "filegroup"} + props := bazel.BazelTargetModuleProperties{ + Rule_class: "filegroup", + Bzl_load_location: "//build/bazel/rules:filegroup.bzl", + } ctx.CreateBazelTargetModule(BazelFileGroupFactory, fg.Name(), props, attrs) } diff --git a/bazel/properties.go b/bazel/properties.go index b2d68da52..951081cc3 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -137,6 +137,39 @@ func SubtractStrings(haystack []string, needle []string) []string { return strings } +// Map a function over all labels in a LabelList. +func MapLabelList(mapOver LabelList, mapFn func(string) string) LabelList { + var includes []Label + for _, inc := range mapOver.Includes { + mappedLabel := Label{Label: mapFn(inc.Label), OriginalModuleName: inc.OriginalModuleName} + includes = append(includes, mappedLabel) + } + // mapFn is not applied over excludes, but they are propagated as-is. + return LabelList{Includes: includes, Excludes: mapOver.Excludes} +} + +// Map a function over all Labels in a LabelListAttribute +func MapLabelListAttribute(mapOver LabelListAttribute, mapFn func(string) string) LabelListAttribute { + var result LabelListAttribute + + result.Value = MapLabelList(mapOver.Value, mapFn) + + for arch := range PlatformArchMap { + result.SetValueForArch(arch, MapLabelList(mapOver.GetValueForArch(arch), mapFn)) + } + + for os := range PlatformOsMap { + result.SetOsValueForTarget(os, MapLabelList(mapOver.GetOsValueForTarget(os), mapFn)) + + // TODO(b/187530594): Should we handle arch=CONDITIONS_DEFAULT here? (not in ArchValues) + for _, arch := range AllArches { + result.SetOsArchValueForTarget(os, arch, MapLabelList(mapOver.GetOsArchValueForTarget(os, arch), mapFn)) + } + } + + return result +} + // Return all needles in a given haystack, where needleFn is true for needles. func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList { var includes []Label @@ -145,6 +178,7 @@ func FilterLabelList(haystack LabelList, needleFn func(string) bool) LabelList { includes = append(includes, inc) } } + // needleFn is not applied over excludes, but they are propagated as-is. return LabelList{Includes: includes, Excludes: haystack.Excludes} } diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index b87d71330..c8ae031a2 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -47,6 +47,7 @@ func runCcLibraryTestCase(t *testing.T, tc bp2buildTestCase) { func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) @@ -535,6 +536,139 @@ cc_library_static { name: "android_dep_for_shared" } }) } +func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library shared/static props with c/cpp/s mixed sources", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build}, + dir: "foo/bar", + filesystem: map[string]string{ + "foo/bar/both_source.cpp": "", + "foo/bar/both_source.cc": "", + "foo/bar/both_source.c": "", + "foo/bar/both_source.s": "", + "foo/bar/both_source.S": "", + "foo/bar/shared_source.cpp": "", + "foo/bar/shared_source.cc": "", + "foo/bar/shared_source.c": "", + "foo/bar/shared_source.s": "", + "foo/bar/shared_source.S": "", + "foo/bar/static_source.cpp": "", + "foo/bar/static_source.cc": "", + "foo/bar/static_source.c": "", + "foo/bar/static_source.s": "", + "foo/bar/static_source.S": "", + "foo/bar/Android.bp": ` +cc_library { + name: "a", + srcs: [ + "both_source.cpp", + "both_source.cc", + "both_source.c", + "both_source.s", + "both_source.S", + ":both_filegroup", + ], + static: { + srcs: [ + "static_source.cpp", + "static_source.cc", + "static_source.c", + "static_source.s", + "static_source.S", + ":static_filegroup", + ], + }, + shared: { + srcs: [ + "shared_source.cpp", + "shared_source.cc", + "shared_source.c", + "shared_source.s", + "shared_source.S", + ":shared_filegroup", + ], + }, + bazel_module: { bp2build_available: true }, +} + +filegroup { + name: "both_filegroup", + srcs: [ + // Not relevant, handled by filegroup macro + ], +} + +filegroup { + name: "shared_filegroup", + srcs: [ + // Not relevant, handled by filegroup macro + ], +} + +filegroup { + name: "static_filegroup", + srcs: [ + // Not relevant, handled by filegroup macro + ], +} +`, + }, + blueprint: soongCcLibraryPreamble, + expectedBazelTargets: []string{`cc_library( + name = "a", + copts = [ + "-Ifoo/bar", + "-I$(BINDIR)/foo/bar", + ], + shared_srcs = [ + ":shared_filegroup_cpp_srcs", + "shared_source.cc", + "shared_source.cpp", + ], + shared_srcs_as = [ + "shared_source.s", + "shared_source.S", + ":shared_filegroup_as_srcs", + ], + shared_srcs_c = [ + "shared_source.c", + ":shared_filegroup_c_srcs", + ], + srcs = [ + ":both_filegroup_cpp_srcs", + "both_source.cc", + "both_source.cpp", + ], + srcs_as = [ + "both_source.s", + "both_source.S", + ":both_filegroup_as_srcs", + ], + srcs_c = [ + "both_source.c", + ":both_filegroup_c_srcs", + ], + static_srcs = [ + ":static_filegroup_cpp_srcs", + "static_source.cc", + "static_source.cpp", + ], + static_srcs_as = [ + "static_source.s", + "static_source.S", + ":static_filegroup_as_srcs", + ], + static_srcs_c = [ + "static_source.c", + ":static_filegroup_c_srcs", + ], +)`}, + }) +} + func TestCcLibraryNonConfiguredVersionScript(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ description: "cc_library non-configured version script", diff --git a/cc/bp2build.go b/cc/bp2build.go index fed993670..a156d5444 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -14,6 +14,7 @@ package cc import ( + "fmt" "path/filepath" "strings" @@ -164,13 +165,86 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { // staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties -- // properties which apply to either the shared or static version of a cc_library module. type staticOrSharedAttributes struct { - copts bazel.StringListAttribute - srcs bazel.LabelListAttribute + srcs bazel.LabelListAttribute + srcs_c bazel.LabelListAttribute + srcs_as bazel.LabelListAttribute + + copts bazel.StringListAttribute + staticDeps bazel.LabelListAttribute dynamicDeps bazel.LabelListAttribute wholeArchiveDeps bazel.LabelListAttribute } +func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) { + // Branch srcs into three language-specific groups. + // C++ is the "catch-all" group, and comprises generated sources because we don't + // know the language of these sources until the genrule is executed. + // TODO(b/190006308): Handle language detection of sources in a Bazel rule. + isCSrcOrFilegroup := func(s string) bool { + return strings.HasSuffix(s, ".c") || strings.HasSuffix(s, "_c_srcs") + } + + isAsmSrcOrFilegroup := func(s string) bool { + return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") || strings.HasSuffix(s, "_as_srcs") + } + + // Check that a module is a filegroup type named <label>. + isFilegroupNamed := func(m android.Module, fullLabel string) bool { + if ctx.OtherModuleType(m) != "filegroup" { + return false + } + labelParts := strings.Split(fullLabel, ":") + if len(labelParts) > 2 { + // There should not be more than one colon in a label. + panic(fmt.Errorf("%s is not a valid Bazel label for a filegroup", fullLabel)) + } else { + return m.Name() == labelParts[len(labelParts)-1] + } + } + + // Convert the filegroup dependencies into the extension-specific filegroups + // filtered in the filegroup.bzl macro. + cppFilegroup := func(label string) string { + ctx.VisitDirectDeps(func(m android.Module) { + if isFilegroupNamed(m, label) { + label = label + "_cpp_srcs" + return + } + }) + return label + } + cFilegroup := func(label string) string { + ctx.VisitDirectDeps(func(m android.Module) { + if isFilegroupNamed(m, label) { + label = label + "_c_srcs" + return + } + }) + return label + } + asFilegroup := func(label string) string { + ctx.VisitDirectDeps(func(m android.Module) { + if isFilegroupNamed(m, label) { + label = label + "_as_srcs" + return + } + }) + return label + } + + cSrcs = bazel.MapLabelListAttribute(srcs, cFilegroup) + cSrcs = bazel.FilterLabelListAttribute(cSrcs, isCSrcOrFilegroup) + + asSrcs = bazel.MapLabelListAttribute(srcs, asFilegroup) + asSrcs = bazel.FilterLabelListAttribute(asSrcs, isAsmSrcOrFilegroup) + + cppSrcs = bazel.MapLabelListAttribute(srcs, cppFilegroup) + cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, cSrcs) + cppSrcs = bazel.SubtractBazelLabelListAttribute(cppSrcs, asSrcs) + return +} + // bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library. func bp2BuildParseSharedProps(ctx android.TopDownMutatorContext, module *Module) staticOrSharedAttributes { lib, ok := module.compiler.(*libraryDecorator) @@ -265,6 +339,11 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module } } + cppSrcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, attrs.srcs) + attrs.srcs = cppSrcs + attrs.srcs_c = cSrcs + attrs.srcs_as = asSrcs + return attrs } @@ -528,20 +607,8 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul } } - // Branch srcs into three language-specific groups. - // C++ is the "catch-all" group, and comprises generated sources because we don't - // know the language of these sources until the genrule is executed. - // TODO(b/): Handle language detection of sources in a Bazel rule. - isCSrc := func(s string) bool { - return strings.HasSuffix(s, ".c") - } - isAsmSrc := func(s string) bool { - return strings.HasSuffix(s, ".S") || strings.HasSuffix(s, ".s") - } - cSrcs := bazel.FilterLabelListAttribute(srcs, isCSrc) - asSrcs := bazel.FilterLabelListAttribute(srcs, isAsmSrc) - srcs = bazel.SubtractBazelLabelListAttribute(srcs, cSrcs) - srcs = bazel.SubtractBazelLabelListAttribute(srcs, asSrcs) + srcs, cSrcs, asSrcs := groupSrcsByExtension(ctx, srcs) + return compilerAttributes{ copts: copts, srcs: srcs, diff --git a/cc/library.go b/cc/library.go index 5e70c51e9..cdac01cbc 100644 --- a/cc/library.go +++ b/cc/library.go @@ -221,25 +221,29 @@ func RegisterLibraryBuildComponents(ctx android.RegistrationContext) { // For bp2build conversion. type bazelCcLibraryAttributes struct { // Attributes pertaining to both static and shared variants. - Srcs bazel.LabelListAttribute + Srcs bazel.LabelListAttribute + Srcs_c bazel.LabelListAttribute + Srcs_as bazel.LabelListAttribute + + Copts bazel.StringListAttribute + Cppflags bazel.StringListAttribute + Conlyflags bazel.StringListAttribute + Asflags bazel.StringListAttribute + Hdrs bazel.LabelListAttribute Deps bazel.LabelListAttribute Implementation_deps bazel.LabelListAttribute Dynamic_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute - Copts bazel.StringListAttribute Includes bazel.StringListAttribute Linkopts bazel.StringListAttribute - Cppflags bazel.StringListAttribute - Srcs_c bazel.LabelListAttribute - Conlyflags bazel.StringListAttribute - Srcs_as bazel.LabelListAttribute - Asflags bazel.StringListAttribute - // Attributes pertaining to shared variant. - Shared_copts bazel.StringListAttribute - Shared_srcs bazel.LabelListAttribute + Shared_srcs bazel.LabelListAttribute + Shared_srcs_c bazel.LabelListAttribute + Shared_srcs_as bazel.LabelListAttribute + Shared_copts bazel.StringListAttribute + Exported_deps_for_shared bazel.LabelListAttribute Static_deps_for_shared bazel.LabelListAttribute Dynamic_deps_for_shared bazel.LabelListAttribute @@ -248,8 +252,11 @@ type bazelCcLibraryAttributes struct { Version_script bazel.LabelAttribute // Attributes pertaining to static variant. - Static_copts bazel.StringListAttribute - Static_srcs bazel.LabelListAttribute + Static_srcs bazel.LabelListAttribute + Static_srcs_c bazel.LabelListAttribute + Static_srcs_as bazel.LabelListAttribute + Static_copts bazel.StringListAttribute + Exported_deps_for_static bazel.LabelListAttribute Static_deps_for_static bazel.LabelListAttribute Dynamic_deps_for_static bazel.LabelListAttribute @@ -302,29 +309,35 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { srcs.Append(compilerAttrs.srcs) attrs := &bazelCcLibraryAttributes{ - Srcs: srcs, + Srcs: srcs, + Srcs_c: compilerAttrs.cSrcs, + Srcs_as: compilerAttrs.asSrcs, + + Copts: compilerAttrs.copts, + Cppflags: compilerAttrs.cppFlags, + Conlyflags: compilerAttrs.conlyFlags, + Asflags: compilerAttrs.asFlags, + Implementation_deps: linkerAttrs.deps, Deps: linkerAttrs.exportedDeps, Dynamic_deps: linkerAttrs.dynamicDeps, Whole_archive_deps: linkerAttrs.wholeArchiveDeps, - Copts: compilerAttrs.copts, Includes: exportedIncludes, Linkopts: linkerAttrs.linkopts, - Cppflags: compilerAttrs.cppFlags, - Srcs_c: compilerAttrs.cSrcs, - Conlyflags: compilerAttrs.conlyFlags, - Srcs_as: compilerAttrs.asSrcs, - Asflags: compilerAttrs.asFlags, - Shared_copts: sharedAttrs.copts, Shared_srcs: sharedAttrs.srcs, + Shared_srcs_c: sharedAttrs.srcs_c, + Shared_srcs_as: sharedAttrs.srcs_as, + Shared_copts: sharedAttrs.copts, Static_deps_for_shared: sharedAttrs.staticDeps, Whole_archive_deps_for_shared: sharedAttrs.wholeArchiveDeps, Dynamic_deps_for_shared: sharedAttrs.dynamicDeps, Version_script: linkerAttrs.versionScript, - Static_copts: staticAttrs.copts, Static_srcs: staticAttrs.srcs, + Static_srcs_c: staticAttrs.srcs_c, + Static_srcs_as: staticAttrs.srcs_as, + Static_copts: staticAttrs.copts, Static_deps_for_static: staticAttrs.staticDeps, Whole_archive_deps_for_static: staticAttrs.wholeArchiveDeps, Dynamic_deps_for_static: staticAttrs.dynamicDeps, |