1/* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package provenance 18 19import ( 20 "android/soong/android" 21 "github.com/google/blueprint" 22) 23 24var ( 25 pctx = android.NewPackageContext("android/soong/provenance") 26 rule = pctx.HostBinToolVariable("gen_provenance_metadata", "gen_provenance_metadata") 27 28 genProvenanceMetaData = pctx.AndroidStaticRule("genProvenanceMetaData", 29 blueprint.RuleParams{ 30 Command: `rm -rf "$out" && ` + 31 `${gen_provenance_metadata} --module_name=${module_name} ` + 32 `--artifact_path=$in --install_path=${install_path} --metadata_path=$out`, 33 CommandDeps: []string{"${gen_provenance_metadata}"}, 34 }, "module_name", "install_path") 35 36 mergeProvenanceMetaData = pctx.AndroidStaticRule("mergeProvenanceMetaData", 37 blueprint.RuleParams{ 38 Command: `rm -rf $out $out.temp && ` + 39 `echo -e "# proto-file: build/soong/provenance/proto/provenance_metadata.proto\n# proto-message: ProvenanceMetaDataList" > $out && ` + 40 `touch $out.temp && cat $out.temp $in | grep -v "^#.*" >> $out && rm -rf $out.temp`, 41 }) 42) 43 44type ProvenanceMetadata interface { 45 ProvenanceMetaDataFile() android.OutputPath 46} 47 48func init() { 49 RegisterProvenanceSingleton(android.InitRegistrationContext) 50} 51 52func RegisterProvenanceSingleton(ctx android.RegistrationContext) { 53 ctx.RegisterSingletonType("provenance_metadata_singleton", provenanceInfoSingletonFactory) 54} 55 56var PrepareForTestWithProvenanceSingleton = android.FixtureRegisterWithContext(RegisterProvenanceSingleton) 57 58func provenanceInfoSingletonFactory() android.Singleton { 59 return &provenanceInfoSingleton{} 60} 61 62type provenanceInfoSingleton struct { 63 mergedMetaDataFile android.OutputPath 64} 65 66func (p *provenanceInfoSingleton) GenerateBuildActions(context android.SingletonContext) { 67 allMetaDataFiles := make([]android.Path, 0) 68 context.VisitAllModulesIf(moduleFilter, func(module android.Module) { 69 if p, ok := module.(ProvenanceMetadata); ok { 70 allMetaDataFiles = append(allMetaDataFiles, p.ProvenanceMetaDataFile()) 71 } 72 }) 73 p.mergedMetaDataFile = android.PathForOutput(context, "provenance_metadata.textproto") 74 context.Build(pctx, android.BuildParams{ 75 Rule: mergeProvenanceMetaData, 76 Description: "merge provenance metadata", 77 Inputs: allMetaDataFiles, 78 Output: p.mergedMetaDataFile, 79 }) 80 81 context.Build(pctx, android.BuildParams{ 82 Rule: blueprint.Phony, 83 Description: "phony rule of merge provenance metadata", 84 Inputs: []android.Path{p.mergedMetaDataFile}, 85 Output: android.PathForPhony(context, "provenance_metadata"), 86 }) 87 88 context.Phony("droidcore", android.PathForPhony(context, "provenance_metadata")) 89} 90 91func moduleFilter(module android.Module) bool { 92 if !module.Enabled() || module.IsSkipInstall() { 93 return false 94 } 95 if p, ok := module.(ProvenanceMetadata); ok { 96 return p.ProvenanceMetaDataFile().String() != "" 97 } 98 return false 99} 100 101func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.OutputPath { 102 onDevicePathOfInstalledFile := android.InstallPathToOnDevicePath(ctx, installedFile) 103 artifactMetaDataFile := android.PathForIntermediates(ctx, "provenance_metadata", ctx.ModuleDir(), ctx.ModuleName(), "provenance_metadata.textproto") 104 ctx.Build(pctx, android.BuildParams{ 105 Rule: genProvenanceMetaData, 106 Description: "generate artifact provenance metadata", 107 Inputs: []android.Path{artifactPath}, 108 Output: artifactMetaDataFile, 109 Args: map[string]string{ 110 "module_name": ctx.ModuleName(), 111 "install_path": onDevicePathOfInstalledFile, 112 }}) 113 114 return artifactMetaDataFile 115} 116 117func (p *provenanceInfoSingleton) MakeVars(ctx android.MakeVarsContext) { 118 ctx.DistForGoal("droidcore", p.mergedMetaDataFile) 119} 120 121var _ android.SingletonMakeVarsProvider = (*provenanceInfoSingleton)(nil) 122