bp2build: cc_library converter for //bionic/libdl:libdl_android

This CL contains the converter for libdl_android, a cc_library that
expands into a cc_shared_library and a regular cc_library.

Test: TH
Test: bp2build; bazel test //build/bazel/tests/...

Change-Id: If70641a538211b0d6b2aac0e4d0d06912318304d
diff --git a/cc/bp2build.go b/cc/bp2build.go
index cffeb24..e7e4aa8 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -59,72 +59,95 @@
 	ctx.AddDependency(module, nil, android.SortedUniqueStrings(allDeps)...)
 }
 
-// bp2buildParseCflags creates a label list attribute containing the cflags of a module, including
-func bp2BuildParseCflags(ctx android.TopDownMutatorContext, module *Module) bazel.StringListAttribute {
-	var ret bazel.StringListAttribute
+// bp2BuildParseCompilerProps returns copts, srcs and hdrs and other attributes.
+func bp2BuildParseCompilerProps(
+	ctx android.TopDownMutatorContext,
+	module *Module) (
+	copts bazel.StringListAttribute,
+	srcs bazel.LabelListAttribute,
+	hdrs bazel.LabelListAttribute) {
+
+	hdrsAndSrcs := func(baseCompilerProps *BaseCompilerProperties) (bazel.LabelList, bazel.LabelList) {
+		srcsList := android.BazelLabelForModuleSrcExcludes(
+			ctx, baseCompilerProps.Srcs, baseCompilerProps.Exclude_srcs)
+		hdrsList := android.BazelLabelForModuleSrc(ctx, srcsList.LooseHdrsGlobs(headerExts))
+		return hdrsList, srcsList
+	}
+
 	for _, props := range module.compiler.compilerProps() {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			ret.Value = baseCompilerProps.Cflags
+			hdrs.Value, srcs.Value = hdrsAndSrcs(baseCompilerProps)
+			copts.Value = baseCompilerProps.Cflags
 			break
 		}
 	}
 
 	for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			ret.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
+			hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
+			hdrs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
+			srcs.SetValueForArch(arch.Name, srcsList)
+			copts.SetValueForArch(arch.Name, baseCompilerProps.Cflags)
 		}
 	}
 
 	for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			ret.SetValueForOS(os.Name, baseCompilerProps.Cflags)
+			hdrsList, srcsList := hdrsAndSrcs(baseCompilerProps)
+			hdrs.SetValueForOS(os.Name, bazel.SubtractBazelLabelList(hdrsList, hdrs.Value))
+			srcs.SetValueForOS(os.Name, srcsList)
+			copts.SetValueForOS(os.Name, baseCompilerProps.Cflags)
 		}
 	}
 
-	return ret
+	return copts, srcs, hdrs
 }
 
-// bp2BuildParseHeaderLibs creates a label list attribute containing the header library deps of a module, including
+// bp2BuildParseLinkerProps creates a label list attribute containing the header library deps of a module, including
 // configurable attribute values.
-func bp2BuildParseHeaderLibs(ctx android.TopDownMutatorContext, module *Module) bazel.LabelListAttribute {
-	var ret bazel.LabelListAttribute
+func bp2BuildParseLinkerProps(
+	ctx android.TopDownMutatorContext, module *Module) (bazel.LabelListAttribute, bazel.StringListAttribute) {
+
+	var deps bazel.LabelListAttribute
+	var linkopts bazel.StringListAttribute
+
 	for _, linkerProps := range module.linker.linkerProps() {
 		if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
 			libs := baseLinkerProps.Header_libs
 			libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
-			ret = bazel.MakeLabelListAttribute(
+			deps = bazel.MakeLabelListAttribute(
 				android.BazelLabelForModuleDeps(ctx, android.SortedUniqueStrings(libs)))
+			linkopts.Value = baseLinkerProps.Ldflags
 			break
 		}
 	}
 
+	for arch, p := range module.GetArchProperties(&BaseLinkerProperties{}) {
+		if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
+			libs := baseLinkerProps.Header_libs
+			libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
+			libs = android.SortedUniqueStrings(libs)
+			deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
+			linkopts.SetValueForArch(arch.Name, baseLinkerProps.Ldflags)
+		}
+	}
+
 	for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) {
 		if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok {
 			libs := baseLinkerProps.Header_libs
 			libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
 			libs = android.SortedUniqueStrings(libs)
-			ret.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
+			deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
+			linkopts.SetValueForOS(os.Name, baseLinkerProps.Ldflags)
 		}
 	}
 
