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

Commit 6c0a9f69 authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge "Remove global state from VNDK"

parents d7e51e08 7821224d
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -408,9 +408,22 @@ type VendorProperties struct {
	// IsLLNDK is set to true for the vendor variant of a cc_library module that has LLNDK stubs.
	IsLLNDK bool `blueprint:"mutated"`

	// IsLLNDKPrivate is set to true for the vendor variant of a cc_library module that has LLNDK
	// stubs and also sets llndk.private: true.
	IsLLNDKPrivate bool `blueprint:"mutated"`
	// IsVNDKUsingCoreVariant is true for VNDK modules if the global VndkUseCoreVariant option is
	// set and the module is not listed in VndkMustUseVendorVariantList.
	IsVNDKUsingCoreVariant bool `blueprint:"mutated"`

	// IsVNDKCore is set if a VNDK module does not set the vndk.support_system_process property.
	IsVNDKCore bool `blueprint:"mutated"`

	// IsVNDKSP is set if a VNDK module sets the vndk.support_system_process property.
	IsVNDKSP bool `blueprint:"mutated"`

	// IsVNDKPrivate is set if a VNDK module sets the vndk.private property or an LLNDK
	// module sets the llndk.private property.
	IsVNDKPrivate bool `blueprint:"mutated"`

	// IsVNDKProduct is set if a VNDK module sets the product_available property.
	IsVNDKProduct bool `blueprint:"mutated"`
}

// ModuleContextIntf is an interface (on a module context helper) consisting of functions related
@@ -1070,7 +1083,7 @@ func (c *Module) IsLlndk() bool {

// IsLlndkPublic returns true only for LLNDK (public) libs.
func (c *Module) IsLlndkPublic() bool {
	return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsLLNDKPrivate
	return c.VendorProperties.IsLLNDK && !c.VendorProperties.IsVNDKPrivate
}

// isImplementationForLLNDKPublic returns true for any variant of a cc_library that has LLNDK stubs
+29 −19
Original line number Diff line number Diff line
@@ -316,16 +316,8 @@ func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expe

func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) {
	t.Helper()
	vndkLibraries := ctx.ModuleForTests(module, "")

	var output string
	if module != "vndkcorevariant.libraries.txt" {
		output = insertVndkVersion(module, "VER")
	} else {
		output = module
	}

	checkWriteFileOutput(t, vndkLibraries.Output(output), expected)
	got := ctx.ModuleForTests(module, "").Module().(*vndkLibrariesTxt).fileNames
	assertArrayString(t, got, expected)
}

func TestVndk(t *testing.T) {
@@ -3171,7 +3163,25 @@ func TestMakeLinkType(t *testing.T) {
			name: "libllndkprivate.llndk",
			private: true,
			symbol_file: "",
		}`
		}

		llndk_libraries_txt {
			name: "llndk.libraries.txt",
		}
		vndkcore_libraries_txt {
			name: "vndkcore.libraries.txt",
		}
		vndksp_libraries_txt {
			name: "vndksp.libraries.txt",
		}
		vndkprivate_libraries_txt {
			name: "vndkprivate.libraries.txt",
		}
		vndkcorevariant_libraries_txt {
			name: "vndkcorevariant.libraries.txt",
			insert_vndk_version: false,
		}
	`

	config := TestConfig(buildDir, android.Android, nil, bp, nil)
	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
@@ -3179,14 +3189,14 @@ func TestMakeLinkType(t *testing.T) {
	// native:vndk
	ctx := testCcWithConfig(t, config)

	assertMapKeys(t, vndkCoreLibraries(config),
		[]string{"libvndk", "libvndkprivate"})
	assertMapKeys(t, vndkSpLibraries(config),
		[]string{"libc++", "libvndksp"})
	assertMapKeys(t, llndkLibraries(config),
		[]string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
	assertMapKeys(t, vndkPrivateLibraries(config),
		[]string{"libft2", "libllndkprivate", "libvndkprivate"})
	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt",
		[]string{"libvndk.so", "libvndkprivate.so"})
	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt",
		[]string{"libc++.so", "libvndksp.so"})
	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt",
		[]string{"libc.so", "libdl.so", "libft2.so", "libllndk.so", "libllndkprivate.so", "libm.so"})
	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt",
		[]string{"libft2.so", "libllndkprivate.so", "libvndkprivate.so"})

	vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"

