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 && ` + 39 `echo "# proto-file: build/soong/provenance/proto/provenance_metadata.proto" > $out && ` + 40 `echo "# proto-message: ProvenanceMetaDataList" >> $out && ` + 41 `for file in $in; do echo '' >> $out; echo 'metadata {' | cat - $$file | grep -Ev "^#.*|^$$" >> $out; echo '}' >> $out; done`, 42 }) 43) 44 45type ProvenanceMetadata interface { 46 ProvenanceMetaDataFile() android.OutputPath 47} 48 49func init() { 50 RegisterProvenanceSingleton(android.InitRegistrationContext) 51} 52 53func RegisterProvenanceSingleton(ctx android.RegistrationContext) { 54 ctx.RegisterSingletonType("provenance_metadata_singleton", provenanceInfoSingletonFactory) 55} 56 57var PrepareForTestWithProvenanceSingleton = android.FixtureRegisterWithContext(RegisterProvenanceSingleton) 58 59func provenanceInfoSingletonFactory() android.Singleton { 60 return &provenanceInfoSingleton{} 61} 62 63type provenanceInfoSingleton struct { 64 mergedMetaDataFile android.OutputPath 65} 66 67func (p *provenanceInfoSingleton) GenerateBuildActions(context android.SingletonContext) { 68 allMetaDataFiles := make([]android.Path, 0) 69 context.VisitAllModulesIf(moduleFilter, func(module android.Module) { 70 if p, ok := module.(ProvenanceMetadata); ok { 71 allMetaDataFiles = append(allMetaDataFiles, p.ProvenanceMetaDataFile()) 72 } 73 }) 74 p.mergedMetaDataFile = android.PathForOutput(context, "provenance_metadata.textproto") 75 context.Build(pctx, android.BuildParams{ 76 Rule: mergeProvenanceMetaData, 77 Description: "merge provenance metadata", 78 Inputs: allMetaDataFiles, 79 Output: p.mergedMetaDataFile, 80 }) 81 82 context.Build(pctx, android.BuildParams{ 83 Rule: blueprint.Phony, 84 Description: "phony rule of merge provenance metadata", 85 Inputs: []android.Path{p.mergedMetaDataFile}, 86 Output: android.PathForPhony(context, "provenance_metadata"), 87 }) 88 89 context.Phony("droidcore", android.PathForPhony(context, "provenance_metadata")) 90} 91 92func moduleFilter(module android.Module) bool { 93 if !module.Enabled() || module.IsSkipInstall() { 94 return false 95 } 96 if p, ok := module.(ProvenanceMetadata); ok { 97 return p.ProvenanceMetaDataFile().String() != "" 98 } 99 return false 100} 101 102func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.OutputPath { 103 onDevicePathOfInstalledFile := android.InstallPathToOnDevicePath(ctx, installedFile) 104 artifactMetaDataFile := android.PathForIntermediates(ctx, "provenance_metadata", ctx.ModuleDir(), ctx.ModuleName(), "provenance_metadata.textproto") 105 ctx.Build(pctx, android.BuildParams{ 106 Rule: genProvenanceMetaData, 107 Description: "generate artifact provenance metadata", 108 Inputs: []android.Path{artifactPath}, 109 Output: artifactMetaDataFile, 110 Args: map[string]string{ 111 "module_name": ctx.ModuleName(), 112 "install_path": onDevicePathOfInstalledFile, 113 }}) 114 115 return artifactMetaDataFile 116} 117 118func (p *provenanceInfoSingleton) MakeVars(ctx android.MakeVarsContext) { 119 ctx.DistForGoal("droidcore", p.mergedMetaDataFile) 120} 121 122var _ android.SingletonMakeVarsProvider = (*provenanceInfoSingleton)(nil) 123