bp2build: Add support for export_.*headers props
Soong supports export_.*_headers properties, the libraries contained in
this list must also be within a shared/static/whole_static/header libs
property. For bp2build, we eliminate this duplication. The libraries
not listed in an export_.*_headers property will migrate to an attribute
prepended with implementation_, those in export_.*_headers will not have
a prefix.
Test: build/bazel/ci/bp2build.sh
Test: build/bazel/ci/mixed_libc.sh
Bug: 198241472
Change-Id: I3eb84c983ec5d241c8a568e411dfd5619d3184a7
diff --git a/cc/bp2build.go b/cc/bp2build.go
index e48f757..1b38a75 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -33,9 +34,11 @@
Srcs_as bazel.LabelListAttribute
Copts bazel.StringListAttribute
- Static_deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- Whole_archive_deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Implementation_deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Implementation_dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
System_dynamic_deps bazel.LabelListAttribute
}
@@ -131,16 +134,50 @@
return bp2BuildParseLibProps(ctx, module, true)
}
+type depsPartition struct {
+ export bazel.LabelList
+ implementation bazel.LabelList
+}
+
+type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList
+
+func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+ implementation, export := android.FilterList(allDeps, exportedDeps)
+
+ return depsPartition{
+ export: fn(ctx, export),
+ implementation: fn(ctx, implementation),
+ }
+}
+
+type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList
+
+func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+ implementation, export := android.FilterList(allDeps, exportedDeps)
+
+ return depsPartition{
+ export: fn(ctx, export, excludes),
+ implementation: fn(ctx, implementation, excludes),
+ }
+}
+
func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
attrs := staticOrSharedAttributes{}
setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
attrs.Copts.SetSelectValue(axis, config, props.Cflags)
attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
- attrs.Static_deps.SetSelectValue(axis, config, bazelLabelForStaticDeps(ctx, props.Static_libs))
- attrs.Dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.Shared_libs))
- attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
+
+ staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps)
+ attrs.Deps.SetSelectValue(axis, config, staticDeps.export)
+ attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation)
+
+ sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps)
+ attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export)
+ attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
+
+ attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
}
// system_dynamic_deps distinguishes between nil/empty list behavior:
// nil -> use default values
@@ -328,11 +365,13 @@
// Convenience struct to hold all attributes parsed from linker properties.
type linkerAttributes struct {
- deps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- systemDynamicDeps bazel.LabelListAttribute
- wholeArchiveDeps bazel.LabelListAttribute
- exportedDeps bazel.LabelListAttribute
+ deps bazel.LabelListAttribute
+ implementationDeps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ implementationDynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
+ systemDynamicDeps bazel.LabelListAttribute
+
useLibcrt bazel.BoolAttribute
linkopts bazel.StringListAttribute
versionScript bazel.LabelAttribute
@@ -355,12 +394,16 @@
// bp2BuildParseLinkerProps parses the linker properties of a module, including
// configurable attribute values.
func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
+
var headerDeps bazel.LabelListAttribute
- var staticDeps bazel.LabelListAttribute
- var exportedDeps bazel.LabelListAttribute
+ var implementationHeaderDeps bazel.LabelListAttribute
+ var deps bazel.LabelListAttribute
+ var implementationDeps bazel.LabelListAttribute
var dynamicDeps bazel.LabelListAttribute
+ var implementationDynamicDeps bazel.LabelListAttribute
var wholeArchiveDeps bazel.LabelListAttribute
systemSharedDeps := bazel.LabelListAttribute{ForceSpecifyEmptyList: true}
+
var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute
var useLibcrt bazel.BoolAttribute
@@ -386,12 +429,16 @@
for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) {
for config, props := range configToProps {
if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok {
+
// Excludes to parallel Soong:
// https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0
staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs)
- staticDeps.SetSelectValue(axis, config, bazelLabelForStaticDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs))
- wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
- wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs))
+ staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes)
+ deps.SetSelectValue(axis, config, staticDeps.export)
+ implementationDeps.SetSelectValue(axis, config, staticDeps.implementation)
+
+ wholeStaticLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs)
+ wholeArchiveDeps.SetSelectValue(axis, config, bazelLabelForWholeDepsExcludes(ctx, wholeStaticLibs, baseLinkerProps.Exclude_static_libs))
systemSharedLibs := baseLinkerProps.System_shared_libs
// systemSharedLibs distinguishes between nil/empty list behavior:
@@ -403,12 +450,15 @@
systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs))
sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs)
- dynamicDeps.SetSelectValue(axis, config, bazelLabelForSharedDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs))
+ sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes)
+ dynamicDeps.SetSelectValue(axis, config, sharedDeps.export)
+ implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation)
headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs)
- headerDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, headerLibs))
- exportedLibs := android.FirstUniqueStrings(baseLinkerProps.Export_header_lib_headers)
- exportedDeps.SetSelectValue(axis, config, bazelLabelForHeaderDeps(ctx, exportedLibs))
+ hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps)
+
+ headerDeps.SetSelectValue(axis, config, hDeps.export)
+ implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation)
linkopts.SetSelectValue(axis, config, getBp2BuildLinkerFlags(baseLinkerProps))
if baseLinkerProps.Version_script != nil {
@@ -430,8 +480,8 @@
productVarToDepFields := map[string]productVarDep{
// product variables do not support exclude_shared_libs
- "Shared_libs": productVarDep{attribute: &dynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
- "Static_libs": productVarDep{"Exclude_static_libs", &staticDeps, bazelLabelForStaticDepsExcludes},
+ "Shared_libs": productVarDep{attribute: &implementationDynamicDeps, depResolutionFunc: bazelLabelForSharedDepsExcludes},
+ "Static_libs": productVarDep{"Exclude_static_libs", &implementationDeps, bazelLabelForStaticDepsExcludes},
"Whole_static_libs": productVarDep{"Exclude_static_libs", &wholeArchiveDeps, bazelLabelForWholeDepsExcludes},
}
@@ -471,21 +521,26 @@
}
}
- staticDeps.ResolveExcludes()
+ headerDeps.Append(deps)
+ implementationHeaderDeps.Append(implementationDeps)
+
+ headerDeps.ResolveExcludes()
+ implementationHeaderDeps.ResolveExcludes()
dynamicDeps.ResolveExcludes()
+ implementationDynamicDeps.ResolveExcludes()
wholeArchiveDeps.ResolveExcludes()
- headerDeps.Append(staticDeps)
-
return linkerAttributes{
- deps: headerDeps,
- exportedDeps: exportedDeps,
- dynamicDeps: dynamicDeps,
- systemDynamicDeps: systemSharedDeps,
- wholeArchiveDeps: wholeArchiveDeps,
- linkopts: linkopts,
- useLibcrt: useLibcrt,
- versionScript: versionScript,
+ deps: headerDeps,
+ implementationDeps: implementationHeaderDeps,
+ dynamicDeps: dynamicDeps,
+ implementationDynamicDeps: implementationDynamicDeps,
+ wholeArchiveDeps: wholeArchiveDeps,
+ systemDynamicDeps: systemSharedDeps,
+
+ linkopts: linkopts,
+ useLibcrt: useLibcrt,
+ versionScript: versionScript,
// Strip properties
stripKeepSymbols: stripKeepSymbols,