Snap for 12361654 from e021e615fa to 24Q4-release

Change-Id: I7083a22c54bad320f5dfb85aa3af19bfeb194225
This commit is contained in:
Android Build Coastguard Worker
2024-09-12 23:00:32 +00:00
61 changed files with 1056 additions and 1818 deletions

View File

@@ -187,6 +187,20 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries
}
}
func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) {
info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey)
if !ok || len(info.AconfigFiles) == 0 {
return
}
// All of the files in the module potentially depend on the aconfig flag values.
infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
if len(infos.ExtraInfo) > 0 {
for _, ei := range (*infos).ExtraInfo {
ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
}
}
}
func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths {
inputs = SortedUniquePaths(inputs)
if len(inputs) == 1 {

View File

@@ -34,7 +34,6 @@ import (
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
)
@@ -502,6 +501,7 @@ type fillInEntriesContext interface {
otherModuleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
ModuleType(module blueprint.Module) string
OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
HasMutatorFinished(mutatorName string) bool
}
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
@@ -806,15 +806,19 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs
// Additional cases here require review for correct license propagation to make.
var err error
switch x := mod.(type) {
case AndroidMkDataProvider:
err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
case bootstrap.GoBinaryTool:
err = translateGoBinaryModule(ctx, w, mod, x)
case AndroidMkEntriesProvider:
err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
default:
// Not exported to make so no make variables to set.
if info, ok := ctx.otherModuleProvider(mod, AndroidMkInfoProvider); ok {
androidMkEntriesInfos := info.(*AndroidMkProviderInfo)
err = translateAndroidMkEntriesInfoModule(ctx, w, moduleInfoJSONs, mod, androidMkEntriesInfos)
} else {
switch x := mod.(type) {
case AndroidMkDataProvider:
err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
case AndroidMkEntriesProvider:
err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
default:
// Not exported to make so no make variables to set.
}
}
if err != nil {
@@ -824,23 +828,6 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs
return err
}
// A simple, special Android.mk entry output func to make it possible to build blueprint tools using
// m by making them phony targets.
func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
goBinary bootstrap.GoBinaryTool) error {
name := ctx.ModuleName(mod)
fmt.Fprintln(w, ".PHONY:", name)
fmt.Fprintln(w, name+":", goBinary.InstallPath())
fmt.Fprintln(w, "")
// Assuming no rules in make include go binaries in distributables.
// If the assumption is wrong, make will fail to build without the necessary .meta_lic and .meta_module files.
// In that case, add the targets and rules here to build a .meta_lic file for `name` and a .meta_module for
// `goBinary.InstallPath()` pointing to the `name`.meta_lic file.
return nil
}
func (data *AndroidMkData) fillInData(ctx fillInEntriesContext, mod blueprint.Module) {
// Get the preamble content through AndroidMkEntries logic.
data.Entries = AndroidMkEntries{
@@ -983,11 +970,11 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn
return nil
}
func ShouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module Module) bool {
func ShouldSkipAndroidMkProcessing(ctx ConfigurableEvaluatorContext, module Module) bool {
return shouldSkipAndroidMkProcessing(ctx, module.base())
}
func shouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module *ModuleBase) bool {
func shouldSkipAndroidMkProcessing(ctx ConfigurableEvaluatorContext, module *ModuleBase) bool {
if !module.commonProperties.NamespaceExportedToMake {
// TODO(jeffrygaston) do we want to validate that there are no modules being
// exported to Kati that depend on this module?
@@ -1063,3 +1050,564 @@ func AndroidMkEmitAssignList(w io.Writer, varName string, lists ...[]string) {
}
fmt.Fprintln(w)
}
type AndroidMkProviderInfo struct {
PrimaryInfo AndroidMkInfo
ExtraInfo []AndroidMkInfo
}
type AndroidMkInfo struct {
// Android.mk class string, e.g. EXECUTABLES, JAVA_LIBRARIES, ETC
Class string
// Optional suffix to append to the module name. Useful when a module wants to return multiple
// AndroidMkEntries objects. For example, when a java_library returns an additional entry for
// its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a
// different name than the parent's.
SubName string
// If set, this value overrides the base module name. SubName is still appended.
OverrideName string
// Dist files to output
DistFiles TaggedDistFiles
// The output file for Kati to process and/or install. If absent, the module is skipped.
OutputFile OptionalPath
// If true, the module is skipped and does not appear on the final Android-<product name>.mk
// file. Useful when a module needs to be skipped conditionally.
Disabled bool
// The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk
// If not set, $(BUILD_SYSTEM)/prebuilt.mk is used.
Include string
// Required modules that need to be built and included in the final build output when building
// this module.
Required []string
// Required host modules that need to be built and included in the final build output when
// building this module.
Host_required []string
// Required device modules that need to be built and included in the final build output when
// building this module.
Target_required []string
HeaderStrings []string
FooterStrings []string
// A map that holds the up-to-date Make variable values. Can be accessed from tests.
EntryMap map[string][]string
// A list of EntryMap keys in insertion order. This serves a few purposes:
// 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this,
// the outputted Android-*.mk file may change even though there have been no content changes.
// 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR),
// without worrying about the variables being mixed up in the actual mk file.
// 3. Makes troubleshooting and spotting errors easier.
EntryOrder []string
}
// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone.
var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]()
func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error {
if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
return nil
}
// Deep copy the provider info since we need to modify the info later
info := deepCopyAndroidMkProviderInfo(providerInfo)
aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info)
// Any new or special cases here need review to verify correct propagation of license information.
info.PrimaryInfo.fillInEntries(ctx, mod)
info.PrimaryInfo.write(w)
if len(info.ExtraInfo) > 0 {
for _, ei := range info.ExtraInfo {
ei.fillInEntries(ctx, mod)
ei.write(w)
}
}
if !info.PrimaryInfo.disabled() {
if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
*moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
}
}
return nil
}
// Utility funcs to manipulate Android.mk variable entries.
// SetString sets a Make variable with the given name to the given value.
func (a *AndroidMkInfo) SetString(name, value string) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{value}
}
// SetPath sets a Make variable with the given name to the given path string.
func (a *AndroidMkInfo) SetPath(name string, path Path) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{path.String()}
}
// SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
// It is a no-op if the given path is invalid.
func (a *AndroidMkInfo) SetOptionalPath(name string, path OptionalPath) {
if path.Valid() {
a.SetPath(name, path.Path())
}
}
// AddPath appends the given path string to a Make variable with the given name.
func (a *AndroidMkInfo) AddPath(name string, path Path) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], path.String())
}
// AddOptionalPath appends the given path string to a Make variable with the given name if it is
// valid. It is a no-op if the given path is invalid.
func (a *AndroidMkInfo) AddOptionalPath(name string, path OptionalPath) {
if path.Valid() {
a.AddPath(name, path.Path())
}
}
// SetPaths sets a Make variable with the given name to a slice of the given path strings.
func (a *AndroidMkInfo) SetPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = paths.Strings()
}
// SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
// only if there are a non-zero amount of paths.
func (a *AndroidMkInfo) SetOptionalPaths(name string, paths Paths) {
if len(paths) > 0 {
a.SetPaths(name, paths)
}
}
// AddPaths appends the given path strings to a Make variable with the given name.
func (a *AndroidMkInfo) AddPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
}
// SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
// It is a no-op if the given flag is false.
func (a *AndroidMkInfo) SetBoolIfTrue(name string, flag bool) {
if flag {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{"true"}
}
}
// SetBool sets a Make variable with the given name to if the given bool flag value.
func (a *AndroidMkInfo) SetBool(name string, flag bool) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
if flag {
a.EntryMap[name] = []string{"true"}
} else {
a.EntryMap[name] = []string{"false"}
}
}
// AddStrings appends the given strings to a Make variable with the given name.
func (a *AndroidMkInfo) AddStrings(name string, value ...string) {
if len(value) == 0 {
return
}
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], value...)
}
// AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
// for partial MTS and MCTS test suites.
func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) {
// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
// we add the full test suite to our list.
if PrefixInList(suites, "mts-") && !InList("mts", suites) {
suites = append(suites, "mts")
}
if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
suites = append(suites, "mcts")
}
a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
}
func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
helperInfo := AndroidMkInfo{
EntryMap: make(map[string][]string),
}
amod := mod.(Module)
base := amod.base()
name := base.BaseModuleName()
if a.OverrideName != "" {
name = a.OverrideName
}
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
for _, distString := range a.GetDistForGoals(ctx, mod) {
a.HeaderStrings = append(a.HeaderStrings, distString)
}
a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)))
// Collect make variable assignment entries.
helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
helperInfo.SetString("LOCAL_MODULE_CLASS", a.Class)
helperInfo.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
// If the install rule was generated by Soong tell Make about it.
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
if len(info.KatiInstalls) > 0 {
// Assume the primary install file is last since it probably needs to depend on any other
// installed files. If that is not the case we can add a method to specify the primary
// installed file.
helperInfo.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to)
helperInfo.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled())
helperInfo.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", info.KatiSymlinks.InstallPaths().Paths())
} else {
// Soong may not have generated the install rule also when `no_full_install: true`.
// Mark this module as uninstallable in order to prevent Make from creating an
// install rule there.
helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
}
if len(info.TestData) > 0 {
helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
}
if am, ok := mod.(ApexModule); ok {
helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
}
archStr := base.Arch().ArchType.String()
host := false
switch base.Os().Class {
case Host:
if base.Target().HostCross {
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
if base.Arch().ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
}
} else {
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
if base.Arch().ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
}
}
host = true
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
if base.Arch().ArchType != Common {
if base.Target().NativeBridge {
hostArchStr := base.Target().NativeBridgeHostArchName
if hostArchStr != "" {
helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
}
} else {
helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
}
}
if !base.InVendorRamdisk() {
helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
}
if len(info.VintfFragmentsPaths) > 0 {
helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
}
helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
helperInfo.SetString("LOCAL_VENDOR_MODULE", "true")
}
helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
if base.commonProperties.Owner != nil {
helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
}
}
if host {
makeOs := base.Os().String()
if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
makeOs = "linux"
}
helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs)
helperInfo.SetString("LOCAL_IS_HOST_MODULE", "true")
}
prefix := ""
if base.ArchSpecific() {
switch base.Os().Class {
case Host:
if base.Target().HostCross {
prefix = "HOST_CROSS_"
} else {
prefix = "HOST_"
}
case Device:
prefix = "TARGET_"
}
if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok {
helperInfo.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
}
if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
helperInfo.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true)
}
a.mergeEntries(&helperInfo)
// Write to footer.
a.FooterStrings = append([]string{"include " + a.Include}, a.FooterStrings...)
}
// This method merges the entries to helperInfo, then replaces a's EntryMap and
// EntryOrder with helperInfo's
func (a *AndroidMkInfo) mergeEntries(helperInfo *AndroidMkInfo) {
for _, extraEntry := range a.EntryOrder {
if v, ok := helperInfo.EntryMap[extraEntry]; ok {
v = append(v, a.EntryMap[extraEntry]...)
} else {
helperInfo.EntryMap[extraEntry] = a.EntryMap[extraEntry]
helperInfo.EntryOrder = append(helperInfo.EntryOrder, extraEntry)
}
}
a.EntryOrder = helperInfo.EntryOrder
a.EntryMap = helperInfo.EntryMap
}
func (a *AndroidMkInfo) disabled() bool {
return a.Disabled || !a.OutputFile.Valid()
}
// write flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
// given Writer object.
func (a *AndroidMkInfo) write(w io.Writer) {
if a.disabled() {
return
}
combinedHeaderString := strings.Join(a.HeaderStrings, "\n")
combinedFooterString := strings.Join(a.FooterStrings, "\n")
w.Write([]byte(combinedHeaderString))
for _, name := range a.EntryOrder {
AndroidMkEmitAssignList(w, name, a.EntryMap[name])
}
w.Write([]byte(combinedFooterString))
}
// Compute the list of Make strings to declare phony goals and dist-for-goals
// calls from the module's dist and dists properties.
func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string {
distContributions := a.getDistContributions(ctx, mod)
if distContributions == nil {
return nil
}
return generateDistContributionsForMake(distContributions)
}
// Compute the contributions that the module makes to the dist.
func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions {
amod := mod.(Module).base()
name := amod.BaseModuleName()
// Collate the set of associated tag/paths available for copying to the dist.
// Start with an empty (nil) set.
var availableTaggedDists TaggedDistFiles
// Then merge in any that are provided explicitly by the module.
if a.DistFiles != nil {
// Merge the DistFiles into the set.
availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
}
// If no paths have been provided for the DefaultDistTag and the output file is
// valid then add that as the default dist path.
if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
}
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
// If the distFiles created by GenerateTaggedDistFiles contains paths for the
// DefaultDistTag then that takes priority so delete any existing paths.
if _, ok := info.DistFiles[DefaultDistTag]; ok {
delete(availableTaggedDists, DefaultDistTag)
}
// Finally, merge the distFiles created by GenerateTaggedDistFiles.
availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
if len(availableTaggedDists) == 0 {
// Nothing dist-able for this module.
return nil
}
// Collate the contributions this module makes to the dist.
distContributions := &distContributions{}
if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
distContributions.licenseMetadataFile = info.LicenseMetadataFile
}
// Iterate over this module's dist structs, merged from the dist and dists properties.
for _, dist := range amod.Dists() {
// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
goals := strings.Join(dist.Targets, " ")
// Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
var tag string
if dist.Tag == nil {
// If the dist struct does not specify a tag, use the default output files tag.
tag = DefaultDistTag
} else {
tag = *dist.Tag
}
// Get the paths of the output files to be dist'd, represented by the tag.
// Can be an empty list.
tagPaths := availableTaggedDists[tag]
if len(tagPaths) == 0 {
// Nothing to dist for this tag, continue to the next dist.
continue
}
if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
"file for %q goals tag %q in module %s. The list of dist files, " +
"which should have a single element, is:\n%s"
panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
}
copiesForGoals := distContributions.getCopiesForGoals(goals)
// Iterate over each path adding a copy instruction to copiesForGoals
for _, path := range tagPaths {
// It's possible that the Path is nil from errant modules. Be defensive here.
if path == nil {
tagName := "default" // for error message readability
if dist.Tag != nil {
tagName = *dist.Tag
}
panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
}
dest := filepath.Base(path.String())
if dist.Dest != nil {
var err error
if dest, err = validateSafePath(*dist.Dest); err != nil {
// This was checked in ModuleBase.GenerateBuildActions
panic(err)
}
}
ext := filepath.Ext(dest)
suffix := ""
if dist.Suffix != nil {
suffix = *dist.Suffix
}
productString := ""
if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
}
if suffix != "" || productString != "" {
dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
}
if dist.Dir != nil {
var err error
if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
// This was checked in ModuleBase.GenerateBuildActions
panic(err)
}
}
copiesForGoals.addCopyInstruction(path, dest)
}
}
return distContributions
}
func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo {
info := AndroidMkProviderInfo{
PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo),
}
if len(providerInfo.ExtraInfo) > 0 {
for _, i := range providerInfo.ExtraInfo {
info.ExtraInfo = append(info.ExtraInfo, deepCopyAndroidMkInfo(&i))
}
}
return info
}
func deepCopyAndroidMkInfo(mkinfo *AndroidMkInfo) AndroidMkInfo {
info := AndroidMkInfo{
Class: mkinfo.Class,
SubName: mkinfo.SubName,
OverrideName: mkinfo.OverrideName,
// There is no modification on DistFiles or OutputFile, so no need to
// make their deep copy.
DistFiles: mkinfo.DistFiles,
OutputFile: mkinfo.OutputFile,
Disabled: mkinfo.Disabled,
Include: mkinfo.Include,
Required: deepCopyStringSlice(mkinfo.Required),
Host_required: deepCopyStringSlice(mkinfo.Host_required),
Target_required: deepCopyStringSlice(mkinfo.Target_required),
HeaderStrings: deepCopyStringSlice(mkinfo.HeaderStrings),
FooterStrings: deepCopyStringSlice(mkinfo.FooterStrings),
EntryOrder: deepCopyStringSlice(mkinfo.EntryOrder),
}
info.EntryMap = make(map[string][]string)
for k, v := range mkinfo.EntryMap {
info.EntryMap[k] = deepCopyStringSlice(v)
}
return info
}
func deepCopyStringSlice(original []string) []string {
result := make([]string, len(original))
copy(result, original)
return result
}

