diff --git a/android/bazel.go b/android/bazel.go index 7123ed2c7..e3d017fe6 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -204,16 +204,11 @@ var ( "libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx "fmtlib", // cc_library_static, fatal error: 'cassert' file not found, from libcxx "fmtlib_ndk", // cc_library_static, fatal error: 'cassert' file not found + "liblog", // http://b/186822772: cc_library, 'sys/cdefs.h' file not found "libbase", // Requires liblog. http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx. + // Also depends on fmtlib. - // http://b/186024507: Includes errors because of the system_shared_libs default value. - // Missing -isystem bionic/libc/include through the libc/libm/libdl - // default dependencies if system_shared_libs is unset. - "liblog", // http://b/186822772: cc_library, 'sys/cdefs.h' file not found - "libjemalloc5_jet", // cc_library, 'sys/cdefs.h' file not found - "libseccomp_policy", // http://b/186476753: cc_library, 'linux/filter.h' not found - "note_memtag_heap_async", // http://b/185127353: cc_library_static, error: feature.h not found - "note_memtag_heap_sync", // http://b/185127353: cc_library_static, error: feature.h not found + "libseccomp_policy", // depends on libbase "gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset diff --git a/android/bazel_paths.go b/android/bazel_paths.go index b05077446..c09d218f4 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -115,6 +115,11 @@ func BazelLabelForModuleWholeDepsExcludes(ctx BazelConversionPathContext, module func bazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string, isWholeLibs bool) bazel.LabelList { var labels bazel.LabelList + // In some cases, a nil string list is different than an explicitly empty list. + if len(modules) == 0 && modules != nil { + labels.Includes = []bazel.Label{} + return labels + } for _, module := range modules { bpText := module if m := SrcIsModule(module); m == "" { diff --git a/bazel/configurability.go b/bazel/configurability.go index f5f0913ee..7aaff9aef 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -56,7 +56,7 @@ const ( // This is consistently named "conditions_default" to mirror the Soong // config variable default key in an Android.bp file, although there's no // integration with Soong config variables (yet). - conditionsDefault = "conditions_default" + ConditionsDefaultConfigKey = "conditions_default" ConditionsDefaultSelectKey = "//conditions:default" @@ -72,45 +72,45 @@ var ( // A map of architectures to the Bazel label of the constraint_value // for the @platforms//cpu:cpu constraint_setting platformArchMap = map[string]string{ - archArm: "//build/bazel/platforms/arch:arm", - archArm64: "//build/bazel/platforms/arch:arm64", - archX86: "//build/bazel/platforms/arch:x86", - archX86_64: "//build/bazel/platforms/arch:x86_64", - conditionsDefault: ConditionsDefaultSelectKey, // The default condition of as arch select map. + archArm: "//build/bazel/platforms/arch:arm", + archArm64: "//build/bazel/platforms/arch:arm64", + archX86: "//build/bazel/platforms/arch:x86", + archX86_64: "//build/bazel/platforms/arch:x86_64", + ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of as arch select map. } // A map of target operating systems to the Bazel label of the // constraint_value for the @platforms//os:os constraint_setting platformOsMap = map[string]string{ - osAndroid: "//build/bazel/platforms/os:android", - osDarwin: "//build/bazel/platforms/os:darwin", - osLinux: "//build/bazel/platforms/os:linux", - osLinuxMusl: "//build/bazel/platforms/os:linux_musl", - osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", - osWindows: "//build/bazel/platforms/os:windows", - conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + osAndroid: "//build/bazel/platforms/os:android", + osDarwin: "//build/bazel/platforms/os:darwin", + osLinux: "//build/bazel/platforms/os:linux", + osLinuxMusl: "//build/bazel/platforms/os:linux_musl", + osLinuxBionic: "//build/bazel/platforms/os:linux_bionic", + osWindows: "//build/bazel/platforms/os:windows", + ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } platformBionicMap = map[string]string{ - "bionic": "//build/bazel/platforms/os:bionic", - conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + "bionic": "//build/bazel/platforms/os:bionic", + ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } platformOsArchMap = map[string]string{ - osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", - osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", - osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86", - osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64", - osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64", - osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86", - osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64", - osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86", - osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64", - osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64", - osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64", - osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86", - osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", - conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", + osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", + osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86", + osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64", + osArchDarwinX86_64: "//build/bazel/platforms/os_arch:darwin_x86_64", + osArchLinuxX86: "//build/bazel/platforms/os_arch:linux_glibc_x86", + osArchLinuxX86_64: "//build/bazel/platforms/os_arch:linux_glibc_x86_64", + osArchLinuxMuslX86: "//build/bazel/platforms/os_arch:linux_musl_x86", + osArchLinuxMuslX86_64: "//build/bazel/platforms/os_arch:linux_musl_x86_64", + osArchLinuxBionicArm64: "//build/bazel/platforms/os_arch:linux_bionic_arm64", + osArchLinuxBionicX86_64: "//build/bazel/platforms/os_arch:linux_bionic_x86_64", + osArchWindowsX86: "//build/bazel/platforms/os_arch:windows_x86", + osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64", + ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map. } ) @@ -181,7 +181,7 @@ func (ct configurationType) SelectKey(config string) string { case bionic: return platformBionicMap[config] case productVariables: - if config == conditionsDefault { + if config == ConditionsDefaultConfigKey { return ConditionsDefaultSelectKey } return fmt.Sprintf("%s:%s", productVariableBazelPackage, strings.ToLower(config)) diff --git a/bazel/properties.go b/bazel/properties.go index 2656badb5..1a846ba6a 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -69,6 +69,23 @@ type LabelList struct { Excludes []Label } +func (ll *LabelList) Equals(other LabelList) bool { + if len(ll.Includes) != len(other.Includes) || len(ll.Excludes) != len(other.Excludes) { + return false + } + for i, _ := range ll.Includes { + if ll.Includes[i] != other.Includes[i] { + return false + } + } + for i, _ := range ll.Excludes { + if ll.Excludes[i] != other.Excludes[i] { + return false + } + } + return true +} + func (ll *LabelList) IsNil() bool { return ll.Includes == nil && ll.Excludes == nil } @@ -446,7 +463,7 @@ func (ll labelListSelectValues) appendSelects(other labelListSelectValues) { // HasConfigurableValues returns whether there are configurable values within this set of selects. func (ll labelListSelectValues) HasConfigurableValues() bool { for _, v := range ll { - if len(v.Includes) > 0 { + if v.Includes != nil { return true } } @@ -462,6 +479,13 @@ type LabelListAttribute struct { // The configured attribute label list Values. Optional // a map of independent configurability axes ConfigurableValues configurableLabelLists + + // If true, differentiate between "nil" and "empty" list. nil means that + // this attribute should not be specified at all, and "empty" means that + // the attribute should be explicitly specified as an empty list. + // This mode facilitates use of attribute defaults: an empty list should + // override the default. + ForceSpecifyEmptyList bool } type configurableLabelLists map[ConfigurationAxis]labelListSelectValues @@ -546,6 +570,9 @@ func (lla *LabelListAttribute) SortedConfigurationAxes() []ConfigurationAxis { // Append all values, including os and arch specific ones, from another // LabelListAttribute to this LabelListAttribute. func (lla *LabelListAttribute) Append(other LabelListAttribute) { + if lla.ForceSpecifyEmptyList && !other.Value.IsNil() { + lla.Value.Includes = []Label{} + } lla.Value.Append(other.Value) if lla.ConfigurableValues == nil { lla.ConfigurableValues = make(configurableLabelLists) @@ -595,7 +622,7 @@ func (lla *LabelListAttribute) ResolveExcludes() { // Now that the Value list is finalized for this axis, compare it with the original // list, and put the difference into the default condition for the axis. - lla.ConfigurableValues[axis][conditionsDefault] = SubtractBazelLabelList(baseLabels, lla.Value) + lla.ConfigurableValues[axis][ConditionsDefaultConfigKey] = SubtractBazelLabelList(baseLabels, lla.Value) // if everything ends up without includes, just delete the axis if !lla.ConfigurableValues[axis].HasConfigurableValues() { diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 8dcba5500..bff192f53 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -1454,3 +1454,213 @@ cc_library { )`}, }) } + +func TestCcLibrary_SystemSharedLibsRootEmpty(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty at root", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "root_empty", + system_shared_libs: [], +} +`, + expectedBazelTargets: []string{`cc_library( + name = "root_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + system_dynamic_deps = [], +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsStaticEmpty(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty for static variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "static_empty", + static: { + system_shared_libs: [], + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "static_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + static = { + "system_dynamic_deps": [], + }, +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsSharedEmpty(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty for shared variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "shared_empty", + shared: { + system_shared_libs: [], + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "shared_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + shared = { + "system_dynamic_deps": [], + }, +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsSharedBionicEmpty(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty for shared, bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "shared_empty", + target: { + bionic: { + shared: { + system_shared_libs: [], + } + } + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "shared_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + shared = { + "system_dynamic_deps": [], + }, +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsLinuxBionicEmpty(t *testing.T) { + // Note that this behavior is technically incorrect (it's a simplification). + // The correct behavior would be if bp2build wrote `system_dynamic_deps = []` + // only for linux_bionic, but `android` had `["libc", "libdl", "libm"]. + // b/195791252 tracks the fix. + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty for linux_bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "target_linux_bionic_empty", + target: { + linux_bionic: { + system_shared_libs: [], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "target_linux_bionic_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + system_dynamic_deps = [], +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsBionicEmpty(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs empty for bionic variant", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "target_bionic_empty", + target: { + bionic: { + system_shared_libs: [], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "target_bionic_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + system_dynamic_deps = [], +)`}, + }) +} + +func TestCcLibrary_SystemSharedLibsSharedAndRoot(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library system_shared_libs set for shared and root", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + ` +cc_library {name: "libc"} +cc_library {name: "libm"} + +cc_library { + name: "foo", + system_shared_libs: ["libc"], + shared: { + system_shared_libs: ["libm"], + }, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "foo", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + shared = { + "system_dynamic_deps": [":libm"], + }, + system_dynamic_deps = [":libc"], +)`, `cc_library( + name = "libc", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], +)`, `cc_library( + name = "libm", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], +)`}, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 1dc6713de..d9145f668 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -73,6 +73,8 @@ func registerCcLibraryStaticModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) ctx.RegisterModuleType("genrule", genrule.GenRuleFactory) + // Required for system_shared_libs dependencies. + ctx.RegisterModuleType("cc_library", cc.LibraryFactory) } func runCcLibraryStaticTestCase(t *testing.T, tc bp2buildTestCase) { @@ -1427,3 +1429,185 @@ cc_library_static { )`}, }) } + +func TestStaticLibrary_SystemSharedLibsRootEmpty(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_lib empty root", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library_static { + name: "root_empty", + system_shared_libs: [], +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "root_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = [], +)`}, + }) +} + +func TestStaticLibrary_SystemSharedLibsStaticEmpty(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_lib empty static default", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_defaults { + name: "static_empty_defaults", + static: { + system_shared_libs: [], + }, +} +cc_library_static { + name: "static_empty", + defaults: ["static_empty_defaults"], +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "static_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = [], +)`}, + }) +} + +func TestStaticLibrary_SystemSharedLibsBionicEmpty(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_lib empty for bionic variant", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library_static { + name: "target_bionic_empty", + target: { + bionic: { + system_shared_libs: [], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "target_bionic_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = [], +)`}, + }) +} + +func TestStaticLibrary_SystemSharedLibsLinuxBionicEmpty(t *testing.T) { + // Note that this behavior is technically incorrect (it's a simplification). + // The correct behavior would be if bp2build wrote `system_dynamic_deps = []` + // only for linux_bionic, but `android` had `["libc", "libdl", "libm"]. + // b/195791252 tracks the fix. + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_lib empty for linux_bionic variant", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library_static { + name: "target_linux_bionic_empty", + target: { + linux_bionic: { + system_shared_libs: [], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "target_linux_bionic_empty", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = [], +)`}, + }) +} + +func TestStaticLibrary_SystemSharedLibsBionic(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_libs set for bionic variant", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library{name: "libc"} + +cc_library_static { + name: "target_bionic", + target: { + bionic: { + system_shared_libs: ["libc"], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "target_bionic", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = select({ + "//build/bazel/platforms/os:bionic": [":libc"], + "//conditions:default": [], + }), +)`}, + }) +} + +func TestStaticLibrary_SystemSharedLibsLinuxRootAndLinuxBionic(t *testing.T) { + runCcLibraryStaticTestCase(t, bp2buildTestCase{ + description: "cc_library_static system_shared_libs set for root and linux_bionic variant", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, + blueprint: soongCcLibraryStaticPreamble + ` +cc_library{name: "libc"} +cc_library{name: "libm"} + +cc_library_static { + name: "target_linux_bionic", + system_shared_libs: ["libc"], + target: { + linux_bionic: { + system_shared_libs: ["libm"], + }, + }, +} +`, + expectedBazelTargets: []string{`cc_library_static( + name = "target_linux_bionic", + copts = [ + "-I.", + "-I$(BINDIR)/.", + ], + linkstatic = True, + system_dynamic_deps = [":libc"] + select({ + "//build/bazel/platforms/os:linux_bionic": [":libm"], + "//conditions:default": [], + }), +)`}, + }) +} diff --git a/bp2build/configurability.go b/bp2build/configurability.go index c8105eb9b..005f13dd2 100644 --- a/bp2build/configurability.go +++ b/bp2build/configurability.go @@ -82,7 +82,12 @@ func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects continue } archSelects := map[string]reflect.Value{} + defaultVal := configToLabels[bazel.ConditionsDefaultConfigKey] for config, labels := range configToLabels { + // Omit any entries in the map which match the default value, for brevity. + if config != bazel.ConditionsDefaultConfigKey && labels.Equals(defaultVal) { + continue + } selectKey := axis.SelectKey(config) if use, value := labelListSelectValue(selectKey, labels); use { archSelects[selectKey] = value @@ -118,6 +123,8 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { var value reflect.Value var configurableAttrs []selects var defaultSelectValue *string + // If true, print the default attribute value, even if the attribute is zero. + shouldPrintDefault := false switch list := v.(type) { case bazel.StringListAttribute: value, configurableAttrs = getStringListValues(list) @@ -125,6 +132,9 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { case bazel.LabelListAttribute: value, configurableAttrs = getLabelListValues(list) defaultSelectValue = &emptyBazelList + if list.ForceSpecifyEmptyList && (!value.IsNil() || list.HasConfigurableValues()) { + shouldPrintDefault = true + } case bazel.LabelAttribute: value, configurableAttrs = getLabelValue(list) defaultSelectValue = &bazelNone @@ -166,6 +176,9 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { } } + if ret == "" && shouldPrintDefault { + return *defaultSelectValue, nil + } return ret, nil } diff --git a/cc/bp2build.go b/cc/bp2build.go index 68afd0db5..7a57477e3 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -35,6 +35,8 @@ type staticOrSharedAttributes struct { Static_deps bazel.LabelListAttribute Dynamic_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute + + System_dynamic_deps bazel.LabelListAttribute } func groupSrcsByExtension(ctx android.TopDownMutatorContext, srcs bazel.LabelListAttribute) (cppSrcs, cSrcs, asSrcs bazel.LabelListAttribute) { @@ -137,12 +139,19 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module props = lib.SharedProperties.Shared } + system_dynamic_deps := bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.System_shared_libs)) + system_dynamic_deps.ForceSpecifyEmptyList = true + if system_dynamic_deps.IsEmpty() && props.System_shared_libs != nil { + system_dynamic_deps.Value.Includes = []bazel.Label{} + } + attrs := staticOrSharedAttributes{ - Copts: bazel.StringListAttribute{Value: props.Cflags}, - Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)), - Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)), - Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, append(props.Shared_libs, props.System_shared_libs...))), - Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)), + Copts: bazel.StringListAttribute{Value: props.Cflags}, + Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)), + Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)), + Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)), + Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)), + System_dynamic_deps: system_dynamic_deps, } setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) { @@ -151,6 +160,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module attrs.Static_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Static_libs)) attrs.Dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.Shared_libs)) attrs.Whole_archive_deps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)) + attrs.System_dynamic_deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, props.System_shared_libs)) } if isStatic { @@ -377,6 +387,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul type linkerAttributes struct { deps bazel.LabelListAttribute dynamicDeps bazel.LabelListAttribute + systemDynamicDeps bazel.LabelListAttribute wholeArchiveDeps bazel.LabelListAttribute exportedDeps bazel.LabelListAttribute useLibcrt bazel.BoolAttribute @@ -406,6 +417,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) var exportedDeps bazel.LabelListAttribute var dynamicDeps bazel.LabelListAttribute var wholeArchiveDeps bazel.LabelListAttribute + var systemSharedDeps bazel.LabelListAttribute var linkopts bazel.StringListAttribute var versionScript bazel.LabelAttribute var useLibcrt bazel.BoolAttribute @@ -445,9 +457,16 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) - // TODO(b/186024507): Handle system_shared_libs as its own attribute, so that the appropriate default - // may be supported. - sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...)) + + systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs) + systemSharedDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, systemSharedLibs)) + systemSharedDeps.ForceSpecifyEmptyList = true + if systemSharedDeps.Value.IsNil() && baseLinkerProps.System_shared_libs != nil { + systemSharedDeps.Value.Includes = []bazel.Label{} + } + + sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) + dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) @@ -474,7 +493,14 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) - sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...)) + + systemSharedLibs := android.FirstUniqueStrings(baseLinkerProps.System_shared_libs) + if len(systemSharedLibs) == 0 && baseLinkerProps.System_shared_libs != nil { + systemSharedLibs = baseLinkerProps.System_shared_libs + } + systemSharedDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, systemSharedLibs)) + + sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) @@ -550,13 +576,14 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) headerDeps.Append(staticDeps) return linkerAttributes{ - deps: headerDeps, - exportedDeps: exportedDeps, - dynamicDeps: dynamicDeps, - wholeArchiveDeps: wholeArchiveDeps, - linkopts: linkopts, - useLibcrt: useLibcrt, - versionScript: versionScript, + deps: headerDeps, + exportedDeps: exportedDeps, + dynamicDeps: dynamicDeps, + systemDynamicDeps: systemSharedDeps, + wholeArchiveDeps: wholeArchiveDeps, + linkopts: linkopts, + useLibcrt: useLibcrt, + versionScript: versionScript, // Strip properties stripKeepSymbols: stripKeepSymbols, diff --git a/cc/library.go b/cc/library.go index 8f302fcb9..1478a1623 100644 --- a/cc/library.go +++ b/cc/library.go @@ -23,13 +23,12 @@ import ( "strings" "sync" - "github.com/google/blueprint" - "github.com/google/blueprint/pathtools" - "android/soong/android" "android/soong/bazel" "android/soong/bazel/cquery" "android/soong/cc/config" + "github.com/google/blueprint" + "github.com/google/blueprint/pathtools" ) // LibraryProperties is a collection of properties shared by cc library rules. @@ -233,6 +232,7 @@ type bazelCcLibraryAttributes struct { Implementation_deps bazel.LabelListAttribute Dynamic_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute + System_dynamic_deps bazel.LabelListAttribute Includes bazel.StringListAttribute Linkopts bazel.StringListAttribute Use_libcrt bazel.BoolAttribute @@ -319,6 +319,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Deps: linkerAttrs.exportedDeps, Dynamic_deps: linkerAttrs.dynamicDeps, Whole_archive_deps: linkerAttrs.wholeArchiveDeps, + System_dynamic_deps: linkerAttrs.systemDynamicDeps, Includes: exportedIncludes, Linkopts: linkerAttrs.linkopts, Use_libcrt: linkerAttrs.useLibcrt, @@ -2329,6 +2330,8 @@ type bazelCcLibraryStaticAttributes struct { Implementation_deps bazel.LabelListAttribute Deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute + Dynamic_deps bazel.LabelListAttribute + System_dynamic_deps bazel.LabelListAttribute Linkopts bazel.StringListAttribute Linkstatic bool Use_libcrt bazel.BoolAttribute @@ -2340,6 +2343,8 @@ type bazelCcLibraryStaticAttributes struct { Conlyflags bazel.StringListAttribute Srcs_as bazel.LabelListAttribute Asflags bazel.StringListAttribute + + Static staticOrSharedAttributes } type bazelCcLibraryStatic struct { @@ -2365,12 +2370,28 @@ func ccLibraryStaticBp2BuildInternal(ctx android.TopDownMutatorContext, module * asFlags = bazel.MakeStringListAttribute(nil) } + // Append static{} stanza properties. These won't be specified on + // cc_library_static itself, but may be specified in cc_defaults that this module + // depends on. + staticAttrs := bp2BuildParseStaticProps(ctx, module) + + compilerAttrs.srcs.Append(staticAttrs.Srcs) + compilerAttrs.cSrcs.Append(staticAttrs.Srcs_c) + compilerAttrs.asSrcs.Append(staticAttrs.Srcs_as) + compilerAttrs.copts.Append(staticAttrs.Copts) + linkerAttrs.exportedDeps.Append(staticAttrs.Static_deps) + linkerAttrs.dynamicDeps.Append(staticAttrs.Dynamic_deps) + linkerAttrs.wholeArchiveDeps.Append(staticAttrs.Whole_archive_deps) + linkerAttrs.systemDynamicDeps.Append(staticAttrs.System_dynamic_deps) + attrs := &bazelCcLibraryStaticAttributes{ Copts: compilerAttrs.copts, Srcs: compilerAttrs.srcs, Implementation_deps: linkerAttrs.deps, Deps: linkerAttrs.exportedDeps, Whole_archive_deps: linkerAttrs.wholeArchiveDeps, + Dynamic_deps: linkerAttrs.dynamicDeps, + System_dynamic_deps: linkerAttrs.systemDynamicDeps, Linkopts: linkerAttrs.linkopts, Linkstatic: true, diff --git a/cc/library_headers.go b/cc/library_headers.go index d6b45290e..e596ff7a8 100644 --- a/cc/library_headers.go +++ b/cc/library_headers.go @@ -108,6 +108,7 @@ type bazelCcLibraryHeadersAttributes struct { Includes bazel.StringListAttribute Deps bazel.LabelListAttribute Implementation_deps bazel.LabelListAttribute + System_dynamic_deps bazel.LabelListAttribute } type bazelCcLibraryHeaders struct { @@ -146,6 +147,7 @@ func CcLibraryHeadersBp2Build(ctx android.TopDownMutatorContext) { Includes: exportedIncludes, Implementation_deps: linkerAttrs.deps, Deps: linkerAttrs.exportedDeps, + System_dynamic_deps: linkerAttrs.systemDynamicDeps, } props := bazel.BazelTargetModuleProperties{