Loading cc/cc.go +69 −19 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ func init() { ctx.BottomUp("vndk", vndkMutator).Parallel() ctx.BottomUp("ndk_api", ndkApiMutator).Parallel() ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() }) Loading Loading @@ -945,6 +946,16 @@ func (c *Module) beginMutator(actx android.BottomUpMutatorContext) { c.begin(ctx) } // Split name#version into name and version func stubsLibNameAndVersion(name string) (string, string) { if sharp := strings.LastIndex(name, "#"); sharp != -1 && sharp != len(name)-1 { version := name[sharp+1:] libname := name[:sharp] return libname, version } return name, "" } func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { ctx := &depsContext{ BottomUpMutatorContext: actx, Loading Loading @@ -979,25 +990,28 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { variantLibs = []string{} nonvariantLibs = []string{} for _, entry := range list { if ctx.useSdk() && inList(entry, ndkPrebuiltSharedLibraries) { if !inList(entry, ndkMigratedLibs) { nonvariantLibs = append(nonvariantLibs, entry+".ndk."+version) // strip #version suffix out name, _ := stubsLibNameAndVersion(entry) if ctx.useSdk() && inList(name, ndkPrebuiltSharedLibraries) { if !inList(name, ndkMigratedLibs) { nonvariantLibs = append(nonvariantLibs, name+".ndk."+version) } else { variantLibs = append(variantLibs, entry+ndkLibrarySuffix) variantLibs = append(variantLibs, name+ndkLibrarySuffix) } } else if ctx.useVndk() && inList(entry, llndkLibraries) { nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(entry, vendorPublicLibraries) { vendorPublicLib := entry + vendorPublicLibrarySuffix } else if ctx.useVndk() && inList(name, llndkLibraries) { nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, vendorPublicLibraries) { vendorPublicLib := name + vendorPublicLibrarySuffix if actx.OtherModuleExists(vendorPublicLib) { nonvariantLibs = append(nonvariantLibs, vendorPublicLib) } else { // This can happen if vendor_public_library module is defined in a // namespace that isn't visible to the current module. In that case, // link to the original library. nonvariantLibs = append(nonvariantLibs, entry) nonvariantLibs = append(nonvariantLibs, name) } } else { // put name#version back nonvariantLibs = append(nonvariantLibs, entry) } } Loading @@ -1009,6 +1023,15 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders) } if c.linker != nil { if library, ok := c.linker.(*libraryDecorator); ok { if library.buildStubs() { // Stubs lib does not have dependency to other libraries. Don't proceed. return } } } for _, lib := range deps.HeaderLibs { depTag := headerDepTag if inList(lib, deps.ReexportHeaderLibHeaders) { Loading @@ -1035,19 +1058,40 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { {Mutator: "link", Variation: "static"}, }, lateStaticDepTag, deps.LateStaticLibs...) // shared lib names without the #version suffix var sharedLibNames []string for _, lib := range deps.SharedLibs { name, version := stubsLibNameAndVersion(lib) sharedLibNames = append(sharedLibNames, name) depTag := sharedDepTag if inList(lib, deps.ReexportSharedLibHeaders) { depTag = sharedExportDepTag } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, }, depTag, lib) var variations []blueprint.Variation variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) if version != "" && ctx.Os() == android.Android && !ctx.useVndk() && !c.inRecovery() { variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) } actx.AddVariationDependencies(variations, depTag, name) } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, }, lateSharedDepTag, deps.LateSharedLibs...) for _, lib := range deps.LateSharedLibs { name, version := stubsLibNameAndVersion(lib) if inList(name, sharedLibNames) { // This is to handle the case that some of the late shared libs (libc, libdl, libm, ...) // are added also to SharedLibs with version (e.g., libc#10). If not skipped, we will be // linking against both the stubs lib and the non-stubs lib at the same time. continue } depTag := lateSharedDepTag var variations []blueprint.Variation variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) if version != "" && ctx.Os() == android.Android && !ctx.useVndk() && !c.inRecovery() { variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) } actx.AddVariationDependencies(variations, depTag, name) } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, Loading Loading @@ -1629,8 +1673,8 @@ func imageMutator(mctx android.BottomUpMutatorContext) { return } if genrule, ok := mctx.Module().(*genrule.Module); ok { if props, ok := genrule.Extra.(*GenruleExtraProperties); ok { if g, ok := mctx.Module().(*genrule.Module); ok { if props, ok := g.Extra.(*GenruleExtraProperties); ok { var coreVariantNeeded bool = false var vendorVariantNeeded bool = false var recoveryVariantNeeded bool = false Loading @@ -1650,7 +1694,7 @@ func imageMutator(mctx android.BottomUpMutatorContext) { if recoveryVariantNeeded { primaryArch := mctx.Config().DevicePrimaryArchType() moduleArch := genrule.Target().Arch.ArchType moduleArch := g.Target().Arch.ArchType if moduleArch != primaryArch { recoveryVariantNeeded = false } Loading @@ -1666,7 +1710,13 @@ func imageMutator(mctx android.BottomUpMutatorContext) { if recoveryVariantNeeded { variants = append(variants, recoveryMode) } mctx.CreateVariations(variants...) mod := mctx.CreateVariations(variants...) for i, v := range variants { if v == recoveryMode { m := mod[i].(*genrule.Module) m.Extra.(*GenruleExtraProperties).InRecovery = true } } } } Loading cc/cc_test.go +61 −6 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. ctx.BottomUp("image", imageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() ctx.BottomUp("vndk", vndkMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() }) ctx.Register() Loading Loading @@ -211,6 +212,7 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. "a.proto": nil, "b.aidl": nil, "my_include": nil, "foo.map.txt": nil, }) return ctx Loading Loading @@ -1730,5 +1732,58 @@ func TestRecovery(t *testing.T) { if !recoveryModule.Platform() { t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product") } } func TestVersionedStubs(t *testing.T) { ctx := testCc(t, ` cc_library_shared { name: "libFoo", stubs: { symbol_file: "foo.map.txt", versions: ["1", "2", "3"], }, } cc_library_shared { name: "libBar", shared_libs: ["libFoo#1"], }`) variants := ctx.ModuleVariantsForTests("libFoo") expectedVariants := []string{ "android_arm64_armv8-a_core_shared", "android_arm64_armv8-a_core_shared_1", "android_arm64_armv8-a_core_shared_2", "android_arm64_armv8-a_core_shared_3", "android_arm_armv7-a-neon_core_shared", "android_arm_armv7-a-neon_core_shared_1", "android_arm_armv7-a-neon_core_shared_2", "android_arm_armv7-a-neon_core_shared_3", } variantsMismatch := false if len(variants) != len(expectedVariants) { variantsMismatch = true } else { for _, v := range expectedVariants { if !inList(v, variants) { variantsMismatch = false } } } if variantsMismatch { t.Errorf("variants of libFoo expected:\n") for _, v := range expectedVariants { t.Errorf("%q\n", v) } t.Errorf(", but got:\n") for _, v := range variants { t.Errorf("%q\n", v) } } libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld") libFlags := libBarLinkRule.Args["libFlags"] libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so" if !strings.Contains(libFlags, libFoo1StubPath) { t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags) } } cc/genrule.go +3 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,9 @@ func init() { type GenruleExtraProperties struct { Vendor_available *bool Recovery_available *bool // This genrule is for recovery variant InRecovery bool `blueprint:"mutated"` } // cc_genrule is a genrule that can depend on other cc_* objects. Loading cc/library.go +79 −3 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import ( "android/soong/android" "android/soong/cc/config" "android/soong/genrule" ) type LibraryProperties struct { Loading Loading @@ -65,6 +66,15 @@ type LibraryProperties struct { } Static_ndk_lib *bool Stubs struct { // Relative path to the symbol map. The symbol map provides the list of // symbols that are exported for stubs variant of this library. Symbol_file *string // List versions to generate stubs libs for. Versions []string } } type LibraryMutatedProperties struct { Loading @@ -78,6 +88,11 @@ type LibraryMutatedProperties struct { VariantIsShared bool `blueprint:"mutated"` // This variant is static VariantIsStatic bool `blueprint:"mutated"` // This variant is a stubs lib BuildStubs bool `blueprint:"mutated"` // Version of the stubs lib StubsVersion string `blueprint:"mutated"` } type FlagExporterProperties struct { Loading Loading @@ -240,6 +255,8 @@ type libraryDecorator struct { // Location of the linked, unstripped library for shared libraries unstrippedOutputFile android.Path versionScriptPath android.ModuleGenPath // Decorated interafaces *baseCompiler *baseLinker Loading Loading @@ -313,7 +330,11 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d flags.YasmFlags = append(flags.YasmFlags, f) } return library.baseCompiler.compilerFlags(ctx, flags, deps) flags = library.baseCompiler.compilerFlags(ctx, flags, deps) if library.buildStubs() { flags = addStubLibraryCompilerFlags(flags) } return flags } func extractExportIncludesFromFlags(flags []string) []string { Loading @@ -336,6 +357,12 @@ func extractExportIncludesFromFlags(flags []string) []string { } func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { if library.buildStubs() { objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "") library.versionScriptPath = versionScript return objs } if !library.buildShared() && !library.buildStatic() { if len(library.baseCompiler.Properties.Srcs) > 0 { ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") Loading Loading @@ -422,8 +449,10 @@ func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { location = InstallInSanitizerDir } library.baseInstaller.location = location library.baseLinker.linkerInit(ctx) // Let baseLinker know whether this variant is for stubs or not, so that // it can omit things that are not required for linking stubs. library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs() } func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { Loading Loading @@ -735,7 +764,8 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { if Bool(library.Properties.Static_ndk_lib) && library.static() && !ctx.useVndk() && !ctx.inRecovery() && ctx.Device() && library.baseLinker.sanitize.isUnsanitizedVariant() { library.baseLinker.sanitize.isUnsanitizedVariant() && !library.buildStubs() { installPath := getNdkSysrootBase(ctx).Join( ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) Loading Loading @@ -785,6 +815,14 @@ func (library *libraryDecorator) HeaderOnly() { library.MutatedProperties.BuildStatic = false } func (library *libraryDecorator) buildStubs() bool { return library.MutatedProperties.BuildStubs } func (library *libraryDecorator) stubsVersion() string { return library.MutatedProperties.StubsVersion } func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { module := newModule(hod, android.MultilibBoth) Loading Loading @@ -847,3 +885,41 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) { } } } // Version mutator splits a module into the mandatory non-stubs variant // (which is named "impl") and zero or more stubs variants. func versionMutator(mctx android.BottomUpMutatorContext) { if mctx.Os() != android.Android { return } if m, ok := mctx.Module().(*Module); ok && !m.inRecovery() && m.linker != nil { if library, ok := m.linker.(*libraryDecorator); ok && library.buildShared() { versions := []string{""} for _, v := range library.Properties.Stubs.Versions { versions = append(versions, v) } modules := mctx.CreateVariations(versions...) for i, m := range modules { l := m.(*Module).linker.(*libraryDecorator) if i == 0 { l.MutatedProperties.BuildStubs = false continue } // Mark that this variant is for stubs. l.MutatedProperties.BuildStubs = true l.MutatedProperties.StubsVersion = versions[i] m.(*Module).Properties.HideFromMake = true } } else { mctx.CreateVariations("") } return } if genrule, ok := mctx.Module().(*genrule.Module); ok { if props, ok := genrule.Extra.(*GenruleExtraProperties); ok && !props.InRecovery { mctx.CreateVariations("") return } } } cc/linker.go +32 −23 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ type baseLinker struct { MoreProperties MoreBaseLinkerProperties dynamicProperties struct { RunPaths []string `blueprint:"mutated"` BuildStubs bool `blueprint:"mutated"` } sanitize *sanitize Loading Loading @@ -269,9 +270,13 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") } // Version_script is not needed when linking stubs lib where the version // script is created from the symbol map file. if !linker.dynamicProperties.BuildStubs { android.ExtractSourceDeps(ctx, linker.MoreProperties.Version_script) android.ExtractSourceDeps(ctx, linker.MoreProperties.Target.Vendor.Version_script) } return deps } Loading Loading @@ -375,6 +380,9 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags.GroupStaticLibs = true } // Version_script is not needed when linking stubs lib where the version // script is created from the symbol map file. if !linker.dynamicProperties.BuildStubs { versionScript := ctx.ExpandOptionalSource( linker.MoreProperties.Version_script, "version_script") Loading @@ -400,6 +408,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } } } } return flags } Loading Loading
cc/cc.go +69 −19 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ func init() { ctx.BottomUp("vndk", vndkMutator).Parallel() ctx.BottomUp("ndk_api", ndkApiMutator).Parallel() ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() }) Loading Loading @@ -945,6 +946,16 @@ func (c *Module) beginMutator(actx android.BottomUpMutatorContext) { c.begin(ctx) } // Split name#version into name and version func stubsLibNameAndVersion(name string) (string, string) { if sharp := strings.LastIndex(name, "#"); sharp != -1 && sharp != len(name)-1 { version := name[sharp+1:] libname := name[:sharp] return libname, version } return name, "" } func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { ctx := &depsContext{ BottomUpMutatorContext: actx, Loading Loading @@ -979,25 +990,28 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { variantLibs = []string{} nonvariantLibs = []string{} for _, entry := range list { if ctx.useSdk() && inList(entry, ndkPrebuiltSharedLibraries) { if !inList(entry, ndkMigratedLibs) { nonvariantLibs = append(nonvariantLibs, entry+".ndk."+version) // strip #version suffix out name, _ := stubsLibNameAndVersion(entry) if ctx.useSdk() && inList(name, ndkPrebuiltSharedLibraries) { if !inList(name, ndkMigratedLibs) { nonvariantLibs = append(nonvariantLibs, name+".ndk."+version) } else { variantLibs = append(variantLibs, entry+ndkLibrarySuffix) variantLibs = append(variantLibs, name+ndkLibrarySuffix) } } else if ctx.useVndk() && inList(entry, llndkLibraries) { nonvariantLibs = append(nonvariantLibs, entry+llndkLibrarySuffix) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(entry, vendorPublicLibraries) { vendorPublicLib := entry + vendorPublicLibrarySuffix } else if ctx.useVndk() && inList(name, llndkLibraries) { nonvariantLibs = append(nonvariantLibs, name+llndkLibrarySuffix) } else if (ctx.Platform() || ctx.ProductSpecific()) && inList(name, vendorPublicLibraries) { vendorPublicLib := name + vendorPublicLibrarySuffix if actx.OtherModuleExists(vendorPublicLib) { nonvariantLibs = append(nonvariantLibs, vendorPublicLib) } else { // This can happen if vendor_public_library module is defined in a // namespace that isn't visible to the current module. In that case, // link to the original library. nonvariantLibs = append(nonvariantLibs, entry) nonvariantLibs = append(nonvariantLibs, name) } } else { // put name#version back nonvariantLibs = append(nonvariantLibs, entry) } } Loading @@ -1009,6 +1023,15 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { deps.ReexportSharedLibHeaders, _ = rewriteNdkLibs(deps.ReexportSharedLibHeaders) } if c.linker != nil { if library, ok := c.linker.(*libraryDecorator); ok { if library.buildStubs() { // Stubs lib does not have dependency to other libraries. Don't proceed. return } } } for _, lib := range deps.HeaderLibs { depTag := headerDepTag if inList(lib, deps.ReexportHeaderLibHeaders) { Loading @@ -1035,19 +1058,40 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { {Mutator: "link", Variation: "static"}, }, lateStaticDepTag, deps.LateStaticLibs...) // shared lib names without the #version suffix var sharedLibNames []string for _, lib := range deps.SharedLibs { name, version := stubsLibNameAndVersion(lib) sharedLibNames = append(sharedLibNames, name) depTag := sharedDepTag if inList(lib, deps.ReexportSharedLibHeaders) { depTag = sharedExportDepTag } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, }, depTag, lib) var variations []blueprint.Variation variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) if version != "" && ctx.Os() == android.Android && !ctx.useVndk() && !c.inRecovery() { variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) } actx.AddVariationDependencies(variations, depTag, name) } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, }, lateSharedDepTag, deps.LateSharedLibs...) for _, lib := range deps.LateSharedLibs { name, version := stubsLibNameAndVersion(lib) if inList(name, sharedLibNames) { // This is to handle the case that some of the late shared libs (libc, libdl, libm, ...) // are added also to SharedLibs with version (e.g., libc#10). If not skipped, we will be // linking against both the stubs lib and the non-stubs lib at the same time. continue } depTag := lateSharedDepTag var variations []blueprint.Variation variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"}) if version != "" && ctx.Os() == android.Android && !ctx.useVndk() && !c.inRecovery() { variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version}) } actx.AddVariationDependencies(variations, depTag, name) } actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "shared"}, Loading Loading @@ -1629,8 +1673,8 @@ func imageMutator(mctx android.BottomUpMutatorContext) { return } if genrule, ok := mctx.Module().(*genrule.Module); ok { if props, ok := genrule.Extra.(*GenruleExtraProperties); ok { if g, ok := mctx.Module().(*genrule.Module); ok { if props, ok := g.Extra.(*GenruleExtraProperties); ok { var coreVariantNeeded bool = false var vendorVariantNeeded bool = false var recoveryVariantNeeded bool = false Loading @@ -1650,7 +1694,7 @@ func imageMutator(mctx android.BottomUpMutatorContext) { if recoveryVariantNeeded { primaryArch := mctx.Config().DevicePrimaryArchType() moduleArch := genrule.Target().Arch.ArchType moduleArch := g.Target().Arch.ArchType if moduleArch != primaryArch { recoveryVariantNeeded = false } Loading @@ -1666,7 +1710,13 @@ func imageMutator(mctx android.BottomUpMutatorContext) { if recoveryVariantNeeded { variants = append(variants, recoveryMode) } mctx.CreateVariations(variants...) mod := mctx.CreateVariations(variants...) for i, v := range variants { if v == recoveryMode { m := mod[i].(*genrule.Module) m.Extra.(*GenruleExtraProperties).InRecovery = true } } } } Loading
cc/cc_test.go +61 −6 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. ctx.BottomUp("image", imageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() ctx.BottomUp("vndk", vndkMutator).Parallel() ctx.BottomUp("version", versionMutator).Parallel() ctx.BottomUp("begin", BeginMutator).Parallel() }) ctx.Register() Loading Loading @@ -211,6 +212,7 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android. "a.proto": nil, "b.aidl": nil, "my_include": nil, "foo.map.txt": nil, }) return ctx Loading Loading @@ -1730,5 +1732,58 @@ func TestRecovery(t *testing.T) { if !recoveryModule.Platform() { t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product") } } func TestVersionedStubs(t *testing.T) { ctx := testCc(t, ` cc_library_shared { name: "libFoo", stubs: { symbol_file: "foo.map.txt", versions: ["1", "2", "3"], }, } cc_library_shared { name: "libBar", shared_libs: ["libFoo#1"], }`) variants := ctx.ModuleVariantsForTests("libFoo") expectedVariants := []string{ "android_arm64_armv8-a_core_shared", "android_arm64_armv8-a_core_shared_1", "android_arm64_armv8-a_core_shared_2", "android_arm64_armv8-a_core_shared_3", "android_arm_armv7-a-neon_core_shared", "android_arm_armv7-a-neon_core_shared_1", "android_arm_armv7-a-neon_core_shared_2", "android_arm_armv7-a-neon_core_shared_3", } variantsMismatch := false if len(variants) != len(expectedVariants) { variantsMismatch = true } else { for _, v := range expectedVariants { if !inList(v, variants) { variantsMismatch = false } } } if variantsMismatch { t.Errorf("variants of libFoo expected:\n") for _, v := range expectedVariants { t.Errorf("%q\n", v) } t.Errorf(", but got:\n") for _, v := range variants { t.Errorf("%q\n", v) } } libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_core_shared").Rule("ld") libFlags := libBarLinkRule.Args["libFlags"] libFoo1StubPath := "libFoo/android_arm64_armv8-a_core_shared_1/libFoo.so" if !strings.Contains(libFlags, libFoo1StubPath) { t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags) } }
cc/genrule.go +3 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,9 @@ func init() { type GenruleExtraProperties struct { Vendor_available *bool Recovery_available *bool // This genrule is for recovery variant InRecovery bool `blueprint:"mutated"` } // cc_genrule is a genrule that can depend on other cc_* objects. Loading
cc/library.go +79 −3 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import ( "android/soong/android" "android/soong/cc/config" "android/soong/genrule" ) type LibraryProperties struct { Loading Loading @@ -65,6 +66,15 @@ type LibraryProperties struct { } Static_ndk_lib *bool Stubs struct { // Relative path to the symbol map. The symbol map provides the list of // symbols that are exported for stubs variant of this library. Symbol_file *string // List versions to generate stubs libs for. Versions []string } } type LibraryMutatedProperties struct { Loading @@ -78,6 +88,11 @@ type LibraryMutatedProperties struct { VariantIsShared bool `blueprint:"mutated"` // This variant is static VariantIsStatic bool `blueprint:"mutated"` // This variant is a stubs lib BuildStubs bool `blueprint:"mutated"` // Version of the stubs lib StubsVersion string `blueprint:"mutated"` } type FlagExporterProperties struct { Loading Loading @@ -240,6 +255,8 @@ type libraryDecorator struct { // Location of the linked, unstripped library for shared libraries unstrippedOutputFile android.Path versionScriptPath android.ModuleGenPath // Decorated interafaces *baseCompiler *baseLinker Loading Loading @@ -313,7 +330,11 @@ func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags, d flags.YasmFlags = append(flags.YasmFlags, f) } return library.baseCompiler.compilerFlags(ctx, flags, deps) flags = library.baseCompiler.compilerFlags(ctx, flags, deps) if library.buildStubs() { flags = addStubLibraryCompilerFlags(flags) } return flags } func extractExportIncludesFromFlags(flags []string) []string { Loading @@ -336,6 +357,12 @@ func extractExportIncludesFromFlags(flags []string) []string { } func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects { if library.buildStubs() { objs, versionScript := compileStubLibrary(ctx, flags, String(library.Properties.Stubs.Symbol_file), library.MutatedProperties.StubsVersion, "") library.versionScriptPath = versionScript return objs } if !library.buildShared() && !library.buildStatic() { if len(library.baseCompiler.Properties.Srcs) > 0 { ctx.PropertyErrorf("srcs", "cc_library_headers must not have any srcs") Loading Loading @@ -422,8 +449,10 @@ func (library *libraryDecorator) linkerInit(ctx BaseModuleContext) { location = InstallInSanitizerDir } library.baseInstaller.location = location library.baseLinker.linkerInit(ctx) // Let baseLinker know whether this variant is for stubs or not, so that // it can omit things that are not required for linking stubs. library.baseLinker.dynamicProperties.BuildStubs = library.buildStubs() } func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { Loading Loading @@ -735,7 +764,8 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { if Bool(library.Properties.Static_ndk_lib) && library.static() && !ctx.useVndk() && !ctx.inRecovery() && ctx.Device() && library.baseLinker.sanitize.isUnsanitizedVariant() { library.baseLinker.sanitize.isUnsanitizedVariant() && !library.buildStubs() { installPath := getNdkSysrootBase(ctx).Join( ctx, "usr/lib", config.NDKTriple(ctx.toolchain()), file.Base()) Loading Loading @@ -785,6 +815,14 @@ func (library *libraryDecorator) HeaderOnly() { library.MutatedProperties.BuildStatic = false } func (library *libraryDecorator) buildStubs() bool { return library.MutatedProperties.BuildStubs } func (library *libraryDecorator) stubsVersion() string { return library.MutatedProperties.StubsVersion } func NewLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { module := newModule(hod, android.MultilibBoth) Loading Loading @@ -847,3 +885,41 @@ func LinkageMutator(mctx android.BottomUpMutatorContext) { } } } // Version mutator splits a module into the mandatory non-stubs variant // (which is named "impl") and zero or more stubs variants. func versionMutator(mctx android.BottomUpMutatorContext) { if mctx.Os() != android.Android { return } if m, ok := mctx.Module().(*Module); ok && !m.inRecovery() && m.linker != nil { if library, ok := m.linker.(*libraryDecorator); ok && library.buildShared() { versions := []string{""} for _, v := range library.Properties.Stubs.Versions { versions = append(versions, v) } modules := mctx.CreateVariations(versions...) for i, m := range modules { l := m.(*Module).linker.(*libraryDecorator) if i == 0 { l.MutatedProperties.BuildStubs = false continue } // Mark that this variant is for stubs. l.MutatedProperties.BuildStubs = true l.MutatedProperties.StubsVersion = versions[i] m.(*Module).Properties.HideFromMake = true } } else { mctx.CreateVariations("") } return } if genrule, ok := mctx.Module().(*genrule.Module); ok { if props, ok := genrule.Extra.(*GenruleExtraProperties); ok && !props.InRecovery { mctx.CreateVariations("") return } } }
cc/linker.go +32 −23 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ type baseLinker struct { MoreProperties MoreBaseLinkerProperties dynamicProperties struct { RunPaths []string `blueprint:"mutated"` BuildStubs bool `blueprint:"mutated"` } sanitize *sanitize Loading Loading @@ -269,9 +270,13 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") } // Version_script is not needed when linking stubs lib where the version // script is created from the symbol map file. if !linker.dynamicProperties.BuildStubs { android.ExtractSourceDeps(ctx, linker.MoreProperties.Version_script) android.ExtractSourceDeps(ctx, linker.MoreProperties.Target.Vendor.Version_script) } return deps } Loading Loading @@ -375,6 +380,9 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags.GroupStaticLibs = true } // Version_script is not needed when linking stubs lib where the version // script is created from the symbol map file. if !linker.dynamicProperties.BuildStubs { versionScript := ctx.ExpandOptionalSource( linker.MoreProperties.Version_script, "version_script") Loading @@ -400,6 +408,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } } } } return flags } Loading