View File

@@ -23,7 +23,6 @@ import (
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/proptools"
)
@@ -397,33 +396,8 @@ func (target Target) Variations() []blueprint.Variation {
// device_supported and host_supported properties to determine which OsTypes are enabled for this
// module, then searches through the Targets to determine which have enabled Targets for this
// module.
func osMutator(bpctx blueprint.BottomUpMutatorContext) {
var module Module
var ok bool
if module, ok = bpctx.Module().(Module); !ok {
// The module is not a Soong module, it is a Blueprint module.
if bootstrap.IsBootstrapModule(bpctx.Module()) {
// Bootstrap Go modules are always the build OS or linux bionic.
config := bpctx.Config().(Config)
osNames := []string{config.BuildOSTarget.OsVariation()}
for _, hostCrossTarget := range config.Targets[LinuxBionic] {
if hostCrossTarget.Arch.ArchType == config.BuildOSTarget.Arch.ArchType {
osNames = append(osNames, hostCrossTarget.OsVariation())
}
}
osNames = FirstUniqueStrings(osNames)
bpctx.CreateVariations(osNames...)
}
return
}
// Bootstrap Go module support above requires this mutator to be a
// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
// filters out non-Soong modules. Now that we've handled them, create a
// normal android.BottomUpMutatorContext.
mctx := bottomUpMutatorContextFactory(bpctx, module, false)
defer bottomUpMutatorContextPool.Put(mctx)
func osMutator(mctx BottomUpMutatorContext) {
module := mctx.Module()
base := module.base()
// Nothing to do for modules that are not architecture specific (e.g. a genrule).
@@ -553,24 +527,8 @@ var DarwinUniversalVariantTag = archDepTag{name: "darwin universal binary"}
//
// Modules can be initialized with InitAndroidMultiTargetsArchModule, in which case they will be split by OsClass,
// but will have a common Target that is expected to handle all other selected Targets via ctx.MultiTargets().
func archMutator(bpctx blueprint.BottomUpMutatorContext) {
var module Module
var ok bool
if module, ok = bpctx.Module().(Module); !ok {
if bootstrap.IsBootstrapModule(bpctx.Module()) {
// Bootstrap Go modules are always the build architecture.
bpctx.CreateVariations(bpctx.Config().(Config).BuildOSTarget.ArchVariation())
}
return
}
// Bootstrap Go module support above requires this mutator to be a
// blueprint.BottomUpMutatorContext because android.BottomUpMutatorContext
// filters out non-Soong modules. Now that we've handled them, create a
// normal android.BottomUpMutatorContext.
mctx := bottomUpMutatorContextFactory(bpctx, module, false)
defer bottomUpMutatorContextPool.Put(mctx)
func archMutator(mctx BottomUpMutatorContext) {
module := mctx.Module()
base := module.base()
if !base.ArchSpecific() {

View File

@@ -220,6 +220,10 @@ type BaseModuleContext interface {
// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
// can be used to evaluate the final value of Configurable properties.
EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
// HasMutatorFinished returns true if the given mutator has finished running.
// It will panic if given an invalid mutator name.
HasMutatorFinished(mutatorName string) bool
}
type baseModuleContext struct {
@@ -270,6 +274,10 @@ func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value
b.bp.SetProvider(provider, value)
}
func (b *baseModuleContext) HasMutatorFinished(mutatorName string) bool {
return b.bp.HasMutatorFinished(mutatorName)
}
func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
return b.bp.GetDirectDepWithTag(name, tag)
}

View File

@@ -1663,6 +1663,17 @@ func (c *config) ApexTrimEnabled() bool {
return Bool(c.productVariables.TrimmedApex)
}
func (c *config) UseSoongSystemImage() bool {
return Bool(c.productVariables.UseSoongSystemImage)
}
func (c *config) SoongDefinedSystemImage() string {
if c.UseSoongSystemImage() {
return String(c.productVariables.ProductSoongDefinedSystemImage)
}
return ""
}
func (c *config) EnforceSystemCertificate() bool {
return Bool(c.productVariables.EnforceSystemCertificate)
}

View File

@@ -58,7 +58,7 @@ type Module interface {
base() *ModuleBase
Disable()
Enabled(ctx ConfigAndErrorContext) bool
Enabled(ctx ConfigurableEvaluatorContext) bool
Target() Target
MultiTargets() []Target
@@ -109,12 +109,12 @@ type Module interface {
// Get information about the properties that can contain visibility rules.
visibilityProperties() []visibilityProperty
RequiredModuleNames(ctx ConfigAndErrorContext) []string
RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
HostRequiredModuleNames() []string
TargetRequiredModuleNames() []string
VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string
VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator
ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
}
// Qualified id for a module
@@ -1339,7 +1339,7 @@ func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
return partition
}
func (m *ModuleBase) Enabled(ctx ConfigAndErrorContext) bool {
func (m *ModuleBase) Enabled(ctx ConfigurableEvaluatorContext) bool {
if m.commonProperties.ForcedDisabled {
return false
}
@@ -1536,7 +1536,7 @@ func (m *ModuleBase) InRecovery() bool {
return m.base().commonProperties.ImageVariation == RecoveryVariation
}
func (m *ModuleBase) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
func (m *ModuleBase) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
@@ -1548,7 +1548,7 @@ func (m *ModuleBase) TargetRequiredModuleNames() []string {
return m.base().commonProperties.Target_required
}
func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigAndErrorContext) []string {
func (m *ModuleBase) VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string {
return m.base().commonProperties.Vintf_fragment_modules.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
}
@@ -2204,17 +2204,17 @@ func (m *ModuleBase) IsNativeBridgeSupported() bool {
return proptools.Bool(m.commonProperties.Native_bridge_supported)
}
type ConfigAndErrorContext interface {
type ConfigurableEvaluatorContext interface {
Config() Config
OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
}
type configurationEvalutor struct {
ctx ConfigAndErrorContext
ctx ConfigurableEvaluatorContext
m Module
}
func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.ConfigurableEvaluator {
func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
return configurationEvalutor{
ctx: ctx,
m: m.module,

View File

@@ -85,7 +85,9 @@ type ModuleBuildParams BuildParams
type ModuleContext interface {
BaseModuleContext
blueprintModuleContext() blueprint.ModuleContext
// BlueprintModuleContext returns the blueprint.ModuleContext that the ModuleContext wraps. It may only be
// used by the golang module types that need to call into the bootstrap module types.
BlueprintModuleContext() blueprint.ModuleContext
// Deprecated: use ModuleContext.Build instead.
ModuleBuild(pctx PackageContext, params ModuleBuildParams)
@@ -194,7 +196,7 @@ type ModuleContext interface {
InstallInVendor() bool
InstallForceOS() (*OsType, *ArchType)
RequiredModuleNames(ctx ConfigAndErrorContext) []string
RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
HostRequiredModuleNames() []string
TargetRequiredModuleNames() []string
@@ -779,7 +781,7 @@ func (m *moduleContext) UncheckedModule() {
m.uncheckedModule = true
}
func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext {
func (m *moduleContext) BlueprintModuleContext() blueprint.ModuleContext {
return m.bp
}
@@ -855,7 +857,7 @@ func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) Optional
return OptionalPath{}
}
func (m *moduleContext) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
func (m *moduleContext) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
return m.module.RequiredModuleNames(ctx)
}

View File

@@ -148,9 +148,9 @@ var preArch = []RegisterMutatorFunc{
}
func registerArchMutator(ctx RegisterMutatorsContext) {
ctx.BottomUpBlueprint("os", osMutator).Parallel()
ctx.BottomUp("os", osMutator).Parallel()
ctx.Transition("image", &imageTransitionMutator{})
ctx.BottomUpBlueprint("arch", archMutator).Parallel()
ctx.BottomUp("arch", archMutator).Parallel()
}
var preDeps = []RegisterMutatorFunc{

View File

@@ -27,7 +27,6 @@ import (
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/pathtools"
)
@@ -94,6 +93,7 @@ type ModuleWithDepsPathContext interface {
EarlyModulePathContext
VisitDirectDepsBlueprint(visit func(blueprint.Module))
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
HasMutatorFinished(mutatorName string) bool
}
// ModuleMissingDepsPathContext is a subset of *ModuleContext methods required by
@@ -554,13 +554,6 @@ func (p OutputPaths) Strings() []string {
return ret
}
// PathForGoBinary returns the path to the installed location of a bootstrap_go_binary module.
func PathForGoBinary(ctx PathContext, goBinary bootstrap.GoBinaryTool) Path {
goBinaryInstallDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin")
rel := Rel(ctx, goBinaryInstallDir.String(), goBinary.InstallPath())
return goBinaryInstallDir.Join(ctx, rel)
}
// Expands Paths to a SourceFileProducer or OutputFileProducer module dependency referenced via ":name" or ":name{.tag}" syntax.
// If the dependency is not found, a missingErrorDependency is returned.
// If the module dependency is not a SourceFileProducer or OutputFileProducer, appropriate errors will be returned.
@@ -572,10 +565,6 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag
if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) {
return nil, missingDependencyError{[]string{moduleName}}
}
if goBinary, ok := module.(bootstrap.GoBinaryTool); ok && tag == "" {
goBinaryPath := PathForGoBinary(ctx, goBinary)
return Paths{goBinaryPath}, nil
}
outputFiles, err := outputFilesForModule(ctx, module, tag)
if outputFiles != nil && err == nil {
return outputFiles, nil

View File

@@ -813,8 +813,6 @@ type SdkMemberProperties interface {
// SdkMemberContext provides access to information common to a specific member.
type SdkMemberContext interface {
ConfigAndErrorContext
// SdkModuleContext returns the module context of the sdk common os variant which is creating the
// snapshot.
//

View File

@@ -90,6 +90,10 @@ type SingletonContext interface {
// OtherModulePropertyErrorf reports an error on the line number of the given property of the given module
OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{})
// HasMutatorFinished returns true if the given mutator has finished running.
// It will panic if given an invalid mutator name.
HasMutatorFinished(mutatorName string) bool
}
type singletonAdaptor struct {
@@ -286,3 +290,7 @@ func (s *singletonContextAdaptor) otherModuleProvider(module blueprint.Module, p
func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) {
s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...)
}
func (s *singletonContextAdaptor) HasMutatorFinished(mutatorName string) bool {
return s.blueprintSingletonContext().HasMutatorFinished(mutatorName)
}

View File

@@ -1326,7 +1326,11 @@ func (ctx *panickingConfigAndErrorContext) Config() Config {
return ctx.ctx.Config()
}
func PanickingConfigAndErrorContext(ctx *TestContext) ConfigAndErrorContext {
func (ctx *panickingConfigAndErrorContext) HasMutatorFinished(mutatorName string) bool {
return ctx.ctx.HasMutatorFinished(mutatorName)
}
func PanickingConfigAndErrorContext(ctx *TestContext) ConfigurableEvaluatorContext {
return &panickingConfigAndErrorContext{
ctx: ctx,
}

View File

@@ -177,6 +177,41 @@ func setFromList[T comparable](l []T) map[T]bool {
return m
}
// PrettyConcat returns the formatted concatenated string suitable for displaying user-facing
// messages.
func PrettyConcat(list []string, quote bool, lastSep string) string {
if len(list) == 0 {
return ""
}
quoteStr := func(v string) string {
if !quote {
return v
}
return fmt.Sprintf("%q", v)
}
if len(list) == 1 {
return quoteStr(list[0])
}
var sb strings.Builder
for i, val := range list {
if i > 0 {
sb.WriteString(", ")
}
if i == len(list)-1 {
sb.WriteString(lastSep)
if lastSep != "" {
sb.WriteString(" ")
}
}
sb.WriteString(quoteStr(val))
}
return sb.String()
}
// ListSetDifference checks if the two lists contain the same elements. It returns
// a boolean which is true if there is a difference, and then returns lists of elements
// that are in l1 but not l2, and l2 but not l1.

View File

@@ -867,3 +867,51 @@ func TestHasIntersection(t *testing.T) {
})
}
}
var prettyConcatTestCases = []struct {
name string
list []string
quote bool
lastSeparator string
expected string
}{
{
name: "empty",
list: []string{},
quote: false,
lastSeparator: "and",
expected: ``,
},
{
name: "single",
list: []string{"a"},
quote: true,
lastSeparator: "and",
expected: `"a"`,
},
{
name: "with separator",
list: []string{"a", "b", "c"},
quote: true,
lastSeparator: "or",
expected: `"a", "b", or "c"`,
},
{
name: "without separator",
list: []string{"a", "b", "c"},
quote: false,
lastSeparator: "",
expected: `a, b, c`,
},
}
func TestPrettyConcat(t *testing.T) {
for _, testCase := range prettyConcatTestCases {
t.Run(testCase.name, func(t *testing.T) {
concatString := PrettyConcat(testCase.list, testCase.quote, testCase.lastSeparator)
if !reflect.DeepEqual(concatString, testCase.expected) {
t.Errorf("expected %#v, got %#v", testCase.expected, concatString)
}
})
}
}

View File

@@ -423,6 +423,9 @@ type ProductVariables struct {
TargetFSConfigGen []string `json:",omitempty"`
UseSoongSystemImage *bool `json:",omitempty"`
ProductSoongDefinedSystemImage *string `json:",omitempty"`
EnforceProductPartitionInterface *bool `json:",omitempty"`
EnforceInterPartitionJavaSdkLibrary *bool `json:",omitempty"`

View File

@@ -15,7 +15,6 @@ bootstrap_go_package {
"soong-cc",
"soong-filesystem",
"soong-java",
"soong-multitree",
"soong-provenance",
"soong-python",
"soong-rust",

View File

@@ -32,7 +32,6 @@ import (
prebuilt_etc "android/soong/etc"
"android/soong/filesystem"
"android/soong/java"
"android/soong/multitree"
"android/soong/rust"
"android/soong/sh"
)
@@ -431,7 +430,6 @@ type apexBundle struct {
android.ModuleBase
android.DefaultableModuleBase
android.OverridableModuleBase
multitree.ExportableModuleBase
// Properties
properties apexBundleProperties
@@ -1399,8 +1397,6 @@ func (a *apexBundle) DepIsInSameApex(_ android.BaseModuleContext, _ android.Modu
return true
}
var _ multitree.Exportable = (*apexBundle)(nil)
func (a *apexBundle) Exportable() bool {
return true
}
@@ -2528,7 +2524,6 @@ func newApexBundle() *apexBundle {
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.overridableProperties.Overrides)
multitree.InitExportableModule(module)
return module
}
@@ -2785,7 +2780,7 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
return false
}
if to.AvailableFor(apexName) || baselineApexAvailable(apexName, toName) {
if to.AvailableFor(apexName) {
return true
}
@@ -2845,74 +2840,6 @@ func (a *apexBundle) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeI
dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...)
}
var (
apexAvailBaseline = makeApexAvailableBaseline()
inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
)
func baselineApexAvailable(apex, moduleName string) bool {
key := apex
moduleName = normalizeModuleName(moduleName)
if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
return true
}
key = android.AvailableToAnyApex
if val, ok := apexAvailBaseline[key]; ok && android.InList(moduleName, val) {
return true
}
return false
}
func normalizeModuleName(moduleName string) string {
// Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build
// system. Trim the prefix for the check since they are confusing
moduleName = android.RemoveOptionalPrebuiltPrefix(moduleName)
if strings.HasPrefix(moduleName, "libclang_rt.") {
// This module has many arch variants that depend on the product being built.
// We don't want to list them all
moduleName = "libclang_rt"
}
if strings.HasPrefix(moduleName, "androidx.") {
// TODO(b/156996905) Set apex_available/min_sdk_version for androidx support libraries
moduleName = "androidx"
}
return moduleName
}
// Transform the map of apex -> modules to module -> apexes.
func invertApexBaseline(m map[string][]string) map[string][]string {
r := make(map[string][]string)
for apex, modules := range m {
for _, module := range modules {
r[module] = append(r[module], apex)
}
}
return r
}
// Retrieve the baseline of apexes to which the supplied module belongs.
func BaselineApexAvailable(moduleName string) []string {
return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
}
// This is a map from apex to modules, which overrides the apex_available setting for that
// particular module to make it available for the apex regardless of its setting.
// TODO(b/147364041): remove this
func makeApexAvailableBaseline() map[string][]string {
// The "Module separator"s below are employed to minimize merge conflicts.
m := make(map[string][]string)
//
// Module separator
//
m["com.android.runtime"] = []string{
"libz",
}
return m
}
func init() {
android.AddNeverAllowRules(createBcpPermittedPackagesRules(qBcpPackages())...)
android.AddNeverAllowRules(createBcpPermittedPackagesRules(rBcpPackages())...)

View File

@@ -10273,208 +10273,6 @@ func TestUpdatableApexEnforcesAppUpdatability(t *testing.T) {
}
}
func TestApexBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
bp := `
apex {
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libbaz"],
binaries: ["binfoo"],
min_sdk_version: "29",
}
apex_key {
name: "myapex.key",
}
cc_binary {
name: "binfoo",
shared_libs: ["libbar", "libbaz", "libqux",],
apex_available: ["myapex"],
min_sdk_version: "29",
recovery_available: false,
}
cc_library {
name: "libbar",
srcs: ["libbar.cc"],
stubs: {
symbol_file: "libbar.map.txt",
versions: [
"29",
],
},
}
cc_library {
name: "libbaz",
srcs: ["libbaz.cc"],
apex_available: ["myapex"],
min_sdk_version: "29",
stubs: {
symbol_file: "libbaz.map.txt",
versions: [
"29",
],
},
}
cc_api_library {
name: "libbar",
src: "libbar_stub.so",
min_sdk_version: "29",
variants: ["apex.29"],
}
cc_api_variant {
name: "libbar",
variant: "apex",
version: "29",
src: "libbar_apex_29.so",
}
cc_api_library {
name: "libbaz",
src: "libbaz_stub.so",
min_sdk_version: "29",
variants: ["apex.29"],
}
cc_api_variant {
name: "libbaz",
variant: "apex",
version: "29",
src: "libbaz_apex_29.so",
}
cc_api_library {
name: "libqux",
src: "libqux_stub.so",
min_sdk_version: "29",
variants: ["apex.29"],
}
cc_api_variant {
name: "libqux",
variant: "apex",
version: "29",
src: "libqux_apex_29.so",
}
api_imports {
name: "api_imports",
apex_shared_libs: [
"libbar",
"libbaz",
"libqux",
],
}
`
result := testApex(t, bp)
hasDep := func(m android.Module, wantDep android.Module) bool {
t.Helper()
var found bool
result.VisitDirectDeps(m, func(dep blueprint.Module) {
if dep == wantDep {
found = true
}
})
return found
}
// Library defines stubs and cc_api_library should be used with cc_api_library
binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Module()
libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a_apex29").Rule("ld").Args["libFlags"]
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
// Library defined in the same APEX should be linked with original definition instead of cc_api_library
libbazApexVariant := result.ModuleForTests("libbaz", "android_arm64_armv8-a_shared_apex29").Module()
libbazApiImportCoreVariant := result.ModuleForTests("libbaz.apiimport", "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even from same APEX", true, hasDep(binfooApexVariant, libbazApiImportCoreVariant))
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbazApexVariant))
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbaz.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbaz.apiimport.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbaz.apex.29.apiimport.so")
// cc_api_library defined without original library should be linked with cc_api_library
libquxApiImportApexVariant := result.ModuleForTests("libqux.apiimport", "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries even original library definition does not exist", true, hasDep(binfooApexVariant, libquxApiImportApexVariant))
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libqux.apex.29.apiimport.so")
}
func TestPlatformBinaryBuildsAgainstApiSurfaceStubLibraries(t *testing.T) {
bp := `
apex {
name: "myapex",
key: "myapex.key",
native_shared_libs: ["libbar"],
min_sdk_version: "29",
}
apex_key {
name: "myapex.key",
}
cc_binary {
name: "binfoo",
shared_libs: ["libbar"],
recovery_available: false,
}
cc_library {
name: "libbar",
srcs: ["libbar.cc"],
apex_available: ["myapex"],
min_sdk_version: "29",
stubs: {
symbol_file: "libbar.map.txt",
versions: [
"29",
],
},
}
cc_api_library {
name: "libbar",
src: "libbar_stub.so",
variants: ["apex.29"],
}
cc_api_variant {
name: "libbar",
variant: "apex",
version: "29",
src: "libbar_apex_29.so",
}
api_imports {
name: "api_imports",
apex_shared_libs: [
"libbar",
],
}
`
result := testApex(t, bp)
hasDep := func(m android.Module, wantDep android.Module) bool {
t.Helper()
var found bool
result.VisitDirectDeps(m, func(dep blueprint.Module) {
if dep == wantDep {
found = true
}
})
return found
}
// Library defines stubs and cc_api_library should be used with cc_api_library
binfooApexVariant := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Module()
libbarCoreVariant := result.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
libbarApiImportCoreVariant := result.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_shared").Module()
android.AssertBoolEquals(t, "apex variant should link against API surface stub libraries", true, hasDep(binfooApexVariant, libbarApiImportCoreVariant))
android.AssertBoolEquals(t, "apex variant should link against original library if exists", true, hasDep(binfooApexVariant, libbarCoreVariant))
binFooCFlags := result.ModuleForTests("binfoo", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
android.AssertStringDoesContain(t, "binfoo should link against APEX variant", binFooCFlags, "libbar.apex.29.apiimport.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against cc_api_library itself", binFooCFlags, "libbar.apiimport.so")
android.AssertStringDoesNotContain(t, "binfoo should not link against original definition", binFooCFlags, "libbar.so")
}
func TestTrimmedApex(t *testing.T) {
bp := `
apex {
@@ -10513,21 +10311,6 @@ func TestTrimmedApex(t *testing.T) {
apex_available: ["myapex","mydcla"],
min_sdk_version: "29",
}
cc_api_library {
name: "libc",
src: "libc.so",
min_sdk_version: "29",
recovery_available: true,
vendor_available: true,
product_available: true,
}
api_imports {
name: "api_imports",
shared_libs: [
"libc",
],
header_libs: [],
}
`
ctx := testApex(t, bp)
module := ctx.ModuleForTests("myapex", "android_common_myapex")

View File

@@ -40,6 +40,7 @@ kzip_targets=(
merge_zips
xref_cxx
xref_java
xref_kotlin
# TODO: b/286390153 - reenable rust
# xref_rust
)

View File

@@ -16,7 +16,6 @@ bootstrap_go_package {
"soong-etc",
"soong-fuzz",
"soong-genrule",
"soong-multitree",
"soong-testing",
"soong-tradefed",
],
@@ -65,7 +64,6 @@ bootstrap_go_package {
"library.go",
"library_headers.go",
"library_sdk_member.go",
"library_stub.go",
"native_bridge_sdk_trait.go",
"object.go",
"test.go",

View File

@@ -21,7 +21,6 @@ import (
"strings"
"android/soong/android"
"android/soong/multitree"
)
var (
@@ -479,34 +478,6 @@ func (p *prebuiltBinaryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *a
androidMkWritePrebuiltOptions(p.baseLinker, entries)
}
func (a *apiLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.Class = "SHARED_LIBRARIES"
entries.SubName += multitree.GetApiImportSuffix()
entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
a.libraryDecorator.androidMkWriteExportedFlags(entries)
src := *a.properties.Src
path, file := filepath.Split(src)
stem, suffix, ext := android.SplitFileExt(file)
entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
entries.SetString("LOCAL_MODULE_STEM", stem)
entries.SetString("LOCAL_MODULE_PATH", path)
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
entries.SetString("LOCAL_SOONG_TOC", a.toc().String())
})
}
func (a *apiHeadersDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
entries.Class = "HEADER_LIBRARIES"
entries.SubName += multitree.GetApiImportSuffix()
entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
a.libraryDecorator.androidMkWriteExportedFlags(entries)
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
})
}
func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkEntries) {
allow := linker.Properties.Allow_undefined_symbols
if allow != nil {

View File

@@ -132,7 +132,7 @@ func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberCo
if ccModule.linker != nil {
specifiedDeps := specifiedDeps{}
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx, ccModule, specifiedDeps)
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps)
p.SharedLibs = specifiedDeps.sharedLibs
p.SystemSharedLibs = specifiedDeps.systemSharedLibs

125
cc/cc.go
View File

@@ -34,7 +34,6 @@ import (
"android/soong/cc/config"
"android/soong/fuzz"
"android/soong/genrule"
"android/soong/multitree"
)
func init() {
@@ -613,7 +612,7 @@ type linker interface {
coverageOutputFilePath() android.OptionalPath
// Get the deps that have been explicitly specified in the properties.
linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps
linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps
moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON)
}
@@ -970,7 +969,7 @@ func (c *Module) HiddenFromMake() bool {
return c.Properties.HideFromMake
}
func (c *Module) RequiredModuleNames(ctx android.ConfigAndErrorContext) []string {
func (c *Module) RequiredModuleNames(ctx android.ConfigurableEvaluatorContext) []string {
required := android.CopyOf(c.ModuleBase.RequiredModuleNames(ctx))
if c.ImageVariation().Variation == android.CoreVariation {
required = append(required, c.Properties.Target.Platform.Required...)
@@ -2361,24 +2360,6 @@ func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mo
}
}
func GetApiImports(c LinkableInterface, actx android.BottomUpMutatorContext) multitree.ApiImportInfo {
apiImportInfo := multitree.ApiImportInfo{}
if c.Device() {
var apiImportModule []blueprint.Module
if actx.OtherModuleExists("api_imports") {
apiImportModule = actx.AddDependency(c, nil, "api_imports")
if len(apiImportModule) > 0 && apiImportModule[0] != nil {
apiInfo, _ := android.OtherModuleProvider(actx, apiImportModule[0], multitree.ApiImportsProvider)
apiImportInfo = apiInfo
android.SetProvider(actx, multitree.ApiImportsProvider, apiInfo)
}
}
}
return apiImportInfo
}
func GetReplaceModuleName(lib string, replaceMap map[string]string) string {
if snapshot, ok := replaceMap[lib]; ok {
return snapshot
@@ -2448,11 +2429,6 @@ func (c *Module) shouldUseApiSurface() bool {
// NDK Variant
return true
}
if c.isImportedApiLibrary() {
// API Library should depend on API headers
return true
}
}
return false
@@ -2472,19 +2448,10 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
ctx.ctx = ctx
deps := c.deps(ctx)
apiImportInfo := GetApiImports(c, actx)
apiNdkLibs := []string{}
apiLateNdkLibs := []string{}
if c.shouldUseApiSurface() {
deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
deps.ReexportHeaderLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportHeaderLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
deps.ReexportSharedLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportSharedLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
}
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
variantNdkLibs := []string{}
@@ -2501,11 +2468,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
depTag.reexportFlags = true
}
// Check header lib replacement from API surface first, and then check again with VSDK
if c.shouldUseApiSurface() {
lib = GetReplaceModuleName(lib, apiImportInfo.HeaderLibs)
}
if c.isNDKStubLibrary() {
variationExists := actx.OtherModuleDependencyVariantExists(nil, lib)
if variationExists {
@@ -2515,7 +2477,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
// any variants.
actx.AddFarVariationDependencies([]blueprint.Variation{}, depTag, lib)
}
} else if c.IsStubs() && !c.isImportedApiLibrary() {
} else if c.IsStubs() {
actx.AddFarVariationDependencies(append(ctx.Target().Variations(), c.ImageVariation()),
depTag, lib)
} else {
@@ -2591,22 +2553,12 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
}
name, version := StubsLibNameAndVersion(lib)
if apiLibraryName, ok := apiImportInfo.SharedLibs[name]; ok && !ctx.OtherModuleExists(name) {
name = apiLibraryName
}
sharedLibNames = append(sharedLibNames, name)
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
}
if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, apiLibraryName, version, false)
}
AddSharedLibDependenciesWithVersions(ctx, c, variations, depTag, name, version, false)
}
for _, lib := range deps.LateStaticLibs {
@@ -2701,7 +2653,6 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
)
}
updateImportedLibraryDependency(ctx)
}
func BeginMutator(ctx android.BottomUpMutatorContext) {
@@ -2730,10 +2681,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin
return
}
// TODO(b/244244438) : Remove this once all variants are implemented
if ccFrom, ok := from.(*Module); ok && ccFrom.isImportedApiLibrary() {
return
}
if from.SdkVersion() == "" {
// Platform code can link to anything
return
@@ -2756,10 +2703,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin
// the NDK.
return
}
if c.isImportedApiLibrary() {
// Imported library from the API surface is a stub library built against interface definition.
return
}
}
if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" {
@@ -2935,47 +2878,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
skipModuleList := map[string]bool{}
var apiImportInfo multitree.ApiImportInfo
hasApiImportInfo := false
ctx.VisitDirectDeps(func(dep android.Module) {
if dep.Name() == "api_imports" {
apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider)
hasApiImportInfo = true
}
})
if hasApiImportInfo {
targetStubModuleList := map[string]string{}
targetOrigModuleList := map[string]string{}
// Search for dependency which both original module and API imported library with APEX stub exists
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
targetStubModuleList[apiLibrary] = depName
}
})
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if origLibrary, ok := targetStubModuleList[depName]; ok {
targetOrigModuleList[origLibrary] = depName
}
})
// Decide which library should be used between original and API imported library
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if apiLibrary, ok := targetOrigModuleList[depName]; ok {
if ShouldUseStubForApex(ctx, dep) {
skipModuleList[depName] = true
} else {
skipModuleList[apiLibrary] = true
}
}
})
}
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
@@ -3404,17 +3306,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
// bootstrap modules, always link to non-stub variant
isNotInPlatform := dep.(android.ApexModule).NotInPlatform()
isApexImportedApiLibrary := false
if cc, ok := dep.(*Module); ok {
if apiLibrary, ok := cc.linker.(*apiLibraryDecorator); ok {
if apiLibrary.hasApexStubs() {
isApexImportedApiLibrary = true
}
}
}
useStubs = (isNotInPlatform || isApexImportedApiLibrary) && !bootstrap
useStubs = isNotInPlatform && !bootstrap
if useStubs {
// Another exception: if this module is a test for an APEX, then
@@ -3439,7 +3331,7 @@ func ShouldUseStubForApex(ctx android.ModuleContext, dep android.Module) bool {
// only partially overlapping apex_available. For that test_for
// modules would need to be split into APEX variants and resolved
// separately for each APEX they have access to.
if !isApexImportedApiLibrary && android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
if android.AvailableToSameApexes(thisModule, dep.(android.ApexModule)) {
useStubs = false
}
}
@@ -4023,11 +3915,6 @@ func (c *Module) IsSdkVariant() bool {
return c.Properties.IsSdkVariant
}
func (c *Module) isImportedApiLibrary() bool {
_, ok := c.linker.(*apiLibraryDecorator)
return ok
}
func kytheExtractAllFactory() android.Singleton {
return &kytheExtractAllSingleton{}
}

View File

@@ -919,7 +919,7 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
return deps
}
func (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
func (library *libraryDecorator) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
specifiedDeps = library.baseLinker.linkerSpecifiedDeps(ctx, module, specifiedDeps)
var properties StaticOrSharedProperties
if library.static() {
@@ -2350,9 +2350,8 @@ func (versionTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, varia
if library := moduleLibraryInterface(ctx.Module()); library != nil && canBeVersionVariant(m) {
isLLNDK := m.IsLlndk()
isVendorPublicLibrary := m.IsVendorPublicLibrary()
isImportedApiLibrary := m.isImportedApiLibrary()
if variation != "" || isLLNDK || isVendorPublicLibrary || isImportedApiLibrary {
if variation != "" || isLLNDK || isVendorPublicLibrary {
// A stubs or LLNDK stubs variant.
if m.sanitize != nil {
m.sanitize.Properties.ForceDisable = true

View File

@@ -543,7 +543,7 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(ctx android.SdkMemberConte
p.ExportedFlags = exportedInfo.Flags
if ccModule.linker != nil {
specifiedDeps := specifiedDeps{}
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx, ccModule, specifiedDeps)
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(ctx.SdkModuleContext(), ccModule, specifiedDeps)
if lib := ccModule.library; lib != nil {
if !lib.hasStubsVariants() {

View File

@@ -1,512 +0,0 @@
// Copyright 2021 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cc
import (
"regexp"
"strings"
"android/soong/android"
"android/soong/multitree"
"github.com/google/blueprint/proptools"
)
var (
ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
stubVariantRegex = regexp.MustCompile("apex\\.([a-zA-Z0-9]+)")
)
func init() {
RegisterLibraryStubBuildComponents(android.InitRegistrationContext)
}
func RegisterLibraryStubBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_api_library", CcApiLibraryFactory)
ctx.RegisterModuleType("cc_api_headers", CcApiHeadersFactory)
ctx.RegisterModuleType("cc_api_variant", CcApiVariantFactory)
}
func updateImportedLibraryDependency(ctx android.BottomUpMutatorContext) {
m, ok := ctx.Module().(*Module)
if !ok {
return
}
apiLibrary, ok := m.linker.(*apiLibraryDecorator)
if !ok {
return
}
if m.InVendorOrProduct() && apiLibrary.hasLLNDKStubs() {
// Add LLNDK variant dependency
if inList("llndk", apiLibrary.properties.Variants) {
variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
ctx.AddDependency(m, nil, variantName)
}
} else if m.IsSdkVariant() {
// Add NDK variant dependencies
targetVariant := "ndk." + m.StubsVersion()
if inList(targetVariant, apiLibrary.properties.Variants) {
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
ctx.AddDependency(m, nil, variantName)
}
} else if m.IsStubs() {
targetVariant := "apex." + m.StubsVersion()
if inList(targetVariant, apiLibrary.properties.Variants) {
variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
ctx.AddDependency(m, nil, variantName)
}
}
}
// 'cc_api_library' is a module type which is from the exported API surface
// with C shared library type. The module will replace original module, and
// offer a link to the module that generates shared library object from the
// map file.
type apiLibraryProperties struct {
Src *string `android:"arch_variant"`
Variants []string
}
type apiLibraryDecorator struct {
*libraryDecorator
properties apiLibraryProperties
}
func CcApiLibraryFactory() android.Module {
module, decorator := NewLibrary(android.DeviceSupported)
apiLibraryDecorator := &apiLibraryDecorator{
libraryDecorator: decorator,
}
apiLibraryDecorator.BuildOnlyShared()
module.stl = nil
module.sanitize = nil
decorator.disableStripping()
module.compiler = nil
module.linker = apiLibraryDecorator
module.installer = nil
module.library = apiLibraryDecorator
module.AddProperties(&module.Properties, &apiLibraryDecorator.properties)
// Prevent default system libs (libc, libm, and libdl) from being linked
if apiLibraryDecorator.baseLinker.Properties.System_shared_libs == nil {
apiLibraryDecorator.baseLinker.Properties.System_shared_libs = []string{}
}
apiLibraryDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
apiLibraryDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
module.Init()
return module
}
func (d *apiLibraryDecorator) Name(basename string) string {
return basename + multitree.GetApiImportSuffix()
}
// Export include dirs without checking for existence.
// The directories are not guaranteed to exist during Soong analysis.
func (d *apiLibraryDecorator) exportIncludes(ctx ModuleContext) {
exporterProps := d.flagExporter.Properties
for _, dir := range exporterProps.Export_include_dirs.GetOrDefault(ctx, nil) {
d.dirs = append(d.dirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
}
// system headers
for _, dir := range exporterProps.Export_system_include_dirs {
d.systemDirs = append(d.systemDirs, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), dir))
}
}
func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) {
d.baseLinker.linkerInit(ctx)
if d.hasNDKStubs() {
// Set SDK version of module as current
ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current")
// Add NDK stub as NDK known libs
name := ctx.ModuleName()
ndkKnownLibsLock.Lock()
ndkKnownLibs := getNDKKnownLibs(ctx.Config())
if !inList(name, *ndkKnownLibs) {
*ndkKnownLibs = append(*ndkKnownLibs, name)
}
ndkKnownLibsLock.Unlock()
}
}
func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
m, _ := ctx.Module().(*Module)
var in android.Path
// src might not exist during the beginning of soong analysis in Multi-tree
if src := String(d.properties.Src); src != "" {
in = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), src)
}
libName := m.BaseModuleName() + multitree.GetApiImportSuffix()
load_cc_variant := func(apiVariantModule string) {
var mod android.Module
ctx.VisitDirectDeps(func(depMod android.Module) {
if depMod.Name() == apiVariantModule {
mod = depMod
libName = apiVariantModule
}
})
if mod != nil {
variantMod, ok := mod.(*CcApiVariant)
if ok {
in = variantMod.Src()
// Copy LLDNK properties to cc_api_library module
exportIncludeDirs := append(d.libraryDecorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil),
variantMod.exportProperties.Export_include_dirs...)
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](
nil,
[]proptools.ConfigurableCase[[]string]{
proptools.NewConfigurableCase[[]string](nil, &exportIncludeDirs),
},
)
// Export headers as system include dirs if specified. Mostly for libc
if Bool(variantMod.exportProperties.Export_headers_as_system) {
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
d.libraryDecorator.flagExporter.Properties.Export_include_dirs.GetOrDefault(ctx, nil)...)
d.libraryDecorator.flagExporter.Properties.Export_include_dirs = proptools.NewConfigurable[[]string](nil, nil)
}
}
}
}
if m.InVendorOrProduct() && d.hasLLNDKStubs() {
// LLNDK variant
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "llndk", ""))
} else if m.IsSdkVariant() {
// NDK Variant
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion()))
} else if m.IsStubs() {
// APEX Variant
load_cc_variant(BuildApiVariantName(m.BaseModuleName(), "apex", m.StubsVersion()))
}
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
d.exportIncludes(ctx)
d.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
d.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
d.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
d.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
d.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
if in == nil {
ctx.PropertyErrorf("src", "Unable to locate source property")
return nil
}
// Make the _compilation_ of rdeps have an order-only dep on cc_api_library.src (an .so file)
// The .so file itself has an order-only dependency on the headers contributed by this library.
// Creating this dependency ensures that the headers are assembled before compilation of rdeps begins.
d.libraryDecorator.reexportDeps(in)
d.libraryDecorator.flagExporter.setProvider(ctx)
d.unstrippedOutputFile = in
libName += flags.Toolchain.ShlibSuffix()
tocFile := android.PathForModuleOut(ctx, libName+".toc")
d.tocFile = android.OptionalPathForPath(tocFile)
TransformSharedObjectToToc(ctx, in, tocFile)
outputFile := android.PathForModuleOut(ctx, libName)
// TODO(b/270485584) This copies with a new name, just to avoid conflict with prebuilts.
// We can just use original input if there is any way to avoid name conflict without copy.
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Description: "API surface imported library",
Input: in,
Output: outputFile,
Args: map[string]string{
"cpFlags": "-L",
},
})
android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
SharedLibrary: outputFile,
Target: ctx.Target(),
TableOfContents: d.tocFile,
})
d.shareStubs(ctx)
return outputFile
}
// Share additional information about stub libraries with provider
func (d *apiLibraryDecorator) shareStubs(ctx ModuleContext) {
stubs := ctx.GetDirectDepsWithTag(stubImplDepTag)
if len(stubs) > 0 {
var stubsInfo []SharedStubLibrary
for _, stub := range stubs {
stubInfo, _ := android.OtherModuleProvider(ctx, stub, SharedLibraryInfoProvider)
flagInfo, _ := android.OtherModuleProvider(ctx, stub, FlagExporterInfoProvider)
stubsInfo = append(stubsInfo, SharedStubLibrary{
Version: moduleLibraryInterface(stub).stubsVersion(),
SharedLibraryInfo: stubInfo,
FlagExporterInfo: flagInfo,
})
}
android.SetProvider(ctx, SharedLibraryStubsProvider, SharedLibraryStubsInfo{
SharedStubLibraries: stubsInfo,
IsLLNDK: ctx.IsLlndk(),
})
}
}
func (d *apiLibraryDecorator) availableFor(what string) bool {
// Stub from API surface should be available for any APEX.
return true
}
func (d *apiLibraryDecorator) hasApexStubs() bool {
for _, variant := range d.properties.Variants {
if strings.HasPrefix(variant, "apex") {
return true
}
}
return false
}
func (d *apiLibraryDecorator) hasStubsVariants() bool {
return d.hasApexStubs()
}
func (d *apiLibraryDecorator) stubsVersions(ctx android.BaseModuleContext) []string {
m, ok := ctx.Module().(*Module)
if !ok {
return nil
}
// TODO(b/244244438) Create more version information for NDK and APEX variations
// NDK variants
if m.IsSdkVariant() {
// TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
if d.hasNDKStubs() {
return d.getNdkVersions()
}
}
if d.hasLLNDKStubs() && m.InVendorOrProduct() {
// LLNDK libraries only need a single stubs variant.
return []string{android.FutureApiLevel.String()}
}
stubsVersions := d.getStubVersions()
if len(stubsVersions) != 0 {
return stubsVersions
}
if m.MinSdkVersion() == "" {
return nil
}
firstVersion, err := nativeApiLevelFromUser(ctx,
m.MinSdkVersion())
if err != nil {
return nil
}
return ndkLibraryVersions(ctx, firstVersion)
}
func (d *apiLibraryDecorator) hasLLNDKStubs() bool {
return inList("llndk", d.properties.Variants)
}
func (d *apiLibraryDecorator) hasNDKStubs() bool {
for _, variant := range d.properties.Variants {
if ndkVariantRegex.MatchString(variant) {
return true
}
}
return false
}
func (d *apiLibraryDecorator) getNdkVersions() []string {
ndkVersions := []string{}
for _, variant := range d.properties.Variants {
if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
ndkVersions = append(ndkVersions, match[1])
}
}
return ndkVersions
}
func (d *apiLibraryDecorator) getStubVersions() []string {
stubVersions := []string{}
for _, variant := range d.properties.Variants {
if match := stubVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
stubVersions = append(stubVersions, match[1])
}
}
return stubVersions
}
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
// header libraries. The module will replace any dependencies to existing
// original header libraries.
type apiHeadersDecorator struct {
*libraryDecorator
}
func CcApiHeadersFactory() android.Module {
module, decorator := NewLibrary(android.DeviceSupported)
apiHeadersDecorator := &apiHeadersDecorator{
libraryDecorator: decorator,
}
apiHeadersDecorator.HeaderOnly()
module.stl = nil
module.sanitize = nil
decorator.disableStripping()
module.compiler = nil
module.linker = apiHeadersDecorator
module.installer = nil
// Prevent default system libs (libc, libm, and libdl) from being linked
if apiHeadersDecorator.baseLinker.Properties.System_shared_libs == nil {
apiHeadersDecorator.baseLinker.Properties.System_shared_libs = []string{}
}
apiHeadersDecorator.baseLinker.Properties.No_libcrt = BoolPtr(true)
apiHeadersDecorator.baseLinker.Properties.Nocrt = BoolPtr(true)
module.Init()
return module
}
func (d *apiHeadersDecorator) Name(basename string) string {
return basename + multitree.GetApiImportSuffix()
}
func (d *apiHeadersDecorator) availableFor(what string) bool {
// Stub from API surface should be available for any APEX.
return true
}
type ccApiexportProperties struct {
Src *string `android:"arch_variant"`
Variant *string
Version *string
}
type variantExporterProperties struct {
// Header directory to export
Export_include_dirs []string `android:"arch_variant"`
// Export all headers as system include
Export_headers_as_system *bool
}
type CcApiVariant struct {
android.ModuleBase
properties ccApiexportProperties
exportProperties variantExporterProperties
src android.Path
}
var _ android.Module = (*CcApiVariant)(nil)
var _ android.ImageInterface = (*CcApiVariant)(nil)
func CcApiVariantFactory() android.Module {
module := &CcApiVariant{}
module.AddProperties(&module.properties)
module.AddProperties(&module.exportProperties)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
return module
}
func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// No need to build
if String(v.properties.Src) == "" {
ctx.PropertyErrorf("src", "src is a required property")
}
// Skip the existence check of the stub prebuilt file.
// The file is not guaranteed to exist during Soong analysis.
// Build orchestrator will be responsible for creating a connected ninja graph.
v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), String(v.properties.Src))
}
func (v *CcApiVariant) Name() string {
version := String(v.properties.Version)
return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version)
}
func (v *CcApiVariant) Src() android.Path {
return v.src
}
func BuildApiVariantName(baseName string, variant string, version string) string {
names := []string{baseName, variant}
if version != "" {
names = append(names, version)
}
return strings.Join(names[:], ".") + multitree.GetApiImportSuffix()
}
// Implement ImageInterface to generate image variants
func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
func (v *CcApiVariant) VendorVariantNeeded(ctx android.BaseModuleContext) bool {
return String(v.properties.Variant) == "llndk"
}
func (v *CcApiVariant) ProductVariantNeeded(ctx android.BaseModuleContext) bool {
return String(v.properties.Variant) == "llndk"
}
func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
return inList(String(v.properties.Variant), []string{"ndk", "apex"})
}
func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil }
func (v *CcApiVariant) SetImageVariation(ctx android.BaseModuleContext, variation string) {
}

