1*333d2b36SAndroid Build Coastguard Worker// Copyright 2021 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 "github.com/google/blueprint/depset" 19*333d2b36SAndroid Build Coastguard Worker "sort" 20*333d2b36SAndroid Build Coastguard Worker "strings" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 23*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 24*333d2b36SAndroid Build Coastguard Worker) 25*333d2b36SAndroid Build Coastguard Worker 26*333d2b36SAndroid Build Coastguard Workervar ( 27*333d2b36SAndroid Build Coastguard Worker _ = pctx.HostBinToolVariable("licenseMetadataCmd", "build_license_metadata") 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Worker licenseMetadataRule = pctx.AndroidStaticRule("licenseMetadataRule", blueprint.RuleParams{ 30*333d2b36SAndroid Build Coastguard Worker Command: "${licenseMetadataCmd} -o $out @${out}.rsp", 31*333d2b36SAndroid Build Coastguard Worker CommandDeps: []string{"${licenseMetadataCmd}"}, 32*333d2b36SAndroid Build Coastguard Worker Rspfile: "${out}.rsp", 33*333d2b36SAndroid Build Coastguard Worker RspfileContent: "${args}", 34*333d2b36SAndroid Build Coastguard Worker }, "args") 35*333d2b36SAndroid Build Coastguard Worker) 36*333d2b36SAndroid Build Coastguard Worker 37*333d2b36SAndroid Build Coastguard Workerfunc buildLicenseMetadata(ctx *moduleContext, licenseMetadataFile WritablePath) { 38*333d2b36SAndroid Build Coastguard Worker base := ctx.Module().base() 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker if !base.Enabled(ctx) { 41*333d2b36SAndroid Build Coastguard Worker return 42*333d2b36SAndroid Build Coastguard Worker } 43*333d2b36SAndroid Build Coastguard Worker 44*333d2b36SAndroid Build Coastguard Worker if exemptFromRequiredApplicableLicensesProperty(ctx.Module()) { 45*333d2b36SAndroid Build Coastguard Worker return 46*333d2b36SAndroid Build Coastguard Worker } 47*333d2b36SAndroid Build Coastguard Worker 48*333d2b36SAndroid Build Coastguard Worker var outputFiles Paths 49*333d2b36SAndroid Build Coastguard Worker if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil { 50*333d2b36SAndroid Build Coastguard Worker outputFiles = PathsIfNonNil(outputFiles...) 51*333d2b36SAndroid Build Coastguard Worker } 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Worker // Only pass the last installed file to isContainerFromFileExtensions so a *.zip file in test data 54*333d2b36SAndroid Build Coastguard Worker // doesn't mark the whole module as a container. 55*333d2b36SAndroid Build Coastguard Worker var installFiles InstallPaths 56*333d2b36SAndroid Build Coastguard Worker if len(ctx.installFiles) > 0 { 57*333d2b36SAndroid Build Coastguard Worker installFiles = InstallPaths{ctx.installFiles[len(ctx.installFiles)-1]} 58*333d2b36SAndroid Build Coastguard Worker } 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker isContainer := isContainerFromFileExtensions(installFiles, outputFiles) 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Worker var allDepMetadataFiles Paths 63*333d2b36SAndroid Build Coastguard Worker var allDepMetadataArgs []string 64*333d2b36SAndroid Build Coastguard Worker var allDepOutputFiles Paths 65*333d2b36SAndroid Build Coastguard Worker var allDepMetadataDepSets []depset.DepSet[Path] 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDeps(func(dep Module) { 68*333d2b36SAndroid Build Coastguard Worker if !dep.Enabled(ctx) { 69*333d2b36SAndroid Build Coastguard Worker return 70*333d2b36SAndroid Build Coastguard Worker } 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker // Defaults add properties and dependencies that get processed on their own. 73*333d2b36SAndroid Build Coastguard Worker if ctx.OtherModuleDependencyTag(dep) == DefaultsDepTag { 74*333d2b36SAndroid Build Coastguard Worker return 75*333d2b36SAndroid Build Coastguard Worker } 76*333d2b36SAndroid Build Coastguard Worker // The required dependencies just say modules A and B should be installed together. 77*333d2b36SAndroid Build Coastguard Worker // It doesn't mean that one is built using the other. 78*333d2b36SAndroid Build Coastguard Worker if ctx.OtherModuleDependencyTag(dep) == RequiredDepTag { 79*333d2b36SAndroid Build Coastguard Worker return 80*333d2b36SAndroid Build Coastguard Worker } 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Worker if info, ok := OtherModuleProvider(ctx, dep, LicenseMetadataProvider); ok { 83*333d2b36SAndroid Build Coastguard Worker allDepMetadataFiles = append(allDepMetadataFiles, info.LicenseMetadataPath) 84*333d2b36SAndroid Build Coastguard Worker if isContainer || isInstallDepNeeded(dep, ctx.OtherModuleDependencyTag(dep)) { 85*333d2b36SAndroid Build Coastguard Worker allDepMetadataDepSets = append(allDepMetadataDepSets, info.LicenseMetadataDepSet) 86*333d2b36SAndroid Build Coastguard Worker } 87*333d2b36SAndroid Build Coastguard Worker 88*333d2b36SAndroid Build Coastguard Worker depAnnotations := licenseAnnotationsFromTag(ctx.OtherModuleDependencyTag(dep)) 89*333d2b36SAndroid Build Coastguard Worker 90*333d2b36SAndroid Build Coastguard Worker allDepMetadataArgs = append(allDepMetadataArgs, info.LicenseMetadataPath.String()+depAnnotations) 91*333d2b36SAndroid Build Coastguard Worker 92*333d2b36SAndroid Build Coastguard Worker if depInstallFiles := OtherModuleProviderOrDefault(ctx, dep, InstallFilesProvider).InstallFiles; len(depInstallFiles) > 0 { 93*333d2b36SAndroid Build Coastguard Worker allDepOutputFiles = append(allDepOutputFiles, depInstallFiles.Paths()...) 94*333d2b36SAndroid Build Coastguard Worker } else if depOutputFiles, err := outputFilesForModule(ctx, dep, ""); err == nil { 95*333d2b36SAndroid Build Coastguard Worker depOutputFiles = PathsIfNonNil(depOutputFiles...) 96*333d2b36SAndroid Build Coastguard Worker allDepOutputFiles = append(allDepOutputFiles, depOutputFiles...) 97*333d2b36SAndroid Build Coastguard Worker } 98*333d2b36SAndroid Build Coastguard Worker } 99*333d2b36SAndroid Build Coastguard Worker }) 100*333d2b36SAndroid Build Coastguard Worker 101*333d2b36SAndroid Build Coastguard Worker allDepMetadataFiles = SortedUniquePaths(allDepMetadataFiles) 102*333d2b36SAndroid Build Coastguard Worker sort.Strings(allDepMetadataArgs) 103*333d2b36SAndroid Build Coastguard Worker allDepOutputFiles = SortedUniquePaths(allDepOutputFiles) 104*333d2b36SAndroid Build Coastguard Worker 105*333d2b36SAndroid Build Coastguard Worker var orderOnlyDeps Paths 106*333d2b36SAndroid Build Coastguard Worker var args []string 107*333d2b36SAndroid Build Coastguard Worker 108*333d2b36SAndroid Build Coastguard Worker if n := ctx.ModuleName(); n != "" { 109*333d2b36SAndroid Build Coastguard Worker args = append(args, 110*333d2b36SAndroid Build Coastguard Worker "-mn "+proptools.NinjaAndShellEscape(n)) 111*333d2b36SAndroid Build Coastguard Worker } 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Worker if t := ctx.ModuleType(); t != "" { 114*333d2b36SAndroid Build Coastguard Worker args = append(args, 115*333d2b36SAndroid Build Coastguard Worker "-mt "+proptools.NinjaAndShellEscape(t)) 116*333d2b36SAndroid Build Coastguard Worker } 117*333d2b36SAndroid Build Coastguard Worker 118*333d2b36SAndroid Build Coastguard Worker args = append(args, 119*333d2b36SAndroid Build Coastguard Worker "-r "+proptools.NinjaAndShellEscape(ctx.ModuleDir()), 120*333d2b36SAndroid Build Coastguard Worker "-mc UNKNOWN") 121*333d2b36SAndroid Build Coastguard Worker 122*333d2b36SAndroid Build Coastguard Worker if p := base.commonProperties.Effective_package_name; p != nil { 123*333d2b36SAndroid Build Coastguard Worker args = append(args, 124*333d2b36SAndroid Build Coastguard Worker `-p `+proptools.NinjaAndShellEscapeIncludingSpaces(*p)) 125*333d2b36SAndroid Build Coastguard Worker } 126*333d2b36SAndroid Build Coastguard Worker 127*333d2b36SAndroid Build Coastguard Worker args = append(args, 128*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.commonProperties.Effective_license_kinds), "-k ")) 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Worker args = append(args, 131*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.commonProperties.Effective_license_conditions), "-c ")) 132*333d2b36SAndroid Build Coastguard Worker 133*333d2b36SAndroid Build Coastguard Worker args = append(args, 134*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(base.commonProperties.Effective_license_text.Strings()), "-n ")) 135*333d2b36SAndroid Build Coastguard Worker 136*333d2b36SAndroid Build Coastguard Worker if isContainer { 137*333d2b36SAndroid Build Coastguard Worker transitiveDeps := Paths(depset.New[Path](depset.TOPOLOGICAL, nil, allDepMetadataDepSets).ToList()) 138*333d2b36SAndroid Build Coastguard Worker args = append(args, 139*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(transitiveDeps.Strings()), "-d ")) 140*333d2b36SAndroid Build Coastguard Worker orderOnlyDeps = append(orderOnlyDeps, transitiveDeps...) 141*333d2b36SAndroid Build Coastguard Worker } else { 142*333d2b36SAndroid Build Coastguard Worker args = append(args, 143*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(allDepMetadataArgs), "-d ")) 144*333d2b36SAndroid Build Coastguard Worker orderOnlyDeps = append(orderOnlyDeps, allDepMetadataFiles...) 145*333d2b36SAndroid Build Coastguard Worker } 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker args = append(args, 148*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(allDepOutputFiles.Strings()), "-s ")) 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker // Install map 151*333d2b36SAndroid Build Coastguard Worker args = append(args, 152*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.licenseInstallMap), "-m ")) 153*333d2b36SAndroid Build Coastguard Worker 154*333d2b36SAndroid Build Coastguard Worker // Built files 155*333d2b36SAndroid Build Coastguard Worker if len(outputFiles) > 0 { 156*333d2b36SAndroid Build Coastguard Worker args = append(args, 157*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(outputFiles.Strings()), "-t ")) 158*333d2b36SAndroid Build Coastguard Worker } 159*333d2b36SAndroid Build Coastguard Worker 160*333d2b36SAndroid Build Coastguard Worker // Installed files 161*333d2b36SAndroid Build Coastguard Worker args = append(args, 162*333d2b36SAndroid Build Coastguard Worker JoinWithPrefix(proptools.NinjaAndShellEscapeListIncludingSpaces(ctx.installFiles.Strings()), "-i ")) 163*333d2b36SAndroid Build Coastguard Worker 164*333d2b36SAndroid Build Coastguard Worker if isContainer { 165*333d2b36SAndroid Build Coastguard Worker args = append(args, "--is_container") 166*333d2b36SAndroid Build Coastguard Worker } 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Worker ctx.Build(pctx, BuildParams{ 169*333d2b36SAndroid Build Coastguard Worker Rule: licenseMetadataRule, 170*333d2b36SAndroid Build Coastguard Worker Output: licenseMetadataFile, 171*333d2b36SAndroid Build Coastguard Worker OrderOnly: orderOnlyDeps, 172*333d2b36SAndroid Build Coastguard Worker Description: "license metadata", 173*333d2b36SAndroid Build Coastguard Worker Args: map[string]string{ 174*333d2b36SAndroid Build Coastguard Worker "args": strings.Join(args, " "), 175*333d2b36SAndroid Build Coastguard Worker }, 176*333d2b36SAndroid Build Coastguard Worker }) 177*333d2b36SAndroid Build Coastguard Worker 178*333d2b36SAndroid Build Coastguard Worker SetProvider(ctx, LicenseMetadataProvider, &LicenseMetadataInfo{ 179*333d2b36SAndroid Build Coastguard Worker LicenseMetadataPath: licenseMetadataFile, 180*333d2b36SAndroid Build Coastguard Worker LicenseMetadataDepSet: depset.New(depset.TOPOLOGICAL, Paths{licenseMetadataFile}, allDepMetadataDepSets), 181*333d2b36SAndroid Build Coastguard Worker }) 182*333d2b36SAndroid Build Coastguard Worker} 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Workerfunc isContainerFromFileExtensions(installPaths InstallPaths, builtPaths Paths) bool { 185*333d2b36SAndroid Build Coastguard Worker var paths Paths 186*333d2b36SAndroid Build Coastguard Worker if len(installPaths) > 0 { 187*333d2b36SAndroid Build Coastguard Worker paths = installPaths.Paths() 188*333d2b36SAndroid Build Coastguard Worker } else { 189*333d2b36SAndroid Build Coastguard Worker paths = builtPaths 190*333d2b36SAndroid Build Coastguard Worker } 191*333d2b36SAndroid Build Coastguard Worker 192*333d2b36SAndroid Build Coastguard Worker for _, path := range paths { 193*333d2b36SAndroid Build Coastguard Worker switch path.Ext() { 194*333d2b36SAndroid Build Coastguard Worker case ".zip", ".tar", ".tgz", ".tar.gz", ".img", ".srcszip", ".apex", ".capex": 195*333d2b36SAndroid Build Coastguard Worker return true 196*333d2b36SAndroid Build Coastguard Worker } 197*333d2b36SAndroid Build Coastguard Worker } 198*333d2b36SAndroid Build Coastguard Worker 199*333d2b36SAndroid Build Coastguard Worker return false 200*333d2b36SAndroid Build Coastguard Worker} 201*333d2b36SAndroid Build Coastguard Worker 202*333d2b36SAndroid Build Coastguard Worker// LicenseMetadataProvider is used to propagate license metadata paths between modules. 203*333d2b36SAndroid Build Coastguard Workervar LicenseMetadataProvider = blueprint.NewProvider[*LicenseMetadataInfo]() 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker// LicenseMetadataInfo stores the license metadata path for a module. 206*333d2b36SAndroid Build Coastguard Workertype LicenseMetadataInfo struct { 207*333d2b36SAndroid Build Coastguard Worker LicenseMetadataPath Path 208*333d2b36SAndroid Build Coastguard Worker LicenseMetadataDepSet depset.DepSet[Path] 209*333d2b36SAndroid Build Coastguard Worker} 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Worker// licenseAnnotationsFromTag returns the LicenseAnnotations for a tag (if any) converted into 212*333d2b36SAndroid Build Coastguard Worker// a string, or an empty string if there are none. 213*333d2b36SAndroid Build Coastguard Workerfunc licenseAnnotationsFromTag(tag blueprint.DependencyTag) string { 214*333d2b36SAndroid Build Coastguard Worker if annoTag, ok := tag.(LicenseAnnotationsDependencyTag); ok { 215*333d2b36SAndroid Build Coastguard Worker annos := annoTag.LicenseAnnotations() 216*333d2b36SAndroid Build Coastguard Worker if len(annos) > 0 { 217*333d2b36SAndroid Build Coastguard Worker annoStrings := make([]string, len(annos)) 218*333d2b36SAndroid Build Coastguard Worker for i, s := range annos { 219*333d2b36SAndroid Build Coastguard Worker annoStrings[i] = string(s) 220*333d2b36SAndroid Build Coastguard Worker } 221*333d2b36SAndroid Build Coastguard Worker return ":" + strings.Join(annoStrings, ",") 222*333d2b36SAndroid Build Coastguard Worker } 223*333d2b36SAndroid Build Coastguard Worker } 224*333d2b36SAndroid Build Coastguard Worker return "" 225*333d2b36SAndroid Build Coastguard Worker} 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotationsDependencyTag is implemented by dependency tags in order to provide a 228*333d2b36SAndroid Build Coastguard Worker// list of license dependency annotations. 229*333d2b36SAndroid Build Coastguard Workertype LicenseAnnotationsDependencyTag interface { 230*333d2b36SAndroid Build Coastguard Worker LicenseAnnotations() []LicenseAnnotation 231*333d2b36SAndroid Build Coastguard Worker} 232*333d2b36SAndroid Build Coastguard Worker 233*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotation is an enum of annotations that can be applied to dependencies for propagating 234*333d2b36SAndroid Build Coastguard Worker// license information. 235*333d2b36SAndroid Build Coastguard Workertype LicenseAnnotation string 236*333d2b36SAndroid Build Coastguard Worker 237*333d2b36SAndroid Build Coastguard Workerconst ( 238*333d2b36SAndroid Build Coastguard Worker // LicenseAnnotationSharedDependency should be returned by LicenseAnnotations implementations 239*333d2b36SAndroid Build Coastguard Worker // of dependency tags when the usage of the dependency is dynamic, for example a shared library 240*333d2b36SAndroid Build Coastguard Worker // linkage for native modules or as a classpath library for java modules. 241*333d2b36SAndroid Build Coastguard Worker // 242*333d2b36SAndroid Build Coastguard Worker // Dependency tags that need to always return LicenseAnnotationSharedDependency 243*333d2b36SAndroid Build Coastguard Worker // can embed LicenseAnnotationSharedDependencyTag to implement LicenseAnnotations. 244*333d2b36SAndroid Build Coastguard Worker LicenseAnnotationSharedDependency LicenseAnnotation = "dynamic" 245*333d2b36SAndroid Build Coastguard Worker 246*333d2b36SAndroid Build Coastguard Worker // LicenseAnnotationToolchain should be returned by LicenseAnnotations implementations of 247*333d2b36SAndroid Build Coastguard Worker // dependency tags when the dependency is used as a toolchain. 248*333d2b36SAndroid Build Coastguard Worker // 249*333d2b36SAndroid Build Coastguard Worker // Dependency tags that need to always return LicenseAnnotationToolchain 250*333d2b36SAndroid Build Coastguard Worker // can embed LicenseAnnotationToolchainDependencyTag to implement LicenseAnnotations. 251*333d2b36SAndroid Build Coastguard Worker LicenseAnnotationToolchain LicenseAnnotation = "toolchain" 252*333d2b36SAndroid Build Coastguard Worker) 253*333d2b36SAndroid Build Coastguard Worker 254*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotationSharedDependencyTag can be embedded in a dependency tag to implement 255*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotations that always returns LicenseAnnotationSharedDependency. 256*333d2b36SAndroid Build Coastguard Workertype LicenseAnnotationSharedDependencyTag struct{} 257*333d2b36SAndroid Build Coastguard Worker 258*333d2b36SAndroid Build Coastguard Workerfunc (LicenseAnnotationSharedDependencyTag) LicenseAnnotations() []LicenseAnnotation { 259*333d2b36SAndroid Build Coastguard Worker return []LicenseAnnotation{LicenseAnnotationSharedDependency} 260*333d2b36SAndroid Build Coastguard Worker} 261*333d2b36SAndroid Build Coastguard Worker 262*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotationToolchainDependencyTag can be embedded in a dependency tag to implement 263*333d2b36SAndroid Build Coastguard Worker// LicenseAnnotations that always returns LicenseAnnotationToolchain. 264*333d2b36SAndroid Build Coastguard Workertype LicenseAnnotationToolchainDependencyTag struct{} 265*333d2b36SAndroid Build Coastguard Worker 266*333d2b36SAndroid Build Coastguard Workerfunc (LicenseAnnotationToolchainDependencyTag) LicenseAnnotations() []LicenseAnnotation { 267*333d2b36SAndroid Build Coastguard Worker return []LicenseAnnotation{LicenseAnnotationToolchain} 268*333d2b36SAndroid Build Coastguard Worker} 269