From b0bb376efae63aa0493bd241ff057b7bfabb2f91 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Thu, 6 May 2021 16:48:05 +0100 Subject: [PATCH] Add license modules to the sdk Adds initial support for adding license modules to the sdk, along with any referenced license text files. There is a number of minor improvements to be made but the core of the support is there and it works for ART sdks. Basically, this change will automatically add license modules referenced from any sdk member module as an internal sdk member. An internal module has an sdk snapshot specific name that will not conflict with the source module and which cannot be referenced from outside the sdk snapshot. Bug: 181569894 Test: m art-module-sdk art-module-host-exports art-module-test-exports - diff output before and after this change made sure that every prebuilt had a licenses field and that the license modules were added Change-Id: I0c5ccabf58f4ef487e42ef8e61a5b2a74c0e81af --- android/Android.bp | 1 + android/license_sdk_member.go | 118 ++++++++++++++++++++++++++++++++++ android/licenses.go | 33 +++++++++- sdk/license_sdk_test.go | 35 +++++++++- sdk/update.go | 13 ++++ 5 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 android/license_sdk_member.go diff --git a/android/Android.bp b/android/Android.bp index 6124654a4..5d0f2b941 100644 --- a/android/Android.bp +++ b/android/Android.bp @@ -42,6 +42,7 @@ bootstrap_go_package { "image.go", "license.go", "license_kind.go", + "license_sdk_member.go", "licenses.go", "makefile_goal.go", "makevars.go", diff --git a/android/license_sdk_member.go b/android/license_sdk_member.go new file mode 100644 index 000000000..cd36ed6c5 --- /dev/null +++ b/android/license_sdk_member.go @@ -0,0 +1,118 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package android + +import ( + "path/filepath" + + "github.com/google/blueprint" +) + +// Contains support for adding license modules to an sdk. + +func init() { + RegisterSdkMemberType(LicenseModuleSdkMemberType) +} + +// licenseSdkMemberType determines how a license module is added to the sdk. +type licenseSdkMemberType struct { + SdkMemberTypeBase +} + +func (l *licenseSdkMemberType) AddDependencies(mctx BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { + // Add dependencies onto the license module from the sdk module. + mctx.AddDependency(mctx.Module(), dependencyTag, names...) +} + +func (l *licenseSdkMemberType) IsInstance(module Module) bool { + // Verify that the module being added is compatible with this module type. + _, ok := module.(*licenseModule) + return ok +} + +func (l *licenseSdkMemberType) AddPrebuiltModule(ctx SdkMemberContext, member SdkMember) BpModule { + // Add the basics of a prebuilt module. + return ctx.SnapshotBuilder().AddPrebuiltModule(member, "license") +} + +func (l *licenseSdkMemberType) CreateVariantPropertiesStruct() SdkMemberProperties { + // Create the structure into which the properties of the license module that need to be output to + // the snapshot will be placed. The structure may be populated with information from a variant or + // may be used as the destination for properties that are common to a set of variants. + return &licenseSdkMemberProperties{} +} + +// LicenseModuleSdkMemberType is the instance of licenseSdkMemberType +var LicenseModuleSdkMemberType = &licenseSdkMemberType{ + SdkMemberTypeBase{ + PropertyName: "licenses", + + // This should never be added directly to an sdk/module_exports, all license modules should be + // added indirectly as transitive dependencies of other sdk members. + BpPropertyNotRequired: true, + + SupportsSdk: true, + + // The snapshot of the license module is just another license module (not a prebuilt). They are + // internal modules only so will have an sdk specific name that will not clash with the + // originating source module. + UseSourceModuleTypeInSnapshot: true, + }, +} + +var _ SdkMemberType = (*licenseSdkMemberType)(nil) + +// licenseSdkMemberProperties is the set of properties that need to be added to the license module +// in the snapshot. +type licenseSdkMemberProperties struct { + SdkMemberPropertiesBase + + // The kinds of licenses provided by the module. + License_kinds []string + + // The source paths to the files containing license text. + License_text Paths +} + +func (p *licenseSdkMemberProperties) PopulateFromVariant(_ SdkMemberContext, variant Module) { + // Populate the properties from the variant. + l := variant.(*licenseModule) + p.License_kinds = l.properties.License_kinds + p.License_text = l.base().commonProperties.Effective_license_text +} + +func (p *licenseSdkMemberProperties) AddToPropertySet(ctx SdkMemberContext, propertySet BpPropertySet) { + // Just pass any specified license_kinds straight through. + if len(p.License_kinds) > 0 { + propertySet.AddProperty("license_kinds", p.License_kinds) + } + + // Copy any license test files to the snapshot into a module specific location. + if len(p.License_text) > 0 { + dests := []string{} + for _, path := range p.License_text { + // The destination path only uses the path of the license file in the source not the license + // module name. That ensures that if the same license file is used by multiple license modules + // that it only gets copied once as the snapshot builder will dedup copies where the source + // and destination match. + dest := filepath.Join("licenses", path.String()) + dests = append(dests, dest) + ctx.SnapshotBuilder().CopyToSnapshot(path, dest) + } + propertySet.AddProperty("license_text", dests) + } +} + +var _ SdkMemberProperties = (*licenseSdkMemberProperties)(nil) diff --git a/android/licenses.go b/android/licenses.go index c9e1da40f..464ba49b4 100644 --- a/android/licenses.go +++ b/android/licenses.go @@ -32,8 +32,23 @@ type licensesDependencyTag struct { blueprint.BaseDependencyTag } +func (l licensesDependencyTag) SdkMemberType(Module) SdkMemberType { + // Add the supplied module to the sdk as a license module. + return LicenseModuleSdkMemberType +} + +func (l licensesDependencyTag) ExportMember() bool { + // The license module will only every be referenced from within the sdk. This will ensure that it + // gets a unique name and so avoid clashing with the original license module. + return false +} + var ( licensesTag = licensesDependencyTag{} + + // 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 ) // Describes the property provided by a module to reference applicable licenses. @@ -140,7 +155,6 @@ func licensesPropertyGatherer(ctx BottomUpMutatorContext) { } licenses := getLicenses(ctx, m) - ctx.AddVariationDependencies(nil, licensesTag, licenses...) } @@ -191,8 +205,10 @@ func licensesPropertyFlattener(ctx ModuleContext) { return } + var licenses []string for _, module := range ctx.GetDirectDepsWithTag(licensesTag) { if l, ok := module.(*licenseModule); ok { + licenses = append(licenses, ctx.OtherModuleName(module)) if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil { m.base().commonProperties.Effective_package_name = l.properties.Package_name } @@ -209,6 +225,12 @@ func licensesPropertyFlattener(ctx ModuleContext) { ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module)) } } + + // Make the license information available for other modules. + licenseInfo := LicenseInfo{ + Licenses: licenses, + } + ctx.SetProvider(LicenseInfoProvider, licenseInfo) } // Update a property string array with a distinct union of its values and a list of new values. @@ -277,3 +299,12 @@ func exemptFromRequiredApplicableLicensesProperty(module Module) bool { } return true } + +// LicenseInfo contains information about licenses for a specific module. +type LicenseInfo struct { + // The list of license modules this depends upon, either explicitly or through default package + // configuration. + Licenses []string +} + +var LicenseInfoProvider = blueprint.NewProvider(LicenseInfo{}) diff --git a/sdk/license_sdk_test.go b/sdk/license_sdk_test.go index 9d6ab0698..97ac6a94f 100644 --- a/sdk/license_sdk_test.go +++ b/sdk/license_sdk_test.go @@ -68,9 +68,23 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], + licenses: ["mysdk_mylicense"], jars: ["java/myjavalib.jar"], } -`), + +license { + name: "mysdk_mylicense", + visibility: ["//visibility:private"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "legacy_unencumbered", + ], + license_text: [ + "licenses/NOTICE1", + "licenses/NOTICE2", + ], +} + `), checkVersionedAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -79,17 +93,34 @@ java_import { sdk_member_name: "myjavalib", visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], + licenses: ["mysdk_mylicense@current"], jars: ["java/myjavalib.jar"], } +license { + name: "mysdk_mylicense@current", + sdk_member_name: "mylicense", + visibility: ["//visibility:private"], + license_kinds: [ + "SPDX-license-identifier-Apache-2.0", + "legacy_unencumbered", + ], + license_text: [ + "licenses/NOTICE1", + "licenses/NOTICE2", + ], +} + sdk_snapshot { name: "mysdk@current", visibility: ["//visibility:public"], java_header_libs: ["mysdk_myjavalib@current"], } -`), + `), checkAllCopyRules(` .intermediates/myjavalib/android_common/turbine-combined/myjavalib.jar -> java/myjavalib.jar +NOTICE1 -> licenses/NOTICE1 +NOTICE2 -> licenses/NOTICE2 `), ) } diff --git a/sdk/update.go b/sdk/update.go index a265676e7..deac0ec20 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -893,6 +893,13 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType m.AddProperty("apex_available", apexAvailable) } + // The licenses are the same for all variants. + mctx := s.ctx + licenseInfo := mctx.OtherModuleProvider(variant, android.LicenseInfoProvider).(android.LicenseInfo) + if len(licenseInfo.Licenses) > 0 { + m.AddPropertyWithTag("licenses", licenseInfo.Licenses, s.OptionalSdkMemberReferencePropertyTag()) + } + deviceSupported := false hostSupported := false @@ -920,6 +927,12 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType } func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, bpModule *bpModule) { + // If neither device or host is supported then this module does not support either so will not + // recognize the properties. + if !deviceSupported && !hostSupported { + return + } + if !deviceSupported { bpModule.AddProperty("device_supported", false) }