123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- // Copyright 2020 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 (
- "fmt"
- "path/filepath"
- "strings"
- "github.com/google/blueprint/proptools"
- )
- func init() {
- RegisterGenNoticeBuildComponents(InitRegistrationContext)
- }
- // Register the gen_notice module type.
- func RegisterGenNoticeBuildComponents(ctx RegistrationContext) {
- ctx.RegisterParallelSingletonType("gen_notice_build_rules", GenNoticeBuildRulesFactory)
- ctx.RegisterModuleType("gen_notice", GenNoticeFactory)
- }
- type genNoticeBuildRules struct{}
- func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) {
- ctx.VisitAllModules(func(m Module) {
- gm, ok := m.(*genNoticeModule)
- if !ok {
- return
- }
- if len(gm.missing) > 0 {
- missingReferencesRule(ctx, gm)
- return
- }
- out := BuildNoticeTextOutputFromLicenseMetadata
- if proptools.Bool(gm.properties.Xml) {
- out = BuildNoticeXmlOutputFromLicenseMetadata
- } else if proptools.Bool(gm.properties.Html) {
- out = BuildNoticeHtmlOutputFromLicenseMetadata
- }
- defaultName := ""
- if len(gm.properties.For) > 0 {
- defaultName = gm.properties.For[0]
- }
- modules := make([]Module, 0)
- for _, name := range gm.properties.For {
- mods := ctx.ModuleVariantsFromName(gm, name)
- for _, mod := range mods {
- if mod == nil {
- continue
- }
- if !mod.Enabled() { // don't depend on variants without build rules
- continue
- }
- modules = append(modules, mod)
- }
- }
- if ctx.Failed() {
- return
- }
- out(ctx, gm.output, ctx.ModuleName(gm),
- proptools.StringDefault(gm.properties.ArtifactName, defaultName),
- []string{
- filepath.Join(ctx.Config().OutDir(), "target", "product", ctx.Config().DeviceName()) + "/",
- ctx.Config().OutDir() + "/",
- ctx.Config().SoongOutDir() + "/",
- }, modules...)
- })
- }
- func GenNoticeBuildRulesFactory() Singleton {
- return &genNoticeBuildRules{}
- }
- type genNoticeProperties struct {
- // For specifies the modules for which to generate a notice file.
- For []string
- // ArtifactName specifies the internal name to use for the notice file.
- // It appears in the "used by:" list for targets whose entire name is stripped by --strip_prefix.
- ArtifactName *string
- // Stem specifies the base name of the output file.
- Stem *string `android:"arch_variant"`
- // Html indicates an html-format file is needed. The default is text. Can be Html or Xml but not both.
- Html *bool
- // Xml indicates an xml-format file is needed. The default is text. Can be Html or Xml but not both.
- Xml *bool
- // Gzipped indicates the output file must be compressed with gzip. Will append .gz to suffix if not there.
- Gzipped *bool
- // Suffix specifies the file extension to use. Defaults to .html for html, .xml for xml, or no extension for text.
- Suffix *string
- // Visibility specifies where this license can be used
- Visibility []string
- }
- type genNoticeModule struct {
- ModuleBase
- DefaultableModuleBase
- properties genNoticeProperties
- output OutputPath
- missing []string
- }
- func (m *genNoticeModule) DepsMutator(ctx BottomUpMutatorContext) {
- if ctx.ContainsProperty("licenses") {
- ctx.PropertyErrorf("licenses", "not supported on \"gen_notice\" modules")
- }
- if proptools.Bool(m.properties.Html) && proptools.Bool(m.properties.Xml) {
- ctx.ModuleErrorf("can be html or xml but not both")
- }
- if !ctx.Config().AllowMissingDependencies() {
- var missing []string
- // Verify the modules for which to generate notices exist.
- for _, otherMod := range m.properties.For {
- if !ctx.OtherModuleExists(otherMod) {
- missing = append(missing, otherMod)
- }
- }
- if len(missing) == 1 {
- ctx.PropertyErrorf("for", "no %q module exists", missing[0])
- } else if len(missing) > 1 {
- ctx.PropertyErrorf("for", "modules \"%s\" do not exist", strings.Join(missing, "\", \""))
- }
- }
- }
- func (m *genNoticeModule) getStem() string {
- stem := m.base().BaseModuleName()
- if m.properties.Stem != nil {
- stem = proptools.String(m.properties.Stem)
- }
- return stem
- }
- func (m *genNoticeModule) getSuffix() string {
- suffix := ""
- if m.properties.Suffix == nil {
- if proptools.Bool(m.properties.Html) {
- suffix = ".html"
- } else if proptools.Bool(m.properties.Xml) {
- suffix = ".xml"
- }
- } else {
- suffix = proptools.String(m.properties.Suffix)
- }
- if proptools.Bool(m.properties.Gzipped) && !strings.HasSuffix(suffix, ".gz") {
- suffix += ".gz"
- }
- return suffix
- }
- func (m *genNoticeModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- if ctx.Config().AllowMissingDependencies() {
- // Verify the modules for which to generate notices exist.
- for _, otherMod := range m.properties.For {
- if !ctx.OtherModuleExists(otherMod) {
- m.missing = append(m.missing, otherMod)
- }
- }
- m.missing = append(m.missing, ctx.GetMissingDependencies()...)
- m.missing = FirstUniqueStrings(m.missing)
- }
- out := m.getStem() + m.getSuffix()
- m.output = PathForModuleOut(ctx, out).OutputPath
- }
- func GenNoticeFactory() Module {
- module := &genNoticeModule{}
- base := module.base()
- module.AddProperties(&base.nameProperties, &module.properties)
- // The visibility property needs to be checked and parsed by the visibility module.
- setPrimaryVisibilityProperty(module, "visibility", &module.properties.Visibility)
- InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
- InitDefaultableModule(module)
- return module
- }
- var _ OutputFileProducer = (*genNoticeModule)(nil)
- // Implements OutputFileProducer
- func (m *genNoticeModule) OutputFiles(tag string) (Paths, error) {
- if tag == "" {
- return Paths{m.output}, nil
- }
- return nil, fmt.Errorf("unrecognized tag %q", tag)
- }
- var _ AndroidMkEntriesProvider = (*genNoticeModule)(nil)
- // Implements AndroidMkEntriesProvider
- func (m *genNoticeModule) AndroidMkEntries() []AndroidMkEntries {
- return []AndroidMkEntries{AndroidMkEntries{
- Class: "ETC",
- OutputFile: OptionalPathForPath(m.output),
- }}
- }
- // missingReferencesRule emits an ErrorRule for missing module references.
- func missingReferencesRule(ctx BuilderContext, m *genNoticeModule) {
- if len(m.missing) < 1 {
- panic(fmt.Errorf("missing references rule requested with no missing references"))
- }
- ctx.Build(pctx, BuildParams{
- Rule: ErrorRule,
- Output: m.output,
- Description: "notice for " + proptools.StringDefault(m.properties.ArtifactName, "container"),
- Args: map[string]string{
- "error": m.Name() + " references missing module(s): " + strings.Join(m.missing, ", "),
- },
- })
- }
|