Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14a8bda3 authored by Jingwen Chen's avatar Jingwen Chen
Browse files

bp2build: split as, c, and cpp srcs for cc_library

This CL adds support for cc_library to correctly split c, as and cpp
srcs in shared/static nested props, as well as splitting
the *filegroup* deps in those props, where each filegroup is expanded
into its own c, cpp and as srcs filegroups. This ensures that the
correct sources go into cc_library_static's underlying cc_libraries for
c, cpp and as sources respectively.

See the bp2build conversion test for a better visualization.

Bug: 183064430

Test: TH
Change-Id: I29add5140672d042adff65527d8b65f4a5f0a05b
parent 7e21d3cd
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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)
}
+34 −0
Original line number Diff line number Diff line
@@ -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}
}

+134 −0
Original line number Diff line number Diff line
@@ -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",
+83 −16
Original line number Diff line number Diff line
@@ -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_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,
+34 −21
Original line number Diff line number Diff line
@@ -222,24 +222,28 @@ func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
type bazelCcLibraryAttributes struct {
	// Attributes pertaining to both static and shared variants.
	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_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_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
@@ -303,28 +310,34 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {

	attrs := &bazelCcLibraryAttributes{
		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,