Gen a header library when genrules export includes
Embedding multiple includes from a genrule may be difficult to read, instead we generate a header library that contains the headers and all include dirs that Soong generates. Test: go test bp2build tests Change-Id: I590c74c133f015f27cccf5a2fd916153ad9c125e
This commit is contained in:
@@ -1003,6 +1003,38 @@ cc_library_static {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCcLibraryStaticGeneratedHeadersMultipleExports(t *testing.T) {
|
||||||
|
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
|
||||||
|
Blueprint: soongCcLibraryStaticPreamble + `
|
||||||
|
genrule {
|
||||||
|
name: "generated_hdr",
|
||||||
|
cmd: "nothing to see here",
|
||||||
|
export_include_dirs: ["foo", "bar"],
|
||||||
|
bazel_module: { bp2build_available: false },
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "export_generated_hdr",
|
||||||
|
cmd: "nothing to see here",
|
||||||
|
export_include_dirs: ["a", "b"],
|
||||||
|
bazel_module: { bp2build_available: false },
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "foo_static",
|
||||||
|
generated_headers: ["generated_hdr", "export_generated_hdr"],
|
||||||
|
export_generated_headers: ["export_generated_hdr"],
|
||||||
|
include_build_directory: false,
|
||||||
|
}`,
|
||||||
|
ExpectedBazelTargets: []string{
|
||||||
|
MakeBazelTarget("cc_library_static", "foo_static", AttrNameToString{
|
||||||
|
"deps": `[":export_generated_hdr__header_library"]`,
|
||||||
|
"implementation_deps": `[":generated_hdr__header_library"]`,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// generated_headers has "variant_prepend" tag. In bp2build output,
|
// generated_headers has "variant_prepend" tag. In bp2build output,
|
||||||
// variant info(select) should go before general info.
|
// variant info(select) should go before general info.
|
||||||
func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
|
func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
|
||||||
|
@@ -16,6 +16,7 @@ package bp2build
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -695,3 +696,79 @@ func TestCcGenruleArchAndExcludeSrcs(t *testing.T) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGenruleWithExportIncludeDirs(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
moduleType string
|
||||||
|
factory android.ModuleFactory
|
||||||
|
hod android.HostOrDeviceSupported
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
moduleType: "genrule",
|
||||||
|
factory: genrule.GenRuleFactory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleType: "cc_genrule",
|
||||||
|
factory: cc.GenRuleFactory,
|
||||||
|
hod: android.DeviceSupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleType: "java_genrule",
|
||||||
|
factory: java.GenRuleFactory,
|
||||||
|
hod: android.DeviceSupported,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
moduleType: "java_genrule_host",
|
||||||
|
factory: java.GenRuleFactoryHost,
|
||||||
|
hod: android.HostSupported,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := "baz"
|
||||||
|
|
||||||
|
bp := `%s {
|
||||||
|
name: "foo",
|
||||||
|
out: ["foo.out.h"],
|
||||||
|
srcs: ["foo.in"],
|
||||||
|
cmd: "cp $(in) $(out)",
|
||||||
|
export_include_dirs: ["foo", "bar", "."],
|
||||||
|
bazel_module: { bp2build_available: true },
|
||||||
|
}`
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
moduleAttrs := AttrNameToString{
|
||||||
|
"cmd": `"cp $(SRCS) $(OUTS)"`,
|
||||||
|
"outs": `["foo.out.h"]`,
|
||||||
|
"srcs": `["foo.in"]`,
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedBazelTargets := []string{
|
||||||
|
makeBazelTargetHostOrDevice("genrule", "foo", moduleAttrs, tc.hod),
|
||||||
|
makeBazelTargetHostOrDevice("cc_library_headers", "foo__header_library", AttrNameToString{
|
||||||
|
"hdrs": `[":foo"]`,
|
||||||
|
"export_includes": `[
|
||||||
|
"foo",
|
||||||
|
"baz/foo",
|
||||||
|
"bar",
|
||||||
|
"baz/bar",
|
||||||
|
".",
|
||||||
|
"baz",
|
||||||
|
]`,
|
||||||
|
},
|
||||||
|
tc.hod),
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run(tc.moduleType, func(t *testing.T) {
|
||||||
|
RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
|
||||||
|
Bp2buildTestCase{
|
||||||
|
ModuleTypeUnderTest: tc.moduleType,
|
||||||
|
ModuleTypeUnderTestFactory: tc.factory,
|
||||||
|
Filesystem: map[string]string{
|
||||||
|
filepath.Join(dir, "Android.bp"): fmt.Sprintf(bp, tc.moduleType),
|
||||||
|
},
|
||||||
|
Dir: dir,
|
||||||
|
ExpectedBazelTargets: expectedBazelTargets,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import (
|
|||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
"android/soong/bazel"
|
"android/soong/bazel"
|
||||||
"android/soong/cc/config"
|
"android/soong/cc/config"
|
||||||
|
"android/soong/genrule"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
|
|
||||||
@@ -45,6 +46,8 @@ const (
|
|||||||
|
|
||||||
xsdSrcPartition = "xsd"
|
xsdSrcPartition = "xsd"
|
||||||
|
|
||||||
|
genrulePartition = "genrule"
|
||||||
|
|
||||||
hdrPartition = "hdr"
|
hdrPartition = "hdr"
|
||||||
|
|
||||||
stubsSuffix = "_stub_libs_current"
|
stubsSuffix = "_stub_libs_current"
|
||||||
@@ -173,6 +176,7 @@ func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.Lab
|
|||||||
func partitionHeaders(ctx android.BazelConversionPathContext, hdrs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
|
func partitionHeaders(ctx android.BazelConversionPathContext, hdrs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
|
||||||
labels := bazel.LabelPartitions{
|
labels := bazel.LabelPartitions{
|
||||||
xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
|
xsdSrcPartition: bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
|
||||||
|
genrulePartition: bazel.LabelPartition{LabelMapper: genrule.GenruleCcHeaderLabelMapper},
|
||||||
hdrPartition: bazel.LabelPartition{Keep_remainder: true},
|
hdrPartition: bazel.LabelPartition{Keep_remainder: true},
|
||||||
}
|
}
|
||||||
return bazel.PartitionLabelListAttribute(ctx, &hdrs, labels)
|
return bazel.PartitionLabelListAttribute(ctx, &hdrs, labels)
|
||||||
@@ -419,6 +423,10 @@ type compilerAttributes struct {
|
|||||||
xsdSrcs bazel.LabelListAttribute
|
xsdSrcs bazel.LabelListAttribute
|
||||||
exportXsdSrcs bazel.LabelListAttribute
|
exportXsdSrcs bazel.LabelListAttribute
|
||||||
|
|
||||||
|
// genrule headers
|
||||||
|
genruleHeaders bazel.LabelListAttribute
|
||||||
|
exportGenruleHeaders bazel.LabelListAttribute
|
||||||
|
|
||||||
// Lex sources and options
|
// Lex sources and options
|
||||||
lSrcs bazel.LabelListAttribute
|
lSrcs bazel.LabelListAttribute
|
||||||
llSrcs bazel.LabelListAttribute
|
llSrcs bazel.LabelListAttribute
|
||||||
@@ -606,6 +614,9 @@ func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, i
|
|||||||
ca.exportXsdSrcs = partitionedHdrs[xsdSrcPartition]
|
ca.exportXsdSrcs = partitionedHdrs[xsdSrcPartition]
|
||||||
ca.xsdSrcs = bazel.FirstUniqueBazelLabelListAttribute(xsdSrcs)
|
ca.xsdSrcs = bazel.FirstUniqueBazelLabelListAttribute(xsdSrcs)
|
||||||
|
|
||||||
|
ca.genruleHeaders = partitionedImplHdrs[genrulePartition]
|
||||||
|
ca.exportGenruleHeaders = partitionedHdrs[genrulePartition]
|
||||||
|
|
||||||
ca.srcs = partitionedSrcs[cppSrcPartition]
|
ca.srcs = partitionedSrcs[cppSrcPartition]
|
||||||
ca.cSrcs = partitionedSrcs[cSrcPartition]
|
ca.cSrcs = partitionedSrcs[cSrcPartition]
|
||||||
ca.asSrcs = partitionedSrcs[asSrcPartition]
|
ca.asSrcs = partitionedSrcs[asSrcPartition]
|
||||||
@@ -900,6 +911,9 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module)
|
|||||||
|
|
||||||
(&compilerAttrs.srcs).Add(bp2BuildYasm(ctx, module, compilerAttrs))
|
(&compilerAttrs.srcs).Add(bp2BuildYasm(ctx, module, compilerAttrs))
|
||||||
|
|
||||||
|
(&linkerAttrs).deps.Append(compilerAttrs.exportGenruleHeaders)
|
||||||
|
(&linkerAttrs).implementationDeps.Append(compilerAttrs.genruleHeaders)
|
||||||
|
|
||||||
(&linkerAttrs).wholeArchiveDeps.Append(compilerAttrs.exportXsdSrcs)
|
(&linkerAttrs).wholeArchiveDeps.Append(compilerAttrs.exportXsdSrcs)
|
||||||
(&linkerAttrs).implementationWholeArchiveDeps.Append(compilerAttrs.xsdSrcs)
|
(&linkerAttrs).implementationWholeArchiveDeps.Append(compilerAttrs.xsdSrcs)
|
||||||
|
|
||||||
|
@@ -994,6 +994,7 @@ func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
|||||||
|
|
||||||
tags := android.ApexAvailableTagsWithoutTestApexes(ctx, m)
|
tags := android.ApexAvailableTagsWithoutTestApexes(ctx, m)
|
||||||
|
|
||||||
|
bazelName := m.Name()
|
||||||
if ctx.ModuleType() == "gensrcs" {
|
if ctx.ModuleType() == "gensrcs" {
|
||||||
props := bazel.BazelTargetModuleProperties{
|
props := bazel.BazelTargetModuleProperties{
|
||||||
Rule_class: "gensrcs",
|
Rule_class: "gensrcs",
|
||||||
@@ -1021,7 +1022,6 @@ func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bazelName := m.Name()
|
|
||||||
for _, out := range outs {
|
for _, out := range outs {
|
||||||
if out == bazelName {
|
if out == bazelName {
|
||||||
// This is a workaround to circumvent a Bazel warning where a genrule's
|
// This is a workaround to circumvent a Bazel warning where a genrule's
|
||||||
@@ -1046,6 +1046,54 @@ func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
|
|||||||
Tags: tags,
|
Tags: tags,
|
||||||
}, attrs)
|
}, attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.needsCcLibraryHeadersBp2build() {
|
||||||
|
includeDirs := make([]string, len(m.properties.Export_include_dirs)*2)
|
||||||
|
for i, dir := range m.properties.Export_include_dirs {
|
||||||
|
includeDirs[i*2] = dir
|
||||||
|
includeDirs[i*2+1] = filepath.Clean(filepath.Join(ctx.ModuleDir(), dir))
|
||||||
|
}
|
||||||
|
attrs := &ccHeaderLibraryAttrs{
|
||||||
|
Hdrs: []string{":" + bazelName},
|
||||||
|
Export_includes: includeDirs,
|
||||||
|
}
|
||||||
|
props := bazel.BazelTargetModuleProperties{
|
||||||
|
Rule_class: "cc_library_headers",
|
||||||
|
Bzl_load_location: "//build/bazel/rules/cc:cc_library_headers.bzl",
|
||||||
|
}
|
||||||
|
ctx.CreateBazelTargetModule(props, android.CommonAttributes{
|
||||||
|
Name: m.Name() + genruleHeaderLibrarySuffix,
|
||||||
|
Tags: tags,
|
||||||
|
}, attrs)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const genruleHeaderLibrarySuffix = "__header_library"
|
||||||
|
|
||||||
|
func (m *Module) needsCcLibraryHeadersBp2build() bool {
|
||||||
|
return len(m.properties.Export_include_dirs) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenruleCcHeaderMapper is a bazel.LabelMapper function to map genrules to a cc_library_headers
|
||||||
|
// target when they export multiple include directories.
|
||||||
|
func GenruleCcHeaderLabelMapper(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
|
||||||
|
mod, exists := ctx.ModuleFromName(label.OriginalModuleName)
|
||||||
|
if !exists {
|
||||||
|
return label.Label, false
|
||||||
|
}
|
||||||
|
if m, ok := mod.(*Module); ok {
|
||||||
|
if m.needsCcLibraryHeadersBp2build() {
|
||||||
|
return label.Label + genruleHeaderLibrarySuffix, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label.Label, false
|
||||||
|
}
|
||||||
|
|
||||||
|
type ccHeaderLibraryAttrs struct {
|
||||||
|
Hdrs []string
|
||||||
|
|
||||||
|
Export_includes []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var Bool = proptools.Bool
|
var Bool = proptools.Bool
|
||||||
@@ -1099,6 +1147,7 @@ func getSandboxingAllowlistSets(ctx android.PathContext) *sandboxingAllowlistSet
|
|||||||
}
|
}
|
||||||
}).(*sandboxingAllowlistSets)
|
}).(*sandboxingAllowlistSets)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder {
|
func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder {
|
||||||
if !ctx.DeviceConfig().GenruleSandboxing() {
|
if !ctx.DeviceConfig().GenruleSandboxing() {
|
||||||
return r.SandboxTools()
|
return r.SandboxTools()
|
||||||
|
Reference in New Issue
Block a user