Merge "Remove fallback code path for missing BCP fragments that is no longer necessary."
diff --git a/android/arch.go b/android/arch.go
index f7eb963..ddc082b 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -631,8 +631,7 @@
image := base.commonProperties.ImageVariation
// Filter NativeBridge targets unless they are explicitly supported.
// Skip creating native bridge variants for non-core modules.
- if os == Android &&
- !(Bool(base.commonProperties.Native_bridge_supported) && image == CoreVariation) {
+ if os == Android && !(base.IsNativeBridgeSupported() && image == CoreVariation) {
var targets []Target
for _, t := range osTargets {
diff --git a/android/bazel.go b/android/bazel.go
index 22846e8..facd116 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -61,8 +61,8 @@
HandcraftedLabel() string
GetBazelLabel(ctx BazelConversionPathContext, module blueprint.Module) string
ConvertWithBp2build(ctx BazelConversionPathContext) bool
+ convertWithBp2build(ctx BazelConversionPathContext, module blueprint.Module) bool
GetBazelBuildFileContents(c Config, path, name string) (string, error)
- ConvertedToBazel(ctx BazelConversionPathContext) bool
}
// BazelModule is a lightweight wrapper interface around Module for Bazel-convertible modules.
@@ -312,9 +312,10 @@
if !ctx.Config().BazelContext.BazelEnabled() {
return false
}
- if len(b.GetBazelLabel(ctx, ctx.Module())) == 0 {
+ if !convertedToBazel(ctx, ctx.Module()) {
return false
}
+
if GenerateCcLibraryStaticOnly(ctx) {
// Don't use partially-converted cc_library targets in mixed builds,
// since mixed builds would generally rely on both static and shared
@@ -324,20 +325,33 @@
return !mixedBuildsDisabled[ctx.Module().Name()]
}
+// ConvertedToBazel returns whether this module has been converted (with bp2build or manually) to Bazel.
+func convertedToBazel(ctx BazelConversionPathContext, module blueprint.Module) bool {
+ b, ok := module.(Bazelable)
+ if !ok {
+ return false
+ }
+ return b.convertWithBp2build(ctx, module) || b.HasHandcraftedLabel()
+}
+
// ConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build.
func (b *BazelModuleBase) ConvertWithBp2build(ctx BazelConversionPathContext) bool {
- if bp2buildModuleDoNotConvert[ctx.Module().Name()] {
+ return b.convertWithBp2build(ctx, ctx.Module())
+}
+
+func (b *BazelModuleBase) convertWithBp2build(ctx BazelConversionPathContext, module blueprint.Module) bool {
+ if bp2buildModuleDoNotConvert[module.Name()] {
return false
}
// Ensure that the module type of this module has a bp2build converter. This
// prevents mixed builds from using auto-converted modules just by matching
// the package dir; it also has to have a bp2build mutator as well.
- if ctx.Config().bp2buildModuleTypeConfig[ctx.ModuleType()] == false {
+ if ctx.Config().bp2buildModuleTypeConfig[ctx.OtherModuleType(module)] == false {
return false
}
- packagePath := ctx.ModuleDir()
+ packagePath := ctx.OtherModuleDir(module)
config := ctx.Config().bp2buildPackageConfig
// This is a tristate value: true, false, or unset.
@@ -408,9 +422,3 @@
}
return string(data[:]), nil
}
-
-// ConvertedToBazel returns whether this module has been converted to Bazel, whether automatically
-// or manually
-func (b *BazelModuleBase) ConvertedToBazel(ctx BazelConversionPathContext) bool {
- return b.ConvertWithBp2build(ctx) || b.HasHandcraftedLabel()
-}
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index a4bd2ef..ccbc156 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -75,9 +75,10 @@
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
ModuleFromName(name string) (blueprint.Module, bool)
Module() Module
- ModuleType() string
+ OtherModuleType(m blueprint.Module) string
OtherModuleName(m blueprint.Module) string
OtherModuleDir(m blueprint.Module) string
+ AddUnconvertedBp2buildDep(string)
}
// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
@@ -345,6 +346,9 @@
if m == nil {
panic(fmt.Errorf("No module named %q found, but was a direct dep of %q", dep, ctx.Module().Name()))
}
+ if !convertedToBazel(ctx, m) {
+ ctx.AddUnconvertedBp2buildDep(dep)
+ }
otherLabel := bazelModuleLabel(ctx, m, tag)
label := bazelModuleLabel(ctx, ctx.Module(), "")
if isWholeLibs {
@@ -363,11 +367,10 @@
func bazelModuleLabel(ctx BazelConversionPathContext, module blueprint.Module, tag string) string {
// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
- b, ok := module.(Bazelable)
- // TODO(b/181155349): perhaps return an error here if the module can't be/isn't being converted
- if !ok || !b.ConvertedToBazel(ctx) {
+ if !convertedToBazel(ctx, module) {
return bp2buildModuleLabel(ctx, module)
}
+ b, _ := module.(Bazelable)
return b.GetBazelLabel(ctx, module)
}
diff --git a/android/config.go b/android/config.go
index 993aaa7..3e41fbb 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1659,20 +1659,6 @@
return ConfiguredJarList{apexes, jars}
}
-// Append a list of (apex, jar) pairs to the list.
-func (l *ConfiguredJarList) AppendList(other ConfiguredJarList) ConfiguredJarList {
- apexes := make([]string, 0, l.Len()+other.Len())
- jars := make([]string, 0, l.Len()+other.Len())
-
- apexes = append(apexes, l.apexes...)
- jars = append(jars, l.jars...)
-
- apexes = append(apexes, other.apexes...)
- jars = append(jars, other.jars...)
-
- return ConfiguredJarList{apexes, jars}
-}
-
// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs.
func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList {
apexes := make([]string, 0, l.Len())
diff --git a/android/licenses.go b/android/licenses.go
index 7ee78c7..bcd85f9 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -48,7 +48,7 @@
// License modules, i.e. modules depended upon via a licensesTag, must be automatically added to
// any sdk/module_exports to which their referencing module is a member.
- _ SdkMemberTypeDependencyTag = licensesTag
+ _ SdkMemberDependencyTag = licensesTag
)
// Describes the property provided by a module to reference applicable licenses.
diff --git a/android/module.go b/android/module.go
index dd6a25a..2803455 100644
--- a/android/module.go
+++ b/android/module.go
@@ -316,6 +316,9 @@
AddMissingDependencies(missingDeps []string)
+ // AddUnconvertedBp2buildDep stores module name of a direct dependency that was not converted via bp2build
+ AddUnconvertedBp2buildDep(dep string)
+
Target() Target
TargetPrimary() bool
@@ -496,6 +499,7 @@
IsConvertedByBp2build() bool
// Bp2buildTargets returns the target(s) generated for Bazel via bp2build for this module
Bp2buildTargets() []bp2buildInfo
+ GetUnconvertedBp2buildDeps() []string
BuildParamsForTests() []BuildParams
RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
@@ -833,6 +837,10 @@
// supported as Soong handles some things within a single target that we may choose to split into
// multiple targets, e.g. renderscript, protos, yacc within a cc module.
Bp2buildInfo []bp2buildInfo `blueprint:"mutated"`
+
+ // UnconvertedBp2buildDep stores the module names of direct dependency that were not converted to
+ // Bazel
+ UnconvertedBp2buildDeps []string `blueprint:"mutated"`
}
type distProperties struct {
@@ -1212,6 +1220,18 @@
return m.commonProperties.Bp2buildInfo
}
+// AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel.
+func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) {
+ unconvertedDeps := &b.Module().base().commonProperties.UnconvertedBp2buildDeps
+ *unconvertedDeps = append(*unconvertedDeps, dep)
+}
+
+// GetUnconvertedBp2buildDeps returns the list of module names of this module's direct dependencies that
+// were not converted to Bazel.
+func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string {
+ return m.commonProperties.UnconvertedBp2buildDeps
+}
+
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
(*d)["Android"] = map[string]interface{}{}
}
@@ -1229,7 +1249,30 @@
}
func (m *ModuleBase) BuildParamsForTests() []BuildParams {
- return m.buildParams
+ // Expand the references to module variables like $flags[0-9]*,
+ // so we do not need to change many existing unit tests.
+ // This looks like undoing the shareFlags optimization in cc's
+ // transformSourceToObj, and should only affects unit tests.
+ vars := m.VariablesForTests()
+ buildParams := append([]BuildParams(nil), m.buildParams...)
+ for i, _ := range buildParams {
+ newArgs := make(map[string]string)
+ for k, v := range buildParams[i].Args {
+ newArgs[k] = v
+ // Replaces both ${flags1} and $flags1 syntax.
+ if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
+ if value, found := vars[v[2:len(v)-1]]; found {
+ newArgs[k] = value
+ }
+ } else if strings.HasPrefix(v, "$") {
+ if value, found := vars[v[1:]]; found {
+ newArgs[k] = value
+ }
+ }
+ }
+ buildParams[i].Args = newArgs
+ }
+ return buildParams
}
func (m *ModuleBase) RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams {
diff --git a/android/mutator.go b/android/mutator.go
index 20ec621..c6b6676 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -532,7 +532,6 @@
BazelProps: bazelProps,
Attrs: attrs,
}
-
t.Module().base().addBp2buildInfo(info)
}
diff --git a/android/sdk.go b/android/sdk.go
index b8f76c1..100f63b 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -22,6 +22,8 @@
"github.com/google/blueprint/proptools"
)
+// RequiredSdks provides access to the set of SDKs required by an APEX and its contents.
+//
// Extracted from SdkAware to make it easier to define custom subsets of the
// SdkAware interface and improve code navigation within the IDE.
//
@@ -30,11 +32,11 @@
// is expected to implement RequiredSdks() by reading its own properties like
// `uses_sdks`.
type RequiredSdks interface {
- // The set of SDKs required by an APEX and its contents.
+ // RequiredSdks returns the set of SDKs required by an APEX and its contents.
RequiredSdks() SdkRefs
}
-// Provided to improve code navigation with the IDE.
+// sdkAwareWithoutModule is provided simply to improve code navigation with the IDE.
type sdkAwareWithoutModule interface {
RequiredSdks
@@ -233,75 +235,85 @@
return false
}
-// Provide support for generating the build rules which will build the snapshot.
+// SnapshotBuilder provides support for generating the build rules which will build the snapshot.
type SnapshotBuilder interface {
- // Copy src to the dest (which is a snapshot relative path) and add the dest
- // to the zip
+ // CopyToSnapshot generates a rule that will copy the src to the dest (which is a snapshot
+ // relative path) and add the dest to the zip.
CopyToSnapshot(src Path, dest string)
- // Return the path to an empty file.
+ // EmptyFile returns the path to an empty file.
//
// This can be used by sdk member types that need to create an empty file in the snapshot, simply
// pass the value returned from this to the CopyToSnapshot() method.
EmptyFile() Path
- // Unzip the supplied zip into the snapshot relative directory destDir.
+ // UnzipToSnapshot generates a rule that will unzip the supplied zip into the snapshot relative
+ // directory destDir.
UnzipToSnapshot(zipPath Path, destDir string)
- // Add a new prebuilt module to the snapshot. The returned module
- // must be populated with the module type specific properties. The following
- // properties will be automatically populated.
+ // AddPrebuiltModule adds a new prebuilt module to the snapshot.
+ //
+ // It is intended to be called from SdkMemberType.AddPrebuiltModule which can add module type
+ // specific properties that are not variant specific. The following properties will be
+ // automatically populated before returning.
//
// * name
// * sdk_member_name
// * prefer
//
- // This will result in two Soong modules being generated in the Android. One
- // that is versioned, coupled to the snapshot version and marked as
- // prefer=true. And one that is not versioned, not marked as prefer=true and
- // will only be used if the equivalently named non-prebuilt module is not
- // present.
+ // Properties that are variant specific will be handled by SdkMemberProperties structure.
+ //
+ // Each module created by this method can be output to the generated Android.bp file in two
+ // different forms, depending on the setting of the SOONG_SDK_SNAPSHOT_VERSION build property.
+ // The two forms are:
+ // 1. A versioned Soong module that is referenced from a corresponding similarly versioned
+ // snapshot module.
+ // 2. An unversioned Soong module that.
+ //
+ // See sdk/update.go for more information.
AddPrebuiltModule(member SdkMember, moduleType string) BpModule
- // The property tag to use when adding a property to a BpModule that contains
- // references to other sdk members. Using this will ensure that the reference
- // is correctly output for both versioned and unversioned prebuilts in the
- // snapshot.
+ // SdkMemberReferencePropertyTag returns a property tag to use when adding a property to a
+ // BpModule that contains references to other sdk members.
//
- // "required: true" means that the property must only contain references
- // to other members of the sdk. Passing a reference to a module that is not a
- // member of the sdk will result in a build error.
+ // Using this will ensure that the reference is correctly output for both versioned and
+ // unversioned prebuilts in the snapshot.
//
- // "required: false" means that the property can contain references to modules
- // that are either members or not members of the sdk. If a reference is to a
- // module that is a non member then the reference is left unchanged, i.e. it
- // is not transformed as references to members are.
+ // "required: true" means that the property must only contain references to other members of the
+ // sdk. Passing a reference to a module that is not a member of the sdk will result in a build
+ // error.
//
- // The handling of the member names is dependent on whether it is an internal or
- // exported member. An exported member is one whose name is specified in one of
- // the member type specific properties. An internal member is one that is added
- // due to being a part of an exported (or other internal) member and is not itself
- // an exported member.
+ // "required: false" means that the property can contain references to modules that are either
+ // members or not members of the sdk. If a reference is to a module that is a non member then the
+ // reference is left unchanged, i.e. it is not transformed as references to members are.
+ //
+ // The handling of the member names is dependent on whether it is an internal or exported member.
+ // An exported member is one whose name is specified in one of the member type specific
+ // properties. An internal member is one that is added due to being a part of an exported (or
+ // other internal) member and is not itself an exported member.
//
// Member names are handled as follows:
- // * When creating the unversioned form of the module the name is left unchecked
- // unless the member is internal in which case it is transformed into an sdk
- // specific name, i.e. by prefixing with the sdk name.
+ // * When creating the unversioned form of the module the name is left unchecked unless the member
+ // is internal in which case it is transformed into an sdk specific name, i.e. by prefixing with
+ // the sdk name.
//
- // * When creating the versioned form of the module the name is transformed into
- // a versioned sdk specific name, i.e. by prefixing with the sdk name and
- // suffixing with the version.
+ // * When creating the versioned form of the module the name is transformed into a versioned sdk
+ // specific name, i.e. by prefixing with the sdk name and suffixing with the version.
//
// e.g.
// bpPropertySet.AddPropertyWithTag("libs", []string{"member1", "member2"}, builder.SdkMemberReferencePropertyTag(true))
SdkMemberReferencePropertyTag(required bool) BpPropertyTag
}
+// BpPropertyTag is a marker interface that can be associated with properties in a BpPropertySet to
+// provide additional information which can be used to customize their behavior.
type BpPropertyTag interface{}
-// A set of properties for use in a .bp file.
+// BpPropertySet is a set of properties for use in a .bp file.
type BpPropertySet interface {
- // Add a property, the value can be one of the following types:
+ // AddProperty adds a property.
+ //
+ // The value can be one of the following types:
// * string
// * array of the above
// * bool
@@ -326,18 +338,18 @@
// * Otherwise, if a property exists with the name then it is an error.
AddProperty(name string, value interface{})
- // Add a property with an associated tag
+ // AddPropertyWithTag adds a property with an associated property tag.
AddPropertyWithTag(name string, value interface{}, tag BpPropertyTag)
- // Add a property set with the specified name and return so that additional
- // properties can be added.
+ // AddPropertySet adds a property set with the specified name and returns it so that additional
+ // properties can be added to it.
AddPropertySet(name string) BpPropertySet
- // Add comment for property (or property set).
+ // AddCommentForProperty adds a comment for the named property (or property set).
AddCommentForProperty(name, text string)
}
-// A .bp module definition.
+// BpModule represents a module definition in a .bp file.
type BpModule interface {
BpPropertySet
@@ -364,19 +376,20 @@
var _ BpPrintable = BpPrintableBase{}
-// An individual member of the SDK, includes all of the variants that the SDK
-// requires.
+// SdkMember is an individual member of the SDK.
+//
+// It includes all of the variants that the SDK depends upon.
type SdkMember interface {
- // The name of the member.
+ // Name returns the name of the member.
Name() string
- // All the variants required by the SDK.
+ // Variants returns all the variants of this module depended upon by the SDK.
Variants() []SdkAware
}
-// SdkMemberTypeDependencyTag is the interface that a tag must implement in order to allow the
+// SdkMemberDependencyTag is the interface that a tag must implement in order to allow the
// dependent module to be automatically added to the sdk.
-type SdkMemberTypeDependencyTag interface {
+type SdkMemberDependencyTag interface {
blueprint.DependencyTag
// SdkMemberType returns the SdkMemberType that will be used to automatically add the child module
@@ -401,37 +414,37 @@
ExportMember() bool
}
-var _ SdkMemberTypeDependencyTag = (*sdkMemberTypeDependencyTag)(nil)
-var _ ReplaceSourceWithPrebuilt = (*sdkMemberTypeDependencyTag)(nil)
+var _ SdkMemberDependencyTag = (*sdkMemberDependencyTag)(nil)
+var _ ReplaceSourceWithPrebuilt = (*sdkMemberDependencyTag)(nil)
-type sdkMemberTypeDependencyTag struct {
+type sdkMemberDependencyTag struct {
blueprint.BaseDependencyTag
memberType SdkMemberType
export bool
}
-func (t *sdkMemberTypeDependencyTag) SdkMemberType(_ Module) SdkMemberType {
+func (t *sdkMemberDependencyTag) SdkMemberType(_ Module) SdkMemberType {
return t.memberType
}
-func (t *sdkMemberTypeDependencyTag) ExportMember() bool {
+func (t *sdkMemberDependencyTag) ExportMember() bool {
return t.export
}
-// Prevent dependencies from the sdk/module_exports onto their members from being
-// replaced with a preferred prebuilt.
-func (t *sdkMemberTypeDependencyTag) ReplaceSourceWithPrebuilt() bool {
+// ReplaceSourceWithPrebuilt prevents dependencies from the sdk/module_exports onto their members
+// from being replaced with a preferred prebuilt.
+func (t *sdkMemberDependencyTag) ReplaceSourceWithPrebuilt() bool {
return false
}
-// DependencyTagForSdkMemberType creates an SdkMemberTypeDependencyTag that will cause any
+// DependencyTagForSdkMemberType creates an SdkMemberDependencyTag that will cause any
// dependencies added by the tag to be added to the sdk as the specified SdkMemberType and exported
// (or not) as specified by the export parameter.
-func DependencyTagForSdkMemberType(memberType SdkMemberType, export bool) SdkMemberTypeDependencyTag {
- return &sdkMemberTypeDependencyTag{memberType: memberType, export: export}
+func DependencyTagForSdkMemberType(memberType SdkMemberType, export bool) SdkMemberDependencyTag {
+ return &sdkMemberDependencyTag{memberType: memberType, export: export}
}
-// Interface that must be implemented for every type that can be a member of an
+// SdkMemberType is the interface that must be implemented for every type that can be a member of an
// sdk.
//
// The basic implementation should look something like this, where ModuleType is
@@ -452,43 +465,43 @@
// ...methods...
//
type SdkMemberType interface {
- // The name of the member type property on an sdk module.
+ // SdkPropertyName returns the name of the member type property on an sdk module.
SdkPropertyName() string
// RequiresBpProperty returns true if this member type requires its property to be usable within
// an Android.bp file.
RequiresBpProperty() bool
- // True if the member type supports the sdk/sdk_snapshot, false otherwise.
+ // UsableWithSdkAndSdkSnapshot returns true if the member type supports the sdk/sdk_snapshot,
+ // false otherwise.
UsableWithSdkAndSdkSnapshot() bool
- // Return true if prebuilt host artifacts may be specific to the host OS. Only
- // applicable to modules where HostSupported() is true. If this is true,
- // snapshots will list each host OS variant explicitly and disable all other
- // host OS'es.
+ // IsHostOsDependent returns true if prebuilt host artifacts may be specific to the host OS. Only
+ // applicable to modules where HostSupported() is true. If this is true, snapshots will list each
+ // host OS variant explicitly and disable all other host OS'es.
IsHostOsDependent() bool
- // Add dependencies from the SDK module to all the module variants the member
- // type contributes to the SDK. `names` is the list of module names given in
- // the member type property (as returned by SdkPropertyName()) in the SDK
- // module. The exact set of variants required is determined by the SDK and its
- // properties. The dependencies must be added with the supplied tag.
+ // AddDependencies adds dependencies from the SDK module to all the module variants the member
+ // type contributes to the SDK. `names` is the list of module names given in the member type
+ // property (as returned by SdkPropertyName()) in the SDK module. The exact set of variants
+ // required is determined by the SDK and its properties. The dependencies must be added with the
+ // supplied tag.
//
// The BottomUpMutatorContext provided is for the SDK module.
AddDependencies(ctx SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string)
- // Return true if the supplied module is an instance of this member type.
+ // IsInstance returns true if the supplied module is an instance of this member type.
//
- // This is used to check the type of each variant before added to the
- // SdkMember. Returning false will cause an error to be logged expaining that
- // the module is not allowed in whichever sdk property it was added.
+ // This is used to check the type of each variant before added to the SdkMember. Returning false
+ // will cause an error to be logged explaining that the module is not allowed in whichever sdk
+ // property it was added.
IsInstance(module Module) bool
// UsesSourceModuleTypeInSnapshot returns true when the AddPrebuiltModule() method returns a
// source module type.
UsesSourceModuleTypeInSnapshot() bool
- // Add a prebuilt module that the sdk will populate.
+ // AddPrebuiltModule is called to add a prebuilt module that the sdk will populate.
//
// The sdk module code generates the snapshot as follows:
//
@@ -525,7 +538,8 @@
//
AddPrebuiltModule(ctx SdkMemberContext, member SdkMember) BpModule
- // Create a structure into which variant specific properties can be added.
+ // CreateVariantPropertiesStruct creates a structure into which variant specific properties can be
+ // added.
CreateVariantPropertiesStruct() SdkMemberProperties
}
@@ -535,7 +549,8 @@
BottomUpMutatorContext
}
-// Base type for SdkMemberType implementations.
+// SdkMemberTypeBase is the base type for SdkMemberType implementations and must be embedded in any
+// struct that implements SdkMemberType.
type SdkMemberTypeBase struct {
PropertyName string
@@ -572,7 +587,7 @@
return b.UseSourceModuleTypeInSnapshot
}
-// Encapsulates the information about registered SdkMemberTypes.
+// SdkMemberTypesRegistry encapsulates the information about registered SdkMemberTypes.
type SdkMemberTypesRegistry struct {
// The list of types sorted by property name.
list []SdkMemberType
@@ -610,14 +625,15 @@
return NewCustomOnceKey(r)
}
-// The set of registered SdkMemberTypes for module_exports modules.
+// ModuleExportsMemberTypes is the set of registered SdkMemberTypes for module_exports modules.
var ModuleExportsMemberTypes = &SdkMemberTypesRegistry{}
-// The set of registered SdkMemberTypes for sdk modules.
+// SdkMemberTypes is the set of registered SdkMemberTypes for sdk modules.
var SdkMemberTypes = &SdkMemberTypesRegistry{}
-// Register an SdkMemberType object to allow them to be used in the sdk and sdk_snapshot module
-// types.
+// RegisterSdkMemberType registers an SdkMemberType object to allow them to be used in the
+// module_exports, module_exports_snapshot and (depending on the value returned from
+// SdkMemberType.UsableWithSdkAndSdkSnapshot) the sdk and sdk_snapshot module types.
func RegisterSdkMemberType(memberType SdkMemberType) {
// All member types are usable with module_exports.
ModuleExportsMemberTypes = ModuleExportsMemberTypes.copyAndAppend(memberType)
@@ -628,7 +644,8 @@
}
}
-// Base structure for all implementations of SdkMemberProperties.
+// SdkMemberPropertiesBase is the base structure for all implementations of SdkMemberProperties and
+// must be embedded in any struct that implements SdkMemberProperties.
//
// Contains common properties that apply across many different member types.
type SdkMemberPropertiesBase struct {
@@ -655,7 +672,7 @@
Compile_multilib string `android:"arch_variant"`
}
-// The os prefix to use for any file paths in the sdk.
+// OsPrefix returns the os prefix to use for any file paths in the sdk.
//
// Is an empty string if the member only provides variants for a single os type, otherwise
// is the OsType.Name.
@@ -671,35 +688,47 @@
return b
}
-// Interface to be implemented on top of a structure that contains variant specific
-// information.
+// SdkMemberProperties is the interface to be implemented on top of a structure that contains
+// variant specific information.
//
-// Struct fields that are capitalized are examined for common values to extract. Fields
-// that are not capitalized are assumed to be arch specific.
+// Struct fields that are capitalized are examined for common values to extract. Fields that are not
+// capitalized are assumed to be arch specific.
type SdkMemberProperties interface {
- // Access the base structure.
+ // Base returns the base structure.
Base() *SdkMemberPropertiesBase
- // Populate this structure with information from the variant.
+ // PopulateFromVariant populates this structure with information from a module variant.
+ //
+ // It will typically be called once for each variant of a member module that the SDK depends upon.
PopulateFromVariant(ctx SdkMemberContext, variant Module)
- // Add the information from this structure to the property set.
+ // AddToPropertySet adds the information from this structure to the property set.
+ //
+ // This will be called for each instance of this structure on which the PopulateFromVariant method
+ // was called and also on a number of different instances of this structure into which properties
+ // common to one or more variants have been copied. Therefore, implementations of this must handle
+ // the case when this structure is only partially populated.
AddToPropertySet(ctx SdkMemberContext, propertySet BpPropertySet)
}
-// Provides access to information common to a specific member.
+// SdkMemberContext provides access to information common to a specific member.
type SdkMemberContext interface {
- // The module context of the sdk common os variant which is creating the snapshot.
+ // SdkModuleContext returns the module context of the sdk common os variant which is creating the
+ // snapshot.
+ //
+ // This is common to all members of the sdk and is not specific to the member being processed.
+ // If information about the member being processed needs to be obtained from this ModuleContext it
+ // must be obtained using one of the OtherModule... methods not the Module... methods.
SdkModuleContext() ModuleContext
- // The builder of the snapshot.
+ // SnapshotBuilder the builder of the snapshot.
SnapshotBuilder() SnapshotBuilder
- // The type of the member.
+ // MemberType returns the type of the member currently being processed.
MemberType() SdkMemberType
- // The name of the member.
+ // Name returns the name of the member currently being processed.
//
// Provided for use by sdk members to create a member specific location within the snapshot
// into which to copy the prebuilt files.
diff --git a/apex/apex.go b/apex/apex.go
index 2d153e2..e3edc68 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1569,11 +1569,6 @@
af.jacocoReportClassesFile = module.JacocoReportClassesFile()
af.lintDepSets = module.LintDepSets()
af.customStem = module.Stem() + ".jar"
- if dexpreopter, ok := module.(java.DexpreopterInterface); ok {
- for _, install := range dexpreopter.DexpreoptBuiltInstalledForApex() {
- af.requiredModuleNames = append(af.requiredModuleNames, install.FullModuleName())
- }
- }
return af
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 6027f9b..bcbf1ad 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -932,9 +932,17 @@
// .. and not linking to the stubs variant of mylib3
ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so")
+ // Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go
+ // is replaced by sharing of "cFlags" in cc/builder.go.
+ // The "cflags" contains "-include mylib.h", but cFlags contained only a reference to the
+ // module variable representing "cflags". So it was not detected by ensureNotContains.
+ // Now "cFlags" is a reference to a module variable like $flags1, which includes all previous
+ // content of "cflags". ModuleForTests...Args["cFlags"] returns the full string of $flags1,
+ // including the original cflags's "-include mylib.h".
+ //
// Ensure that stubs libs are built without -include flags
- mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylib2Cflags, "-include ")
+ // mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ // ensureNotContains(t, mylib2Cflags, "-include ")
// Ensure that genstub is invoked with --apex
ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 06a7306..48b2945 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -19,6 +19,7 @@
"android/soong/bazel"
"fmt"
"os"
+ "strings"
)
// Codegen is the backend of bp2build. The code generator is responsible for
@@ -29,14 +30,22 @@
bp2buildDir := android.PathForOutput(ctx, "bp2build")
android.RemoveAllOutputDir(bp2buildDir)
- buildToTargets, metrics, compatLayer := GenerateBazelTargets(ctx, true)
- bp2buildFiles := CreateBazelFiles(nil, buildToTargets, ctx.mode)
+ res, errs := GenerateBazelTargets(ctx, true)
+ if len(errs) > 0 {
+ errMsgs := make([]string, len(errs))
+ for i, err := range errs {
+ errMsgs[i] = fmt.Sprintf("%q", err)
+ }
+ fmt.Printf("ERROR: Encountered %d error(s): \nERROR: %s", len(errs), strings.Join(errMsgs, "\n"))
+ os.Exit(1)
+ }
+ bp2buildFiles := CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
writeFiles(ctx, bp2buildDir, bp2buildFiles)
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
- writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(compatLayer))
+ writeFiles(ctx, soongInjectionDir, CreateSoongInjectionFiles(res.compatLayer))
- return metrics
+ return res.metrics
}
// Get the output directory and create it if it doesn't exist.
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index f652a35..10e2329 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -153,10 +153,11 @@
}
type CodegenContext struct {
- config android.Config
- context android.Context
- mode CodegenMode
- additionalDeps []string
+ config android.Config
+ context android.Context
+ mode CodegenMode
+ additionalDeps []string
+ unconvertedDepMode unconvertedDepsMode
}
func (c *CodegenContext) Mode() CodegenMode {
@@ -181,6 +182,16 @@
QueryView
)
+type unconvertedDepsMode int
+
+const (
+ // Include a warning in conversion metrics about converted modules with unconverted direct deps
+ warnUnconvertedDeps unconvertedDepsMode = iota
+ // Error and fail conversion if encountering a module with unconverted direct deps
+ // Enabled by setting environment variable `BP2BUILD_ERROR_UNCONVERTED`
+ errorModulesUnconvertedDeps
+)
+
func (mode CodegenMode) String() string {
switch mode {
case Bp2Build:
@@ -211,10 +222,15 @@
// NewCodegenContext creates a wrapper context that conforms to PathContext for
// writing BUILD files in the output directory.
func NewCodegenContext(config android.Config, context android.Context, mode CodegenMode) *CodegenContext {
+ var unconvertedDeps unconvertedDepsMode
+ if config.IsEnvTrue("BP2BUILD_ERROR_UNCONVERTED") {
+ unconvertedDeps = errorModulesUnconvertedDeps
+ }
return &CodegenContext{
- context: context,
- config: config,
- mode: mode,
+ context: context,
+ config: config,
+ mode: mode,
+ unconvertedDepMode: unconvertedDeps,
}
}
@@ -230,7 +246,17 @@
return attributes
}
-func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (map[string]BazelTargets, CodegenMetrics, CodegenCompatLayer) {
+type conversionResults struct {
+ buildFileToTargets map[string]BazelTargets
+ metrics CodegenMetrics
+ compatLayer CodegenCompatLayer
+}
+
+func (r conversionResults) BuildDirToTargets() map[string]BazelTargets {
+ return r.buildFileToTargets
+}
+
+func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (conversionResults, []error) {
buildFileToTargets := make(map[string]BazelTargets)
buildFileToAppend := make(map[string]bool)
@@ -245,6 +271,8 @@
dirs := make(map[string]bool)
+ var errs []error
+
bpCtx := ctx.Context()
bpCtx.VisitAllModules(func(m blueprint.Module) {
dir := bpCtx.ModuleDir(m)
@@ -266,13 +294,24 @@
}
t, err := getHandcraftedBuildContent(ctx, b, pathToBuildFile)
if err != nil {
- panic(fmt.Errorf("Error converting %s: %s", bpCtx.ModuleName(m), err))
+ errs = append(errs, fmt.Errorf("Error converting %s: %s", bpCtx.ModuleName(m), err))
+ return
}
targets = append(targets, t)
// TODO(b/181575318): currently we append the whole BUILD file, let's change that to do
// something more targeted based on the rule type and target
buildFileToAppend[pathToBuildFile] = true
} else if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
+ if unconvertedDeps := aModule.GetUnconvertedBp2buildDeps(); len(unconvertedDeps) > 0 {
+ msg := fmt.Sprintf("%q depends on unconverted modules: %s", m.Name(), strings.Join(unconvertedDeps, ", "))
+ if ctx.unconvertedDepMode == warnUnconvertedDeps {
+ metrics.moduleWithUnconvertedDepsMsgs = append(metrics.moduleWithUnconvertedDepsMsgs, msg)
+ } else if ctx.unconvertedDepMode == errorModulesUnconvertedDeps {
+ metrics.TotalModuleCount += 1
+ errs = append(errs, fmt.Errorf(msg))
+ return
+ }
+ }
targets = generateBazelTargets(bpCtx, aModule)
for _, t := range targets {
if t.name == m.Name() {
@@ -295,11 +334,17 @@
t := generateSoongModuleTarget(bpCtx, m)
targets = append(targets, t)
default:
- panic(fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
+ errs = append(errs, fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
+ return
}
buildFileToTargets[dir] = append(buildFileToTargets[dir], targets...)
})
+
+ if len(errs) > 0 {
+ return conversionResults{}, errs
+ }
+
if generateFilegroups {
// Add a filegroup target that exposes all sources in the subtree of this package
// NOTE: This also means we generate a BUILD file for every Android.bp file (as long as it has at least one module)
@@ -312,7 +357,11 @@
}
}
- return buildFileToTargets, metrics, compatLayer
+ return conversionResults{
+ buildFileToTargets: buildFileToTargets,
+ metrics: metrics,
+ compatLayer: compatLayer,
+ }, errs
}
func getBazelPackagePath(b android.Bazelable) string {
@@ -575,6 +624,19 @@
// Ignore zero-valued fields
continue
}
+ // if the struct is embedded (anonymous), flatten the properties into the containing struct
+ if field.Anonymous {
+ if field.Type.Kind() == reflect.Ptr {
+ fieldValue = fieldValue.Elem()
+ }
+ if fieldValue.Type().Kind() == reflect.Struct {
+ propsToMerge := extractStructProperties(fieldValue, indent)
+ for prop, value := range propsToMerge {
+ ret[prop] = value
+ }
+ continue
+ }
+ }
propertyName := proptools.PropertyNameForField(field.Name)
prettyPrintedValue, err := prettyPrint(fieldValue, indent+1)
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index ecea6b2..e904627 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "fmt"
"strings"
"testing"
)
@@ -199,7 +200,8 @@
android.FailIfErrored(t, errs)
codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
}
@@ -322,6 +324,30 @@
)`,
},
},
+ {
+ blueprint: `custom {
+ name: "embedded_props",
+ embedded_prop: "abc",
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`custom(
+ name = "embedded_props",
+ embedded_attr = "abc",
+)`,
+ },
+ },
+ {
+ blueprint: `custom {
+ name: "ptr_to_embedded_props",
+ other_embedded_prop: "abc",
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{`custom(
+ name = "ptr_to_embedded_props",
+ other_embedded_attr = "abc",
+)`,
+ },
+ },
}
dir := "."
@@ -341,7 +367,8 @@
}
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("Expected %d bazel target, got %d", expectedCount, actualCount)
@@ -502,7 +529,8 @@
android.FailIfErrored(t, errs)
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount := len(bazelTargets); actualCount != testCase.expectedBazelTargetCount {
t.Fatalf("Expected %d bazel target, got %d", testCase.expectedBazelTargetCount, actualCount)
}
@@ -679,59 +707,38 @@
"other/Android.bp": `filegroup {
name: "foo",
srcs: ["a", "b"],
+ bazel_module: { bp2build_available: true },
+}`,
+ },
+ },
+ {
+ description: "depends_on_other_unconverted_module_error",
+ moduleTypeUnderTest: "filegroup",
+ moduleTypeUnderTestFactory: android.FileGroupFactory,
+ moduleTypeUnderTestBp2BuildMutator: android.FilegroupBp2Build,
+ unconvertedDepsMode: errorModulesUnconvertedDeps,
+ blueprint: `filegroup {
+ name: "foobar",
+ srcs: [
+ ":foo",
+ "c",
+ ],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedErr: fmt.Errorf(`"foobar" depends on unconverted modules: foo`),
+ filesystem: map[string]string{
+ "other/Android.bp": `filegroup {
+ name: "foo",
+ srcs: ["a", "b"],
}`,
},
},
}
- dir := "."
for _, testCase := range testCases {
- fs := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range testCase.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- fs[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, testCase.blueprint, fs)
- ctx := android.NewTestContext(config)
- ctx.RegisterModuleType(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildMutator(testCase.moduleTypeUnderTest, testCase.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if errored(t, testCase, errs) {
- continue
- }
- _, errs = ctx.ResolveDependencies(config)
- if errored(t, testCase, errs) {
- continue
- }
-
- checkDir := dir
- if testCase.dir != "" {
- checkDir = testCase.dir
- }
-
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := testCase.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- testCase.description,
- w,
- g,
- )
- }
- }
- }
+ t.Run(testCase.description, func(t *testing.T) {
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, testCase)
+ })
}
}
@@ -809,7 +816,8 @@
android.FailIfErrored(t, errs)
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount := len(bazelTargets); actualCount != testCase.expectedCount {
t.Fatalf("%s: Expected %d bazel target, got %d", testCase.description, testCase.expectedCount, actualCount)
}
@@ -921,7 +929,8 @@
// For each directory, test that the expected number of generated targets is correct.
for dir, expectedCount := range testCase.expectedCount {
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount := len(bazelTargets); actualCount != expectedCount {
t.Fatalf(
"%s: Expected %d bazel target for %s package, got %d",
@@ -1064,7 +1073,9 @@
if testCase.dir != "" {
checkDir = testCase.dir
}
- bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, checkDir)
+ android.FailIfErrored(t, err)
bazelTargets.sort()
actualCount := len(bazelTargets)
expectedCount := len(testCase.expectedBazelTargets)
@@ -1185,7 +1196,9 @@
if testCase.dir != "" {
checkDir = testCase.dir
}
- bazelTargets := generateBazelTargetsForDir(NewCodegenContext(config, *ctx.Context, Bp2Build), checkDir)
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, checkDir)
+ android.FailIfErrored(t, err)
if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("%s: Expected %d bazel target, got %d\n%s", testCase.description, expectedCount, actualCount, bazelTargets)
} else {
diff --git a/bp2build/bzl_conversion.go b/bp2build/bzl_conversion.go
index f2f6b01..992cc1c 100644
--- a/bp2build/bzl_conversion.go
+++ b/bp2build/bzl_conversion.go
@@ -160,8 +160,15 @@
if shouldSkipStructField(field) {
continue
}
-
- properties = append(properties, extractPropertyDescriptions(field.Name, field.Type)...)
+ subProps := extractPropertyDescriptions(field.Name, field.Type)
+ // if the struct is embedded (anonymous), flatten the properties into the containing struct
+ if field.Anonymous {
+ for _, prop := range subProps {
+ properties = append(properties, prop.properties...)
+ }
+ } else {
+ properties = append(properties, subProps...)
+ }
}
return properties
}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 9e0c0a1..1e78c0e 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -92,6 +92,7 @@
# bazel_module end
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
+ "embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
# "nested_prop": attr.string(),
@@ -99,6 +100,7 @@
# nested_props_ptr start
# "nested_prop": attr.string(),
# nested_props_ptr end
+ "other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
@@ -118,6 +120,7 @@
"arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
+ "embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
# "nested_prop": attr.string(),
@@ -125,6 +128,7 @@
# nested_props_ptr start
# "nested_prop": attr.string(),
# nested_props_ptr end
+ "other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
@@ -144,6 +148,7 @@
"arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
+ "embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
# "nested_prop": attr.string(),
@@ -151,6 +156,7 @@
# nested_props_ptr start
# "nested_prop": attr.string(),
# nested_props_ptr end
+ "other_embedded_prop": attr.string(),
"string_list_prop": attr.string_list(),
"string_prop": attr.string(),
"string_ptr_prop": attr.string(),
diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go
index a991180..f3bc1ba 100644
--- a/bp2build/genrule_conversion_test.go
+++ b/bp2build/genrule_conversion_test.go
@@ -267,7 +267,8 @@
}
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, checkDir)
+ android.FailIfErrored(t, err)
if actualCount, expectedCount := len(bazelTargets), len(testCase.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("%s: Expected %d bazel target, got %d", testCase.description, expectedCount, actualCount)
} else {
@@ -461,7 +462,8 @@
android.FailIfErrored(t, errs)
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
+ bazelTargets, err := generateBazelTargetsForDir(codegenCtx, dir)
+ android.FailIfErrored(t, err)
if actualCount := len(bazelTargets); actualCount != 1 {
t.Fatalf("%s: Expected 1 bazel target, got %d", testCase.description, actualCount)
}
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
index 65b06c6..645ef2d 100644
--- a/bp2build/metrics.go
+++ b/bp2build/metrics.go
@@ -3,6 +3,7 @@
import (
"android/soong/android"
"fmt"
+ "strings"
)
// Simple metrics struct to collect information about a Blueprint to BUILD
@@ -16,6 +17,8 @@
// Total number of handcrafted targets
handCraftedTargetCount int
+
+ moduleWithUnconvertedDepsMsgs []string
}
// Print the codegen metrics to stdout.
@@ -27,8 +30,10 @@
generatedTargetCount += count
}
fmt.Printf(
- "[bp2build] Generated %d total BUILD targets and included %d handcrafted BUILD targets from %d Android.bp modules.\n",
+ "[bp2build] Generated %d total BUILD targets and included %d handcrafted BUILD targets from %d Android.bp modules.\n With %d modules with unconverted deps \n\t%s",
generatedTargetCount,
metrics.handCraftedTargetCount,
- metrics.TotalModuleCount)
+ metrics.TotalModuleCount,
+ len(metrics.moduleWithUnconvertedDepsMsgs),
+ strings.Join(metrics.moduleWithUnconvertedDepsMsgs, "\n\t"))
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 3ebe63d..74084b1 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -39,9 +39,8 @@
func checkError(t *testing.T, errs []error, expectedErr error) bool {
t.Helper()
- // expectedErr is not nil, find it in the list of errors
if len(errs) != 1 {
- t.Errorf("Expected only 1 error, got %d: %q", len(errs), errs)
+ return false
}
if errs[0].Error() == expectedErr.Error() {
return true
@@ -83,6 +82,7 @@
filesystem map[string]string
dir string
expectedErr error
+ unconvertedDepsMode unconvertedDepsMode
}
func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
@@ -126,7 +126,13 @@
checkDir = tc.dir
}
codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
+ codegenCtx.unconvertedDepMode = tc.unconvertedDepsMode
+ bazelTargets, errs := generateBazelTargetsForDir(codegenCtx, checkDir)
+ if tc.expectedErr != nil && checkError(t, errs, tc.expectedErr) {
+ return
+ } else {
+ android.FailIfErrored(t, errs)
+ }
if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
t.Errorf("%s: Expected %d bazel target, got %d; %v",
tc.description, expectedCount, actualCount, bazelTargets)
@@ -148,7 +154,18 @@
Nested_prop string
}
+type EmbeddedProps struct {
+ Embedded_prop string
+}
+
+type OtherEmbeddedProps struct {
+ Other_embedded_prop string
+}
+
type customProps struct {
+ EmbeddedProps
+ *OtherEmbeddedProps
+
Bool_prop bool
Bool_ptr_prop *bool
// Ensure that properties tagged `blueprint:mutated` are omitted
@@ -246,7 +263,17 @@
return m
}
+type EmbeddedAttr struct {
+ Embedded_attr string
+}
+
+type OtherEmbeddedAttr struct {
+ Other_embedded_attr string
+}
+
type customBazelModuleAttributes struct {
+ EmbeddedAttr
+ *OtherEmbeddedAttr
String_prop string
String_list_prop []string
Arch_paths bazel.LabelListAttribute
@@ -275,6 +302,10 @@
String_list_prop: m.props.String_list_prop,
Arch_paths: paths,
}
+ attrs.Embedded_attr = m.props.Embedded_prop
+ if m.props.OtherEmbeddedProps != nil {
+ attrs.OtherEmbeddedAttr = &OtherEmbeddedAttr{Other_embedded_attr: m.props.OtherEmbeddedProps.Other_embedded_prop}
+ }
props := bazel.BazelTargetModuleProperties{
Rule_class: "custom",
@@ -316,10 +347,10 @@
}
// Helper method for tests to easily access the targets in a dir.
-func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) BazelTargets {
+func generateBazelTargetsForDir(codegenCtx *CodegenContext, dir string) (BazelTargets, []error) {
// TODO: Set generateFilegroups to true and/or remove the generateFilegroups argument completely
- buildFileToTargets, _, _ := GenerateBazelTargets(codegenCtx, false)
- return buildFileToTargets[dir]
+ res, err := GenerateBazelTargets(codegenCtx, false)
+ return res.buildFileToTargets[dir], err
}
func registerCustomModuleForBp2buildConversion(ctx *android.TestContext) {
diff --git a/cc/builder.go b/cc/builder.go
index 6a4d940..b07acf1 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -21,6 +21,7 @@
import (
"path/filepath"
"runtime"
+ "strconv"
"strings"
"github.com/google/blueprint"
@@ -510,6 +511,32 @@
cppflags += " ${config.NoOverrideGlobalCflags}"
toolingCppflags += " ${config.NoOverrideGlobalCflags}"
+ // Multiple source files have build rules usually share the same cFlags or tidyFlags.
+ // Define only one version in this module and share it in multiple build rules.
+ // To simplify the code, the shared variables are all named as $flags<nnn>.
+ numSharedFlags := 0
+ flagsMap := make(map[string]string)
+
+ // Share flags only when there are multiple files or tidy rules.
+ var hasMultipleRules = len(srcFiles) > 1 || flags.tidy
+
+ var shareFlags = func(kind string, flags string) string {
+ if !hasMultipleRules || len(flags) < 60 {
+ // Modules have long names and so do the module variables.
+ // It does not save space by replacing a short name with a long one.
+ return flags
+ }
+ mapKey := kind + flags
+ n, ok := flagsMap[mapKey]
+ if !ok {
+ numSharedFlags += 1
+ n = strconv.Itoa(numSharedFlags)
+ flagsMap[mapKey] = n
+ ctx.Variable(pctx, kind+n, flags)
+ }
+ return "$" + kind + n
+ }
+
for i, srcFile := range srcFiles {
objFile := android.ObjPathWithExt(ctx, subdir, srcFile, "o")
@@ -526,7 +553,7 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "asFlags": flags.globalYasmFlags + " " + flags.localYasmFlags,
+ "asFlags": shareFlags("asFlags", flags.globalYasmFlags+" "+flags.localYasmFlags),
},
})
continue
@@ -540,7 +567,7 @@
OrderOnly: pathDeps,
Args: map[string]string{
"windresCmd": mingwCmd(flags.toolchain, "windres"),
- "flags": flags.toolchain.WindresFlags(),
+ "flags": shareFlags("flags", flags.toolchain.WindresFlags()),
},
})
continue
@@ -608,8 +635,8 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "cFlags": moduleFlags,
- "ccCmd": ccCmd,
+ "cFlags": shareFlags("cFlags", moduleFlags),
+ "ccCmd": ccCmd, // short and not shared
},
})
@@ -624,7 +651,7 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "cFlags": moduleFlags,
+ "cFlags": shareFlags("cFlags", moduleFlags),
},
})
kytheFiles = append(kytheFiles, kytheFile)
@@ -651,9 +678,9 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "cFlags": moduleToolingFlags,
- "tidyFlags": config.TidyFlagsForSrcFile(srcFile, flags.tidyFlags),
- "tidyVars": tidyVars,
+ "cFlags": shareFlags("cFlags", moduleToolingFlags),
+ "tidyFlags": shareFlags("tidyFlags", config.TidyFlagsForSrcFile(srcFile, flags.tidyFlags)),
+ "tidyVars": tidyVars, // short and not shared
},
})
}
@@ -675,8 +702,8 @@
Implicits: cFlagsDeps,
OrderOnly: pathDeps,
Args: map[string]string{
- "cFlags": moduleToolingFlags,
- "exportDirs": flags.sAbiFlags,
+ "cFlags": shareFlags("cFlags", moduleToolingFlags),
+ "exportDirs": shareFlags("exportDirs", flags.sAbiFlags),
},
})
}
diff --git a/cc/cc.go b/cc/cc.go
index 300bd98..d2f8a12 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1814,15 +1814,6 @@
flags.AssemblerWithCpp = inList("-xassembler-with-cpp", flags.Local.AsFlags)
- // Optimization to reduce size of build.ninja
- // Replace the long list of flags for each file with a module-local variable
- ctx.Variable(pctx, "cflags", strings.Join(flags.Local.CFlags, " "))
- ctx.Variable(pctx, "cppflags", strings.Join(flags.Local.CppFlags, " "))
- ctx.Variable(pctx, "asflags", strings.Join(flags.Local.AsFlags, " "))
- flags.Local.CFlags = []string{"$cflags"}
- flags.Local.CppFlags = []string{"$cppflags"}
- flags.Local.AsFlags = []string{"$asflags"}
-
var objs Objects
if c.compiler != nil {
objs = c.compiler.compile(ctx, flags, deps)
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 1866ff3..559e940 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -265,8 +265,8 @@
// values where necessary.
for _, propertyInfo := range includeDirProperties {
// Calculate the base directory in the snapshot into which the files will be copied.
- // lib.archType is "" for common properties.
- targetDir := filepath.Join(libInfo.OsPrefix(), libInfo.archType, propertyInfo.snapshotDir)
+ // lib.archSubDir is "" for common properties.
+ targetDir := filepath.Join(libInfo.OsPrefix(), libInfo.archSubDir, propertyInfo.snapshotDir)
propertyName := propertyInfo.propertyName
@@ -334,7 +334,7 @@
// path to the native library. Relative to <sdk_root>/<api_dir>
func nativeLibraryPathFor(lib *nativeLibInfoProperties) string {
- return filepath.Join(lib.OsPrefix(), lib.archType,
+ return filepath.Join(lib.OsPrefix(), lib.archSubDir,
nativeStubDir, lib.outputFile.Base())
}
@@ -347,9 +347,12 @@
memberType *librarySdkMemberType
- // archType is not exported as if set (to a non default value) it is always arch specific.
- // This is "" for common properties.
- archType string
+ // archSubDir is the subdirectory within the OS directory in the sdk snapshot into which arch
+ // specific files will be copied.
+ //
+ // It is not exported since any value other than "" is always going to be arch specific.
+ // This is "" for non-arch specific common properties.
+ archSubDir string
// The list of possibly common exported include dirs.
//
@@ -433,7 +436,7 @@
exportedIncludeDirs, exportedGeneratedIncludeDirs := android.FilterPathListPredicate(
exportedInfo.IncludeDirs, isGeneratedHeaderDirectory)
- p.archType = ccModule.Target().Arch.ArchType.String()
+ p.archSubDir = ccModule.Target().Arch.ArchType.String()
// Make sure that the include directories are unique.
p.ExportedIncludeDirs = android.FirstUniquePaths(exportedIncludeDirs)
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index 98e27c6..d63ded5 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -27,12 +27,12 @@
os.RemoveAll(bazelQueryViewDir)
ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
- // Ignore metrics reporting and compat layers for queryview, since queryview
- // is already a full-repo conversion and can use data from bazel query
- // directly.
- buildToTargets, _, _ := bp2build.GenerateBazelTargets(ctx, true)
+ res, err := bp2build.GenerateBazelTargets(ctx, true)
+ if err != nil {
+ panic(err)
+ }
- filesToWrite := bp2build.CreateBazelFiles(ruleShims, buildToTargets, bp2build.QueryView)
+ filesToWrite := bp2build.CreateBazelFiles(ruleShims, res.BuildDirToTargets(), bp2build.QueryView)
for _, f := range filesToWrite {
if err := writeReadOnlyFile(bazelQueryViewDir, f); err != nil {
return err
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 7733c1b..1401c75 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -110,12 +110,17 @@
return true
}
+ // Don't preopt system server jars that are updatable.
+ if global.ApexSystemServerJars.ContainsJar(module.Name) {
+ return true
+ }
+
// If OnlyPreoptBootImageAndSystemServer=true and module is not in boot class path skip
// Also preopt system server jars since selinux prevents system server from loading anything from
// /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
- !AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk {
+ !global.SystemServerJars.ContainsJar(module.Name) && !module.PreoptExtractedApk {
return true
}
@@ -196,14 +201,6 @@
return profilePath
}
-// Returns the dex location of a system server java library.
-func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
- if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
- return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
- }
- return fmt.Sprintf("/system/framework/%s.jar", lib)
-}
-
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -219,13 +216,6 @@
}
toOdexPath := func(path string) string {
- if global.ApexSystemServerJars.ContainsJar(module.Name) {
- return filepath.Join(
- "/system/framework/oat",
- arch.String(),
- strings.ReplaceAll(path[1:], "/", "@")+"@classes.odex")
- }
-
return filepath.Join(
filepath.Dir(path),
"oat",
@@ -244,21 +234,20 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- systemServerJars := AllSystemServerJars(ctx, global)
+ systemServerJars := NonApexSystemServerJars(ctx, global)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
- if jarIndex := systemServerJars.IndexOfJar(module.Name); jarIndex >= 0 {
+ if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
// System server jars should be dexpreopted together: class loader context of each jar
// should include all preceding jars on the system server classpath.
var clcHost android.Paths
var clcTarget []string
- for i := 0; i < jarIndex; i++ {
- lib := systemServerJars.Jar(i)
+ for _, lib := range systemServerJars[:jarIndex] {
clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
- clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
+ clcTarget = append(clcTarget, filepath.Join("/system/framework", lib+".jar"))
}
// Copy the system server jar to a predefined location where dex2oat will find it.
@@ -373,7 +362,7 @@
if !android.PrefixInList(preoptFlags, "--compiler-filter=") {
var compilerFilter string
- if systemServerJars.ContainsJar(module.Name) {
+ if global.SystemServerJars.ContainsJar(module.Name) {
// Jars of system server, use the product option if it is set, speed otherwise.
if global.SystemServerCompilerFilter != "" {
compilerFilter = global.SystemServerCompilerFilter
@@ -427,7 +416,7 @@
// PRODUCT_SYSTEM_SERVER_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
// PRODUCT_OTHER_JAVA_DEBUG_INFO overrides WITH_DEXPREOPT_DEBUG_INFO.
- if systemServerJars.ContainsJar(module.Name) {
+ if global.SystemServerJars.ContainsJar(module.Name) {
if global.AlwaysSystemServerDebugInfo {
debugInfo = true
} else if global.NeverSystemServerDebugInfo {
@@ -529,15 +518,14 @@
}
}
-var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
+var nonApexSystemServerJarsKey = android.NewOnceKey("nonApexSystemServerJars")
// TODO: eliminate the superficial global config parameter by moving global config definition
// from java subpackage to dexpreopt.
-func AllSystemServerJars(ctx android.PathContext, global *GlobalConfig) *android.ConfiguredJarList {
- return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
- allSystemServerJars := global.SystemServerJars.AppendList(global.ApexSystemServerJars)
- return &allSystemServerJars
- }).(*android.ConfiguredJarList)
+func NonApexSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string {
+ return ctx.Config().Once(nonApexSystemServerJarsKey, func() interface{} {
+ return android.RemoveListFromList(global.SystemServerJars.CopyOfJars(), global.ApexSystemServerJars.CopyOfJars())
+ }).([]string)
}
// A predefined location for the system server dex jars. This is needed in order to generate
@@ -563,12 +551,12 @@
mctx, isModule := ctx.(android.ModuleContext)
if isModule {
config := GetGlobalConfig(ctx)
- jars := AllSystemServerJars(ctx, config)
+ jars := NonApexSystemServerJars(ctx, config)
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
- depIndex := jars.IndexOfJar(dep.Name())
+ depIndex := android.IndexList(dep.Name(), jars)
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
- jar := jars.Jar(jarIndex)
- dep := jars.Jar(depIndex)
+ jar := jars[jarIndex]
+ dep := jars[depIndex]
mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
" '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
" references from '%s' to '%s'.\n", jar, dep, jar, dep)
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 798d776..4ee61b6 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -33,35 +33,17 @@
}
func testModuleConfig(ctx android.PathContext, name, partition string) *ModuleConfig {
- return createTestModuleConfig(
- name,
- fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
- android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
- android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
- android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
-}
-
-func testApexModuleConfig(ctx android.PathContext, name, apexName string) *ModuleConfig {
- return createTestModuleConfig(
- name,
- fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, name),
- android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
- android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
- android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
-}
-
-func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig {
return &ModuleConfig{
Name: name,
- DexLocation: dexLocation,
- BuildPath: buildPath,
- DexPath: dexPath,
+ DexLocation: fmt.Sprintf("/%s/app/test/%s.apk", partition, name),
+ BuildPath: android.PathForOutput(ctx, fmt.Sprintf("%s/%s.apk", name, name)),
+ DexPath: android.PathForOutput(ctx, fmt.Sprintf("%s/dex/%s.jar", name, name)),
UncompressedDex: false,
HasApkLibraries: false,
PreoptFlags: nil,
ProfileClassListing: android.OptionalPath{},
ProfileIsTextListing: false,
- EnforceUsesLibrariesStatusFile: enforceUsesLibrariesStatusFile,
+ EnforceUsesLibrariesStatusFile: android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)),
EnforceUsesLibraries: false,
ClassLoaderContexts: nil,
Archs: []android.ArchType{android.Arm},
@@ -158,29 +140,6 @@
}
-func TestDexPreoptApexSystemServerJars(t *testing.T) {
- config := android.TestConfig("out", nil, "", nil)
- ctx := android.BuilderContextForTesting(config)
- globalSoong := globalSoongConfigForTests()
- global := GlobalConfigForTests(ctx)
- module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
-
- global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
- []string{"com.android.apex1:service-A"})
-
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
- if err != nil {
- t.Fatal(err)
- }
-
- wantInstalls := android.RuleBuilderInstalls{
- {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
- {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
- }
-
- android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
-}
-
func TestDexPreoptProfile(t *testing.T) {
config := android.TestConfig("out", nil, "", nil)
ctx := android.BuilderContextForTesting(config)
diff --git a/java/androidmk.go b/java/androidmk.go
index 71370c9..68ccd82 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -61,13 +61,7 @@
var entriesList []android.AndroidMkEntries
if library.hideApexVariantFromMake {
- // For a java library built for an APEX, we don't need a Make module for itself. Otherwise, it
- // will conflict with the platform variant because they have the same module name in the
- // makefile. However, we need to add its dexpreopt outputs as sub-modules, if it is preopted.
- dexpreoptEntries := library.dexpreopter.AndroidMkEntriesForApex()
- if len(dexpreoptEntries) > 0 {
- entriesList = append(entriesList, dexpreoptEntries...)
- }
+ // For a java library built for an APEX we don't need Make module
entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true})
} else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) {
// Platform variant. If not available for the platform, we don't need Make module.
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index f7561b4..b13e2db 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -89,7 +89,7 @@
var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
-var _ android.SdkMemberTypeDependencyTag = bootclasspathFragmentContentDepTag
+var _ android.SdkMemberDependencyTag = bootclasspathFragmentContentDepTag
var _ android.CopyDirectlyInAnyApexTag = bootclasspathFragmentContentDepTag
var _ android.RequiresFilesFromPrebuiltApexTag = bootclasspathFragmentContentDepTag
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index cdd42ed..0faae36 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -15,46 +15,13 @@
package java
import (
- "path/filepath"
- "strings"
-
"android/soong/android"
"android/soong/dexpreopt"
)
-type DexpreopterInterface interface {
+type dexpreopterInterface interface {
IsInstallable() bool // Structs that embed dexpreopter must implement this.
dexpreoptDisabled(ctx android.BaseModuleContext) bool
- DexpreoptBuiltInstalledForApex() []dexpreopterInstall
- AndroidMkEntriesForApex() []android.AndroidMkEntries
-}
-
-type dexpreopterInstall struct {
- // A unique name to distinguish an output from others for the same java library module. Usually in
- // the form of `<arch>-<encoded-path>.odex/vdex/art`.
- name string
-
- // The name of the input java module.
- moduleName string
-
- // The path to the dexpreopt output on host.
- outputPathOnHost android.Path
-
- // The directory on the device for the output to install to.
- installDirOnDevice android.InstallPath
-
- // The basename (the last segment of the path) for the output to install as.
- installFileOnDevice string
-}
-
-// The full module name of the output in the makefile.
-func (install *dexpreopterInstall) FullModuleName() string {
- return install.moduleName + install.SubModuleName()
-}
-
-// The sub-module name of the output in the makefile (the name excluding the java module name).
-func (install *dexpreopterInstall) SubModuleName() string {
- return "-dexpreopt-" + install.name
}
type dexpreopter struct {
@@ -72,9 +39,7 @@
enforceUsesLibs bool
classLoaderContexts dexpreopt.ClassLoaderContextMap
- // See the `dexpreopt` function for details.
- builtInstalled string
- builtInstalledForApex []dexpreopterInstall
+ builtInstalled string
// The config is used for two purposes:
// - Passing dexpreopt information about libraries from Soong to Make. This is needed when
@@ -109,17 +74,6 @@
dexpreopt.DexpreoptRunningInSoong = true
}
-func isApexVariant(ctx android.BaseModuleContext) bool {
- apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
- return !apexInfo.IsForPlatform()
-}
-
-func moduleName(ctx android.BaseModuleContext) string {
- // Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not
- // expected by dexpreopter.
- return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName())
-}
-
func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool {
global := dexpreopt.GetGlobalConfig(ctx)
@@ -127,7 +81,7 @@
return true
}
- if inList(moduleName(ctx), global.DisablePreoptModules) {
+ if inList(ctx.ModuleName(), global.DisablePreoptModules) {
return true
}
@@ -139,7 +93,7 @@
return true
}
- if !ctx.Module().(DexpreopterInterface).IsInstallable() {
+ if !ctx.Module().(dexpreopterInterface).IsInstallable() {
return true
}
@@ -147,17 +101,9 @@
return true
}
- if isApexVariant(ctx) {
- // Don't preopt APEX variant module unless the module is an APEX system server jar and we are
- // building the entire system image.
- if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) || ctx.Config().UnbundledBuild() {
- return true
- }
- } else {
- // Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
- return true
- }
+ // Don't preopt APEX variant module
+ if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
+ return true
}
// TODO: contains no java code
@@ -166,40 +112,17 @@
}
func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) {
- if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
+ if d, ok := ctx.Module().(dexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) {
return
}
dexpreopt.RegisterToolDeps(ctx)
}
-func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
- return dexpreopt.OdexOnSystemOtherByName(moduleName(ctx), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
-}
-
-// Returns the install path of the dex jar of a module.
-//
-// Do not rely on `ApexInfo.ApexVariationName` because it can be something like "apex1000", rather
-// than the `name` in the path `/apex/<name>` as suggested in its comment.
-//
-// This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a
-// system server jar, which is fine because we currently only preopt system server jars for APEXes.
-func (d *dexpreopter) getInstallPath(
- ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath {
- global := dexpreopt.GetGlobalConfig(ctx)
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
- dexLocation := dexpreopt.GetSystemServerDexLocation(global, moduleName(ctx))
- return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/"))
- }
- if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) &&
- filepath.Base(defaultInstallPath.PartitionDir()) != "apex" {
- ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt")
- }
- return defaultInstallPath
+func odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool {
+ return dexpreopt.OdexOnSystemOtherByName(ctx.ModuleName(), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx))
}
func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) {
- global := dexpreopt.GetGlobalConfig(ctx)
-
// TODO(b/148690468): The check on d.installPath is to bail out in cases where
// the dexpreopter struct hasn't been fully initialized before we're called,
// e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively
@@ -210,7 +133,7 @@
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
- providesUsesLib := moduleName(ctx)
+ providesUsesLib := ctx.ModuleName()
if ulib, ok := ctx.Module().(ProvidesUsesLib); ok {
name := ulib.ProvidesUsesLib()
if name != nil {
@@ -224,8 +147,9 @@
return
}
- isSystemServerJar := global.SystemServerJars.ContainsJar(moduleName(ctx)) ||
- global.ApexSystemServerJars.ContainsJar(moduleName(ctx))
+ global := dexpreopt.GetGlobalConfig(ctx)
+
+ isSystemServerJar := global.SystemServerJars.ContainsJar(ctx.ModuleName())
bootImage := defaultBootImageConfig(ctx)
if global.UseArtImage {
@@ -275,15 +199,15 @@
profileIsTextListing = true
} else if global.ProfileDir != "" {
profileClassListing = android.ExistentPathForSource(ctx,
- global.ProfileDir, moduleName(ctx)+".prof")
+ global.ProfileDir, ctx.ModuleName()+".prof")
}
}
// Full dexpreopt config, used to create dexpreopt build rules.
dexpreoptConfig := &dexpreopt.ModuleConfig{
- Name: moduleName(ctx),
+ Name: ctx.ModuleName(),
DexLocation: dexLocation,
- BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath,
+ BuildPath: android.PathForModuleOut(ctx, "dexpreopt", ctx.ModuleName()+".jar").OutputPath,
DexPath: dexJarFile,
ManifestPath: android.OptionalPathForPath(d.manifestFile),
UncompressedDex: d.uncompressedDex,
@@ -332,53 +256,5 @@
dexpreoptRule.Build("dexpreopt", "dexpreopt")
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
- // APEX variants of java libraries are hidden from Make, so their dexpreopt outputs need special
- // handling. Currently, for APEX variants of java libraries, only those in the system server
- // classpath are handled here. Preopting of boot classpath jars in the ART APEX are handled in
- // java/dexpreopt_bootjars.go, and other APEX jars are not preopted.
- for _, install := range dexpreoptRule.Installs() {
- // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
- installDir := strings.TrimPrefix(filepath.Dir(install.To), "/")
- installBase := filepath.Base(install.To)
- arch := filepath.Base(installDir)
- installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir)
- // The installs will be handled by Make as sub-modules of the java library.
- d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{
- name: arch + "-" + installBase,
- moduleName: moduleName(ctx),
- outputPathOnHost: install.From,
- installDirOnDevice: installPath,
- installFileOnDevice: installBase,
- })
- }
- } else {
- // The installs will be handled by Make as LOCAL_SOONG_BUILT_INSTALLED of the java library
- // module.
- d.builtInstalled = dexpreoptRule.Installs().String()
- }
-}
-
-func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall {
- return d.builtInstalledForApex
-}
-
-func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries {
- var entries []android.AndroidMkEntries
- for _, install := range d.builtInstalledForApex {
- install := install
- entries = append(entries, android.AndroidMkEntries{
- Class: "ETC",
- SubName: install.SubModuleName(),
- OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
- ExtraEntries: []android.AndroidMkExtraEntriesFunc{
- func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.ToMakePath().String())
- entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
- entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
- },
- },
- })
- }
- return entries
+ d.builtInstalled = dexpreoptRule.Installs().String()
}
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 1c1070a..8dc7b79 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -17,7 +17,6 @@
import (
"fmt"
"runtime"
- "strings"
"testing"
"android/soong/android"
@@ -25,17 +24,11 @@
"android/soong/dexpreopt"
)
-func init() {
- RegisterFakeRuntimeApexMutator()
-}
-
func TestDexpreoptEnabled(t *testing.T) {
tests := []struct {
- name string
- bp string
- moduleName string
- apexVariant bool
- enabled bool
+ name string
+ bp string
+ enabled bool
}{
{
name: "app",
@@ -155,81 +148,13 @@
}`,
enabled: true,
},
- {
- name: "apex variant",
- bp: `
- java_library {
- name: "foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`,
- apexVariant: true,
- enabled: false,
- },
- {
- name: "apex variant of apex system server jar",
- bp: `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`,
- moduleName: "service-foo",
- apexVariant: true,
- enabled: true,
- },
- {
- name: "apex variant of prebuilt apex system server jar",
- bp: `
- java_library {
- name: "prebuilt_service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`,
- moduleName: "prebuilt_service-foo",
- apexVariant: true,
- enabled: true,
- },
- {
- name: "platform variant of apex system server jar",
- bp: `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`,
- moduleName: "service-foo",
- apexVariant: false,
- enabled: false,
- },
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithFakeApexMutator,
- dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
- )
+ ctx, _ := testJava(t, test.bp)
- result := preparers.RunTestWithBp(t, test.bp)
- ctx := result.TestContext
-
- moduleName := "foo"
- if test.moduleName != "" {
- moduleName = test.moduleName
- }
-
- variant := "android_common"
- if test.apexVariant {
- variant += "_apex1000"
- }
-
- dexpreopt := ctx.ModuleForTests(moduleName, variant).MaybeRule("dexpreopt")
+ dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt")
enabled := dexpreopt.Rule != nil
if enabled != test.enabled {
@@ -295,145 +220,3 @@
testDex2oatToolDep(true, true, true, prebuiltDex2oatPath)
testDex2oatToolDep(false, true, false, prebuiltDex2oatPath)
}
-
-func TestDexpreoptBuiltInstalledForApex(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithFakeApexMutator,
- dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
- )
-
- // An APEX system server jar.
- result := preparers.RunTestWithBp(t, `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`)
- ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
- library := module.Module().(*Library)
-
- installs := library.dexpreopter.DexpreoptBuiltInstalledForApex()
-
- android.AssertIntEquals(t, "install count", 2, len(installs))
-
- android.AssertStringEquals(t, "installs[0] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].FullModuleName())
-
- android.AssertStringEquals(t, "installs[0] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- installs[0].SubModuleName())
-
- android.AssertStringEquals(t, "installs[1] FullModuleName",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].FullModuleName())
-
- android.AssertStringEquals(t, "installs[1] SubModuleName",
- "-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- installs[1].SubModuleName())
-
- // Not an APEX system server jar.
- result = preparers.RunTestWithBp(t, `
- java_library {
- name: "foo",
- installable: true,
- srcs: ["a.java"],
- }`)
- ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
- library = module.Module().(*Library)
-
- installs = library.dexpreopter.DexpreoptBuiltInstalledForApex()
-
- android.AssertIntEquals(t, "install count", 0, len(installs))
-}
-
-func filterDexpreoptEntriesList(entriesList []android.AndroidMkEntries) []android.AndroidMkEntries {
- var results []android.AndroidMkEntries
- for _, entries := range entriesList {
- if strings.Contains(entries.EntryMap["LOCAL_MODULE"][0], "-dexpreopt-") {
- results = append(results, entries)
- }
- }
- return results
-}
-
-func verifyEntries(t *testing.T, message string, expectedModule string,
- expectedPrebuiltModuleFile string, expectedModulePath string, expectedInstalledModuleStem string,
- entries android.AndroidMkEntries) {
- android.AssertStringEquals(t, message+" LOCAL_MODULE", expectedModule,
- entries.EntryMap["LOCAL_MODULE"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_MODULE_CLASS", "ETC",
- entries.EntryMap["LOCAL_MODULE_CLASS"][0])
-
- android.AssertStringDoesContain(t, message+" LOCAL_PREBUILT_MODULE_FILE",
- entries.EntryMap["LOCAL_PREBUILT_MODULE_FILE"][0], expectedPrebuiltModuleFile)
-
- android.AssertStringDoesContain(t, message+" LOCAL_MODULE_PATH",
- entries.EntryMap["LOCAL_MODULE_PATH"][0], expectedModulePath)
-
- android.AssertStringEquals(t, message+" LOCAL_INSTALLED_MODULE_STEM",
- expectedInstalledModuleStem, entries.EntryMap["LOCAL_INSTALLED_MODULE_STEM"][0])
-
- android.AssertStringEquals(t, message+" LOCAL_NOT_AVAILABLE_FOR_PLATFORM",
- "false", entries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"][0])
-}
-
-func TestAndroidMkEntriesForApex(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithFakeApexMutator,
- dexpreopt.FixtureSetApexSystemServerJars("com.android.apex1:service-foo"),
- )
-
- // An APEX system server jar.
- result := preparers.RunTestWithBp(t, `
- java_library {
- name: "service-foo",
- installable: true,
- srcs: ["a.java"],
- apex_available: ["com.android.apex1"],
- }`)
- ctx := result.TestContext
- module := ctx.ModuleForTests("service-foo", "android_common_apex1000")
-
- entriesList := android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 2, len(entriesList))
-
- verifyEntries(t,
- "entriesList[0]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- "/dexpreopt/oat/arm64/javalib.odex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.odex",
- entriesList[0])
-
- verifyEntries(t,
- "entriesList[1]",
- "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- "/dexpreopt/oat/arm64/javalib.vdex",
- "/system/framework/oat/arm64",
- "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex",
- entriesList[1])
-
- // Not an APEX system server jar.
- result = preparers.RunTestWithBp(t, `
- java_library {
- name: "foo",
- installable: true,
- srcs: ["a.java"],
- }`)
- ctx = result.TestContext
- module = ctx.ModuleForTests("foo", "android_common")
-
- entriesList = android.AndroidMkEntriesForTest(t, ctx, module.Module())
- entriesList = filterDexpreoptEntriesList(entriesList)
-
- android.AssertIntEquals(t, "entries count", 0, len(entriesList))
-}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 8e39f40..51cd501 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -218,7 +218,7 @@
var _ android.ExcludeFromVisibilityEnforcementTag = hiddenAPIStubsDependencyTag{}
var _ android.ReplaceSourceWithPrebuilt = hiddenAPIStubsDependencyTag{}
var _ android.ExcludeFromApexContentsTag = hiddenAPIStubsDependencyTag{}
-var _ android.SdkMemberTypeDependencyTag = hiddenAPIStubsDependencyTag{}
+var _ android.SdkMemberDependencyTag = hiddenAPIStubsDependencyTag{}
// hiddenAPIComputeMonolithicStubLibModules computes the set of module names that provide stubs
// needed to produce the hidden API monolithic stub flags file.
diff --git a/java/java.go b/java/java.go
index e2665ef..1a052b4 100644
--- a/java/java.go
+++ b/java/java.go
@@ -487,7 +487,7 @@
}
// Store uncompressed dex files that are preopted on /system.
- if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) {
+ if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) {
return true
}
if ctx.Config().UncompressPrivAppDex() &&
@@ -508,8 +508,7 @@
}
j.checkSdkVersions(ctx)
- j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
- ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+ j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
if j.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
@@ -1369,8 +1368,7 @@
// Dex compilation
- j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
- ctx, android.PathForModuleInstall(ctx, "framework", jarName))
+ j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName)
if j.dexProperties.Uncompress_dex == nil {
// If the value was not force-set by the user, use reasonable default based on the module.
j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
@@ -1511,7 +1509,7 @@
return Bool(j.properties.Installable)
}
-var _ DexpreopterInterface = (*Import)(nil)
+var _ dexpreopterInterface = (*Import)(nil)
// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
//
@@ -1624,8 +1622,7 @@
j.hideApexVariantFromMake = true
}
- j.dexpreopter.installPath = j.dexpreopter.getInstallPath(
- ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar"))
+ j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars")
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 5311f62..de2a978 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -123,10 +123,16 @@
blueprint.BaseDependencyTag
}
+// The systemserverclasspath_fragment contents must never depend on prebuilts.
+func (systemServerClasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
+}
+
// Contents of system server fragments in an apex are considered to be directly in the apex, as if
// they were listed in java_libs.
func (systemServerClasspathFragmentContentDependencyTag) CopyDirectlyInAnyApex() {}
+var _ android.ReplaceSourceWithPrebuilt = systemServerClasspathFragmentContentDepTag
var _ android.CopyDirectlyInAnyApexTag = systemServerClasspathFragmentContentDepTag
// The tag used for the dependency between the systemserverclasspath_fragment module and its contents.
diff --git a/java/testing.go b/java/testing.go
index d8a77cf..8860b45 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -431,45 +431,3 @@
output := sourceGlobalCompatConfig.Output(allOutputs[0])
android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits)
}
-
-// Register the fake APEX mutator to `android.InitRegistrationContext` as if the real mutator exists
-// at runtime. This must be called in `init()` of a test if the test is going to use the fake APEX
-// mutator. Otherwise, we will be missing the runtime mutator because "soong-apex" is not a
-// dependency, which will cause an inconsistency between testing and runtime mutators.
-func RegisterFakeRuntimeApexMutator() {
- registerFakeApexMutator(android.InitRegistrationContext)
-}
-
-var PrepareForTestWithFakeApexMutator = android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(registerFakeApexMutator),
-)
-
-func registerFakeApexMutator(ctx android.RegistrationContext) {
- ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("apex", fakeApexMutator).Parallel()
- })
-}
-
-type apexModuleBase interface {
- ApexAvailable() []string
-}
-
-var _ apexModuleBase = (*Library)(nil)
-var _ apexModuleBase = (*SdkLibrary)(nil)
-
-// A fake APEX mutator that creates a platform variant and an APEX variant for modules with
-// `apex_available`. It helps us avoid a dependency on the real mutator defined in "soong-apex",
-// which will cause a cyclic dependency, and it provides an easy way to create an APEX variant for
-// testing without dealing with all the complexities in the real mutator.
-func fakeApexMutator(mctx android.BottomUpMutatorContext) {
- switch mctx.Module().(type) {
- case *Library, *SdkLibrary:
- if len(mctx.Module().(apexModuleBase).ApexAvailable()) > 0 {
- modules := mctx.CreateVariations("", "apex1000")
- apexInfo := android.ApexInfo{
- ApexVariationName: "apex1000",
- }
- mctx.SetVariationProvider(modules[1], android.ApexInfoProvider, apexInfo)
- }
- }
-}
diff --git a/sdk/member_type.go b/sdk/member_type.go
index ee27c86..9aab61d 100644
--- a/sdk/member_type.go
+++ b/sdk/member_type.go
@@ -35,7 +35,7 @@
// the dependency tag used for items in this list that can be used to determine the memberType
// for a resolved dependency.
- dependencyTag android.SdkMemberTypeDependencyTag
+ dependencyTag android.SdkMemberDependencyTag
}
func (p *sdkMemberTypeListProperty) propertyName() string {
diff --git a/sdk/update.go b/sdk/update.go
index 96a6e69..89a5c92 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -185,7 +185,7 @@
s.multilibUsages = multilibNone
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
tag := ctx.OtherModuleDependencyTag(child)
- if memberTag, ok := tag.(android.SdkMemberTypeDependencyTag); ok {
+ if memberTag, ok := tag.(android.SdkMemberDependencyTag); ok {
memberType := memberTag.SdkMemberType(child)
// If a nil SdkMemberType was returned then this module should not be added to the sdk.
@@ -765,6 +765,8 @@
name string
}
+var _ android.BpPropertyTag = propertyTag{}
+
// A BpPropertyTag to add to a property that contains references to other sdk members.
//
// This will cause the references to be rewritten to a versioned reference in the version
@@ -1563,10 +1565,6 @@
return archInfo
}
-func (archInfo *archTypeSpecificInfo) optimizableProperties() interface{} {
- return archInfo.Properties
-}
-
// Get the link type of the variant
//
// If the variant is not differentiated by link type then it returns "",
@@ -1608,8 +1606,7 @@
addSdkMemberPropertiesToSet(ctx, archInfo.Properties, archTypePropertySet)
for _, linkInfo := range archInfo.linkInfos {
- linkPropertySet := archTypePropertySet.AddPropertySet(linkInfo.linkType)
- addSdkMemberPropertiesToSet(ctx, linkInfo.Properties, linkPropertySet)
+ linkInfo.addToPropertySet(ctx, archTypePropertySet)
}
}
@@ -1640,6 +1637,11 @@
return linkInfo
}
+func (l *linkTypeSpecificInfo) addToPropertySet(ctx *memberContext, propertySet android.BpPropertySet) {
+ linkPropertySet := propertySet.AddPropertySet(l.linkType)
+ addSdkMemberPropertiesToSet(ctx, l.Properties, linkPropertySet)
+}
+
func (l *linkTypeSpecificInfo) String() string {
return fmt.Sprintf("LinkType{%s}", l.linkType)
}