View File

@@ -645,7 +645,7 @@ func (linker *baseLinker) link(ctx ModuleContext,
panic(fmt.Errorf("baseLinker doesn't know how to link"))
}
func (linker *baseLinker) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
func (linker *baseLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
eval := module.ConfigurableEvaluator(ctx)
specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs.GetOrDefault(eval, nil)...)

View File

@@ -203,7 +203,7 @@ func (object *objectLinker) link(ctx ModuleContext,
return outputFile
}
func (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigAndErrorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
func (object *objectLinker) linkerSpecifiedDeps(ctx android.ConfigurableEvaluatorContext, module *Module, specifiedDeps specifiedDeps) specifiedDeps {
eval := module.ConfigurableEvaluator(ctx)
specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, object.Properties.Shared_libs.GetOrDefault(eval, nil)...)

View File

@@ -51,13 +51,6 @@ func (sdkTransitionMutator) Split(ctx android.BaseModuleContext) []string {
return []string{""}
}
}
case *CcApiVariant:
ccApiVariant, _ := ctx.Module().(*CcApiVariant)
if String(ccApiVariant.properties.Variant) == "ndk" {
return []string{"sdk"}
} else {
return []string{""}
}
}
return []string{""}
@@ -84,11 +77,6 @@ func (sdkTransitionMutator) IncomingTransition(ctx android.IncomingTransitionCon
return incomingVariation
}
}
case *CcApiVariant:
ccApiVariant, _ := ctx.Module().(*CcApiVariant)
if String(ccApiVariant.properties.Variant) == "ndk" {
return "sdk"
}
}
if ctx.IsAddingDependency() {

View File

@@ -20,7 +20,6 @@ import (
"android/soong/android"
"android/soong/genrule"
"android/soong/multitree"
)
func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
@@ -29,9 +28,6 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
RegisterBinaryBuildComponents(ctx)
RegisterLibraryBuildComponents(ctx)
RegisterLibraryHeadersBuildComponents(ctx)
RegisterLibraryStubBuildComponents(ctx)
multitree.RegisterApiImportsModule(ctx)
ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)

