Loading android/notices.go +14 −85 Original line number Diff line number Diff line Loading @@ -15,93 +15,9 @@ package android import ( "path/filepath" "strings" "github.com/google/blueprint" ) func init() { pctx.SourcePathVariable("merge_notices", "build/soong/scripts/mergenotice.py") pctx.SourcePathVariable("generate_notice", "build/soong/scripts/generate-notice-files.py") pctx.HostBinToolVariable("minigzip", "minigzip") } type NoticeOutputs struct { Merged OptionalPath TxtOutput OptionalPath HtmlOutput OptionalPath HtmlGzOutput OptionalPath } var ( mergeNoticesRule = pctx.AndroidStaticRule("mergeNoticesRule", blueprint.RuleParams{ Command: `${merge_notices} --output $out $in`, CommandDeps: []string{"${merge_notices}"}, Description: "merge notice files into $out", }) generateNoticeRule = pctx.AndroidStaticRule("generateNoticeRule", blueprint.RuleParams{ Command: `rm -rf $$(dirname $txtOut) $$(dirname $htmlOut) $$(dirname $out) && ` + `mkdir -p $$(dirname $txtOut) $$(dirname $htmlOut) $$(dirname $out) && ` + `${generate_notice} --text-output $txtOut --html-output $htmlOut -t "$title" -s $inputDir && ` + `${minigzip} -c $htmlOut > $out`, CommandDeps: []string{"${generate_notice}", "${minigzip}"}, Description: "produce notice file $out", }, "txtOut", "htmlOut", "title", "inputDir") ) func MergeNotices(ctx ModuleContext, mergedNotice WritablePath, noticePaths []Path) { ctx.Build(pctx, BuildParams{ Rule: mergeNoticesRule, Description: "merge notices", Inputs: noticePaths, Output: mergedNotice, }) } func BuildNoticeOutput(ctx ModuleContext, installPath InstallPath, installFilename string, noticePaths []Path) NoticeOutputs { // Merge all NOTICE files into one. // TODO(jungjw): We should just produce a well-formatted NOTICE.html file in a single pass. // // generate-notice-files.py, which processes the merged NOTICE file, has somewhat strict rules // about input NOTICE file paths. // 1. Their relative paths to the src root become their NOTICE index titles. We want to use // on-device paths as titles, and so output the merged NOTICE file the corresponding location. // 2. They must end with .txt extension. Otherwise, they're ignored. noticeRelPath := InstallPathToOnDevicePath(ctx, installPath.Join(ctx, installFilename+".txt")) mergedNotice := PathForModuleOut(ctx, filepath.Join("NOTICE_FILES/src", noticeRelPath)) MergeNotices(ctx, mergedNotice, noticePaths) // Transform the merged NOTICE file into a gzipped HTML file. txtOuptut := PathForModuleOut(ctx, "NOTICE_txt", "NOTICE.txt") htmlOutput := PathForModuleOut(ctx, "NOTICE_html", "NOTICE.html") htmlGzOutput := PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") title := "Notices for " + ctx.ModuleName() ctx.Build(pctx, BuildParams{ Rule: generateNoticeRule, Description: "generate notice output", Input: mergedNotice, Output: htmlGzOutput, ImplicitOutputs: WritablePaths{txtOuptut, htmlOutput}, Args: map[string]string{ "txtOut": txtOuptut.String(), "htmlOut": htmlOutput.String(), "title": title, "inputDir": PathForModuleOut(ctx, "NOTICE_FILES/src").String(), }, }) return NoticeOutputs{ Merged: OptionalPathForPath(mergedNotice), TxtOutput: OptionalPathForPath(txtOuptut), HtmlOutput: OptionalPathForPath(htmlOutput), HtmlGzOutput: OptionalPathForPath(htmlGzOutput), } } // BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based on the module's // generated license metadata file. func BuildNoticeTextOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) { Loading @@ -112,5 +28,18 @@ func BuildNoticeTextOutputFromLicenseMetadata(ctx ModuleContext, outputFile Writ FlagWithOutput("-o ", outputFile). FlagWithDepFile("-d ", depsFile). Input(ctx.Module().base().licenseMetadataFile) rule.Build("container_notice", "container notice file") rule.Build("text_notice", "container notice file") } // BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based on the module's // generated license metadata file. func BuildNoticeHtmlOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) { depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", ".")) rule := NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("htmlnotice"). FlagWithOutput("-o ", outputFile). FlagWithDepFile("-d ", depsFile). Input(ctx.Module().base().licenseMetadataFile) rule.Build("html_notice", "container notice file") } apex/androidmk.go +0 −4 Original line number Diff line number Diff line Loading @@ -396,10 +396,6 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData { } a.writeRequiredModules(w, moduleNames) if a.mergedNotices.Merged.Valid() { fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", a.mergedNotices.Merged.Path().String()) } fmt.Fprintln(w, "include $(BUILD_PREBUILT)") if apexType == imageApex { Loading apex/apex.go +6 −8 Original line number Diff line number Diff line Loading @@ -414,8 +414,8 @@ type apexBundle struct { // Processed file_contexts files fileContexts android.WritablePath // Struct holding the merged notice file paths in different formats mergedNotices android.NoticeOutputs // Path to notice file in html.gz format. htmlGzNotice android.WritablePath // The built APEX file. This is the main product. // Could be .apex or .capex Loading Loading @@ -488,7 +488,6 @@ const ( type apexFile struct { // buildFile is put in the installDir inside the APEX. builtFile android.Path noticeFiles android.Paths installDir string customStem string symlinks []string // additional symlinks Loading Loading @@ -528,7 +527,6 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM module: module, } if module != nil { ret.noticeFiles = module.NoticeFiles() ret.moduleDir = ctx.OtherModuleDir(module) ret.requiredModuleNames = module.RequiredModuleNames() ret.targetRequiredModuleNames = module.TargetRequiredModuleNames() Loading apex/apex_test.go +0 −9 Original line number Diff line number Diff line Loading @@ -591,15 +591,6 @@ func TestBasicApex(t *testing.T) { t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) } mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("mergeNoticesRule") noticeInputs := mergeNoticesRule.Inputs.Strings() if len(noticeInputs) != 3 { t.Errorf("number of input notice files: expected = 3, actual = %q", len(noticeInputs)) } ensureListContains(t, noticeInputs, "NOTICE") ensureListContains(t, noticeInputs, "custom_notice") ensureListContains(t, noticeInputs, "custom_notice_for_static_lib") fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n") ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex") ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib") Loading apex/builder.go +5 −32 Original line number Diff line number Diff line Loading @@ -305,32 +305,6 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Output return output.OutputPath } // buildNoticeFiles creates a buile rule for aggregating notice files from the modules that // contributes to this APEX. The notice files are merged into a big notice file. func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs { var noticeFiles android.Paths a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { if externalDep { // As soon as the dependency graph crosses the APEX boundary, don't go further. return false } noticeFiles = append(noticeFiles, to.NoticeFiles()...) return true }) // TODO(jiyong): why do we need this? WalkPayloadDeps should have already covered this. for _, fi := range a.filesInfo { noticeFiles = append(noticeFiles, fi.noticeFiles...) } if len(noticeFiles) == 0 { return android.NoticeOutputs{} } return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles)) } // buildInstalledFilesFile creates a build rule for the installed-files.txt file where the list of // files included in this APEX is shown. The text file is dist'ed so that people can see what's // included in the APEX without actually downloading and extracting it. Loading Loading @@ -642,12 +616,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { optFlags = append(optFlags, "--logging_parent ", a.overridableProperties.Logging_parent) } a.mergedNotices = a.buildNoticeFiles(ctx, a.Name()+suffix) if a.mergedNotices.HtmlGzOutput.Valid() { // If there's a NOTICE file, embed it as an asset file in the APEX. implicitInputs = append(implicitInputs, a.mergedNotices.HtmlGzOutput.Path()) optFlags = append(optFlags, "--assets_dir "+filepath.Dir(a.mergedNotices.HtmlGzOutput.String())) } // Create a NOTICE file, and embed it as an asset file in the APEX. a.htmlGzNotice = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, a.htmlGzNotice) implicitInputs = append(implicitInputs, a.htmlGzNotice) optFlags = append(optFlags, "--assets_dir "+filepath.Dir(a.htmlGzNotice.String())) if (moduleMinSdkVersion.GreaterThan(android.SdkVersion_Android10) && !a.shouldGenerateHashtree()) && !compressionEnabled { // Apexes which are supposed to be installed in builtin dirs(/system, etc) Loading Loading
android/notices.go +14 −85 Original line number Diff line number Diff line Loading @@ -15,93 +15,9 @@ package android import ( "path/filepath" "strings" "github.com/google/blueprint" ) func init() { pctx.SourcePathVariable("merge_notices", "build/soong/scripts/mergenotice.py") pctx.SourcePathVariable("generate_notice", "build/soong/scripts/generate-notice-files.py") pctx.HostBinToolVariable("minigzip", "minigzip") } type NoticeOutputs struct { Merged OptionalPath TxtOutput OptionalPath HtmlOutput OptionalPath HtmlGzOutput OptionalPath } var ( mergeNoticesRule = pctx.AndroidStaticRule("mergeNoticesRule", blueprint.RuleParams{ Command: `${merge_notices} --output $out $in`, CommandDeps: []string{"${merge_notices}"}, Description: "merge notice files into $out", }) generateNoticeRule = pctx.AndroidStaticRule("generateNoticeRule", blueprint.RuleParams{ Command: `rm -rf $$(dirname $txtOut) $$(dirname $htmlOut) $$(dirname $out) && ` + `mkdir -p $$(dirname $txtOut) $$(dirname $htmlOut) $$(dirname $out) && ` + `${generate_notice} --text-output $txtOut --html-output $htmlOut -t "$title" -s $inputDir && ` + `${minigzip} -c $htmlOut > $out`, CommandDeps: []string{"${generate_notice}", "${minigzip}"}, Description: "produce notice file $out", }, "txtOut", "htmlOut", "title", "inputDir") ) func MergeNotices(ctx ModuleContext, mergedNotice WritablePath, noticePaths []Path) { ctx.Build(pctx, BuildParams{ Rule: mergeNoticesRule, Description: "merge notices", Inputs: noticePaths, Output: mergedNotice, }) } func BuildNoticeOutput(ctx ModuleContext, installPath InstallPath, installFilename string, noticePaths []Path) NoticeOutputs { // Merge all NOTICE files into one. // TODO(jungjw): We should just produce a well-formatted NOTICE.html file in a single pass. // // generate-notice-files.py, which processes the merged NOTICE file, has somewhat strict rules // about input NOTICE file paths. // 1. Their relative paths to the src root become their NOTICE index titles. We want to use // on-device paths as titles, and so output the merged NOTICE file the corresponding location. // 2. They must end with .txt extension. Otherwise, they're ignored. noticeRelPath := InstallPathToOnDevicePath(ctx, installPath.Join(ctx, installFilename+".txt")) mergedNotice := PathForModuleOut(ctx, filepath.Join("NOTICE_FILES/src", noticeRelPath)) MergeNotices(ctx, mergedNotice, noticePaths) // Transform the merged NOTICE file into a gzipped HTML file. txtOuptut := PathForModuleOut(ctx, "NOTICE_txt", "NOTICE.txt") htmlOutput := PathForModuleOut(ctx, "NOTICE_html", "NOTICE.html") htmlGzOutput := PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") title := "Notices for " + ctx.ModuleName() ctx.Build(pctx, BuildParams{ Rule: generateNoticeRule, Description: "generate notice output", Input: mergedNotice, Output: htmlGzOutput, ImplicitOutputs: WritablePaths{txtOuptut, htmlOutput}, Args: map[string]string{ "txtOut": txtOuptut.String(), "htmlOut": htmlOutput.String(), "title": title, "inputDir": PathForModuleOut(ctx, "NOTICE_FILES/src").String(), }, }) return NoticeOutputs{ Merged: OptionalPathForPath(mergedNotice), TxtOutput: OptionalPathForPath(txtOuptut), HtmlOutput: OptionalPathForPath(htmlOutput), HtmlGzOutput: OptionalPathForPath(htmlGzOutput), } } // BuildNoticeTextOutputFromLicenseMetadata writes out a notice text file based on the module's // generated license metadata file. func BuildNoticeTextOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) { Loading @@ -112,5 +28,18 @@ func BuildNoticeTextOutputFromLicenseMetadata(ctx ModuleContext, outputFile Writ FlagWithOutput("-o ", outputFile). FlagWithDepFile("-d ", depsFile). Input(ctx.Module().base().licenseMetadataFile) rule.Build("container_notice", "container notice file") rule.Build("text_notice", "container notice file") } // BuildNoticeHtmlOutputFromLicenseMetadata writes out a notice text file based on the module's // generated license metadata file. func BuildNoticeHtmlOutputFromLicenseMetadata(ctx ModuleContext, outputFile WritablePath) { depsFile := outputFile.ReplaceExtension(ctx, strings.TrimPrefix(outputFile.Ext()+".d", ".")) rule := NewRuleBuilder(pctx, ctx) rule.Command(). BuiltTool("htmlnotice"). FlagWithOutput("-o ", outputFile). FlagWithDepFile("-d ", depsFile). Input(ctx.Module().base().licenseMetadataFile) rule.Build("html_notice", "container notice file") }
apex/androidmk.go +0 −4 Original line number Diff line number Diff line Loading @@ -396,10 +396,6 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData { } a.writeRequiredModules(w, moduleNames) if a.mergedNotices.Merged.Valid() { fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", a.mergedNotices.Merged.Path().String()) } fmt.Fprintln(w, "include $(BUILD_PREBUILT)") if apexType == imageApex { Loading
apex/apex.go +6 −8 Original line number Diff line number Diff line Loading @@ -414,8 +414,8 @@ type apexBundle struct { // Processed file_contexts files fileContexts android.WritablePath // Struct holding the merged notice file paths in different formats mergedNotices android.NoticeOutputs // Path to notice file in html.gz format. htmlGzNotice android.WritablePath // The built APEX file. This is the main product. // Could be .apex or .capex Loading Loading @@ -488,7 +488,6 @@ const ( type apexFile struct { // buildFile is put in the installDir inside the APEX. builtFile android.Path noticeFiles android.Paths installDir string customStem string symlinks []string // additional symlinks Loading Loading @@ -528,7 +527,6 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM module: module, } if module != nil { ret.noticeFiles = module.NoticeFiles() ret.moduleDir = ctx.OtherModuleDir(module) ret.requiredModuleNames = module.RequiredModuleNames() ret.targetRequiredModuleNames = module.TargetRequiredModuleNames() Loading
apex/apex_test.go +0 −9 Original line number Diff line number Diff line Loading @@ -591,15 +591,6 @@ func TestBasicApex(t *testing.T) { t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds) } mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("mergeNoticesRule") noticeInputs := mergeNoticesRule.Inputs.Strings() if len(noticeInputs) != 3 { t.Errorf("number of input notice files: expected = 3, actual = %q", len(noticeInputs)) } ensureListContains(t, noticeInputs, "NOTICE") ensureListContains(t, noticeInputs, "custom_notice") ensureListContains(t, noticeInputs, "custom_notice_for_static_lib") fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n") ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex") ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib") Loading
apex/builder.go +5 −32 Original line number Diff line number Diff line Loading @@ -305,32 +305,6 @@ func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Output return output.OutputPath } // buildNoticeFiles creates a buile rule for aggregating notice files from the modules that // contributes to this APEX. The notice files are merged into a big notice file. func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs { var noticeFiles android.Paths a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { if externalDep { // As soon as the dependency graph crosses the APEX boundary, don't go further. return false } noticeFiles = append(noticeFiles, to.NoticeFiles()...) return true }) // TODO(jiyong): why do we need this? WalkPayloadDeps should have already covered this. for _, fi := range a.filesInfo { noticeFiles = append(noticeFiles, fi.noticeFiles...) } if len(noticeFiles) == 0 { return android.NoticeOutputs{} } return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles)) } // buildInstalledFilesFile creates a build rule for the installed-files.txt file where the list of // files included in this APEX is shown. The text file is dist'ed so that people can see what's // included in the APEX without actually downloading and extracting it. Loading Loading @@ -642,12 +616,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { optFlags = append(optFlags, "--logging_parent ", a.overridableProperties.Logging_parent) } a.mergedNotices = a.buildNoticeFiles(ctx, a.Name()+suffix) if a.mergedNotices.HtmlGzOutput.Valid() { // If there's a NOTICE file, embed it as an asset file in the APEX. implicitInputs = append(implicitInputs, a.mergedNotices.HtmlGzOutput.Path()) optFlags = append(optFlags, "--assets_dir "+filepath.Dir(a.mergedNotices.HtmlGzOutput.String())) } // Create a NOTICE file, and embed it as an asset file in the APEX. a.htmlGzNotice = android.PathForModuleOut(ctx, "NOTICE", "NOTICE.html.gz") android.BuildNoticeHtmlOutputFromLicenseMetadata(ctx, a.htmlGzNotice) implicitInputs = append(implicitInputs, a.htmlGzNotice) optFlags = append(optFlags, "--assets_dir "+filepath.Dir(a.htmlGzNotice.String())) if (moduleMinSdkVersion.GreaterThan(android.SdkVersion_Android10) && !a.shouldGenerateHashtree()) && !compressionEnabled { // Apexes which are supposed to be installed in builtin dirs(/system, etc) Loading