diff --git a/cc/cc.go b/cc/cc.go index 15cb39a77..0aa101458 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -571,7 +571,8 @@ type specifiedDeps struct { sharedLibs []string // Note nil and [] are semantically distinct. [] prevents linking against the defaults (usually // libc, libm, etc.) - systemSharedLibs []string + systemSharedLibs []string + defaultSharedLibs []string } // installer is the interface for an installer helper object. This helper is responsible for diff --git a/cc/library.go b/cc/library.go index 684694b4e..4fd7c7475 100644 --- a/cc/library.go +++ b/cc/library.go @@ -147,11 +147,12 @@ type StaticOrSharedProperties struct { Cflags []string `android:"arch_variant"` - Enabled *bool `android:"arch_variant"` - Whole_static_libs []string `android:"arch_variant"` - Static_libs []string `android:"arch_variant"` - Shared_libs []string `android:"arch_variant"` - System_shared_libs []string `android:"arch_variant"` + Enabled *bool `android:"arch_variant"` + Whole_static_libs []string `android:"arch_variant"` + Static_libs []string `android:"arch_variant"` + Shared_libs []string `android:"arch_variant"` + System_shared_libs []string `android:"arch_variant"` + Default_shared_libs []string `android:"arch_variant"` Export_shared_lib_headers []string `android:"arch_variant"` Export_static_lib_headers []string `android:"arch_variant"` @@ -1156,11 +1157,17 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { if library.StaticProperties.Static.System_shared_libs != nil { library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs } + if library.StaticProperties.Static.Default_shared_libs != nil { + library.baseLinker.Properties.Default_shared_libs = library.StaticProperties.Static.Default_shared_libs + } } else if library.shared() { // Compare with nil because an empty list needs to be propagated. if library.SharedProperties.Shared.System_shared_libs != nil { library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs } + if library.SharedProperties.Shared.Default_shared_libs != nil { + library.baseLinker.Properties.Default_shared_libs = library.SharedProperties.Shared.Default_shared_libs + } } deps = library.baseLinker.linkerDeps(ctx, deps) @@ -1242,6 +1249,11 @@ func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps } else { specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...) } + if specifiedDeps.defaultSharedLibs == nil { + specifiedDeps.defaultSharedLibs = properties.Default_shared_libs + } else { + specifiedDeps.defaultSharedLibs = append(specifiedDeps.defaultSharedLibs, properties.Default_shared_libs...) + } specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) if len(specifiedDeps.systemSharedLibs) > 0 { @@ -1249,6 +1261,11 @@ func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps // retained. specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) } + if len(specifiedDeps.defaultSharedLibs) > 0 { + // Skip this if defaultSharedLibs is either nil or [], to ensure they are + // retained. + specifiedDeps.defaultSharedLibs = android.FirstUniqueStrings(specifiedDeps.defaultSharedLibs) + } return specifiedDeps } diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 9010a1a89..9ad2742f4 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -258,6 +258,12 @@ func addPossiblyArchSpecificProperties(sdkModuleContext android.ModuleContext, b outputProperties.AddPropertyWithTag("system_shared_libs", libInfo.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) } + // SystemSharedLibs needs to be propagated if it's a list, even if it's empty, + // so check for non-nil instead of nonzero length. + if libInfo.DefaultSharedLibs != nil { + outputProperties.AddPropertyWithTag("default_shared_libs", libInfo.DefaultSharedLibs, builder.SdkMemberReferencePropertyTag(false)) + } + // Map from property name to the include dirs to add to the prebuilt module in the snapshot. includeDirs := make(map[string][]string) @@ -387,6 +393,12 @@ type nativeLibInfoProperties struct { // This field is exported as its contents may not be arch specific. SystemSharedLibs []string `android:"arch_variant"` + // The set of default shared libraries. Note nil and [] are semantically + // distinct - see BaseLinkerProperties.Default_shared_libs. + // + // This field is exported as its contents may not be arch specific. + DefaultSharedLibs []string `android:"arch_variant"` + // The specific stubs version for the lib variant, or empty string if stubs // are not in use. // @@ -462,6 +474,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte } } p.SystemSharedLibs = specifiedDeps.systemSharedLibs + p.DefaultSharedLibs = specifiedDeps.defaultSharedLibs } p.ExportedGeneratedHeaders = exportedInfo.GeneratedHeaders diff --git a/cc/linker.go b/cc/linker.go index 7b16b4097..13df23296 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -45,11 +45,18 @@ type BaseLinkerProperties struct { // list of module-specific flags that will be used for all link steps Ldflags []string `android:"arch_variant"` - // list of system libraries that will be dynamically linked to - // shared library and executable modules. If unset, generally defaults to libc, - // libm, and libdl. Set to [] to prevent linking against the defaults. + // list of system libraries that will be dynamically linked to shared library and executable + // modules that build against bionic (device or Linux bionic modules). If unset, generally + // defaults to libc, libm, and libdl. Set to [] to prevent linking against the defaults. + // Equivalent to default_shared_libs for modules that build against bionic, and ignored on + // modules that do not build against bionic. System_shared_libs []string `android:"arch_variant"` + // list of system libraries that will be dynamically linked to shared library and executable + // modules. If unset, generally defaults to libc, libm, and libdl. Set to [] to prevent + // linking against the defaults. Equivalent to system_shared_libs, but applies to all modules. + Default_shared_libs []string `android:"arch_variant"` + // allow the module to contain undefined symbols. By default, // modules cannot contain undefined symbols that are not satisified by their immediate // dependencies. Set this flag to true to remove --no-undefined from the linker flags. @@ -231,6 +238,19 @@ func (linker *baseLinker) appendLdflags(flags []string) { linker.Properties.Ldflags = append(linker.Properties.Ldflags, flags...) } +// overrideDefaultSharedLibraries returns the contents of the default_shared_libs or +// system_shared_libs properties, and records an error if both are set. +func (linker *baseLinker) overrideDefaultSharedLibraries(ctx BaseModuleContext) []string { + if linker.Properties.System_shared_libs != nil && linker.Properties.Default_shared_libs != nil { + ctx.PropertyErrorf("system_shared_libs", "cannot be specified if default_shared_libs is also specified") + } + if ctx.toolchain().Bionic() && linker.Properties.System_shared_libs != nil { + // system_shared_libs is only honored when building against bionic. + return linker.Properties.System_shared_libs + } + return linker.Properties.Default_shared_libs +} + // linkerInit initializes dynamic properties of the linker (such as runpath). func (linker *baseLinker) linkerInit(ctx BaseModuleContext) { if ctx.toolchain().Is64Bit() { @@ -331,22 +351,22 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Platform.Shared_libs...) } + deps.SystemSharedLibs = linker.overrideDefaultSharedLibraries(ctx) + // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may + // inaccuarately appear unset, which can cause issues with circular dependencies. + if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() { + // Provide a default set of shared libraries if default_shared_libs and system_shared_libs + // are unspecified. Note: If an empty list [] is specified, it implies that the module + // declines the default shared libraries. + deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...) + } + if ctx.toolchain().Bionic() { // libclang_rt.builtins has to be last on the command line if !Bool(linker.Properties.No_libcrt) && !ctx.header() { deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain())) } - deps.SystemSharedLibs = linker.Properties.System_shared_libs - // In Bazel conversion mode, variations have not been specified, so SystemSharedLibs may - // inaccuarately appear unset, which can cause issues with circular dependencies. - if deps.SystemSharedLibs == nil && !ctx.BazelConversionMode() { - // Provide a default system_shared_libs if it is unspecified. Note: If an - // empty list [] is specified, it implies that the module declines the - // default system_shared_libs. - deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...) - } - if inList("libdl", deps.SharedLibs) { // If system_shared_libs has libc but not libdl, make sure shared_libs does not // have libdl to avoid loading libdl before libc. @@ -573,6 +593,11 @@ func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) speci } else { specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...) } + if specifiedDeps.defaultSharedLibs == nil { + specifiedDeps.defaultSharedLibs = linker.Properties.Default_shared_libs + } else { + specifiedDeps.defaultSharedLibs = append(specifiedDeps.defaultSharedLibs, linker.Properties.Default_shared_libs...) + } return specifiedDeps } diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index 31555c02e..98697dcf4 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -2189,7 +2189,7 @@ func TestSystemSharedLibPropagation(t *testing.T) { result := testSdkWithCc(t, ` sdk { name: "mysdk", - native_shared_libs: ["sslnil", "sslempty", "sslnonempty"], + native_shared_libs: ["sslnil", "sslempty", "sslnonempty", "dslnil", "dslempty", "dslnonempty"], } cc_library { @@ -2206,6 +2206,21 @@ func TestSystemSharedLibPropagation(t *testing.T) { name: "sslnonempty", system_shared_libs: ["sslnil"], } + + cc_library { + name: "dslnil", + host_supported: true, + } + + cc_library { + name: "dslempty", + default_shared_libs: [], + } + + cc_library { + name: "dslnonempty", + default_shared_libs: ["sslnil"], + } `) CheckSnapshot(t, result, "mysdk", "", @@ -2261,13 +2276,62 @@ cc_prebuilt_library_shared { }, }, } -`)) + +cc_prebuilt_library_shared { + name: "dslnil", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + compile_multilib: "both", + arch: { + arm64: { + srcs: ["arm64/lib/dslnil.so"], + }, + arm: { + srcs: ["arm/lib/dslnil.so"], + }, + }, +} + +cc_prebuilt_library_shared { + name: "dslempty", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + compile_multilib: "both", + default_shared_libs: [], + arch: { + arm64: { + srcs: ["arm64/lib/dslempty.so"], + }, + arm: { + srcs: ["arm/lib/dslempty.so"], + }, + }, +} + +cc_prebuilt_library_shared { + name: "dslnonempty", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + compile_multilib: "both", + default_shared_libs: ["sslnil"], + arch: { + arm64: { + srcs: ["arm64/lib/dslnonempty.so"], + }, + arm: { + srcs: ["arm/lib/dslnonempty.so"], + }, + }, +}`)) result = testSdkWithCc(t, ` sdk { name: "mysdk", host_supported: true, - native_shared_libs: ["sslvariants"], + native_shared_libs: ["sslvariants", "dslvariants"], } cc_library { @@ -2279,6 +2343,16 @@ cc_prebuilt_library_shared { }, }, } + + cc_library { + name: "dslvariants", + host_supported: true, + target: { + android: { + default_shared_libs: [], + }, + }, + } `) CheckSnapshot(t, result, "mysdk", "", @@ -2315,6 +2389,37 @@ cc_prebuilt_library_shared { }, }, } + +cc_prebuilt_library_shared { + name: "dslvariants", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + host_supported: true, + compile_multilib: "both", + target: { + host: { + enabled: false, + }, + android: { + default_shared_libs: [], + }, + android_arm64: { + srcs: ["android/arm64/lib/dslvariants.so"], + }, + android_arm: { + srcs: ["android/arm/lib/dslvariants.so"], + }, + linux_glibc_x86_64: { + enabled: true, + srcs: ["linux_glibc/x86_64/lib/dslvariants.so"], + }, + linux_glibc_x86: { + enabled: true, + srcs: ["linux_glibc/x86/lib/dslvariants.so"], + }, + }, +} `), checkVersionedAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -2351,11 +2456,46 @@ cc_prebuilt_library_shared { }, } +cc_prebuilt_library_shared { + name: "mysdk_dslvariants@current", + sdk_member_name: "dslvariants", + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + host_supported: true, + installable: false, + compile_multilib: "both", + target: { + host: { + enabled: false, + }, + android: { + default_shared_libs: [], + }, + android_arm64: { + srcs: ["android/arm64/lib/dslvariants.so"], + }, + android_arm: { + srcs: ["android/arm/lib/dslvariants.so"], + }, + linux_glibc_x86_64: { + enabled: true, + srcs: ["linux_glibc/x86_64/lib/dslvariants.so"], + }, + linux_glibc_x86: { + enabled: true, + srcs: ["linux_glibc/x86/lib/dslvariants.so"], + }, + }, +} + sdk_snapshot { name: "mysdk@current", visibility: ["//visibility:public"], host_supported: true, - native_shared_libs: ["mysdk_sslvariants@current"], + native_shared_libs: [ + "mysdk_sslvariants@current", + "mysdk_dslvariants@current", + ], target: { host: { enabled: false,