1
docs/OWNERS Normal file
View File

@@ -0,0 +1 @@
per-file map_files.md = danalbert@google.com

View File

@@ -88,12 +88,17 @@ but is useful when developing APIs for an unknown future release.
### introduced
Indicates the version in which an API was first introduced. For example,
`introduced=21` specifies that the API was first added (or first made public) in
API level 21. This tag can be applied to either a version definition or an
individual symbol. If applied to a version, all symbols contained in the version
will have the tag applied. An `introduced` tag on a symbol overrides the value
set for the version, if both are defined.
Indicates the version in which an API was first introduced in the NDK. For
example, `introduced=21` specifies that the API was first added (or first made
public) in API level 21. This tag can be applied to either a version definition
or an individual symbol. If applied to a version, all symbols contained in the
version will have the tag applied. An `introduced` tag on a symbol overrides the
value set for the version, if both are defined.
The `introduced` tag should only be used with NDK APIs. Other API surface tags
(such as `apex`) will override `introduced`. APIs that are in the NDK should
never use tags like `apex`, and APIs that are not in the NDK should never use
`introduced`.
Note: The map file alone does not contain all the information needed to
determine which API level an API was added in. The `first_version` property of

View File

@@ -136,9 +136,6 @@ type filesystemProperties struct {
// Install aconfig_flags.pb file for the modules installed in this partition.
Gen_aconfig_flags_pb *bool
// Update the Base_dir of the $PRODUCT_OUT directory with the packaging files.
Update_product_out *bool
Fsverity fsverityProperties
}
@@ -335,7 +332,7 @@ func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *andr
}
func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
if !proptools.Bool(f.properties.Update_product_out) {
if f.Name() != ctx.Config().SoongDefinedSystemImage() {
return
}
installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName())