+139 −140
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import (
	"path/filepath"
	"sort"
	"strings"
	"sync"

	"android/soong/android"
	"android/soong/cc/config"
@@ -231,52 +230,59 @@ func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error {
	return nil
}

type moduleListerFunc func(ctx android.SingletonContext) (moduleNames, fileNames []string)

var (
	vndkCoreLibrariesKey             = android.NewOnceKey("vndkCoreLibraries")
	vndkSpLibrariesKey               = android.NewOnceKey("vndkSpLibraries")
	llndkLibrariesKey                = android.NewOnceKey("llndkLibraries")
	vndkPrivateLibrariesKey          = android.NewOnceKey("vndkPrivateLibraries")
	vndkProductLibrariesKey          = android.NewOnceKey("vndkProductLibraries")
	vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibraries")
	vndkMustUseVendorVariantListKey  = android.NewOnceKey("vndkMustUseVendorVariantListKey")
	vndkLibrariesLock                sync.Mutex
	llndkLibraries                = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsLLNDK && !isVestigialLLNDKModule(m) })
	llndkLibrariesWithoutHWASAN   = vndkModuleListRemover(llndkLibraries, "libclang_rt.hwasan-")
	vndkSPLibraries               = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKSP })
	vndkCoreLibraries             = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKCore })
	vndkPrivateLibraries          = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKPrivate && !isVestigialLLNDKModule(m) })
	vndkProductLibraries          = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKProduct })
	vndkUsingCoreVariantLibraries = vndkModuleLister(func(m *Module) bool { return m.VendorProperties.IsVNDKUsingCoreVariant })
)

