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

Commit 4cfa0dff authored by Inseob Kim's avatar Inseob Kim Committed by android-build-merger
Browse files

Merge "Include headers and props to VNDK snapshot"

am: 33769898

Change-Id: Ie21ee147be804d07d7089f9bc59ce658f6d3c21e
parents 72969547 33769898
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -848,6 +848,10 @@ func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
	return ExistentPathForSource(ctx, "frameworks", "base").Valid()
}

func (c *config) VndkSnapshotBuildArtifacts() bool {
	return Bool(c.productVariables.VndkSnapshotBuildArtifacts)
}

func (c *deviceConfig) Arches() []Arch {
	var arches []Arch
	for _, target := range c.config.Targets[Android] {
+2 −1
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ type productVariables struct {
	PgoAdditionalProfileDirs []string `json:",omitempty"`

	VndkUseCoreVariant         *bool `json:",omitempty"`
	VndkSnapshotBuildArtifacts *bool `json:",omitempty"`

	BoardVendorSepolicyDirs      []string `json:",omitempty"`
	BoardOdmSepolicyDirs         []string `json:",omitempty"`
+1 −0
Original line number Diff line number Diff line
@@ -508,6 +508,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
type libraryInterface interface {
	getWholeStaticMissingDeps() []string
	static() bool
	shared() bool
	objs() Objects
	reuseObjs() (Objects, exportedFlagsProducer)
	toc() android.OptionalPath
+187 −133
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
package cc

import (
	"encoding/json"
	"errors"
	"fmt"
	"path/filepath"
	"sort"
	"strings"
@@ -206,16 +206,9 @@ var (
	modulePathsKey                   = android.NewOnceKey("modulePaths")
	vndkSnapshotOutputsKey           = android.NewOnceKey("vndkSnapshotOutputs")
	vndkLibrariesLock                sync.Mutex
)

type vndkSnapshotOutputPaths struct {
	configs         android.Paths
	notices         android.Paths
	vndkCoreLibs    android.Paths
	vndkCoreLibs2nd android.Paths
	vndkSpLibs      android.Paths
	vndkSpLibs2nd   android.Paths
}
	headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
)

func vndkCoreLibraries(config android.Config) *[]string {
	return config.Once(vndkCoreLibrariesKey, func() interface{} {
@@ -253,10 +246,10 @@ func modulePaths(config android.Config) map[string]string {
	}).(map[string]string)
}

func vndkSnapshotOutputs(config android.Config) *vndkSnapshotOutputPaths {
func vndkSnapshotOutputs(config android.Config) *android.RuleBuilderInstalls {
	return config.Once(vndkSnapshotOutputsKey, func() interface{} {
		return &vndkSnapshotOutputPaths{}
	}).(*vndkSnapshotOutputPaths)
		return &android.RuleBuilderInstalls{}
	}).(*android.RuleBuilderInstalls)
}

func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
@@ -357,13 +350,7 @@ func init() {
	android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
	android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
		outputs := vndkSnapshotOutputs(ctx.Config())

		ctx.Strict("SOONG_VNDK_SNAPSHOT_CONFIGS", strings.Join(outputs.configs.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_NOTICES", strings.Join(outputs.notices.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS", strings.Join(outputs.vndkCoreLibs.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS", strings.Join(outputs.vndkSpLibs.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS_2ND", strings.Join(outputs.vndkCoreLibs2nd.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS_2ND", strings.Join(outputs.vndkSpLibs2nd.Strings(), " "))
		ctx.Strict("SOONG_VNDK_SNAPSHOT_FILES", outputs.String())
	})
}

@@ -373,26 +360,6 @@ func VndkSnapshotSingleton() android.Singleton {

type vndkSnapshotSingleton struct{}

func installVndkSnapshotLib(ctx android.SingletonContext, name string, module *Module, dir string) android.Path {
	if !module.outputFile.Valid() {
		panic(fmt.Errorf("module %s has no outputFile\n", name))
	}

	out := android.PathForOutput(ctx, dir, name+".so")

	ctx.Build(pctx, android.BuildParams{
		Rule:        android.Cp,
		Input:       module.outputFile.Path(),
		Output:      out,
		Description: "vndk snapshot " + dir + "/" + name + ".so",
		Args: map[string]string{
			"cpFlags": "-f -L",
		},
	})

	return out
}

func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	// BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
	if ctx.DeviceConfig().VndkVersion() != "current" {
@@ -411,30 +378,58 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex

	snapshotDir := "vndk-snapshot"

	var vndkLibPath, vndkLib2ndPath string
	vndkLibDir := make(map[android.ArchType]string)

	snapshotVariantPath := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
	snapshotVariantDir := ctx.DeviceConfig().DeviceArch()
	for _, target := range ctx.Config().Targets[android.Android] {
		dir := snapshotVariantDir
		if ctx.DeviceConfig().BinderBitness() == "32" {
		vndkLibPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf(
			"arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant()))
		vndkLib2ndPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf(
			"arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant()))
	} else {
		vndkLibPath = filepath.Join(snapshotVariantPath, fmt.Sprintf(
			"arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant()))
		vndkLib2ndPath = filepath.Join(snapshotVariantPath, fmt.Sprintf(
			"arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant()))
			dir = filepath.Join(dir, "binder32")
		}

	vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
	vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
	vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
	vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
	noticePath := filepath.Join(snapshotVariantPath, "NOTICE_FILES")
		arch := "arch-" + target.Arch.ArchType.String()
		if target.Arch.ArchVariant != "" {
			arch += "-" + target.Arch.ArchVariant
		}
		dir = filepath.Join(dir, arch)
		vndkLibDir[target.Arch.ArchType] = dir
	}
	configsDir := filepath.Join(snapshotVariantDir, "configs")
	noticeDir := filepath.Join(snapshotVariantDir, "NOTICE_FILES")
	includeDir := filepath.Join(snapshotVariantDir, "include")
	noticeBuilt := make(map[string]bool)

	installSnapshotFileFromPath := func(path android.Path, out string) {
		ctx.Build(pctx, android.BuildParams{
			Rule:        android.Cp,
			Input:       path,
			Output:      android.PathForOutput(ctx, snapshotDir, out),
			Description: "vndk snapshot " + out,
			Args: map[string]string{
				"cpFlags": "-f -L",
			},
		})
		*outputs = append(*outputs, android.RuleBuilderInstall{
			From: android.PathForOutput(ctx, snapshotDir, out),
			To:   out,
		})
	}
	installSnapshotFileFromContent := func(content, out string) {
		ctx.Build(pctx, android.BuildParams{
			Rule:        android.WriteFile,
			Output:      android.PathForOutput(ctx, snapshotDir, out),
			Description: "vndk snapshot " + out,
			Args: map[string]string{
				"content": content,
			},
		})
		*outputs = append(*outputs, android.RuleBuilderInstall{
			From: android.PathForOutput(ctx, snapshotDir, out),
			To:   out,
		})
	}

	tryBuildNotice := func(m *Module) {
		name := ctx.ModuleName(m)
		name := ctx.ModuleName(m) + ".so.txt"

		if _, ok := noticeBuilt[name]; ok {
			return
@@ -443,17 +438,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
		noticeBuilt[name] = true

		if m.NoticeFile().Valid() {
			out := android.PathForOutput(ctx, noticePath, name+".so.txt")
			ctx.Build(pctx, android.BuildParams{
				Rule:        android.Cp,
				Input:       m.NoticeFile().Path(),
				Output:      out,
				Description: "vndk snapshot notice " + name + ".so.txt",
				Args: map[string]string{
					"cpFlags": "-f -L",
				},
			})
			outputs.notices = append(outputs.notices, out)
			installSnapshotFileFromPath(m.NoticeFile().Path(), filepath.Join(noticeDir, name))
		}
	}

@@ -461,84 +446,160 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
	vndkSpLibraries := vndkSpLibraries(ctx.Config())
	vndkPrivateLibraries := vndkPrivateLibraries(ctx.Config())

	var generatedHeaders android.Paths
	includeDirs := make(map[string]bool)

	type vndkSnapshotLibraryInterface interface {
		exportedFlagsProducer
		libraryInterface
	}

	var _ vndkSnapshotLibraryInterface = (*prebuiltLibraryLinker)(nil)
	var _ vndkSnapshotLibraryInterface = (*libraryDecorator)(nil)

	installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, dir string) bool {
		name := ctx.ModuleName(m)
		libOut := filepath.Join(dir, name+".so")

		installSnapshotFileFromPath(m.outputFile.Path(), libOut)
		tryBuildNotice(m)

		if ctx.Config().VndkSnapshotBuildArtifacts() {
			prop := struct {
				ExportedDirs        []string `json:",omitempty"`
				ExportedSystemDirs  []string `json:",omitempty"`
				ExportedFlags       []string `json:",omitempty"`
				RelativeInstallPath string   `json:",omitempty"`
			}{}
			prop.ExportedFlags = l.exportedFlags()
			prop.ExportedDirs = l.exportedDirs()
			prop.ExportedSystemDirs = l.exportedSystemDirs()
			prop.RelativeInstallPath = m.RelativeInstallPath()

			propOut := libOut + ".json"

			j, err := json.Marshal(prop)
			if err != nil {
				ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
				return false
			}

			installSnapshotFileFromContent(string(j), propOut)
		}
		return true
	}

	isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, libDir string, isVndkSnapshotLib bool) {
		if m.Target().NativeBridge == android.NativeBridgeEnabled {
			return nil, "", false
		}
		if !m.useVndk() || !m.IsForPlatform() || !m.installable() {
			return nil, "", false
		}
		l, ok := m.linker.(vndkSnapshotLibraryInterface)
		if !ok || !l.shared() {
			return nil, "", false
		}
		name := ctx.ModuleName(m)
		if inList(name, *vndkCoreLibraries) {
			return l, filepath.Join("shared", "vndk-core"), true
		} else if inList(name, *vndkSpLibraries) {
			return l, filepath.Join("shared", "vndk-sp"), true
		} else {
			return nil, "", false
		}
	}

	ctx.VisitAllModules(func(module android.Module) {
		m, ok := module.(*Module)
		if !ok || !m.Enabled() || !m.useVndk() || !m.installable() {
		if !ok || !m.Enabled() {
			return
		}

		if m.Target().NativeBridge == android.NativeBridgeEnabled {
		baseDir, ok := vndkLibDir[m.Target().Arch.ArchType]
		if !ok {
			return
		}

		lib, is_lib := m.linker.(*libraryDecorator)
		prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker)
		l, libDir, ok := isVndkSnapshotLibrary(m)
		if !ok {
			return
		}

		if !(is_lib && lib.shared()) && !(is_prebuilt_lib && prebuilt_lib.shared()) {
		if !installVndkSnapshotLib(m, l, filepath.Join(baseDir, libDir)) {
			return
		}

		is_2nd := m.Target().Arch.ArchType != ctx.Config().DevicePrimaryArchType()
		generatedHeaders = append(generatedHeaders, l.exportedDeps()...)
		for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
			includeDirs[dir] = true
		}
	})

		name := ctx.ModuleName(module)
	if ctx.Config().VndkSnapshotBuildArtifacts() {
		headers := make(map[string]bool)

		if inList(name, *vndkCoreLibraries) {
			if is_2nd {
				out := installVndkSnapshotLib(ctx, name, m, vndkCoreLib2ndPath)
				outputs.vndkCoreLibs2nd = append(outputs.vndkCoreLibs2nd, out)
			} else {
				out := installVndkSnapshotLib(ctx, name, m, vndkCoreLibPath)
				outputs.vndkCoreLibs = append(outputs.vndkCoreLibs, out)
		for _, dir := range android.SortedStringKeys(includeDirs) {
			// workaround to determine if dir is under output directory
			if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
				continue
			}
			exts := headerExts
			// Glob all files under this special directory, because of C++ headers.
			if strings.HasPrefix(dir, "external/libcxx/include") {
				exts = []string{""}
			}
			for _, ext := range exts {
				glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
				if err != nil {
					ctx.Errorf("%#v\n", err)
					return
				}
				for _, header := range glob {
					if strings.HasSuffix(header, "/") {
						continue
					}
					headers[header] = true
				}
			tryBuildNotice(m)
		} else if inList(name, *vndkSpLibraries) {
			if is_2nd {
				out := installVndkSnapshotLib(ctx, name, m, vndkSpLib2ndPath)
				outputs.vndkSpLibs2nd = append(outputs.vndkSpLibs2nd, out)
			} else {
				out := installVndkSnapshotLib(ctx, name, m, vndkSpLibPath)
				outputs.vndkSpLibs = append(outputs.vndkSpLibs, out)
			}
			tryBuildNotice(m)
		}
	})

	configsPath := filepath.Join(snapshotVariantPath, "configs")
	vndkCoreTxt := android.PathForOutput(ctx, configsPath, "vndkcore.libraries.txt")
	vndkPrivateTxt := android.PathForOutput(ctx, configsPath, "vndkprivate.libraries.txt")
	modulePathTxt := android.PathForOutput(ctx, configsPath, "module_paths.txt")
		for _, header := range android.SortedStringKeys(headers) {
			installSnapshotFileFromPath(android.PathForSource(ctx, header),
				filepath.Join(includeDir, header))
		}

	ctx.Build(pctx, android.BuildParams{
		Rule:        android.WriteFile,
		Output:      vndkCoreTxt,
		Description: "vndk snapshot vndkcore.libraries.txt",
		Args: map[string]string{
			"content": android.JoinWithSuffix(*vndkCoreLibraries, ".so", "\\n"),
		},
	})
	outputs.configs = append(outputs.configs, vndkCoreTxt)
		isHeader := func(path string) bool {
			for _, ext := range headerExts {
				if strings.HasSuffix(path, ext) {
					return true
				}
			}
			return false
		}

	ctx.Build(pctx, android.BuildParams{
		Rule:        android.WriteFile,
		Output:      vndkPrivateTxt,
		Description: "vndk snapshot vndkprivate.libraries.txt",
		Args: map[string]string{
			"content": android.JoinWithSuffix(*vndkPrivateLibraries, ".so", "\\n"),
		},
	})
	outputs.configs = append(outputs.configs, vndkPrivateTxt)
		for _, path := range android.PathsToDirectorySortedPaths(android.FirstUniquePaths(generatedHeaders)) {
			header := path.String()

			if !isHeader(header) {
				continue
			}

			installSnapshotFileFromPath(path, filepath.Join(includeDir, header))
		}
	}

	installSnapshotFileFromContent(android.JoinWithSuffix(*vndkCoreLibraries, ".so", "\\n"),
		filepath.Join(configsDir, "vndkcore.libraries.txt"))
	installSnapshotFileFromContent(android.JoinWithSuffix(*vndkPrivateLibraries, ".so", "\\n"),
		filepath.Join(configsDir, "vndkprivate.libraries.txt"))

	var modulePathTxtBuilder strings.Builder

	modulePaths := modulePaths(ctx.Config())
	var libs []string
	for lib := range modulePaths {
		libs = append(libs, lib)
	}
	sort.Strings(libs)

	first := true
	for _, lib := range libs {
	for _, lib := range android.SortedStringKeys(modulePaths) {
		if first {
			first = false
		} else {
@@ -549,13 +610,6 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
		modulePathTxtBuilder.WriteString(modulePaths[lib])
	}

	ctx.Build(pctx, android.BuildParams{
		Rule:        android.WriteFile,
		Output:      modulePathTxt,
		Description: "vndk snapshot module_paths.txt",
		Args: map[string]string{
			"content": modulePathTxtBuilder.String(),
		},
	})
	outputs.configs = append(outputs.configs, modulePathTxt)
	installSnapshotFileFromContent(modulePathTxtBuilder.String(),
		filepath.Join(configsDir, "module_paths.txt"))
}
+10 −0
Original line number Diff line number Diff line
@@ -61,6 +61,13 @@ type vndkPrebuiltProperties struct {
	// Prebuilt files for each arch.
	Srcs []string `android:"arch_variant"`

	// list of directories relative to the Blueprints file that will be added to the include
	// path (using -isystem) for any module that links against this module.
	Export_system_include_dirs []string `android:"arch_variant"`

	// list of flags that will be used for any module that links against this module.
	Export_flags []string `android:"arch_variant"`

	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
	// etc).
	Check_elf_files *bool
@@ -123,6 +130,9 @@ func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) andro
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
	flags Flags, deps PathDeps, objs Objects) android.Path {
	if len(p.properties.Srcs) > 0 && p.shared() {
		p.libraryDecorator.exportIncludes(ctx)
		p.libraryDecorator.reexportSystemDirs(p.properties.Export_system_include_dirs...)
		p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
		// current VNDK prebuilts are only shared libs.
		return p.singleSourcePath(ctx)
	}