View File

@@ -213,6 +213,7 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.InstallFile(v.installDir, v.installFileName(), v.output)
ctx.SetOutputFiles([]android.Path{v.output}, "")
android.SetProvider(ctx, android.AndroidMkInfoProvider, v.prepareAndroidMKProviderInfo())
}
// Returns the embedded shell command that prints the rollback index
@@ -265,20 +266,17 @@ func (v *vbmeta) extractPublicKeys(ctx android.ModuleContext) map[string]android
return result
}
var _ android.AndroidMkEntriesProvider = (*vbmeta)(nil)
// Implements android.AndroidMkEntriesProvider
func (v *vbmeta) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "ETC",
OutputFile: android.OptionalPathForPath(v.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", v.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
},
func (v *vbmeta) prepareAndroidMKProviderInfo() *android.AndroidMkProviderInfo {
providerData := android.AndroidMkProviderInfo{
PrimaryInfo: android.AndroidMkInfo{
Class: "ETC",
OutputFile: android.OptionalPathForPath(v.output),
EntryMap: make(map[string][]string),
},
}}
}
providerData.PrimaryInfo.SetString("LOCAL_MODULE_PATH", v.installDir.String())
providerData.PrimaryInfo.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
return &providerData
}
var _ Filesystem = (*vbmeta)(nil)

