Previously, I had changed some loadhook-appended property structs
to use selects instead of the "target" property struct. This seems
to not be exactly equivalent because "target" properties are merged
with the regular properties later, at the time the arch mutator runs.
With this reapplication, leave those target property structs alone
to avoid breakages, but I'll have to look into what the issue is
with them later.
This reverts commit ed5276f082
.
Ignore-AOSP-First: This cl needs to be in a topic with internal-only projects, will cherrypick to aosp after.
Bug: 323382414
Test: m nothing --no-skip-soong-tests
Change-Id: If355d24506e3f117d27b21442a6c02bca3402dc7
231 lines
6.8 KiB
Go
231 lines
6.8 KiB
Go
// 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(ctx) { // 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, ", "),
|
|
},
|
|
})
|
|
}
|