Differentiate between exported and internal sdk members
Internal sdk members are used by an sdk member but not exported by the sdk. The exported sdk members are those listed explicitly in one of the sdk member list properties, e.g. java_header_libs. The prebuilts of an internal sdk member use a unique name so that they do not clash with the source module. The use of the module internally is an implementation detail that must not have any effect outside the snapshot. Having the same name as the source module could cause it to override the source module, hence why it needs a unique name. Similarly, they are marked as private so as to prevent their accidental use from outside the snapshot. Bug: 142940300 Test: m nothing Change-Id: Id5364b410be0592f65666afb3e40e9d3f020251c
This commit is contained in:
parent
7b81f5e9d7
commit
7291095d82
|
@ -588,12 +588,13 @@ func TestSnapshotWithJavaSystemModules(t *testing.T) {
|
|||
result := testSdkWithJava(t, `
|
||||
sdk {
|
||||
name: "mysdk",
|
||||
java_header_libs: ["exported-system-module"],
|
||||
java_system_modules: ["my-system-modules"],
|
||||
}
|
||||
|
||||
java_system_modules {
|
||||
name: "my-system-modules",
|
||||
libs: ["system-module"],
|
||||
libs: ["system-module", "exported-system-module"],
|
||||
}
|
||||
|
||||
java_library {
|
||||
|
@ -602,42 +603,73 @@ func TestSnapshotWithJavaSystemModules(t *testing.T) {
|
|||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "exported-system-module",
|
||||
srcs: ["Test.java"],
|
||||
sdk_version: "none",
|
||||
system_modules: "none",
|
||||
}
|
||||
`)
|
||||
|
||||
result.CheckSnapshot("mysdk", "android_common", "",
|
||||
checkAndroidBpContents(`
|
||||
// This is auto-generated. DO NOT EDIT.
|
||||
|
||||
java_import {
|
||||
name: "mysdk_exported-system-module@current",
|
||||
sdk_member_name: "exported-system-module",
|
||||
jars: ["java/exported-system-module.jar"],
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "exported-system-module",
|
||||
prefer: false,
|
||||
jars: ["java/exported-system-module.jar"],
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "mysdk_system-module@current",
|
||||
sdk_member_name: "system-module",
|
||||
visibility: ["//visibility:private"],
|
||||
jars: ["java/system-module.jar"],
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "system-module",
|
||||
name: "mysdk_system-module",
|
||||
prefer: false,
|
||||
visibility: ["//visibility:private"],
|
||||
jars: ["java/system-module.jar"],
|
||||
}
|
||||
|
||||
java_system_modules_import {
|
||||
name: "mysdk_my-system-modules@current",
|
||||
sdk_member_name: "my-system-modules",
|
||||
libs: ["mysdk_system-module@current"],
|
||||
libs: [
|
||||
"mysdk_system-module@current",
|
||||
"mysdk_exported-system-module@current",
|
||||
],
|
||||
}
|
||||
|
||||
java_system_modules_import {
|
||||
name: "my-system-modules",
|
||||
prefer: false,
|
||||
libs: ["system-module"],
|
||||
libs: [
|
||||
"mysdk_system-module",
|
||||
"exported-system-module",
|
||||
],
|
||||
}
|
||||
|
||||
sdk_snapshot {
|
||||
name: "mysdk@current",
|
||||
java_header_libs: ["mysdk_exported-system-module@current"],
|
||||
java_system_modules: ["mysdk_my-system-modules@current"],
|
||||
}
|
||||
`),
|
||||
checkAllCopyRules(".intermediates/system-module/android_common/turbine-combined/system-module.jar -> java/system-module.jar"),
|
||||
checkAllCopyRules(`
|
||||
.intermediates/exported-system-module/android_common/turbine-combined/exported-system-module.jar -> java/exported-system-module.jar
|
||||
.intermediates/system-module/android_common/turbine-combined/system-module.jar -> java/system-module.jar
|
||||
`),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -677,14 +709,16 @@ func TestHostSnapshotWithJavaSystemModules(t *testing.T) {
|
|||
java_import {
|
||||
name: "mysdk_system-module@current",
|
||||
sdk_member_name: "system-module",
|
||||
visibility: ["//visibility:private"],
|
||||
device_supported: false,
|
||||
host_supported: true,
|
||||
jars: ["java/system-module.jar"],
|
||||
}
|
||||
|
||||
java_import {
|
||||
name: "system-module",
|
||||
name: "mysdk_system-module",
|
||||
prefer: false,
|
||||
visibility: ["//visibility:private"],
|
||||
device_supported: false,
|
||||
host_supported: true,
|
||||
jars: ["java/system-module.jar"],
|
||||
|
@ -703,7 +737,7 @@ java_system_modules_import {
|
|||
prefer: false,
|
||||
device_supported: false,
|
||||
host_supported: true,
|
||||
libs: ["system-module"],
|
||||
libs: ["mysdk_system-module"],
|
||||
}
|
||||
|
||||
sdk_snapshot {
|
||||
|
|
32
sdk/sdk.go
32
sdk/sdk.go
|
@ -50,6 +50,9 @@ type sdk struct {
|
|||
// list properties, e.g. java_libs.
|
||||
dynamicMemberTypeListProperties interface{}
|
||||
|
||||
// The set of exported members.
|
||||
exportedMembers map[string]struct{}
|
||||
|
||||
properties sdkProperties
|
||||
|
||||
snapshotFile android.OptionalPath
|
||||
|
@ -217,6 +220,33 @@ func SnapshotModuleFactory() android.Module {
|
|||
return s
|
||||
}
|
||||
|
||||
func (s *sdk) memberListProperties() []*sdkMemberListProperty {
|
||||
return s.dynamicSdkMemberTypes.memberListProperties
|
||||
}
|
||||
|
||||
func (s *sdk) getExportedMembers() map[string]struct{} {
|
||||
if s.exportedMembers == nil {
|
||||
// Collect all the exported members.
|
||||
s.exportedMembers = make(map[string]struct{})
|
||||
|
||||
for _, memberListProperty := range s.memberListProperties() {
|
||||
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
|
||||
|
||||
// Every member specified explicitly in the properties is exported by the sdk.
|
||||
for _, name := range names {
|
||||
s.exportedMembers[name] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s.exportedMembers
|
||||
}
|
||||
|
||||
func (s *sdk) isInternalMember(memberName string) bool {
|
||||
_, ok := s.getExportedMembers()[memberName]
|
||||
return !ok
|
||||
}
|
||||
|
||||
func (s *sdk) snapshot() bool {
|
||||
return s.properties.Snapshot
|
||||
}
|
||||
|
@ -290,7 +320,7 @@ func (t sdkMemberVersionedDepTag) ExcludeFromVisibilityEnforcement() {}
|
|||
// Step 1: create dependencies from an SDK module to its members.
|
||||
func memberMutator(mctx android.BottomUpMutatorContext) {
|
||||
if s, ok := mctx.Module().(*sdk); ok {
|
||||
for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties {
|
||||
for _, memberListProperty := range s.memberListProperties() {
|
||||
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
|
||||
tag := memberListProperty.dependencyTag
|
||||
memberListProperty.memberType.AddDependencies(mctx, tag, names)
|
||||
|
|
|
@ -130,7 +130,9 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember {
|
|||
byType[memberType] = append(byType[memberType], member)
|
||||
}
|
||||
|
||||
member.variants = append(member.variants, child.(android.SdkAware))
|
||||
// Only append new variants to the list. This is needed because a member can be both
|
||||
// exported by the sdk and also be a transitive sdk member.
|
||||
member.variants = appendUniqueVariants(member.variants, child.(android.SdkAware))
|
||||
|
||||
// If the member type supports transitive sdk members then recurse down into
|
||||
// its dependencies, otherwise exit traversal.
|
||||
|
@ -141,7 +143,7 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember {
|
|||
})
|
||||
|
||||
var members []*sdkMember
|
||||
for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties {
|
||||
for _, memberListProperty := range s.memberListProperties() {
|
||||
membersOfType := byType[memberListProperty.memberType]
|
||||
members = append(members, membersOfType...)
|
||||
}
|
||||
|
@ -149,6 +151,15 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember {
|
|||
return members
|
||||
}
|
||||
|
||||
func appendUniqueVariants(variants []android.SdkAware, newVariant android.SdkAware) []android.SdkAware {
|
||||
for _, v := range variants {
|
||||
if v == newVariant {
|
||||
return variants
|
||||
}
|
||||
}
|
||||
return append(variants, newVariant)
|
||||
}
|
||||
|
||||
// SDK directory structure
|
||||
// <sdk_root>/
|
||||
// Android.bp : definition of a 'sdk' module is here. This is a hand-made one.
|
||||
|
@ -203,17 +214,20 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
|
|||
// Create a transformer that will transform an unversioned module into a versioned module.
|
||||
unversionedToVersionedTransformer := unversionedToVersionedTransformation{builder: builder}
|
||||
|
||||
// Create a transformer that will transform an unversioned module by replacing any references
|
||||
// to internal members with a unique module name and setting prefer: false.
|
||||
unversionedTransformer := unversionedTransformation{builder: builder}
|
||||
|
||||
for _, unversioned := range builder.prebuiltOrder {
|
||||
// Copy the unversioned module so it can be modified to make it versioned.
|
||||
versioned := unversioned.deepCopy()
|
||||
|
||||
// Transform the unversioned module into a versioned one.
|
||||
versioned.transform(unversionedToVersionedTransformer)
|
||||
|
||||
bpFile.AddModule(versioned)
|
||||
|
||||
// Set prefer: false - this is not strictly required as that is the default.
|
||||
unversioned.insertAfter("name", "prefer", false)
|
||||
// Transform the unversioned module to make it suitable for use in the snapshot.
|
||||
unversioned.transform(unversionedTransformer)
|
||||
bpFile.AddModule(unversioned)
|
||||
}
|
||||
|
||||
|
@ -235,7 +249,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
|
|||
}
|
||||
|
||||
addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule)
|
||||
for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties {
|
||||
for _, memberListProperty := range s.memberListProperties() {
|
||||
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
|
||||
if len(names) > 0 {
|
||||
snapshotModule.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names))
|
||||
|
@ -319,6 +333,30 @@ func (t unversionedToVersionedTransformation) transformProperty(name string, val
|
|||
}
|
||||
}
|
||||
|
||||
type unversionedTransformation struct {
|
||||
identityTransformation
|
||||
builder *snapshotBuilder
|
||||
}
|
||||
|
||||
func (t unversionedTransformation) transformModule(module *bpModule) *bpModule {
|
||||
// If the module is an internal member then use a unique name for it.
|
||||
name := module.getValue("name").(string)
|
||||
module.setProperty("name", t.builder.unversionedSdkMemberName(name))
|
||||
|
||||
// Set prefer: false - this is not strictly required as that is the default.
|
||||
module.insertAfter("name", "prefer", false)
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
func (t unversionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
|
||||
if tag == sdkMemberReferencePropertyTag {
|
||||
return t.builder.unversionedSdkMemberNames(value.([]string)), tag
|
||||
} else {
|
||||
return value, tag
|
||||
}
|
||||
}
|
||||
|
||||
func generateBpContents(contents *generatedContents, bpFile *bpFile) {
|
||||
contents.Printfln("// This is auto-generated. DO NOT EDIT.")
|
||||
for _, bpModule := range bpFile.order {
|
||||
|
@ -442,11 +480,17 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType
|
|||
m := s.bpFile.newModule(moduleType)
|
||||
m.AddProperty("name", name)
|
||||
|
||||
// Extract visibility information from a member variant. All variants have the same
|
||||
// visibility so it doesn't matter which one is used.
|
||||
visibility := android.EffectiveVisibilityRules(s.ctx, member.Variants()[0])
|
||||
if len(visibility) != 0 {
|
||||
m.AddProperty("visibility", visibility)
|
||||
if s.sdk.isInternalMember(name) {
|
||||
// An internal member is only referenced from the sdk snapshot which is in the
|
||||
// same package so can be marked as private.
|
||||
m.AddProperty("visibility", []string{"//visibility:private"})
|
||||
} else {
|
||||
// Extract visibility information from a member variant. All variants have the same
|
||||
// visibility so it doesn't matter which one is used.
|
||||
visibility := android.EffectiveVisibilityRules(s.ctx, member.Variants()[0])
|
||||
if len(visibility) != 0 {
|
||||
m.AddProperty("visibility", visibility)
|
||||
}
|
||||
}
|
||||
|
||||
addHostDeviceSupportedProperties(&s.sdk.ModuleBase, m)
|
||||
|
@ -482,6 +526,23 @@ func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string {
|
|||
return references
|
||||
}
|
||||
|
||||
// Get an internal name unique to the sdk.
|
||||
func (s *snapshotBuilder) unversionedSdkMemberName(unversionedName string) string {
|
||||
if s.sdk.isInternalMember(unversionedName) {
|
||||
return s.ctx.ModuleName() + "_" + unversionedName
|
||||
} else {
|
||||
return unversionedName
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snapshotBuilder) unversionedSdkMemberNames(members []string) []string {
|
||||
var references []string = nil
|
||||
for _, m := range members {
|
||||
references = append(references, s.unversionedSdkMemberName(m))
|
||||
}
|
||||
return references
|
||||
}
|
||||
|
||||
var _ android.SdkMember = (*sdkMember)(nil)
|
||||
|
||||
type sdkMember struct {
|
||||
|
|
Loading…
Reference in New Issue