View File

@@ -449,7 +449,7 @@ func IsValidFrameworkForModule(targetFramework Framework, lang Lang, moduleFrame
}
}
func IsValid(ctx android.ConfigAndErrorContext, fuzzModule FuzzModule) bool {
func IsValid(ctx android.ConfigurableEvaluatorContext, fuzzModule FuzzModule) bool {
// Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of
// fuzz targets we're going to package anyway.
if !fuzzModule.Enabled(ctx) || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() {

View File

@@ -25,7 +25,6 @@ import (
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -365,11 +364,6 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) {
tools = append(tools, path.Path())
addLocationLabel(tag.label, toolLocation{android.Paths{path.Path()}})
}
case bootstrap.GoBinaryTool:
// A GoBinaryTool provides the install path to a tool, which will be copied.
p := android.PathForGoBinary(ctx, t)
tools = append(tools, p)
addLocationLabel(tag.label, toolLocation{android.Paths{p}})
default:
ctx.ModuleErrorf("%q is not a host tool provider", tool)
return

22
golang/Android.bp Normal file
View File

@@ -0,0 +1,22 @@
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
bootstrap_go_package {
name: "soong-golang",
pkgPath: "android/soong/golang",
deps: [
"blueprint",
"blueprint-pathtools",
"blueprint-bootstrap",
"soong",
"soong-android",
],
srcs: [
"golang.go",
],
testSrcs: [
"golang_test.go",
],
pluginFor: ["soong_build"],
}

122
golang/golang.go Normal file
View File

@@ -0,0 +1,122 @@
// Copyright 2024 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package golang wraps the blueprint blueprint_go_binary and bootstrap_go_binary module types in versions
// that implement android.Module that are used when building in Soong. This simplifies the code in Soong
// so it can always assume modules are an android.Module.
// The original blueprint blueprint_go_binary and bootstrap_go_binary module types are still used during
// bootstrapping, so the Android.bp entries for these module types must be compatible with both the
// original blueprint module types and these wrapped module types.
package golang
import (
"android/soong/android"
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
)
func init() {
// Wrap the blueprint Go module types with Soong ones that interoperate with the rest of the Soong modules.
bootstrap.GoModuleTypesAreWrapped()
RegisterGoModuleTypes(android.InitRegistrationContext)
}
func RegisterGoModuleTypes(ctx android.RegistrationContext) {
ctx.RegisterModuleType("bootstrap_go_package", goPackageModuleFactory)
ctx.RegisterModuleType("blueprint_go_binary", goBinaryModuleFactory)
}
// A GoPackage is a module for building Go packages.
type GoPackage struct {
android.ModuleBase
bootstrap.GoPackage
}
func goPackageModuleFactory() android.Module {
module := &GoPackage{}
module.AddProperties(module.Properties()...)
android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
return module
}
func (g *GoPackage) GenerateBuildActions(ctx blueprint.ModuleContext) {
// The embedded ModuleBase and bootstrap.GoPackage each implement GenerateBuildActions,
// the delegation has to be implemented manually to disambiguate. Call ModuleBase's
// GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call
// bootstrap.GoPackage.GenerateBuildActions.
g.ModuleBase.GenerateBuildActions(ctx)
}
func (g *GoPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
g.GoPackage.GenerateBuildActions(ctx.BlueprintModuleContext())
}
// A GoBinary is a module for building executable binaries from Go sources.
type GoBinary struct {
android.ModuleBase
bootstrap.GoBinary
outputFile android.Path
}
func goBinaryModuleFactory() android.Module {
module := &GoBinary{}
module.AddProperties(module.Properties()...)
android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
return module
}
func (g *GoBinary) GenerateBuildActions(ctx blueprint.ModuleContext) {
// The embedded ModuleBase and bootstrap.GoBinary each implement GenerateBuildActions,
// the delegation has to be implemented manually to disambiguate. Call ModuleBase's
// GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call
// bootstrap.GoBinary.GenerateBuildActions.
g.ModuleBase.GenerateBuildActions(ctx)
}
func (g *GoBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// Install the file in Soong instead of blueprint so that Soong knows about the install rules.
g.GoBinary.SetSkipInstall()
// Run the build actions from the wrapped blueprint bootstrap module.
g.GoBinary.GenerateBuildActions(ctx.BlueprintModuleContext())
// Translate the bootstrap module's string path into a Path
outputFile := android.PathForArbitraryOutput(ctx, android.Rel(ctx, ctx.Config().OutDir(), g.IntermediateFile())).WithoutRel()
g.outputFile = outputFile
installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile)
if !ctx.Config().KatiEnabled() || g.ExportedToMake() {
// Modules in an unexported namespace have no install rule, only add modules in the exported namespaces
// to the blueprint_tools phony rules.
ctx.Phony("blueprint_tools", installPath)
}
ctx.SetOutputFiles(android.Paths{outputFile}, "")
}
func (g *GoBinary) HostToolPath() android.OptionalPath {
return android.OptionalPathForPath(g.outputFile)
}
func (g *GoBinary) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{
{
Class: "EXECUTABLES",
OutputFile: android.OptionalPathForPath(g.outputFile),
Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk",
},
}
}

51
golang/golang_test.go Normal file
View File

@@ -0,0 +1,51 @@
// Copyright 2024 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package golang
import (
"android/soong/android"
"github.com/google/blueprint/bootstrap"
"path/filepath"
"testing"
)
func TestGolang(t *testing.T) {
bp := `
bootstrap_go_package {
name: "gopkg",
pkgPath: "test/pkg",
}
blueprint_go_binary {
name: "gobin",
deps: ["gopkg"],
}
`
result := android.GroupFixturePreparers(
android.PrepareForTestWithArchMutator,
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
RegisterGoModuleTypes(ctx)
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUpBlueprint("bootstrap_deps", bootstrap.BootstrapDeps)
})
}),
).RunTestWithBp(t, bp)
bin := result.ModuleForTests("gobin", result.Config.BuildOSTarget.String())
expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "bin/go/gobin/obj/gobin")
android.AssertPathsRelativeToTopEquals(t, "output files", []string{expected}, bin.OutputFiles(result.TestContext, t, ""))
}

View File

@@ -535,7 +535,8 @@ type Module struct {
linter
// list of the xref extraction files
kytheFiles android.Paths
kytheFiles android.Paths
kytheKotlinFiles android.Paths
hideApexVariantFromMake bool
@@ -1370,7 +1371,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName)
kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName)
kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
if ctx.Failed() {
return
}

View File

