xref: /aosp_15_r20/build/soong/android/sbom.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2024 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
21*333d2b36SAndroid Build Coastguard Worker)
22*333d2b36SAndroid Build Coastguard Worker
23*333d2b36SAndroid Build Coastguard Workervar (
24*333d2b36SAndroid Build Coastguard Worker	// Command line tool to generate SBOM in Soong
25*333d2b36SAndroid Build Coastguard Worker	genSbom = pctx.HostBinToolVariable("genSbom", "gen_sbom")
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker	// Command to generate SBOM in Soong.
28*333d2b36SAndroid Build Coastguard Worker	genSbomRule = pctx.AndroidStaticRule("genSbomRule", blueprint.RuleParams{
29*333d2b36SAndroid Build Coastguard Worker		Command:     "rm -rf $out && ${genSbom} --output_file ${out} --metadata ${in} --product_out ${productOut} --soong_out ${soongOut} --build_version \"$$(cat ${buildFingerprintFile})\" --product_mfr \"${productManufacturer}\" --json",
30*333d2b36SAndroid Build Coastguard Worker		CommandDeps: []string{"${genSbom}"},
31*333d2b36SAndroid Build Coastguard Worker	}, "productOut", "soongOut", "buildFingerprintFile", "productManufacturer")
32*333d2b36SAndroid Build Coastguard Worker)
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workerfunc init() {
35*333d2b36SAndroid Build Coastguard Worker	RegisterSbomSingleton(InitRegistrationContext)
36*333d2b36SAndroid Build Coastguard Worker}
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workerfunc RegisterSbomSingleton(ctx RegistrationContext) {
39*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterParallelSingletonType("sbom_singleton", sbomSingletonFactory)
40*333d2b36SAndroid Build Coastguard Worker}
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker// sbomSingleton is used to generate build actions of generating SBOM of products.
43*333d2b36SAndroid Build Coastguard Workertype sbomSingleton struct {
44*333d2b36SAndroid Build Coastguard Worker	sbomFile OutputPath
45*333d2b36SAndroid Build Coastguard Worker}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Workerfunc sbomSingletonFactory() Singleton {
48*333d2b36SAndroid Build Coastguard Worker	return &sbomSingleton{}
49*333d2b36SAndroid Build Coastguard Worker}
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Worker// Generates SBOM of products
52*333d2b36SAndroid Build Coastguard Workerfunc (this *sbomSingleton) GenerateBuildActions(ctx SingletonContext) {
53*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().HasDeviceProduct() {
54*333d2b36SAndroid Build Coastguard Worker		return
55*333d2b36SAndroid Build Coastguard Worker	}
56*333d2b36SAndroid Build Coastguard Worker	implicits := []Path{}
57*333d2b36SAndroid Build Coastguard Worker	prodVars := ctx.Config().productVariables
58*333d2b36SAndroid Build Coastguard Worker	buildFingerprintFile := PathForArbitraryOutput(ctx, "target", "product", String(prodVars.DeviceName), "build_fingerprint.txt")
59*333d2b36SAndroid Build Coastguard Worker	implicits = append(implicits, buildFingerprintFile)
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker	// Add installed_files.stamp as implicit input, which depends on all installed files of the product.
62*333d2b36SAndroid Build Coastguard Worker	installedFilesStamp := PathForOutput(ctx, "compliance-metadata", ctx.Config().DeviceProduct(), "installed_files.stamp")
63*333d2b36SAndroid Build Coastguard Worker	implicits = append(implicits, installedFilesStamp)
64*333d2b36SAndroid Build Coastguard Worker
65*333d2b36SAndroid Build Coastguard Worker	metadataDb := PathForOutput(ctx, "compliance-metadata", ctx.Config().DeviceProduct(), "compliance-metadata.db")
66*333d2b36SAndroid Build Coastguard Worker	this.sbomFile = PathForOutput(ctx, "sbom", ctx.Config().DeviceProduct(), "sbom.spdx.json")
67*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, BuildParams{
68*333d2b36SAndroid Build Coastguard Worker		Rule:      genSbomRule,
69*333d2b36SAndroid Build Coastguard Worker		Input:     metadataDb,
70*333d2b36SAndroid Build Coastguard Worker		Implicits: implicits,
71*333d2b36SAndroid Build Coastguard Worker		Output:    this.sbomFile,
72*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
73*333d2b36SAndroid Build Coastguard Worker			"productOut":           filepath.Join(ctx.Config().OutDir(), "target", "product", String(prodVars.DeviceName)),
74*333d2b36SAndroid Build Coastguard Worker			"soongOut":             ctx.Config().soongOutDir,
75*333d2b36SAndroid Build Coastguard Worker			"buildFingerprintFile": buildFingerprintFile.String(),
76*333d2b36SAndroid Build Coastguard Worker			"productManufacturer":  ctx.Config().ProductVariables().ProductManufacturer,
77*333d2b36SAndroid Build Coastguard Worker		},
78*333d2b36SAndroid Build Coastguard Worker	})
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().UnbundledBuildApps() {
81*333d2b36SAndroid Build Coastguard Worker		// When building SBOM of products, phony rule "sbom" is for generating product SBOM in Soong.
82*333d2b36SAndroid Build Coastguard Worker		ctx.Build(pctx, BuildParams{
83*333d2b36SAndroid Build Coastguard Worker			Rule:   blueprint.Phony,
84*333d2b36SAndroid Build Coastguard Worker			Inputs: []Path{this.sbomFile},
85*333d2b36SAndroid Build Coastguard Worker			Output: PathForPhony(ctx, "sbom"),
86*333d2b36SAndroid Build Coastguard Worker		})
87*333d2b36SAndroid Build Coastguard Worker	}
88*333d2b36SAndroid Build Coastguard Worker}
89*333d2b36SAndroid Build Coastguard Worker
90*333d2b36SAndroid Build Coastguard Workerfunc (this *sbomSingleton) MakeVars(ctx MakeVarsContext) {
91*333d2b36SAndroid Build Coastguard Worker	// When building SBOM of products
92*333d2b36SAndroid Build Coastguard Worker	if !ctx.Config().UnbundledBuildApps() {
93*333d2b36SAndroid Build Coastguard Worker		ctx.DistForGoalWithFilename("droid", this.sbomFile, "sbom/sbom.spdx.json")
94*333d2b36SAndroid Build Coastguard Worker	}
95*333d2b36SAndroid Build Coastguard Worker}
96