licenses.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // 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. package android
  15. import (
  16. "reflect"
  17. "sync"
  18. "github.com/google/blueprint"
  19. )
  20. // Adds cross-cutting licenses dependency to propagate license metadata through the build system.
  21. //
  22. // Stage 1 - bottom-up records package-level default_applicable_licenses property mapped by package name.
  23. // Stage 2 - bottom-up converts licenses property or package default_applicable_licenses to dependencies.
  24. // Stage 3 - bottom-up type-checks every added applicable license dependency and license_kind dependency.
  25. // Stage 4 - GenerateBuildActions calculates properties for the union of license kinds, conditions and texts.
  26. type licensesDependencyTag struct {
  27. blueprint.BaseDependencyTag
  28. }
  29. func (l licensesDependencyTag) SdkMemberType(Module) SdkMemberType {
  30. // Add the supplied module to the sdk as a license module.
  31. return LicenseModuleSdkMemberType
  32. }
  33. func (l licensesDependencyTag) ExportMember() bool {
  34. // The license module will only every be referenced from within the sdk. This will ensure that it
  35. // gets a unique name and so avoid clashing with the original license module.
  36. return false
  37. }
  38. var (
  39. licensesTag = licensesDependencyTag{}
  40. // License modules, i.e. modules depended upon via a licensesTag, must be automatically added to
  41. // any sdk/module_exports to which their referencing module is a member.
  42. _ SdkMemberDependencyTag = licensesTag
  43. )
  44. // Describes the property provided by a module to reference applicable licenses.
  45. type applicableLicensesProperty interface {
  46. // The name of the property. e.g. default_applicable_licenses or licenses
  47. getName() string
  48. // The values assigned to the property. (Must reference license modules.)
  49. getStrings() []string
  50. }
  51. type applicableLicensesPropertyImpl struct {
  52. name string
  53. licensesProperty *[]string
  54. }
  55. func newApplicableLicensesProperty(name string, licensesProperty *[]string) applicableLicensesProperty {
  56. return applicableLicensesPropertyImpl{
  57. name: name,
  58. licensesProperty: licensesProperty,
  59. }
  60. }
  61. func (p applicableLicensesPropertyImpl) getName() string {
  62. return p.name
  63. }
  64. func (p applicableLicensesPropertyImpl) getStrings() []string {
  65. return *p.licensesProperty
  66. }
  67. // Set the primary applicable licenses property for a module.
  68. func setPrimaryLicensesProperty(module Module, name string, licensesProperty *[]string) {
  69. module.base().primaryLicensesProperty = newApplicableLicensesProperty(name, licensesProperty)
  70. }
  71. // Storage blob for a package's default_applicable_licenses mapped by package directory.
  72. type licensesContainer struct {
  73. licenses []string
  74. }
  75. func (r licensesContainer) getLicenses() []string {
  76. return r.licenses
  77. }
  78. var packageDefaultLicensesMap = NewOnceKey("packageDefaultLicensesMap")
  79. // The map from package dir name to default applicable licenses as a licensesContainer.
  80. func moduleToPackageDefaultLicensesMap(config Config) *sync.Map {
  81. return config.Once(packageDefaultLicensesMap, func() interface{} {
  82. return &sync.Map{}
  83. }).(*sync.Map)
  84. }
  85. // Registers the function that maps each package to its default_applicable_licenses.
  86. //
  87. // This goes before defaults expansion so the defaults can pick up the package default.
  88. func RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
  89. ctx.BottomUp("licensesPackageMapper", licensesPackageMapper).Parallel()
  90. }
  91. // Registers the function that gathers the license dependencies for each module.
  92. //
  93. // This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
  94. func RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
  95. ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer).Parallel()
  96. }
  97. // Registers the function that verifies the licenses and license_kinds dependency types for each module.
  98. func RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
  99. ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker).Parallel()
  100. }
  101. // Maps each package to its default applicable licenses.
  102. func licensesPackageMapper(ctx BottomUpMutatorContext) {
  103. p, ok := ctx.Module().(*packageModule)
  104. if !ok {
  105. return
  106. }
  107. licenses := getLicenses(ctx, p)
  108. dir := ctx.ModuleDir()
  109. c := makeLicensesContainer(licenses)
  110. moduleToPackageDefaultLicensesMap(ctx.Config()).Store(dir, c)
  111. }
  112. // Copies the default_applicable_licenses property values for mapping by package directory.
  113. func makeLicensesContainer(propVals []string) licensesContainer {
  114. licenses := make([]string, 0, len(propVals))
  115. licenses = append(licenses, propVals...)
  116. return licensesContainer{licenses}
  117. }
  118. // Gathers the applicable licenses into dependency references after defaults expansion.
  119. func licensesPropertyGatherer(ctx BottomUpMutatorContext) {
  120. m, ok := ctx.Module().(Module)
  121. if !ok {
  122. return
  123. }
  124. if exemptFromRequiredApplicableLicensesProperty(m) {
  125. return
  126. }
  127. licenses := getLicenses(ctx, m)
  128. ctx.AddVariationDependencies(nil, licensesTag, licenses...)
  129. }
  130. // Verifies the license and license_kind dependencies are each the correct kind of module.
  131. func licensesDependencyChecker(ctx BottomUpMutatorContext) {
  132. m, ok := ctx.Module().(Module)
  133. if !ok {
  134. return
  135. }
  136. // license modules have no licenses, but license_kinds must refer to license_kind modules
  137. if _, ok := m.(*licenseModule); ok {
  138. for _, module := range ctx.GetDirectDepsWithTag(licenseKindTag) {
  139. if _, ok := module.(*licenseKindModule); !ok {
  140. ctx.ModuleErrorf("license_kinds property %q is not a license_kind module", ctx.OtherModuleName(module))
  141. }
  142. }
  143. return
  144. }
  145. if exemptFromRequiredApplicableLicensesProperty(m) {
  146. return
  147. }
  148. for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
  149. if _, ok := module.(*licenseModule); !ok {
  150. propertyName := "licenses"
  151. primaryProperty := m.base().primaryLicensesProperty
  152. if primaryProperty != nil {
  153. propertyName = primaryProperty.getName()
  154. }
  155. ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
  156. }
  157. }
  158. }
  159. // Flattens license and license_kind dependencies into calculated properties.
  160. //
  161. // Re-validates applicable licenses properties refer only to license modules and license_kinds properties refer
  162. // only to license_kind modules.
  163. func licensesPropertyFlattener(ctx ModuleContext) {
  164. m, ok := ctx.Module().(Module)
  165. if !ok {
  166. return
  167. }
  168. if exemptFromRequiredApplicableLicensesProperty(m) {
  169. return
  170. }
  171. var licenses []string
  172. for _, module := range ctx.GetDirectDepsWithTag(licensesTag) {
  173. if l, ok := module.(*licenseModule); ok {
  174. licenses = append(licenses, ctx.OtherModuleName(module))
  175. if m.base().commonProperties.Effective_package_name == nil && l.properties.Package_name != nil {
  176. m.base().commonProperties.Effective_package_name = l.properties.Package_name
  177. }
  178. mergeStringProps(&m.base().commonProperties.Effective_licenses, module.base().commonProperties.Effective_licenses...)
  179. mergeNamedPathProps(&m.base().commonProperties.Effective_license_text, module.base().commonProperties.Effective_license_text...)
  180. mergeStringProps(&m.base().commonProperties.Effective_license_kinds, module.base().commonProperties.Effective_license_kinds...)
  181. mergeStringProps(&m.base().commonProperties.Effective_license_conditions, module.base().commonProperties.Effective_license_conditions...)
  182. } else {
  183. propertyName := "licenses"
  184. primaryProperty := m.base().primaryLicensesProperty
  185. if primaryProperty != nil {
  186. propertyName = primaryProperty.getName()
  187. }
  188. ctx.ModuleErrorf("%s property %q is not a license module", propertyName, ctx.OtherModuleName(module))
  189. }
  190. }
  191. // Make the license information available for other modules.
  192. licenseInfo := LicenseInfo{
  193. Licenses: licenses,
  194. }
  195. ctx.SetProvider(LicenseInfoProvider, licenseInfo)
  196. }
  197. // Update a property string array with a distinct union of its values and a list of new values.
  198. func mergeStringProps(prop *[]string, values ...string) {
  199. *prop = append(*prop, values...)
  200. *prop = SortedUniqueStrings(*prop)
  201. }
  202. // Update a property NamedPath array with a distinct union of its values and a list of new values.
  203. func namePathProps(prop *NamedPaths, name *string, values ...Path) {
  204. if name == nil {
  205. for _, value := range values {
  206. *prop = append(*prop, NamedPath{value, ""})
  207. }
  208. } else {
  209. for _, value := range values {
  210. *prop = append(*prop, NamedPath{value, *name})
  211. }
  212. }
  213. *prop = SortedUniqueNamedPaths(*prop)
  214. }
  215. // Update a property NamedPath array with a distinct union of its values and a list of new values.
  216. func mergeNamedPathProps(prop *NamedPaths, values ...NamedPath) {
  217. *prop = append(*prop, values...)
  218. *prop = SortedUniqueNamedPaths(*prop)
  219. }
  220. // Get the licenses property falling back to the package default.
  221. func getLicenses(ctx BaseModuleContext, module Module) []string {
  222. if exemptFromRequiredApplicableLicensesProperty(module) {
  223. return nil
  224. }
  225. primaryProperty := module.base().primaryLicensesProperty
  226. if primaryProperty == nil {
  227. if !ctx.Config().IsEnvFalse("ANDROID_REQUIRE_LICENSES") {
  228. ctx.ModuleErrorf("module type %q must have an applicable licenses property", ctx.OtherModuleType(module))
  229. }
  230. return nil
  231. }
  232. licenses := primaryProperty.getStrings()
  233. if len(licenses) > 0 {
  234. s := make(map[string]bool)
  235. for _, l := range licenses {
  236. if _, ok := s[l]; ok {
  237. ctx.ModuleErrorf("duplicate %q %s", l, primaryProperty.getName())
  238. }
  239. s[l] = true
  240. }
  241. return licenses
  242. }
  243. dir := ctx.OtherModuleDir(module)
  244. moduleToApplicableLicenses := moduleToPackageDefaultLicensesMap(ctx.Config())
  245. value, ok := moduleToApplicableLicenses.Load(dir)
  246. var c licensesContainer
  247. if ok {
  248. c = value.(licensesContainer)
  249. } else {
  250. c = licensesContainer{}
  251. }
  252. return c.getLicenses()
  253. }
  254. // Returns whether a module is an allowed list of modules that do not have or need applicable licenses.
  255. func exemptFromRequiredApplicableLicensesProperty(module Module) bool {
  256. switch reflect.TypeOf(module).String() {
  257. case "*android.licenseModule": // is a license, doesn't need one
  258. case "*android.licenseKindModule": // is a license, doesn't need one
  259. case "*android.NamespaceModule": // just partitions things, doesn't add anything
  260. case "*android.soongConfigModuleTypeModule": // creates aliases for modules with licenses
  261. case "*android.soongConfigModuleTypeImport": // creates aliases for modules with licenses
  262. case "*android.soongConfigStringVariableDummyModule": // used for creating aliases
  263. case "*android.soongConfigBoolVariableDummyModule": // used for creating aliases
  264. default:
  265. return false
  266. }
  267. return true
  268. }
  269. // LicenseInfo contains information about licenses for a specific module.
  270. type LicenseInfo struct {
  271. // The list of license modules this depends upon, either explicitly or through default package
  272. // configuration.
  273. Licenses []string
  274. }
  275. var LicenseInfoProvider = blueprint.NewProvider(LicenseInfo{})
  276. func init() {
  277. RegisterMakeVarsProvider(pctx, licensesMakeVarsProvider)
  278. }
  279. func licensesMakeVarsProvider(ctx MakeVarsContext) {
  280. ctx.Strict("BUILD_LICENSE_METADATA",
  281. ctx.Config().HostToolPath(ctx, "build_license_metadata").String())
  282. ctx.Strict("HTMLNOTICE", ctx.Config().HostToolPath(ctx, "htmlnotice").String())
  283. ctx.Strict("XMLNOTICE", ctx.Config().HostToolPath(ctx, "xmlnotice").String())
  284. ctx.Strict("TEXTNOTICE", ctx.Config().HostToolPath(ctx, "textnotice").String())
  285. ctx.Strict("COMPLIANCENOTICE_BOM", ctx.Config().HostToolPath(ctx, "compliancenotice_bom").String())
  286. ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String())
  287. }