diff options
-rw-r--r-- | android/androidmk.go | 2 | ||||
-rw-r--r-- | android/module.go | 16 | ||||
-rw-r--r-- | apex/apex.go | 50 | ||||
-rw-r--r-- | apex/apex_test.go | 11 | ||||
-rwxr-xr-x | scripts/mergenotice.py | 49 |
5 files changed, 123 insertions, 5 deletions
diff --git a/android/androidmk.go b/android/androidmk.go index fc34471c..bd49e4c6 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -319,7 +319,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Mod } } - if amod.noticeFile != nil { + if amod.noticeFile.Valid() { fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", amod.noticeFile.String()) } diff --git a/android/module.go b/android/module.go index afd2b714..abf2cae4 100644 --- a/android/module.go +++ b/android/module.go @@ -189,6 +189,7 @@ type Module interface { InstallInRecovery() bool SkipInstall() ExportedToMake() bool + NoticeFile() OptionalPath AddProperties(props ...interface{}) GetProperties() []interface{} @@ -466,7 +467,7 @@ type ModuleBase struct { noAddressSanitizer bool installFiles Paths checkbuildFiles Paths - noticeFile Path + noticeFile OptionalPath // Used by buildTargetSingleton to create checkbuild and per-directory build targets // Only set on the final variant of each module @@ -667,6 +668,10 @@ func (a *ModuleBase) Owner() string { return String(a.commonProperties.Owner) } +func (a *ModuleBase) NoticeFile() OptionalPath { + return a.noticeFile +} + func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { allInstalledFiles := Paths{} allCheckbuildFiles := Paths{} @@ -852,9 +857,12 @@ func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) a.installFiles = append(a.installFiles, ctx.installFiles...) a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...) - if a.commonProperties.Notice != nil { - // For filegroup-based notice file references. - a.noticeFile = PathForModuleSrc(ctx, *a.commonProperties.Notice) + notice := proptools.StringDefault(a.commonProperties.Notice, "NOTICE") + if m := SrcIsModule(notice); m != "" { + a.noticeFile = ctx.ExpandOptionalSource(¬ice, "notice") + } else { + noticePath := filepath.Join(ctx.ModuleDir(), notice) + a.noticeFile = ExistentPathForSource(ctx, noticePath) } } diff --git a/apex/apex.go b/apex/apex.go index ad1ef74f..c1f52a60 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -90,6 +90,12 @@ var ( CommandDeps: []string{"${zip2zip}"}, Description: "app bundle", }, "abi") + + apexMergeNoticeRule = pctx.StaticRule("apexMergeNoticeRule", blueprint.RuleParams{ + Command: `${mergenotice} --output $out $inputs`, + CommandDeps: []string{"${mergenotice}"}, + Description: "merge notice files into $out", + }, "inputs") ) var imageApexSuffix = ".apex" @@ -138,6 +144,8 @@ func init() { pctx.HostBinToolVariable("zip2zip", "zip2zip") pctx.HostBinToolVariable("zipalign", "zipalign") + pctx.SourcePathVariable("mergenotice", "build/soong/scripts/mergenotice.py") + android.RegisterModuleType("apex", apexBundleFactory) android.RegisterModuleType("apex_test", testApexBundleFactory) android.RegisterModuleType("apex_defaults", defaultsFactory) @@ -394,6 +402,8 @@ type apexBundle struct { container_certificate_file android.Path container_private_key_file android.Path + mergedNoticeFile android.WritablePath + // list of files to be included in this apex filesInfo []apexFile @@ -814,6 +824,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.installDir = android.PathForModuleInstall(ctx, "apex") a.filesInfo = filesInfo + a.buildNoticeFile(ctx) + if a.apexTypes.zip() { a.buildUnflattenedApex(ctx, zipApex) } @@ -827,6 +839,37 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } +func (a *apexBundle) buildNoticeFile(ctx android.ModuleContext) { + noticeFiles := []android.Path{} + noticeFilesString := []string{} + for _, f := range a.filesInfo { + if f.module != nil { + notice := f.module.NoticeFile() + if notice.Valid() { + noticeFiles = append(noticeFiles, notice.Path()) + noticeFilesString = append(noticeFilesString, notice.Path().String()) + } + } + } + // append the notice file specified in the apex module itself + if a.NoticeFile().Valid() { + noticeFiles = append(noticeFiles, a.NoticeFile().Path()) + noticeFilesString = append(noticeFilesString, a.NoticeFile().Path().String()) + } + + if len(noticeFiles) > 0 { + a.mergedNoticeFile = android.PathForModuleOut(ctx, "NOTICE") + ctx.Build(pctx, android.BuildParams{ + Rule: apexMergeNoticeRule, + Inputs: noticeFiles, + Output: a.mergedNoticeFile, + Args: map[string]string{ + "inputs": strings.Join(noticeFilesString, " "), + }, + }) + } +} + func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType apexPackaging) { cert := String(a.properties.Certificate) if cert != "" && android.SrcIsModule(cert) == "" { @@ -1078,6 +1121,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, name, moduleDir string, apex if len(fi.symlinks) > 0 { fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " ")) } + + if fi.module != nil && fi.module.NoticeFile().Valid() { + fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", fi.module.NoticeFile().Path().String()) + } } else { fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", pathWhenActivated) } @@ -1168,6 +1215,9 @@ func (a *apexBundle) androidMkForType(apexType apexPackaging) android.AndroidMkD fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", name+apexType.suffix()) fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE :=", !a.installable()) fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key)) + if a.installable() && a.mergedNoticeFile != nil { + fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", a.mergedNoticeFile.String()) + } if len(moduleNames) > 0 { fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " ")) } diff --git a/apex/apex_test.go b/apex/apex_test.go index f221cf22..ac2701f7 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -159,6 +159,8 @@ func testApex(t *testing.T, bp string) *android.TestContext { "testkey.override.pk8": nil, "vendor/foo/devkeys/testkey.avbpubkey": nil, "vendor/foo/devkeys/testkey.pem": nil, + "NOTICE": nil, + "custom_notice": nil, }) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) android.FailIfErrored(t, errs) @@ -280,6 +282,7 @@ func TestBasicApex(t *testing.T) { srcs: ["mylib.cpp"], system_shared_libs: [], stl: "none", + notice: "custom_notice", } `) @@ -319,6 +322,14 @@ func TestBasicApex(t *testing.T) { if !good { t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) } + + apexMergeNoticeRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexMergeNoticeRule") + noticeInputs := strings.Split(apexMergeNoticeRule.Args["inputs"], " ") + if len(noticeInputs) != 3 { + t.Errorf("number of input notice files: expected = 3, actual = %d", len(noticeInputs)) + } + ensureListContains(t, noticeInputs, "NOTICE") + ensureListContains(t, noticeInputs, "custom_notice") } func TestBasicZipApex(t *testing.T) { diff --git a/scripts/mergenotice.py b/scripts/mergenotice.py new file mode 100755 index 00000000..407ae8cc --- /dev/null +++ b/scripts/mergenotice.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright (C) 2019 The Android Open Source Project +# +# 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. +# +""" +Merges input notice files to the output file while ignoring duplicated files +This script shouldn't be confused with build/make/tools/generate-notice-files.py +which is responsible for creating the final notice file for all artifacts +installed. This script has rather limited scope; it is meant to create a merged +notice file for a set of modules that are packaged together, e.g. in an APEX. +The merged notice file does not reveal the individual files in the package. +""" + +import sys +import argparse + +def get_args(): + parser = argparse.ArgumentParser(description='Merge notice files.') + parser.add_argument('--output', help='output file path.') + parser.add_argument('inputs', metavar='INPUT', nargs='+', + help='input notice file') + return parser.parse_args() + +def main(argv): + args = get_args() + + processed = set() + with open(args.output, 'w+') as output: + for input in args.inputs: + with open(input, 'r') as f: + data = f.read().strip() + if data not in processed: + processed.add(data) + output.write('%s\n\n' % data) + +if __name__ == '__main__': + main(sys.argv) |