blob: 100042911bed374a7fea277c1dd4699ac0e90ad4 [file] [log] [blame]
Bob Badour37af0462021-01-07 03:34:31 +00001// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
17import (
18 "reflect"
19 "sync"
20
21 "github.com/google/blueprint"
22)
23
24// Adds cross-cutting licenses dependency to propagate license metadata through the build system.
25//
26// Stage 1 - bottom-up records package-level default_applicable_licenses property mapped by package name.
27// Stage 2 - bottom-up converts licenses property or package default_applicable_licenses to dependencies.
28// Stage 3 - bottom-up type-checks every added applicable license dependency and license_kind dependency.
29// Stage 4 - GenerateBuildActions calculates properties for the union of license kinds, conditions and texts.
30
31type licensesDependencyTag struct {
32 blueprint.BaseDependencyTag
33}
34
35var (
36 licensesTag = licensesDependencyTag{}
37)
38
39// Describes the property provided by a module to reference applicable licenses.
40type applicableLicensesProperty interface {
41 // The name of the property. e.g. default_applicable_licenses or licenses
42 getName() string
43 // The values assigned to the property. (Must reference license modules.)
44 getStrings() []string
45}
46
47type applicableLicensesPropertyImpl struct {
48 name string
49 licensesProperty *[]string
50}
51
52func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
53 return applicableLicensesPropertyImpl{
54 name: name,
55 licensesProperty: licensesProperty,
56 }
57}
58
59func (p applicableLicensesPropertyImpl) getName() string {
60 return p.name
61}
62
63func (p applicableLicensesPropertyImpl) getStrings() []string {
64 return *p.licensesProperty
65}
66
67// Set the primary applicable licenses property for a module.
68func setPrimaryLicensesProperty(module Module, name string, licensesProperty *[]string) {
69 module.base().primaryLicensesProperty = newApplicableLicensesProperty(name, licensesProperty)
70}
71
72// Storage blob for a package's default_applicable_licenses mapped by package directory.
73type licensesContainer struct {
74 licenses []string
75}
76
77func (r licensesContainer) getLicenses() []string {
78 return r.licenses
79}
80
81var packageDefaultLicensesMap = NewOnceKey("packageDefaultLicensesMap")
82
83// The map from package dir name to default applicable licenses as a licensesContainer.
84func moduleToPackageDefaultLicensesMap(config Config) *sync.Map {
85 return config.Once(packageDefaultLicensesMap, func() interface{} {
86 return &sync.Map{}
87 }).(*sync.Map)
88}
89
90// Registers the function that maps each package to its default_applicable_licenses.
91//
92// This goes before defaults expansion so the defaults can pick up the package default.
93func RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
94 ctx.BottomUp("licensesPackageMapper", licensesPackageMapper).Parallel()
95}
96
97// Registers the function that gathers the license dependencies for each module.
98//
99// This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
100func RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
101 ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer).Parallel()
102}
103
104// Registers the function that verifies the licenses and license_kinds dependency types for each module.
105func RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
106 ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker).Parallel()
107}
108
109// Maps each package to its default applicable licenses.
110func licensesPackageMapper(ctx BottomUpMutatorContext) {
111 p, ok := ctx.Module().(*packageModule)
112 if !ok {
113 return
114 }
115
116 licenses := getLicenses(ctx, p)
117
118 dir := ctx.ModuleDir()
119 c := makeLicensesContainer(licenses)
120 moduleToPackageDefaultLicensesMap(ctx.Config()).Store(dir, c)
121}
122
123// Copies the default_applicable_licenses property values for mapping by package directory.
124func makeLicensesContainer(propVals []string) licensesContainer {
125 licenses := make([]string, 0, len(propVals))
126 licenses = append(licenses, propVals...)
127
128 return licensesContainer{licenses}
129}
130
131// Gathers the applicable licenses into dependency references after defaults expansion.
132func licensesPropertyGatherer(ctx BottomUpMutatorContext) {
133 m, ok := ctx.Module().(Module)
134 if !ok {
135 return
136 }
137
138 if exemptFromRequiredApplicableLicensesProperty(m) {
139 return
140 }
141
142 licenses := getLicenses(ctx, m)
143
144 ctx.AddVariationDependencies(nil, licensesTag, licenses...)
145}
146
147// Verifies the license and license_kind dependencies are each the correct kind of module.
148func licensesDependencyChecker(ctx BottomUpMutatorContext) {
149 m, ok := ctx.Module().(Module)
150 if !ok {
151 return
152 }
153
154 // license modules have no licenses, but license_kinds must refer to license_kind modules
155 if _, ok := m.(*licenseModule); ok {
156 for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
157 if _, ok := module.(*licenseKindModule); !ok {
158 ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
159 }
160 }
161 return
162 }
163
164 if exemptFromRequiredApplicableLicensesProperty(m) {
165 return
166 }
167
168 for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
169 if _, ok := module.(*licenseModule); !ok {
170 propertyName := "licenses"
171 primaryProperty := m.base().primaryLicensesProperty
172 if primaryProperty != nil {
173 propertyName = primaryProperty.getName()
174 }
175 ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
176 }
177 }
178}
179
180// Flattens license and license_kind dependencies into calculated properties.
181//
182// Re-validates applicable licenses properties refer only to license modules and license_kinds properties refer
183// only to license_kind modules.
184func licensesPropertyFlattener(ctx ModuleContext) {
185 m, ok := ctx.Module().(Module)
186 if !ok {
187 return
188 }
189
190 // license modules have no licenses, but license_kinds must refer to license_kind modules
191 if l, ok := m.(*licenseModule); ok {
192 mergeProps(&m.base().commonProperties.Effective_licenses, ctx.ModuleName())
193 mergeProps(&m.base().commonProperties.Effective_license_text, PathsForModuleSrc(ctx, l.properties.License_text).Strings()...)
194 for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
195 if lk, ok := module.(*licenseKindModule); ok {
196 mergeProps(&m.base().commonProperties.Effective_license_conditions, lk.properties.Conditions...)
197 mergeProps(&m.base().commonProperties.Effective_license_kinds, ctx.OtherModuleName(module))
198 } else {
199 ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
200 }
201 }
202 return
203 }
204
205 if exemptFromRequiredApplicableLicensesProperty(m) {
206 return
207 }
208
209 for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
210 if l, ok := module.(*licenseModule); ok {
211 if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
212 m.base().commonProperties.Effective_package_name = l.properties.Package_name
213 }
214 mergeProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
215 mergeProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
216 mergeProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
217 mergeProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
218 } else {
219 propertyName := "licenses"
220 primaryProperty := m.base().primaryLicensesProperty
221 if primaryProperty != nil {
222 propertyName = primaryProperty.getName()
223 }
224 ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
225 }
226 }
227}
228
229// Update a property string array with a distinct union of its values and a list of new values.
230func mergeProps(prop *[]string, values ...string) {
231 s := make(map[string]bool)
232 for _, v := range *prop {
233 s[v] = true
234 }
235 for _, v := range values {
236 s[v] = true
237 }
238 *prop = []string{}
239 *prop = append(*prop, SortedStringKeys(s)...)
240}
241
242// Get the licenses property falling back to the package default.
243func getLicenses(ctx BaseModuleContext, module Module) []string {
244 if exemptFromRequiredApplicableLicensesProperty(module) {
245 return nil
246 }
247
248 primaryProperty := module.base().primaryLicensesProperty
249 if primaryProperty == nil {
250 if ctx.Config().IsEnvTrue("ANDROID_REQUIRE_LICENSES") {
251 ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
252 }
253 return nil
254 }
255
256 licenses := primaryProperty.getStrings()
257 if len(licenses) > 0 {
258 s := make(map[string]bool)
259 for _, l := range licenses {
260 if _, ok := s[l]; ok {
261 ctx.ModuleErrorf("duplicate %q %s", l, primaryProperty.getName())
262 }
263 s[l] = true
264 }
265 return licenses
266 }
267
268 dir := ctx.OtherModuleDir(module)
269
270 moduleToApplicableLicenses := moduleToPackageDefaultLicensesMap(ctx.Config())
271 value, ok := moduleToApplicableLicenses.Load(dir)
272 var c licensesContainer
273 if ok {
274 c = value.(licensesContainer)
275 } else {
276 c = licensesContainer{}
277 }
278 return c.getLicenses()
279}
280
281// Returns whether a module is an allowed list of modules that do not have or need applicable licenses.
282func exemptFromRequiredApplicableLicensesProperty(module Module) bool {
283 switch reflect.TypeOf(module).String() {
284 case "*android.licenseModule": // is a license, doesn't need one
285 case "*android.licenseKindModule": // is a license, doesn't need one
286 case "*android.NamespaceModule": // just partitions things, doesn't add anything
287 case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
288 case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
289 case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
290 case "*android.SoongConfigBoolVariableDummyModule": // used for creating aliases
291 default:
292 return false
293 }
294 return true
295}