@@ -21,7 +21,7 @@ import (
// isActiveModule returns true if the given module should be considered for boot
// jars, i.e. if it's enabled and the preferred one in case of source and
// prebuilt alternatives.
func isActiveModule(ctx android.ConfigAndErrorContext, module android.Module) bool {
func isActiveModule(ctx android.ConfigurableEvaluatorContext, module android.Module) bool {
if !module.Enabled(ctx) {
return false
}

View File

@@ -145,6 +145,7 @@ func init() {
pctx.SourcePathVariable("JmodCmd", "${JavaToolchain}/jmod")
pctx.SourcePathVariable("JrtFsJar", "${JavaHome}/lib/jrt-fs.jar")
pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("KotlinKytheExtractor", "prebuilts/build-tools/${hostPrebuiltTag}/bin/kotlinc_extractor")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
pctx.SourcePathVariable("ResourceProcessorBusyBox", "prebuilts/bazel/common/android_tools/android_tools/all_android_tools_deploy.jar")

View File

@@ -356,12 +356,17 @@ type UsesLibraryDependency interface {
// TODO(jungjw): Move this to kythe.go once it's created.
type xref interface {
XrefJavaFiles() android.Paths
XrefKotlinFiles() android.Paths
}
func (j *Module) XrefJavaFiles() android.Paths {
return j.kytheFiles
}
func (j *Module) XrefKotlinFiles() android.Paths {
return j.kytheKotlinFiles
}
func (d dependencyTag) PropagateAconfigValidation() bool {
return d.static
}
@@ -3304,15 +3309,20 @@ type kytheExtractJavaSingleton struct {
func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var xrefTargets android.Paths
var xrefKotlinTargets android.Paths
ctx.VisitAllModules(func(module android.Module) {
if javaModule, ok := module.(xref); ok {
xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
xrefKotlinTargets = append(xrefKotlinTargets, javaModule.XrefKotlinFiles()...)
}
})
// TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
if len(xrefTargets) > 0 {
ctx.Phony("xref_java", xrefTargets...)
}
if len(xrefKotlinTargets) > 0 {
ctx.Phony("xref_kotlin", xrefKotlinTargets...)
}
}
var Bool = proptools.Bool

View File

@@ -2674,7 +2674,7 @@ func TestDisableFromTextStubForCoverageBuild(t *testing.T) {
android.AssertBoolEquals(t, "stub module expected to depend on from-source stub",
true, CheckModuleHasDependency(t, result.TestContext,
apiScopePublic.stubsLibraryModuleName("foo"), "android_common",
apiScopePublic.sourceStubLibraryModuleName("foo")))
apiScopePublic.sourceStubsLibraryModuleName("foo")))
android.AssertBoolEquals(t, "stub module expected to not depend on from-text stub",
false, CheckModuleHasDependency(t, result.TestContext,

View File

@@ -64,6 +64,29 @@ var kotlinc = pctx.AndroidRemoteStaticRule("kotlinc", android.RemoteRuleSupports
"kotlincFlags", "classpath", "srcJars", "commonSrcFilesArg", "srcJarDir", "classesDir",
"headerClassesDir", "headerJar", "kotlinJvmTarget", "kotlinBuildFile", "emptyDir", "name")
var kotlinKytheExtract = pctx.AndroidStaticRule("kotlinKythe",
// TODO (b/265428637): To prevent kotlinc version skew between android builds and internal kotlin indexers (g3), consider embedding the kotlinc used by android into the kzip file.
// This has an impact on .kzip sizes, so defer that for now.
blueprint.RuleParams{
Command: `rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" -f "*.kt" $srcJars && ` +
`${config.KotlinKytheExtractor} -corpus ${kytheCorpus} --srcs @$out.rsp --srcs @"$srcJarDir/list" $commonSrcFilesList --cp @$classpath -o $out --kotlin_out $outJar ` +
// wrap the additional kotlin args.
// Skip Xbuild file, pass the cp explicitly.
// Skip header jars, those should not have an effect on kythe results.
` --args '${config.KotlincGlobalFlags} ` +
` ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
` $kotlincFlags -jvm-target $kotlinJvmTarget'`,
CommandDeps: []string{
"${config.KotlinKytheExtractor}",
"${config.ZipSyncCmd}",
},
Rspfile: "$out.rsp",
RspfileContent: "$in",
},
"classpath", "kotlincFlags", "commonSrcFilesList", "kotlinJvmTarget", "outJar", "srcJars", "srcJarDir",
)
func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Paths) android.OptionalPath {
if len(commonSrcFiles) > 0 {
// The list of common_srcs may be too long to put on the command line, but
@@ -81,7 +104,7 @@ func kotlinCommonSrcsList(ctx android.ModuleContext, commonSrcFiles android.Path
}
// kotlinCompile takes .java and .kt sources and srcJars, and compiles the .kt sources into a classes jar in outputFile.
func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath,
func (j *Module) kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile android.WritablePath,
srcFiles, commonSrcFiles, srcJars android.Paths,
flags javaBuilderFlags) {
@@ -127,6 +150,31 @@ func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile andro
"name": kotlinName,
},
})
// Emit kythe xref rule
if (ctx.Config().EmitXrefRules()) && ctx.Module() == ctx.PrimaryModule() {
extractionFile := outputFile.ReplaceExtension(ctx, "kzip")
args := map[string]string{
"classpath": classpathRspFile.String(),
"kotlincFlags": flags.kotlincFlags,
"kotlinJvmTarget": flags.javaVersion.StringForKotlinc(),
"outJar": outputFile.String(),
"srcJars": strings.Join(srcJars.Strings(), " "),
"srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars.xref").String(),
}
if commonSrcsList.Valid() {
args["commonSrcFilesList"] = "--srcs @" + commonSrcsList.String()
}
ctx.Build(pctx, android.BuildParams{
Rule: kotlinKytheExtract,
Description: "kotlinKythe",
Output: extractionFile,
Inputs: srcFiles,
Implicits: deps,
Args: args,
})
j.kytheKotlinFiles = append(j.kytheKotlinFiles, extractionFile)
}
}
var kaptStubs = pctx.AndroidRemoteStaticRule("kaptStubs", android.RemoteRuleSupports{Goma: true},

View File

@@ -248,7 +248,7 @@ func (scope *apiScope) apiLibraryModuleName(baseName string) string {
return scope.stubsLibraryModuleName(baseName) + ".from-text"
}
func (scope *apiScope) sourceStubLibraryModuleName(baseName string) string {
func (scope *apiScope) sourceStubsLibraryModuleName(baseName string) string {
return scope.stubsLibraryModuleName(baseName) + ".from-source"
}
@@ -830,16 +830,6 @@ func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext,
}
type commonToSdkLibraryAndImportProperties struct {
// The naming scheme to use for the components that this module creates.
//
// If not specified then it defaults to "default".
//
// This is a temporary mechanism to simplify conversion from separate modules for each
// component that follow a different naming pattern to the default one.
//
// TODO(b/155480189) - Remove once naming inconsistencies have been resolved.
Naming_scheme *string
// Specifies whether this module can be used as an Android shared library; defaults
// to true.
//
@@ -915,8 +905,6 @@ type commonToSdkLibraryAndImport struct {
scopePaths map[*apiScope]*scopePaths
namingScheme sdkLibraryComponentNamingScheme
commonSdkLibraryProperties commonToSdkLibraryAndImportProperties
// Paths to commonSdkLibraryProperties.Doctag_files
@@ -944,15 +932,6 @@ func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImpor
}
func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
schemeProperty := proptools.StringDefault(c.commonSdkLibraryProperties.Naming_scheme, "default")
switch schemeProperty {
case "default":
c.namingScheme = &defaultNamingScheme{}
default:
ctx.PropertyErrorf("naming_scheme", "expected 'default' but was %q", schemeProperty)
return false
}
namePtr := proptools.StringPtr(c.module.RootLibraryName())
c.sdkLibraryComponentProperties.SdkLibraryName = namePtr
@@ -995,41 +974,41 @@ func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
// Name of the java_library module that compiles the stubs source.
func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.stubsLibraryModuleName(apiScope, baseName)
return apiScope.stubsLibraryModuleName(baseName)
}
// Name of the java_library module that compiles the exportable stubs source.
func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.exportableStubsLibraryModuleName(apiScope, baseName)
return apiScope.exportableStubsLibraryModuleName(baseName)
}
// Name of the droidstubs module that generates the stubs source and may also
// generate/check the API.
func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.stubsSourceModuleName(apiScope, baseName)
return apiScope.stubsSourceModuleName(baseName)
}
// Name of the java_api_library module that generates the from-text stubs source
// and compiles to a jar file.
func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.apiLibraryModuleName(apiScope, baseName)
return apiScope.apiLibraryModuleName(baseName)
}
// Name of the java_library module that compiles the stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.sourceStubsLibraryModuleName(apiScope, baseName)
return apiScope.sourceStubsLibraryModuleName(baseName)
}
// Name of the java_library module that compiles the exportable stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.RootLibraryName()
return c.namingScheme.exportableSourceStubsLibraryModuleName(apiScope, baseName)
return apiScope.exportableSourceStubsLibraryModuleName(baseName)
}
// The component names for different outputs of the java_sdk_library.
@@ -2395,50 +2374,6 @@ func (module *SdkLibrary) defaultsToStubs() bool {
return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs)
}
// Defines how to name the individual component modules the sdk library creates.
type sdkLibraryComponentNamingScheme interface {
stubsLibraryModuleName(scope *apiScope, baseName string) string
stubsSourceModuleName(scope *apiScope, baseName string) string
apiLibraryModuleName(scope *apiScope, baseName string) string
sourceStubsLibraryModuleName(scope *apiScope, baseName string) string
exportableStubsLibraryModuleName(scope *apiScope, baseName string) string
exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string
}
type defaultNamingScheme struct {
}
func (s *defaultNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.stubsLibraryModuleName(baseName)
}
func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string {
return scope.stubsSourceModuleName(baseName)
}
func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName string) string {
return scope.apiLibraryModuleName(baseName)
}
func (s *defaultNamingScheme) sourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.sourceStubLibraryModuleName(baseName)
}
func (s *defaultNamingScheme) exportableStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.exportableStubsLibraryModuleName(baseName)
}
func (s *defaultNamingScheme) exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.exportableSourceStubsLibraryModuleName(baseName)
}
var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
func moduleStubLinkType(j *Module) (stub bool, ret sdkLinkType) {
kind := android.ToSdkKind(proptools.String(j.properties.Stub_contributing_api))
switch kind {
@@ -3510,7 +3445,6 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
}
}
s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme
s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
s.Compile_dex = sdk.dexProperties.Compile_dex
s.Doctag_paths = sdk.doctagPaths

View File

@@ -422,7 +422,7 @@ func TestJavaSdkLibrary_StubOrImplOnlyLibs(t *testing.T) {
for _, expectation := range expectations {
verify("sdklib.impl", expectation.lib, expectation.on_impl_classpath, expectation.in_impl_combined)
stubName := apiScopePublic.sourceStubLibraryModuleName("sdklib")
stubName := apiScopePublic.sourceStubsLibraryModuleName("sdklib")
verify(stubName, expectation.lib, expectation.on_stub_classpath, expectation.in_stub_combined)
}
}

View File

@@ -1,20 +0,0 @@
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
bootstrap_go_package {
name: "soong-multitree",
pkgPath: "android/soong/multitree",
deps: [
"blueprint",
"soong-android",
],
srcs: [
"api_imports.go",
"api_surface.go",
"export.go",
"metadata.go",
"import.go",
],
pluginFor: ["soong_build"],
}

View File

@@ -1,102 +0,0 @@
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package multitree
import (
"android/soong/android"
"strings"
"github.com/google/blueprint"
)
var (
apiImportNameSuffix = ".apiimport"
)
func init() {
RegisterApiImportsModule(android.InitRegistrationContext)
android.RegisterMakeVarsProvider(pctx, makeVarsProvider)
}
func RegisterApiImportsModule(ctx android.RegistrationContext) {
ctx.RegisterModuleType("api_imports", apiImportsFactory)
}
type ApiImports struct {
android.ModuleBase
properties apiImportsProperties
}
type apiImportsProperties struct {
Shared_libs []string // List of C shared libraries from API surfaces
Header_libs []string // List of C header libraries from API surfaces
Apex_shared_libs []string // List of C shared libraries with APEX stubs
}
// 'api_imports' is a module which describes modules available from API surfaces.
// This module is required to get the list of all imported API modules, because
// it is discouraged to loop and fetch all modules from its type information. The
// only module with name 'api_imports' will be used from the build.
func apiImportsFactory() android.Module {
module := &ApiImports{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
return module
}
func (imports *ApiImports) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// ApiImport module does not generate any build actions
}
type ApiImportInfo struct {
SharedLibs, HeaderLibs, ApexSharedLibs map[string]string
}
var ApiImportsProvider = blueprint.NewMutatorProvider[ApiImportInfo]("deps")
// Store module lists into ApiImportInfo and share it over mutator provider.
func (imports *ApiImports) DepsMutator(ctx android.BottomUpMutatorContext) {
generateNameMapWithSuffix := func(names []string) map[string]string {
moduleNameMap := make(map[string]string)
for _, name := range names {
moduleNameMap[name] = name + apiImportNameSuffix
}
return moduleNameMap
}
sharedLibs := generateNameMapWithSuffix(imports.properties.Shared_libs)
headerLibs := generateNameMapWithSuffix(imports.properties.Header_libs)
apexSharedLibs := generateNameMapWithSuffix(imports.properties.Apex_shared_libs)
android.SetProvider(ctx, ApiImportsProvider, ApiImportInfo{
SharedLibs: sharedLibs,
HeaderLibs: headerLibs,
ApexSharedLibs: apexSharedLibs,
})
}
func GetApiImportSuffix() string {
return apiImportNameSuffix
}
func makeVarsProvider(ctx android.MakeVarsContext) {
ctx.VisitAllModules(func(m android.Module) {
if i, ok := m.(*ApiImports); ok {
ctx.Strict("API_IMPORTED_SHARED_LIBRARIES", strings.Join(i.properties.Shared_libs, " "))
ctx.Strict("API_IMPORTED_HEADER_LIBRARIES", strings.Join(i.properties.Header_libs, " "))
}
})
}

View File

