Merge "Notice support for APEX" am: 21c81326ff
am: 602b6ba221
Change-Id: Idd7a4c7c736fdc55a15f1fe445408a2b57294b2a
This commit is contained in:
commit
ba47ea108a
5 changed files with 123 additions and 5 deletions
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
50
apex/apex.go
50
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, " "))
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
49
scripts/mergenotice.py
Executable file
49
scripts/mergenotice.py
Executable file
|
@ -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)
|
Loading…
Reference in a new issue