-	return ret
+	return deps, linkopts
 }
 
 func bp2BuildListHeadersInDir(ctx android.TopDownMutatorContext, includeDir string) bazel.LabelList {
-	var globInfix string
-
-	if includeDir == "." {
-		globInfix = ""
-	} else {
-		globInfix = "/**"
-	}
-
-	var includeDirGlobs []string
-	includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.h")
-	includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.inc")
-	includeDirGlobs = append(includeDirGlobs, includeDir+globInfix+"/*.hpp")
-
-	return android.BazelLabelForModuleSrc(ctx, includeDirGlobs)
+	globs := bazel.GlobsInDir(includeDir, includeDir != ".", headerExts)
+	return android.BazelLabelForModuleSrc(ctx, globs)
 }
 
 // Bazel wants include paths to be relative to the module
diff --git a/cc/library.go b/cc/library.go
index 18f9fae..0ebcbaa 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -206,6 +206,7 @@
 	RegisterLibraryBuildComponents(android.InitRegistrationContext)
 
 	android.RegisterBp2BuildMutator("cc_library_static", CcLibraryStaticBp2Build)
+	android.RegisterBp2BuildMutator("cc_library", CcLibraryBp2Build)
 }
 
 func RegisterLibraryBuildComponents(ctx android.RegistrationContext) {
@@ -216,6 +217,67 @@
 	ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
 }
 
+// For bp2build conversion.
+type bazelCcLibraryAttributes struct {
+	Srcs            bazel.LabelListAttribute
+	Hdrs            bazel.LabelListAttribute
+	Copts           bazel.StringListAttribute
+	Linkopts        bazel.StringListAttribute
+	Deps            bazel.LabelListAttribute
+	User_link_flags bazel.StringListAttribute
+	Includes        bazel.StringListAttribute
+}
+
+type bazelCcLibrary struct {
+	android.BazelTargetModuleBase
+	bazelCcLibraryAttributes
+}
+
+func (m *bazelCcLibrary) Name() string {
+	return m.BaseModuleName()
+}
+
+func (m *bazelCcLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {}
+
+func BazelCcLibraryFactory() android.Module {
+	module := &bazelCcLibrary{}
+	module.AddProperties(&module.bazelCcLibraryAttributes)
+	android.InitBazelTargetModule(module)
+	return module
+}
+
+func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
+	m, ok := ctx.Module().(*Module)
+	if !ok || !m.ConvertWithBp2build(ctx) {
+		return
+	}
+
+	if ctx.ModuleType() != "cc_library" {
+		return
+	}
+
+	copts, srcs, hdrs := bp2BuildParseCompilerProps(ctx, m)
+	deps, linkopts := bp2BuildParseLinkerProps(ctx, m)
+	exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, m)
+	hdrs.Append(exportedIncludesHeaders)
+
+	attrs := &bazelCcLibraryAttributes{
+		Srcs:     srcs,
+		Hdrs:     hdrs,
+		Copts:    copts,
+		Linkopts: linkopts,
+		Deps:     deps,
+		Includes: exportedIncludes,
+	}
+
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_library",
+		Bzl_load_location: "//build/bazel/rules:full_cc_library.bzl",
+	}
+
+	ctx.CreateBazelTargetModule(BazelCcLibraryFactory, m.Name(), props, attrs)
+}
+
 // cc_library creates both static and/or shared libraries for a device and/or
 // host. By default, a cc_library has a single variant that targets the device.
 // Specifying `host_supported: true` also creates a library that targets the
@@ -2058,9 +2120,10 @@
 }
 
 type bazelCcLibraryStaticAttributes struct {
-	Copts      []string
+	Copts      bazel.StringListAttribute
 	Srcs       bazel.LabelListAttribute
 	Deps       bazel.LabelListAttribute
+	Linkopts   bazel.StringListAttribute
 	Linkstatic bool
 	Includes   bazel.StringListAttribute
 	Hdrs       bazel.LabelListAttribute
@@ -2091,14 +2154,12 @@
 		return
 	}
 
-	var copts []string
-	var srcs []string
+	copts, srcs, hdrs := bp2BuildParseCompilerProps(ctx, module)
+
 	var includeDirs []string
 	var localIncludeDirs []string
 	for _, props := range module.compiler.compilerProps() {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			copts = baseCompilerProps.Cflags
-			srcs = baseCompilerProps.Srcs
 			includeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Include_dirs)
 			localIncludeDirs = bp2BuildMakePathsRelativeToModule(ctx, baseCompilerProps.Local_include_dirs)
 			break