@@ -1,109 +0,0 @@
// Copyright 2021 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package multitree
import (
"android/soong/android"
"github.com/google/blueprint"
)
var (
pctx = android.NewPackageContext("android/soong/multitree")
)
func init() {
RegisterApiSurfaceBuildComponents(android.InitRegistrationContext)
}
var PrepareForTestWithApiSurface = android.FixtureRegisterWithContext(RegisterApiSurfaceBuildComponents)
func RegisterApiSurfaceBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("api_surface", ApiSurfaceFactory)
}
type ApiSurface struct {
android.ModuleBase
ExportableModuleBase
properties apiSurfaceProperties
taggedOutputs map[string]android.Paths
}
type apiSurfaceProperties struct {
Contributions []string
}
func ApiSurfaceFactory() android.Module {
module := &ApiSurface{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
InitExportableModule(module)
return module
}
func (surface *ApiSurface) DepsMutator(ctx android.BottomUpMutatorContext) {
if surface.properties.Contributions != nil {
ctx.AddVariationDependencies(nil, nil, surface.properties.Contributions...)
}
}
func (surface *ApiSurface) GenerateAndroidBuildActions(ctx android.ModuleContext) {
contributionFiles := make(map[string]android.Paths)
var allOutputs android.Paths
ctx.WalkDeps(func(child, parent android.Module) bool {
if contribution, ok := child.(ApiContribution); ok {
copied := contribution.CopyFilesWithTag(ctx)
for tag, files := range copied {
contributionFiles[child.Name()+"#"+tag] = files
}
for _, paths := range copied {
allOutputs = append(allOutputs, paths...)
}
return false // no transitive dependencies
}
return false
})
// phony target
ctx.Build(pctx, android.BuildParams{
Rule: blueprint.Phony,
Output: android.PathForPhony(ctx, ctx.ModuleName()),
Inputs: allOutputs,
})
surface.taggedOutputs = contributionFiles
ctx.SetOutputFiles(allOutputs, "")
}
func (surface *ApiSurface) TaggedOutputs() map[string]android.Paths {
return surface.taggedOutputs
}
func (surface *ApiSurface) Exportable() bool {
return true
}
var _ Exportable = (*ApiSurface)(nil)
type ApiContribution interface {
// copy files necessaryt to construct an API surface
// For C, it will be map.txt and .h files
// For Java, it will be api.txt
CopyFilesWithTag(ctx android.ModuleContext) map[string]android.Paths // output paths
// Generate Android.bp in out/ to use the exported .txt files
// GenerateBuildFiles(ctx ModuleContext) Paths //output paths
}

View File

@@ -1,66 +0,0 @@
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package multitree
import (
"android/soong/android"
"github.com/google/blueprint/proptools"
)
type moduleExportProperty struct {
// True if the module is exported to the other components in a multi-tree.
// Any components in the multi-tree can import this module to use.
Export *bool
}
type ExportableModuleBase struct {
properties moduleExportProperty
}
type Exportable interface {
// Properties for the exporable module.
exportableModuleProps() *moduleExportProperty
// Check if this module can be exported.
// If this returns false, the module will not be exported regardless of the 'export' value.
Exportable() bool
// Returns 'true' if this module has 'export: true'
// This module will not be exported if it returns 'false' to 'Exportable()' interface even if
// it has 'export: true'.
IsExported() bool
// Map from tags to outputs.
// Each module can tag their outputs for convenience.
TaggedOutputs() map[string]android.Paths
}
type ExportableModule interface {
android.Module
Exportable
}
func InitExportableModule(module ExportableModule) {
module.AddProperties(module.exportableModuleProps())
}
func (m *ExportableModuleBase) exportableModuleProps() *moduleExportProperty {
return &m.properties
}
func (m *ExportableModuleBase) IsExported() bool {
return proptools.Bool(m.properties.Export)
}

View File

@@ -1,96 +0,0 @@
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package multitree
import (
"android/soong/android"
)
var (
nameSuffix = ".imported"
)
type MultitreeImportedModuleInterface interface {
GetMultitreeImportedModuleName() string
}
func init() {
android.RegisterModuleType("imported_filegroup", importedFileGroupFactory)
android.PreArchMutators(RegisterMultitreePreArchMutators)
}
type importedFileGroupProperties struct {
// Imported modules from the other components in a multi-tree
Imported []string
}
type importedFileGroup struct {
android.ModuleBase
properties importedFileGroupProperties
srcs android.Paths
}
func (ifg *importedFileGroup) Name() string {
return ifg.BaseModuleName() + nameSuffix
}
func importedFileGroupFactory() android.Module {
module := &importedFileGroup{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
return module
}
var _ MultitreeImportedModuleInterface = (*importedFileGroup)(nil)
func (ifg *importedFileGroup) GetMultitreeImportedModuleName() string {
// The base module name of the imported filegroup is used as the imported module name
return ifg.BaseModuleName()
}
var _ android.SourceFileProducer = (*importedFileGroup)(nil)
func (ifg *importedFileGroup) Srcs() android.Paths {
return ifg.srcs
}
func (ifg *importedFileGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// srcs from this module must not be used. Adding a dot path to avoid the empty
// source failure. Still soong returns error when a module wants to build against
// this source, which is intended.
ifg.srcs = android.PathsForModuleSrc(ctx, []string{"."})
}
func RegisterMultitreePreArchMutators(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("multitree_imported_rename", MultitreeImportedRenameMutator).Parallel()
}
func MultitreeImportedRenameMutator(ctx android.BottomUpMutatorContext) {
if m, ok := ctx.Module().(MultitreeImportedModuleInterface); ok {
name := m.GetMultitreeImportedModuleName()
if !ctx.OtherModuleExists(name) {
// Provide an empty filegroup not to break the build while updating the metadata.
// In other cases, soong will report an error to guide users to run 'm update-meta'
// first.
if !ctx.Config().TargetMultitreeUpdateMeta() {
ctx.ModuleErrorf("\"%s\" filegroup must be imported.\nRun 'm update-meta' first to import the filegroup.", name)
}
ctx.Rename(name)
}
}
}

View File

@@ -1,74 +0,0 @@
// Copyright 2022 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package multitree
import (
"android/soong/android"
"encoding/json"
)
func init() {
android.RegisterParallelSingletonType("update-meta", UpdateMetaSingleton)
}
func UpdateMetaSingleton() android.Singleton {
return &updateMetaSingleton{}
}
type jsonImported struct {
FileGroups map[string][]string `json:",omitempty"`
}
type metadataJsonFlags struct {
Imported jsonImported `json:",omitempty"`
Exported map[string][]string `json:",omitempty"`
}
type updateMetaSingleton struct {
importedModules []string
generatedMetadataFile android.OutputPath
}
func (s *updateMetaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
metadata := metadataJsonFlags{
Imported: jsonImported{
FileGroups: make(map[string][]string),
},
Exported: make(map[string][]string),
}
ctx.VisitAllModules(func(module android.Module) {
if ifg, ok := module.(*importedFileGroup); ok {
metadata.Imported.FileGroups[ifg.BaseModuleName()] = ifg.properties.Imported
}
if e, ok := module.(ExportableModule); ok {
if e.IsExported() && e.Exportable() {
for tag, files := range e.TaggedOutputs() {
// TODO(b/219846705): refactor this to a dictionary
metadata.Exported[e.Name()+":"+tag] = append(metadata.Exported[e.Name()+":"+tag], files.Strings()...)
}
}
}
})
jsonStr, err := json.Marshal(metadata)
if err != nil {
ctx.Errorf(err.Error())
}
s.generatedMetadataFile = android.PathForOutput(ctx, "multitree", "metadata.json")
android.WriteFileRule(ctx, s.generatedMetadataFile, string(jsonStr))
}
func (s *updateMetaSingleton) MakeVars(ctx android.MakeVarsContext) {
ctx.Strict("MULTITREE_METADATA", s.generatedMetadataFile.String())
}

View File

@@ -24,7 +24,7 @@ import (
var (
pctx = android.NewPackageContext("android/soong/rust/config")
RustDefaultVersion = "1.80.1"
RustDefaultVersion = "1.81.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{

View File

@@ -29,7 +29,6 @@ import (
"android/soong/cc"
cc_config "android/soong/cc/config"
"android/soong/fuzz"
"android/soong/multitree"
"android/soong/rust/config"
)
@@ -1218,47 +1217,6 @@ func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
skipModuleList := map[string]bool{}
var apiImportInfo multitree.ApiImportInfo
hasApiImportInfo := false
ctx.VisitDirectDeps(func(dep android.Module) {
if dep.Name() == "api_imports" {
apiImportInfo, _ = android.OtherModuleProvider(ctx, dep, multitree.ApiImportsProvider)
hasApiImportInfo = true
}
})
if hasApiImportInfo {
targetStubModuleList := map[string]string{}
targetOrigModuleList := map[string]string{}
// Search for dependency which both original module and API imported library with APEX stub exists
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if apiLibrary, ok := apiImportInfo.ApexSharedLibs[depName]; ok {
targetStubModuleList[apiLibrary] = depName
}
})
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if origLibrary, ok := targetStubModuleList[depName]; ok {
targetOrigModuleList[origLibrary] = depName
}
})
// Decide which library should be used between original and API imported library
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
if apiLibrary, ok := targetOrigModuleList[depName]; ok {
if cc.ShouldUseStubForApex(ctx, dep) {
skipModuleList[depName] = true
} else {
skipModuleList[apiLibrary] = true
}
}
})
}
var transitiveAndroidMkSharedLibs []*android.DepSet[string]
var directAndroidMkSharedLibs []string
@@ -1609,13 +1567,6 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
deps := mod.deps(ctx)
var commonDepVariations []blueprint.Variation
apiImportInfo := cc.GetApiImports(mod, actx)
if mod.usePublicApi() || mod.useVendorApi() {
for idx, lib := range deps.SharedLibs {
deps.SharedLibs[idx] = cc.GetReplaceModuleName(lib, apiImportInfo.SharedLibs)
}
}
if ctx.Os() == android.Android {
deps.SharedLibs, _ = cc.FilterNdkLibs(mod, ctx.Config(), deps.SharedLibs)
}
@@ -1708,15 +1659,7 @@ func (mod *Module) DepsMutator(actx android.BottomUpMutatorContext) {
variations := []blueprint.Variation{
{Mutator: "link", Variation: "shared"},
}
// For core variant, add a dep on the implementation (if it exists) and its .apiimport (if it exists)
// GenerateAndroidBuildActions will pick the correct impl/stub based on the api_domain boundary
if _, ok := apiImportInfo.ApexSharedLibs[name]; !ok || ctx.OtherModuleExists(name) {
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
}
if apiLibraryName, ok := apiImportInfo.ApexSharedLibs[name]; ok {
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, apiLibraryName, version, false)
}
cc.AddSharedLibDependenciesWithVersions(ctx, mod, variations, depTag, name, version, false)
}
for _, lib := range deps.WholeStaticLibs {

View File

@@ -1703,61 +1703,6 @@ java_sdk_library_import {
)
}
func TestSnapshotWithJavaSdkLibrary_NamingScheme(t *testing.T) {
result := android.GroupFixturePreparers(prepareForSdkTestWithJavaSdkLibrary).RunTestWithBp(t, `
sdk {
name: "mysdk",
java_sdk_libs: ["myjavalib"],
}
java_sdk_library {
name: "myjavalib",
apex_available: ["//apex_available:anyapex"],
srcs: ["Test.java"],
sdk_version: "current",
naming_scheme: "default",
public: {
enabled: true,
},
}
`)
CheckSnapshot(t, result, "mysdk", "",
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
apex_contributions_defaults {
name: "mysdk.contributions",
contents: ["prebuilt_myjavalib"],
}
java_sdk_library_import {
name: "myjavalib",
prefer: false,
visibility: ["//visibility:public"],
apex_available: ["//apex_available:anyapex"],
naming_scheme: "default",
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
}
`),
checkAllCopyRules(`
.intermediates/myjavalib.stubs.exportable/android_common/combined/myjavalib.stubs.exportable.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
.intermediates/myjavalib.stubs.source/android_common/exportable/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
),
)
}
func TestSnapshotWithJavaSdkLibrary_DoctagFiles(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJavaSdkLibrary,

View File

@@ -84,20 +84,6 @@ type sdkProperties struct {
// True if this is a module_exports (or module_exports_snapshot) module type.
Module_exports bool `blueprint:"mutated"`
// The additional visibility to add to the prebuilt modules to allow them to
// reference each other.
//
// This can only be used to widen the visibility of the members:
//
// * Specifying //visibility:public here will make all members visible and
// essentially ignore their own visibility.
// * Specifying //visibility:private here is an error.
// * Specifying any other rule here will add it to the members visibility and
// be output to the member prebuilt in the snapshot. Duplicates will be
// dropped. Adding a rule to members that have //visibility:private will
// cause the //visibility:private to be discarded.
Prebuilt_visibility []string
}
// sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.)
@@ -130,8 +116,6 @@ func newSdkModule(moduleExports bool) *sdk {
s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties, &traitsWrapper)
// Make sure that the prebuilt visibility property is verified for errors.
android.AddVisibilityProperty(s, "prebuilt_visibility", &s.properties.Prebuilt_visibility)
android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(s)
android.AddLoadHook(s, func(ctx android.LoadHookContext) {

View File

@@ -53,9 +53,6 @@ func TestSnapshotVisibility(t *testing.T) {
// generated sdk_snapshot.
":__subpackages__",
],
prebuilt_visibility: [
"//prebuilts/mysdk",
],
java_header_libs: [
"myjavalib",
"mypublicjavalib",
@@ -162,18 +159,6 @@ java_import {
`))
}
func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) {
testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, `
sdk {
name: "mysdk",
prebuilt_visibility: [
"//foo",
"//visibility:private",
],
}
`)
}
func TestSdkInstall(t *testing.T) {
sdk := `
sdk {

View File

@@ -22,7 +22,6 @@ import (
"sort"
"strings"
"android/soong/apex"
"android/soong/cc"
"android/soong/java"
@@ -1137,9 +1136,6 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType
apexAvailable = []string{android.AvailableToPlatform}
}
// Add in any baseline apex available settings.
apexAvailable = append(apexAvailable, apex.BaselineApexAvailable(member.Name())...)
// Remove duplicates and sort.
apexAvailable = android.FirstUniqueStrings(apexAvailable)
sort.Strings(apexAvailable)
@@ -1993,14 +1989,6 @@ func (m *memberContext) IsTargetBuildBeforeTiramisu() bool {
return m.builder.targetBuildRelease.EarlierThan(buildReleaseT)
}
func (m *memberContext) Config() android.Config {
return m.sdkMemberContext.Config()
}
func (m *memberContext) OtherModulePropertyErrorf(module android.Module, property string, fmt string, args ...interface{}) {
m.sdkMemberContext.OtherModulePropertyErrorf(module, property, fmt, args)
}
var _ android.SdkMemberContext = (*memberContext)(nil)
func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModule *bpModule) {

View File

@@ -25,6 +25,8 @@ var androidmk_denylist []string = []string{
"dalvik/",
"developers/",
"development/",
"device/common/",
"device/google_car/",
"device/sample/",
"frameworks/",
// Do not block other directories in kernel/, see b/319658303.
@@ -41,6 +43,15 @@ var androidmk_denylist []string = []string{
"trusty/",
// Add back toolchain/ once defensive Android.mk files are removed
//"toolchain/",
"vendor/google_contexthub/",
"vendor/google_data/",
"vendor/google_elmyra/",
"vendor/google_mhl/",
"vendor/google_pdk/",
"vendor/google_testing/",
"vendor/partner_testing/",
"vendor/partner_tools/",
"vendor/pdk/",
}
func blockAndroidMks(ctx Context, androidMks []string) {

View File

@@ -1375,8 +1375,10 @@ func (c *configImpl) shouldCleanupRBELogsDir() bool {
// Perform a log directory cleanup only when the log directory
// is auto created by the build rather than user-specified.
for _, f := range []string{"RBE_proxy_log_dir", "FLAG_output_dir"} {
if _, ok := c.environ.Get(f); ok {
return false
if v, ok := c.environ.Get(f); ok {
if v != c.rbeTmpDir() {
return false
}
}
}
return true