Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ef8557c authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add support for versioned stubs."

parents d471374f 7ed9de3b
Loading
Loading
Loading
Loading
+69 −19
Original line number Diff line number Diff line
@@ -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()
	})

@@ -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,
@@ -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)
				}
			}
@@ -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) {
@@ -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"},
@@ -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
@@ -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
				}
@@ -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
				}
			}
		}
	}

+61 −6
Original line number Diff line number Diff line
@@ -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()
@@ -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
@@ -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)
	}
}
+3 −0
Original line number Diff line number Diff line
@@ -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.
+79 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import (

	"android/soong/android"
	"android/soong/cc/config"
	"android/soong/genrule"
)

type LibraryProperties struct {
@@ -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 {
@@ -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 {
@@ -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
@@ -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 {
@@ -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")
@@ -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 {
@@ -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())

@@ -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)

@@ -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
		}
	}
}
+32 −23
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ type baseLinker struct {
	MoreProperties    MoreBaseLinkerProperties
	dynamicProperties struct {
		RunPaths   []string `blueprint:"mutated"`
		BuildStubs bool     `blueprint:"mutated"`
	}

	sanitize *sanitize
@@ -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
}
@@ -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")

@@ -400,6 +408,7 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
				}
			}
		}
	}

	return flags
}