@@ -2111,14 +2172,12 @@
 		localIncludeDirs = append(localIncludeDirs, ".")
 	}
 
-	srcsLabels := android.BazelLabelForModuleSrc(ctx, srcs)
-
 	// For Bazel, be more explicit about headers - list all header files in include dirs as srcs
 	for _, includeDir := range includeDirs {
-		srcsLabels.Append(bp2BuildListHeadersInDir(ctx, includeDir))
+		srcs.Value.Append(bp2BuildListHeadersInDir(ctx, includeDir))
 	}
 	for _, localIncludeDir := range localIncludeDirs {
-		srcsLabels.Append(bp2BuildListHeadersInDir(ctx, localIncludeDir))
+		srcs.Value.Append(bp2BuildListHeadersInDir(ctx, localIncludeDir))
 	}
 
 	var staticLibs []string
@@ -2145,16 +2204,18 @@
 	allIncludes.Value = append(allIncludes.Value, includeDirs...)
 	allIncludes.Value = append(allIncludes.Value, localIncludeDirs...)
 
-	headerLibsLabels := bp2BuildParseHeaderLibs(ctx, module)
+	hdrs.Append(exportedIncludesHeaders)
+
+	headerLibsLabels, _ := bp2BuildParseLinkerProps(ctx, module)
 	depsLabels.Append(headerLibsLabels.Value)
 
 	attrs := &bazelCcLibraryStaticAttributes{
 		Copts:      copts,
-		Srcs:       bazel.MakeLabelListAttribute(srcsLabels),
+		Srcs:       srcs,
 		Deps:       bazel.MakeLabelListAttribute(depsLabels),
 		Linkstatic: true,
 		Includes:   allIncludes,
-		Hdrs:       exportedIncludesHeaders,
+		Hdrs:       hdrs,
 	}
 
 	props := bazel.BazelTargetModuleProperties{
diff --git a/cc/library_headers.go b/cc/library_headers.go
index d35748b..0f7f8f8 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -96,11 +96,11 @@
 	}
 
 	exportedIncludes, exportedIncludesHeaders := bp2BuildParseExportedIncludes(ctx, module)
-
-	headerLibs := bp2BuildParseHeaderLibs(ctx, module)
+	copts, _, _ := bp2BuildParseCompilerProps(ctx, module)
+	headerLibs, _ := bp2BuildParseLinkerProps(ctx, module)
 
 	attrs := &bazelCcLibraryHeadersAttributes{
-		Copts:    bp2BuildParseCflags(ctx, module),
+		Copts:    copts,
 		Includes: exportedIncludes,
 		Hdrs:     exportedIncludesHeaders,
 		Deps:     headerLibs,
diff --git a/cc/object.go b/cc/object.go
index 4f8797d..de45293 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -113,6 +113,7 @@
 // For bp2build conversion.
 type bazelObjectAttributes struct {
 	Srcs               bazel.LabelListAttribute
+	Hdrs               bazel.LabelListAttribute
 	Deps               bazel.LabelListAttribute
 	Copts              bazel.StringListAttribute
 	Asflags            []string
@@ -156,16 +157,11 @@
 	}
 
 	// Set arch-specific configurable attributes
-	var srcs bazel.LabelListAttribute
+	copts, srcs, hdrs := bp2BuildParseCompilerProps(ctx, m)
 	var localIncludeDirs []string
 	var asFlags []string
 	for _, props := range m.compiler.compilerProps() {
 		if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
-			srcs = bazel.MakeLabelListAttribute(
-				android.BazelLabelForModuleSrcExcludes(
-					ctx,
-					baseCompilerProps.Srcs,
-					baseCompilerProps.Exclude_srcs))
 			localIncludeDirs = baseCompilerProps.Local_include_dirs
 			break
 		}
@@ -208,8 +204,9 @@
 
 	attrs := &bazelObjectAttributes{
 		Srcs:               srcs,
+		Hdrs:               hdrs,
 		Deps:               deps,
-		Copts:              bp2BuildParseCflags(ctx, m),
+		Copts:              copts,
 		Asflags:            asFlags,
 		Local_include_dirs: localIncludeDirs,
 	}