xref: /aosp_15_r20/build/soong/android/licenses.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"fmt"
19*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
20*333d2b36SAndroid Build Coastguard Worker	"reflect"
21*333d2b36SAndroid Build Coastguard Worker	"strings"
22*333d2b36SAndroid Build Coastguard Worker	"sync"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker// Adds cross-cutting licenses dependency to propagate license metadata through the build system.
28*333d2b36SAndroid Build Coastguard Worker//
29*333d2b36SAndroid Build Coastguard Worker// Stage 1 - bottom-up records package-level default_applicable_licenses property mapped by package name.
30*333d2b36SAndroid Build Coastguard Worker// Stage 2 - bottom-up converts licenses property or package default_applicable_licenses to dependencies.
31*333d2b36SAndroid Build Coastguard Worker// Stage 3 - bottom-up type-checks every added applicable license dependency and license_kind dependency.
32*333d2b36SAndroid Build Coastguard Worker// Stage 4 - GenerateBuildActions calculates properties for the union of license kinds, conditions and texts.
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workertype licensesDependencyTag struct {
35*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
36*333d2b36SAndroid Build Coastguard Worker}
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workerfunc (l licensesDependencyTag) SdkMemberType(Module) SdkMemberType {
39*333d2b36SAndroid Build Coastguard Worker	// Add the supplied module to the sdk as a license module.
40*333d2b36SAndroid Build Coastguard Worker	return LicenseModuleSdkMemberType
41*333d2b36SAndroid Build Coastguard Worker}
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard Workerfunc (l licensesDependencyTag) ExportMember() bool {
44*333d2b36SAndroid Build Coastguard Worker	// The license module will only every be referenced from within the sdk. This will ensure that it
45*333d2b36SAndroid Build Coastguard Worker	// gets a unique name and so avoid clashing with the original license module.
46*333d2b36SAndroid Build Coastguard Worker	return false
47*333d2b36SAndroid Build Coastguard Worker}
48*333d2b36SAndroid Build Coastguard Worker
49*333d2b36SAndroid Build Coastguard Workervar (
50*333d2b36SAndroid Build Coastguard Worker	licensesTag = licensesDependencyTag{}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Worker	// License modules, i.e. modules depended upon via a licensesTag, must be automatically added to
53*333d2b36SAndroid Build Coastguard Worker	// any sdk/module_exports to which their referencing module is a member.
54*333d2b36SAndroid Build Coastguard Worker	_ SdkMemberDependencyTag = licensesTag
55*333d2b36SAndroid Build Coastguard Worker)
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker// Describes the property provided by a module to reference applicable licenses.
58*333d2b36SAndroid Build Coastguard Workertype applicableLicensesProperty interface {
59*333d2b36SAndroid Build Coastguard Worker	// The name of the property. e.g. default_applicable_licenses or licenses
60*333d2b36SAndroid Build Coastguard Worker	getName() string
61*333d2b36SAndroid Build Coastguard Worker	// The values assigned to the property. (Must reference license modules.)
62*333d2b36SAndroid Build Coastguard Worker	getStrings() []string
63*333d2b36SAndroid Build Coastguard Worker}
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Workertype applicableLicensesPropertyImpl struct {
66*333d2b36SAndroid Build Coastguard Worker	name             string
67*333d2b36SAndroid Build Coastguard Worker	licensesProperty *[]string
68*333d2b36SAndroid Build Coastguard Worker}
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard Workerfunc newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
71*333d2b36SAndroid Build Coastguard Worker	return applicableLicensesPropertyImpl{
72*333d2b36SAndroid Build Coastguard Worker		name:             name,
73*333d2b36SAndroid Build Coastguard Worker		licensesProperty: licensesProperty,
74*333d2b36SAndroid Build Coastguard Worker	}
75*333d2b36SAndroid Build Coastguard Worker}
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Workerfunc (p applicableLicensesPropertyImpl) getName() string {
78*333d2b36SAndroid Build Coastguard Worker	return p.name
79*333d2b36SAndroid Build Coastguard Worker}
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Workerfunc (p applicableLicensesPropertyImpl) getStrings() []string {
82*333d2b36SAndroid Build Coastguard Worker	return *p.licensesProperty
83*333d2b36SAndroid Build Coastguard Worker}
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker// Set the primary applicable licenses property for a module.
86*333d2b36SAndroid Build Coastguard Workerfunc setPrimaryLicensesProperty(module Module, name string, licensesProperty *[]string) {
87*333d2b36SAndroid Build Coastguard Worker	module.base().primaryLicensesProperty = newApplicableLicensesProperty(name, licensesProperty)
88*333d2b36SAndroid Build Coastguard Worker}
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Worker// Storage blob for a package's default_applicable_licenses mapped by package directory.
91*333d2b36SAndroid Build Coastguard Workertype licensesContainer struct {
92*333d2b36SAndroid Build Coastguard Worker	licenses []string
93*333d2b36SAndroid Build Coastguard Worker}
94*333d2b36SAndroid Build Coastguard Worker
95*333d2b36SAndroid Build Coastguard Workerfunc (r licensesContainer) getLicenses() []string {
96*333d2b36SAndroid Build Coastguard Worker	return r.licenses
97*333d2b36SAndroid Build Coastguard Worker}
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Workervar packageDefaultLicensesMap = NewOnceKey("packageDefaultLicensesMap")
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker// The map from package dir name to default applicable licenses as a licensesContainer.
102*333d2b36SAndroid Build Coastguard Workerfunc moduleToPackageDefaultLicensesMap(config Config) *sync.Map {
103*333d2b36SAndroid Build Coastguard Worker	return config.Once(packageDefaultLicensesMap, func() interface{} {
104*333d2b36SAndroid Build Coastguard Worker		return &sync.Map{}
105*333d2b36SAndroid Build Coastguard Worker	}).(*sync.Map)
106*333d2b36SAndroid Build Coastguard Worker}
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker// Registers the function that maps each package to its default_applicable_licenses.
109*333d2b36SAndroid Build Coastguard Worker//
110*333d2b36SAndroid Build Coastguard Worker// This goes before defaults expansion so the defaults can pick up the package default.
111*333d2b36SAndroid Build Coastguard Workerfunc RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
112*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("licensesPackageMapper", licensesPackageMapper)
113*333d2b36SAndroid Build Coastguard Worker}
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker// Registers the function that gathers the license dependencies for each module.
116*333d2b36SAndroid Build Coastguard Worker//
117*333d2b36SAndroid Build Coastguard Worker// This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
118*333d2b36SAndroid Build Coastguard Workerfunc RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
119*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer)
120*333d2b36SAndroid Build Coastguard Worker}
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard Worker// Registers the function that verifies the licenses and license_kinds dependency types for each module.
123*333d2b36SAndroid Build Coastguard Workerfunc RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
124*333d2b36SAndroid Build Coastguard Worker	ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker)
125*333d2b36SAndroid Build Coastguard Worker}
126*333d2b36SAndroid Build Coastguard Worker
127*333d2b36SAndroid Build Coastguard Worker// Maps each package to its default applicable licenses.
128*333d2b36SAndroid Build Coastguard Workerfunc licensesPackageMapper(ctx BottomUpMutatorContext) {
129*333d2b36SAndroid Build Coastguard Worker	p, ok := ctx.Module().(*packageModule)
130*333d2b36SAndroid Build Coastguard Worker	if !ok {
131*333d2b36SAndroid Build Coastguard Worker		return
132*333d2b36SAndroid Build Coastguard Worker	}
133*333d2b36SAndroid Build Coastguard Worker
134*333d2b36SAndroid Build Coastguard Worker	licenses := getLicenses(ctx, p)
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Worker	dir := ctx.ModuleDir()
137*333d2b36SAndroid Build Coastguard Worker	c := makeLicensesContainer(licenses)
138*333d2b36SAndroid Build Coastguard Worker	moduleToPackageDefaultLicensesMap(ctx.Config()).Store(dir, c)
139*333d2b36SAndroid Build Coastguard Worker}
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker// Copies the default_applicable_licenses property values for mapping by package directory.
142*333d2b36SAndroid Build Coastguard Workerfunc makeLicensesContainer(propVals []string) licensesContainer {
143*333d2b36SAndroid Build Coastguard Worker	licenses := make([]string, 0, len(propVals))
144*333d2b36SAndroid Build Coastguard Worker	licenses = append(licenses, propVals...)
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Worker	return licensesContainer{licenses}
147*333d2b36SAndroid Build Coastguard Worker}
148*333d2b36SAndroid Build Coastguard Worker
149*333d2b36SAndroid Build Coastguard Worker// Gathers the applicable licenses into dependency references after defaults expansion.
150*333d2b36SAndroid Build Coastguard Workerfunc licensesPropertyGatherer(ctx BottomUpMutatorContext) {
151*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(Module)
152*333d2b36SAndroid Build Coastguard Worker	if !ok {
153*333d2b36SAndroid Build Coastguard Worker		return
154*333d2b36SAndroid Build Coastguard Worker	}
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Worker	if exemptFromRequiredApplicableLicensesProperty(m) {
157*333d2b36SAndroid Build Coastguard Worker		return
158*333d2b36SAndroid Build Coastguard Worker	}
159*333d2b36SAndroid Build Coastguard Worker
160*333d2b36SAndroid Build Coastguard Worker	licenses := getLicenses(ctx, m)
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard Worker	var fullyQualifiedLicenseNames []string
163*333d2b36SAndroid Build Coastguard Worker	for _, license := range licenses {
164*333d2b36SAndroid Build Coastguard Worker		fullyQualifiedLicenseName := license
165*333d2b36SAndroid Build Coastguard Worker		if !strings.HasPrefix(license, "//") {
166*333d2b36SAndroid Build Coastguard Worker			licenseModuleDir := ctx.OtherModuleDir(m)
167*333d2b36SAndroid Build Coastguard Worker			for licenseModuleDir != "." && !ctx.OtherModuleExists(fmt.Sprintf("//%s:%s", licenseModuleDir, license)) {
168*333d2b36SAndroid Build Coastguard Worker				licenseModuleDir = filepath.Dir(licenseModuleDir)
169*333d2b36SAndroid Build Coastguard Worker			}
170*333d2b36SAndroid Build Coastguard Worker			if licenseModuleDir == "." {
171*333d2b36SAndroid Build Coastguard Worker				fullyQualifiedLicenseName = license
172*333d2b36SAndroid Build Coastguard Worker			} else {
173*333d2b36SAndroid Build Coastguard Worker				fullyQualifiedLicenseName = fmt.Sprintf("//%s:%s", licenseModuleDir, license)
174*333d2b36SAndroid Build Coastguard Worker			}
175*333d2b36SAndroid Build Coastguard Worker		}
176*333d2b36SAndroid Build Coastguard Worker		fullyQualifiedLicenseNames = append(fullyQualifiedLicenseNames, fullyQualifiedLicenseName)
177*333d2b36SAndroid Build Coastguard Worker	}
178*333d2b36SAndroid Build Coastguard Worker
179*333d2b36SAndroid Build Coastguard Worker	ctx.AddVariationDependencies(nil, licensesTag, fullyQualifiedLicenseNames...)
180*333d2b36SAndroid Build Coastguard Worker}
181*333d2b36SAndroid Build Coastguard Worker
182*333d2b36SAndroid Build Coastguard Worker// Verifies the license and license_kind dependencies are each the correct kind of module.
183*333d2b36SAndroid Build Coastguard Workerfunc licensesDependencyChecker(ctx BottomUpMutatorContext) {
184*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(Module)
185*333d2b36SAndroid Build Coastguard Worker	if !ok {
186*333d2b36SAndroid Build Coastguard Worker		return
187*333d2b36SAndroid Build Coastguard Worker	}
188*333d2b36SAndroid Build Coastguard Worker
189*333d2b36SAndroid Build Coastguard Worker	// license modules have no licenses, but license_kinds must refer to license_kind modules
190*333d2b36SAndroid Build Coastguard Worker	if _, ok := m.(*licenseModule); ok {
191*333d2b36SAndroid Build Coastguard Worker		for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
192*333d2b36SAndroid Build Coastguard Worker			if _, ok := module.(*licenseKindModule); !ok {
193*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
194*333d2b36SAndroid Build Coastguard Worker			}
195*333d2b36SAndroid Build Coastguard Worker		}
196*333d2b36SAndroid Build Coastguard Worker		return
197*333d2b36SAndroid Build Coastguard Worker	}
198*333d2b36SAndroid Build Coastguard Worker
199*333d2b36SAndroid Build Coastguard Worker	if exemptFromRequiredApplicableLicensesProperty(m) {
200*333d2b36SAndroid Build Coastguard Worker		return
201*333d2b36SAndroid Build Coastguard Worker	}
202*333d2b36SAndroid Build Coastguard Worker
203*333d2b36SAndroid Build Coastguard Worker	for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
204*333d2b36SAndroid Build Coastguard Worker		if _, ok := module.(*licenseModule); !ok {
205*333d2b36SAndroid Build Coastguard Worker			propertyName := "licenses"
206*333d2b36SAndroid Build Coastguard Worker			primaryProperty := m.base().primaryLicensesProperty
207*333d2b36SAndroid Build Coastguard Worker			if primaryProperty != nil {
208*333d2b36SAndroid Build Coastguard Worker				propertyName = primaryProperty.getName()
209*333d2b36SAndroid Build Coastguard Worker			}
210*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
211*333d2b36SAndroid Build Coastguard Worker		}
212*333d2b36SAndroid Build Coastguard Worker	}
213*333d2b36SAndroid Build Coastguard Worker}
214*333d2b36SAndroid Build Coastguard Worker
215*333d2b36SAndroid Build Coastguard Worker// Flattens license and license_kind dependencies into calculated properties.
216*333d2b36SAndroid Build Coastguard Worker//
217*333d2b36SAndroid Build Coastguard Worker// Re-validates applicable licenses properties refer only to license modules and license_kinds properties refer
218*333d2b36SAndroid Build Coastguard Worker// only to license_kind modules.
219*333d2b36SAndroid Build Coastguard Workerfunc licensesPropertyFlattener(ctx ModuleContext) {
220*333d2b36SAndroid Build Coastguard Worker	m, ok := ctx.Module().(Module)
221*333d2b36SAndroid Build Coastguard Worker	if !ok {
222*333d2b36SAndroid Build Coastguard Worker		return
223*333d2b36SAndroid Build Coastguard Worker	}
224*333d2b36SAndroid Build Coastguard Worker
225*333d2b36SAndroid Build Coastguard Worker	if exemptFromRequiredApplicableLicensesProperty(m) {
226*333d2b36SAndroid Build Coastguard Worker		return
227*333d2b36SAndroid Build Coastguard Worker	}
228*333d2b36SAndroid Build Coastguard Worker
229*333d2b36SAndroid Build Coastguard Worker	var licenses []string
230*333d2b36SAndroid Build Coastguard Worker	for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
231*333d2b36SAndroid Build Coastguard Worker		if l, ok := module.(*licenseModule); ok {
232*333d2b36SAndroid Build Coastguard Worker			licenses = append(licenses, ctx.OtherModuleName(module))
233*333d2b36SAndroid Build Coastguard Worker			if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
234*333d2b36SAndroid Build Coastguard Worker				m.base().commonProperties.Effective_package_name = l.properties.Package_name
235*333d2b36SAndroid Build Coastguard Worker			}
236*333d2b36SAndroid Build Coastguard Worker			mergeStringProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
237*333d2b36SAndroid Build Coastguard Worker			mergeNamedPathProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
238*333d2b36SAndroid Build Coastguard Worker			mergeStringProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
239*333d2b36SAndroid Build Coastguard Worker			mergeStringProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
240*333d2b36SAndroid Build Coastguard Worker		} else {
241*333d2b36SAndroid Build Coastguard Worker			propertyName := "licenses"
242*333d2b36SAndroid Build Coastguard Worker			primaryProperty := m.base().primaryLicensesProperty
243*333d2b36SAndroid Build Coastguard Worker			if primaryProperty != nil {
244*333d2b36SAndroid Build Coastguard Worker				propertyName = primaryProperty.getName()
245*333d2b36SAndroid Build Coastguard Worker			}
246*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
247*333d2b36SAndroid Build Coastguard Worker		}
248*333d2b36SAndroid Build Coastguard Worker	}
249*333d2b36SAndroid Build Coastguard Worker
250*333d2b36SAndroid Build Coastguard Worker	// Make the license information available for other modules.
251*333d2b36SAndroid Build Coastguard Worker	licenseInfo := LicenseInfo{
252*333d2b36SAndroid Build Coastguard Worker		Licenses: licenses,
253*333d2b36SAndroid Build Coastguard Worker	}
254*333d2b36SAndroid Build Coastguard Worker	SetProvider(ctx, LicenseInfoProvider, licenseInfo)
255*333d2b36SAndroid Build Coastguard Worker}
256*333d2b36SAndroid Build Coastguard Worker
257*333d2b36SAndroid Build Coastguard Worker// Update a property string array with a distinct union of its values and a list of new values.
258*333d2b36SAndroid Build Coastguard Workerfunc mergeStringProps(prop *[]string, values ...string) {
259*333d2b36SAndroid Build Coastguard Worker	*prop = append(*prop, values...)
260*333d2b36SAndroid Build Coastguard Worker	*prop = SortedUniqueStrings(*prop)
261*333d2b36SAndroid Build Coastguard Worker}
262*333d2b36SAndroid Build Coastguard Worker
263*333d2b36SAndroid Build Coastguard Worker// Update a property NamedPath array with a distinct union of its values and a list of new values.
264*333d2b36SAndroid Build Coastguard Workerfunc namePathProps(prop *NamedPaths, name *string, values ...Path) {
265*333d2b36SAndroid Build Coastguard Worker	if name == nil {
266*333d2b36SAndroid Build Coastguard Worker		for _, value := range values {
267*333d2b36SAndroid Build Coastguard Worker			*prop = append(*prop, NamedPath{value, ""})
268*333d2b36SAndroid Build Coastguard Worker		}
269*333d2b36SAndroid Build Coastguard Worker	} else {
270*333d2b36SAndroid Build Coastguard Worker		for _, value := range values {
271*333d2b36SAndroid Build Coastguard Worker			*prop = append(*prop, NamedPath{value, *name})
272*333d2b36SAndroid Build Coastguard Worker		}
273*333d2b36SAndroid Build Coastguard Worker	}
274*333d2b36SAndroid Build Coastguard Worker	*prop = SortedUniqueNamedPaths(*prop)
275*333d2b36SAndroid Build Coastguard Worker}
276*333d2b36SAndroid Build Coastguard Worker
277*333d2b36SAndroid Build Coastguard Worker// Update a property NamedPath array with a distinct union of its values and a list of new values.
278*333d2b36SAndroid Build Coastguard Workerfunc mergeNamedPathProps(prop *NamedPaths, values ...NamedPath) {
279*333d2b36SAndroid Build Coastguard Worker	*prop = append(*prop, values...)
280*333d2b36SAndroid Build Coastguard Worker	*prop = SortedUniqueNamedPaths(*prop)
281*333d2b36SAndroid Build Coastguard Worker}
282*333d2b36SAndroid Build Coastguard Worker
283*333d2b36SAndroid Build Coastguard Worker// Get the licenses property falling back to the package default.
284*333d2b36SAndroid Build Coastguard Workerfunc getLicenses(ctx BaseModuleContext, module Module) []string {
285*333d2b36SAndroid Build Coastguard Worker	if exemptFromRequiredApplicableLicensesProperty(module) {
286*333d2b36SAndroid Build Coastguard Worker		return nil
287*333d2b36SAndroid Build Coastguard Worker	}
288*333d2b36SAndroid Build Coastguard Worker
289*333d2b36SAndroid Build Coastguard Worker	primaryProperty := module.base().primaryLicensesProperty
290*333d2b36SAndroid Build Coastguard Worker	if primaryProperty == nil {
291*333d2b36SAndroid Build Coastguard Worker		if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
292*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
293*333d2b36SAndroid Build Coastguard Worker		}
294*333d2b36SAndroid Build Coastguard Worker		return nil
295*333d2b36SAndroid Build Coastguard Worker	}
296*333d2b36SAndroid Build Coastguard Worker
297*333d2b36SAndroid Build Coastguard Worker	licenses := primaryProperty.getStrings()
298*333d2b36SAndroid Build Coastguard Worker	if len(licenses) > 0 {
299*333d2b36SAndroid Build Coastguard Worker		s := make(map[string]bool)
300*333d2b36SAndroid Build Coastguard Worker		for _, l := range licenses {
301*333d2b36SAndroid Build Coastguard Worker			if _, ok := s[l]; ok {
302*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("duplicate %q %s", l, primaryProperty.getName())
303*333d2b36SAndroid Build Coastguard Worker			}
304*333d2b36SAndroid Build Coastguard Worker			s[l] = true
305*333d2b36SAndroid Build Coastguard Worker		}
306*333d2b36SAndroid Build Coastguard Worker		return licenses
307*333d2b36SAndroid Build Coastguard Worker	}
308*333d2b36SAndroid Build Coastguard Worker
309*333d2b36SAndroid Build Coastguard Worker	dir := ctx.OtherModuleDir(module)
310*333d2b36SAndroid Build Coastguard Worker
311*333d2b36SAndroid Build Coastguard Worker	moduleToApplicableLicenses := moduleToPackageDefaultLicensesMap(ctx.Config())
312*333d2b36SAndroid Build Coastguard Worker	value, ok := moduleToApplicableLicenses.Load(dir)
313*333d2b36SAndroid Build Coastguard Worker	var c licensesContainer
314*333d2b36SAndroid Build Coastguard Worker	if ok {
315*333d2b36SAndroid Build Coastguard Worker		c = value.(licensesContainer)
316*333d2b36SAndroid Build Coastguard Worker	} else {
317*333d2b36SAndroid Build Coastguard Worker		c = licensesContainer{}
318*333d2b36SAndroid Build Coastguard Worker	}
319*333d2b36SAndroid Build Coastguard Worker	return c.getLicenses()
320*333d2b36SAndroid Build Coastguard Worker}
321*333d2b36SAndroid Build Coastguard Worker
322*333d2b36SAndroid Build Coastguard Worker// Returns whether a module is an allowed list of modules that do not have or need applicable licenses.
323*333d2b36SAndroid Build Coastguard Workerfunc exemptFromRequiredApplicableLicensesProperty(module Module) bool {
324*333d2b36SAndroid Build Coastguard Worker	switch reflect.TypeOf(module).String() {
325*333d2b36SAndroid Build Coastguard Worker	case "*android.licenseModule": // is a license, doesn't need one
326*333d2b36SAndroid Build Coastguard Worker	case "*android.licenseKindModule": // is a license, doesn't need one
327*333d2b36SAndroid Build Coastguard Worker	case "*android.genNoticeModule": // contains license texts as data
328*333d2b36SAndroid Build Coastguard Worker	case "*android.NamespaceModule": // just partitions things, doesn't add anything
329*333d2b36SAndroid Build Coastguard Worker	case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
330*333d2b36SAndroid Build Coastguard Worker	case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
331*333d2b36SAndroid Build Coastguard Worker	case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
332*333d2b36SAndroid Build Coastguard Worker	case "*android.soongConfigBoolVariableDummyModule": // used for creating aliases
333*333d2b36SAndroid Build Coastguard Worker	default:
334*333d2b36SAndroid Build Coastguard Worker		return false
335*333d2b36SAndroid Build Coastguard Worker	}
336*333d2b36SAndroid Build Coastguard Worker	return true
337*333d2b36SAndroid Build Coastguard Worker}
338*333d2b36SAndroid Build Coastguard Worker
339*333d2b36SAndroid Build Coastguard Worker// LicenseInfo contains information about licenses for a specific module.
340*333d2b36SAndroid Build Coastguard Workertype LicenseInfo struct {
341*333d2b36SAndroid Build Coastguard Worker	// The list of license modules this depends upon, either explicitly or through default package
342*333d2b36SAndroid Build Coastguard Worker	// configuration.
343*333d2b36SAndroid Build Coastguard Worker	Licenses []string
344*333d2b36SAndroid Build Coastguard Worker}
345*333d2b36SAndroid Build Coastguard Worker
346*333d2b36SAndroid Build Coastguard Workervar LicenseInfoProvider = blueprint.NewProvider[LicenseInfo]()
347*333d2b36SAndroid Build Coastguard Worker
348*333d2b36SAndroid Build Coastguard Workerfunc init() {
349*333d2b36SAndroid Build Coastguard Worker	RegisterMakeVarsProvider(pctx, licensesMakeVarsProvider)
350*333d2b36SAndroid Build Coastguard Worker}
351*333d2b36SAndroid Build Coastguard Worker
352*333d2b36SAndroid Build Coastguard Workerfunc licensesMakeVarsProvider(ctx MakeVarsContext) {
353*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("BUILD_LICENSE_METADATA",
354*333d2b36SAndroid Build Coastguard Worker		ctx.Config().HostToolPath(ctx, "build_license_metadata").String())
355*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COPY_LICENSE_METADATA",
356*333d2b36SAndroid Build Coastguard Worker		ctx.Config().HostToolPath(ctx, "copy_license_metadata").String())
357*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("HTMLNOTICE", ctx.Config().HostToolPath(ctx, "htmlnotice").String())
358*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("XMLNOTICE", ctx.Config().HostToolPath(ctx, "xmlnotice").String())
359*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("TEXTNOTICE", ctx.Config().HostToolPath(ctx, "textnotice").String())
360*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COMPLIANCENOTICE_BOM", ctx.Config().HostToolPath(ctx, "compliancenotice_bom").String())
361*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String())
362*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COMPLIANCE_LISTSHARE", ctx.Config().HostToolPath(ctx, "compliance_listshare").String())
363*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COMPLIANCE_CHECKSHARE", ctx.Config().HostToolPath(ctx, "compliance_checkshare").String())
364*333d2b36SAndroid Build Coastguard Worker	ctx.Strict("COMPLIANCE_SBOM", ctx.Config().HostToolPath(ctx, "compliance_sbom").String())
365*333d2b36SAndroid Build Coastguard Worker}
366