func vndkCoreLibraries(config android.Config) map[string]string {
	return config.Once(vndkCoreLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
// vndkModuleLister takes a predicate that operates on a Module and returns a moduleListerFunc
// that produces a list of module names and output file names for which the predicate returns true.
func vndkModuleLister(predicate func(*Module) bool) moduleListerFunc {
	return func(ctx android.SingletonContext) (moduleNames, fileNames []string) {
		ctx.VisitAllModules(func(m android.Module) {
			if c, ok := m.(*Module); ok && predicate(c) {
				filename, err := getVndkFileName(c)
				if err != nil {
					ctx.ModuleErrorf(m, "%s", err)
				}

func vndkSpLibraries(config android.Config) map[string]string {
	return config.Once(vndkSpLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
				moduleNames = append(moduleNames, ctx.ModuleName(m))
				fileNames = append(fileNames, filename)
			}

func llndkLibraries(config android.Config) map[string]string {
	return config.Once(llndkLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
		})
		moduleNames = android.SortedUniqueStrings(moduleNames)
		fileNames = android.SortedUniqueStrings(fileNames)
		return
	}

func vndkPrivateLibraries(config android.Config) map[string]string {
	return config.Once(vndkPrivateLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
}

func vndkProductLibraries(config android.Config) map[string]string {
	return config.Once(vndkProductLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
// vndkModuleListRemover takes a moduleListerFunc and a prefix and returns a moduleListerFunc
// that returns the same lists as the input moduleListerFunc, but with  modules with the
// given prefix removed.
func vndkModuleListRemover(lister moduleListerFunc, prefix string) moduleListerFunc {
	return func(ctx android.SingletonContext) (moduleNames, fileNames []string) {
		moduleNames, fileNames = lister(ctx)
		filter := func(in []string) []string {
			out := make([]string, 0, len(in))
			for _, lib := range in {
				if strings.HasPrefix(lib, prefix) {
					continue
				}

func vndkUsingCoreVariantLibraries(config android.Config) map[string]string {
	return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} {
		return make(map[string]string)
	}).(map[string]string)
				out = append(out, lib)
			}
			return out
		}
		return filter(moduleNames), filter(fileNames)
	}
}

var vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey")

func vndkMustUseVendorVariantList(cfg android.Config) []string {
	return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} {
@@ -294,17 +300,10 @@ func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendor

func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
	lib := m.linker.(*llndkStubDecorator)
	name := m.ImplementationModuleName(mctx)
	filename := name + ".so"

	vndkLibrariesLock.Lock()
	defer vndkLibrariesLock.Unlock()

	llndkLibraries(mctx.Config())[name] = filename
	m.VendorProperties.IsLLNDK = true
	if Bool(lib.Properties.Private) {
		vndkPrivateLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsLLNDKPrivate = true
		m.VendorProperties.IsVNDKPrivate = true
	}
}

@@ -316,10 +315,6 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
	}

	name := m.BaseModuleName()
	filename, err := getVndkFileName(m)
	if err != nil {
		panic(err)
	}

	if lib := m.library; lib != nil && lib.hasStubsVariants() && name != "libz" {
		// b/155456180 libz is the ONLY exception here. We don't want to make
@@ -331,26 +326,23 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
		mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK")
	}

	vndkLibrariesLock.Lock()
	defer vndkLibrariesLock.Unlock()

	if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
		m.Properties.MustUseVendorVariant = true
	}
	if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant {
		vndkUsingCoreVariantLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsVNDKUsingCoreVariant = true
	}

	if m.vndkdep.isVndkSp() {
		vndkSpLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsVNDKSP = true
	} else {
		vndkCoreLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsVNDKCore = true
	}
	if m.IsVndkPrivate() {
		vndkPrivateLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsVNDKPrivate = true
	}
	if Bool(m.VendorProperties.Product_available) {
		vndkProductLibraries(mctx.Config())[name] = filename
		m.VendorProperties.IsVNDKProduct = true
	}
}

@@ -424,7 +416,7 @@ func VndkMutator(mctx android.BottomUpMutatorContext) {
			flagExporter.Properties = llndkLib.(*llndkStubDecorator).flagExporter.Properties

			m.VendorProperties.IsLLNDK = llndk.VendorProperties.IsLLNDK
			m.VendorProperties.IsLLNDKPrivate = llndk.VendorProperties.IsLLNDKPrivate
			m.VendorProperties.IsVNDKPrivate = llndk.VendorProperties.IsVNDKPrivate
		}
	}

@@ -454,21 +446,29 @@ func init() {
}

func RegisterVndkLibraryTxtTypes(ctx android.RegistrationContext) {
	ctx.RegisterModuleType("llndk_libraries_txt", VndkLibrariesTxtFactory(libclangRTRemover(llndkLibraries)))
	ctx.RegisterModuleType("vndksp_libraries_txt", VndkLibrariesTxtFactory(vndkSpLibraries))
	ctx.RegisterModuleType("vndkcore_libraries_txt", VndkLibrariesTxtFactory(vndkCoreLibraries))
	ctx.RegisterModuleType("vndkprivate_libraries_txt", VndkLibrariesTxtFactory(vndkPrivateLibraries))
	ctx.RegisterModuleType("vndkproduct_libraries_txt", VndkLibrariesTxtFactory(vndkProductLibraries))
	ctx.RegisterModuleType("vndkcorevariant_libraries_txt", VndkLibrariesTxtFactory(vndkUsingCoreVariantLibraries))
	// Make uses LLNDK_LIBRARIES to determine which libraries to install.
	// HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
	// Therefore, by removing the library here, we cause it to only be installed if libc
	// depends on it.
	ctx.RegisterSingletonModuleType("llndk_libraries_txt", llndkLibrariesTxtFactory)
	ctx.RegisterSingletonModuleType("vndksp_libraries_txt", vndkSPLibrariesTxtFactory)
	ctx.RegisterSingletonModuleType("vndkcore_libraries_txt", vndkCoreLibrariesTxtFactory)
	ctx.RegisterSingletonModuleType("vndkprivate_libraries_txt", vndkPrivateLibrariesTxtFactory)
	ctx.RegisterSingletonModuleType("vndkproduct_libraries_txt", vndkProductLibrariesTxtFactory)
	ctx.RegisterSingletonModuleType("vndkcorevariant_libraries_txt", vndkUsingCoreVariantLibrariesTxtFactory)
}

type vndkLibrariesTxt struct {
	android.ModuleBase
	android.SingletonModuleBase

	lister      moduleListerFunc
	makeVarName string

	lister     func(android.Config) map[string]string
	properties VndkLibrariesTxtProperties

	outputFile  android.OutputPath
	moduleNames []string
	fileNames   []string
}

type VndkLibrariesTxtProperties struct {
@@ -478,26 +478,57 @@ type VndkLibrariesTxtProperties struct {
var _ etc.PrebuiltEtcModule = &vndkLibrariesTxt{}
var _ android.OutputFileProducer = &vndkLibrariesTxt{}

// vndk_libraries_txt is a special kind of module type in that it name is one of
// - llndk.libraries.txt
// - vndkcore.libraries.txt
// - vndksp.libraries.txt
// - vndkprivate.libraries.txt
// - vndkproduct.libraries.txt
// - vndkcorevariant.libraries.txt
// A module behaves like a prebuilt_etc but its content is generated by soong.
// By being a soong module, these files can be referenced by other soong modules.
// llndk_libraries_txt is a singleton module whose content is a list of LLNDK libraries
// generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func llndkLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(llndkLibrariesWithoutHWASAN, "LLNDK_LIBRARIES")
}

// vndksp_libraries_txt is a singleton module whose content is a list of VNDKSP libraries
// generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func vndkSPLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(vndkSPLibraries, "VNDK_SAMEPROCESS_LIBRARIES")
}

// vndkcore_libraries_txt is a singleton module whose content is a list of VNDK core libraries
// generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func vndkCoreLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(vndkCoreLibraries, "VNDK_CORE_LIBRARIES")
}

// vndkprivate_libraries_txt is a singleton module whose content is a list of VNDK private libraries
// generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func vndkPrivateLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(vndkPrivateLibraries, "VNDK_PRIVATE_LIBRARIES")
}

// vndkproduct_libraries_txt is a singleton module whose content is a list of VNDK product libraries
// generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func VndkLibrariesTxtFactory(lister func(android.Config) map[string]string) android.ModuleFactory {
	return func() android.Module {
func vndkProductLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(vndkProductLibraries, "VNDK_PRODUCT_LIBRARIES")
}

// vndkcorevariant_libraries_txt is a singleton module whose content is a list of VNDK libraries
// that are using the core variant, generated by Soong but can be referenced by other modules.
// For example, apex_vndk can depend on these files as prebuilt.
func vndkUsingCoreVariantLibrariesTxtFactory() android.SingletonModule {
	return newVndkLibrariesTxt(vndkUsingCoreVariantLibraries, "VNDK_USING_CORE_VARIANT_LIBRARIES")
}

func newVndkLibrariesTxt(lister moduleListerFunc, makeVarName string) android.SingletonModule {
	m := &vndkLibrariesTxt{
		lister:      lister,
		makeVarName: makeVarName,
	}
	m.AddProperties(&m.properties)
	android.InitAndroidModule(m)
	return m
}
}

func insertVndkVersion(filename string, vndkVersion string) string {
	if index := strings.LastIndex(filename, "."); index != -1 {
@@ -506,23 +537,7 @@ func insertVndkVersion(filename string, vndkVersion string) string {
	return filename
}

func libclangRTRemover(lister func(android.Config) map[string]string) func(android.Config) map[string]string {
	return func(config android.Config) map[string]string {
		libs := lister(config)
		filteredLibs := make(map[string]string, len(libs))
		for lib, v := range libs {
			if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
				continue
			}
			filteredLibs[lib] = v
		}
		return filteredLibs
	}
}

func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	list := android.SortedStringMapValues(txt.lister(ctx.Config()))

	var filename string
	if BoolDefault(txt.properties.Insert_vndk_version, true) {
		filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion())
@@ -531,12 +546,16 @@ func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleConte
	}

	txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
	android.WriteFileRule(ctx, txt.outputFile, strings.Join(list, "\n"))

	installPath := android.PathForModuleInstall(ctx, "etc")
	ctx.InstallFile(installPath, filename, txt.outputFile)
}

func (txt *vndkLibrariesTxt) GenerateSingletonBuildActions(ctx android.SingletonContext) {
	txt.moduleNames, txt.fileNames = txt.lister(ctx)
	android.WriteFileRule(ctx, txt.outputFile, strings.Join(txt.fileNames, "\n"))
}

func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
	return []android.AndroidMkEntries{android.AndroidMkEntries{
		Class:      "ETC",
@@ -549,6 +568,11 @@ func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries {
	}}
}

func (txt *vndkLibrariesTxt) MakeVars(ctx android.MakeVarsContext) {
	ctx.Strict(txt.makeVarName, strings.Join(txt.moduleNames, " "))

}

// PrebuiltEtcModule interface
func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath {
	return txt.outputFile
@@ -829,33 +853,27 @@ func getVndkFileName(m *Module) (string, error) {
	if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
		return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
	}
	if library, ok := m.linker.(*llndkStubDecorator); ok {
		return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
	}
	return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
}

func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) {
	llndk := android.SortedStringMapValues(llndkLibraries(ctx.Config()))
	vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config()))
	vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config()))
	vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config()))
	vndkproduct := android.SortedStringMapValues(vndkProductLibraries(ctx.Config()))

	// Build list of vndk libs as merged & tagged & filter-out(libclang_rt):
	// Since each target have different set of libclang_rt.* files,
	// keep the common set of files in vndk.libraries.txt
	_, llndk := vndkModuleListRemover(llndkLibraries, "libclang_rt.")(ctx)
	_, vndkcore := vndkModuleListRemover(vndkCoreLibraries, "libclang_rt.")(ctx)
	_, vndksp := vndkSPLibraries(ctx)
	_, vndkprivate := vndkPrivateLibraries(ctx)
	_, vndkproduct := vndkModuleListRemover(vndkProductLibraries, "libclang_rt.")(ctx)
	var merged []string
	filterOutLibClangRt := func(libList []string) (filtered []string) {
		for _, lib := range libList {
			if !strings.HasPrefix(lib, "libclang_rt.") {
				filtered = append(filtered, lib)
			}
		}
		return
	}
	merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...)
	merged = append(merged, addPrefix(llndk, "LLNDK: ")...)
	merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...)
	merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...)
	merged = append(merged, addPrefix(vndkcore, "VNDK-core: ")...)
	merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...)
	merged = append(merged, addPrefix(filterOutLibClangRt(vndkproduct), "VNDK-product: ")...)
	merged = append(merged, addPrefix(vndkproduct, "VNDK-product: ")...)
	c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt")
	android.WriteFileRule(ctx, c.vndkLibrariesFile, strings.Join(merged, "\n"))
}
@@ -877,25 +895,6 @@ func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
	ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES",
		strings.Join(android.SortedStringKeys(movedToApexLlndkLibraries), " "))

	// Make uses LLNDK_LIBRARIES to determine which libraries to install.
	// HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN.
	// Therefore, by removing the library here, we cause it to only be installed if libc
	// depends on it.
	installedLlndkLibraries := []string{}
	for lib := range llndkLibraries(ctx.Config()) {
		if strings.HasPrefix(lib, "libclang_rt.hwasan-") {
			continue
		}
		installedLlndkLibraries = append(installedLlndkLibraries, lib)
	}
	sort.Strings(installedLlndkLibraries)
	ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " "))

	ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " "))
	ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " "))
	ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " "))
	ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " "))

	ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String())
	ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String())
}