1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 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 "fmt" 19*333d2b36SAndroid Build Coastguard Worker "path/filepath" 20*333d2b36SAndroid Build Coastguard Worker "sort" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 23*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/gobtools" 24*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 25*333d2b36SAndroid Build Coastguard Worker) 26*333d2b36SAndroid Build Coastguard Worker 27*333d2b36SAndroid Build Coastguard Worker// PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A 28*333d2b36SAndroid Build Coastguard Worker// package can be the traditional <partition>.img, but isn't limited to those. Other examples could 29*333d2b36SAndroid Build Coastguard Worker// be a new filesystem image that is a subset of system.img (e.g. for an Android-like mini OS 30*333d2b36SAndroid Build Coastguard Worker// running on a VM), or a zip archive for some of the host tools. 31*333d2b36SAndroid Build Coastguard Workertype PackagingSpec struct { 32*333d2b36SAndroid Build Coastguard Worker // Path relative to the root of the package 33*333d2b36SAndroid Build Coastguard Worker relPathInPackage string 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Worker // The path to the built artifact 36*333d2b36SAndroid Build Coastguard Worker srcPath Path 37*333d2b36SAndroid Build Coastguard Worker 38*333d2b36SAndroid Build Coastguard Worker // If this is not empty, then relPathInPackage should be a symlink to this target. (Then 39*333d2b36SAndroid Build Coastguard Worker // srcPath is of course ignored.) 40*333d2b36SAndroid Build Coastguard Worker symlinkTarget string 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Worker // Whether relPathInPackage should be marked as executable or not 43*333d2b36SAndroid Build Coastguard Worker executable bool 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker effectiveLicenseFiles *Paths 46*333d2b36SAndroid Build Coastguard Worker 47*333d2b36SAndroid Build Coastguard Worker partition string 48*333d2b36SAndroid Build Coastguard Worker 49*333d2b36SAndroid Build Coastguard Worker // Whether this packaging spec represents an installation of the srcPath (i.e. this struct 50*333d2b36SAndroid Build Coastguard Worker // is created via InstallFile or InstallSymlink) or a simple packaging (i.e. created via 51*333d2b36SAndroid Build Coastguard Worker // PackageFile). 52*333d2b36SAndroid Build Coastguard Worker skipInstall bool 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Worker // Paths of aconfig files for the built artifact 55*333d2b36SAndroid Build Coastguard Worker aconfigPaths *Paths 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker // ArchType of the module which produced this packaging spec 58*333d2b36SAndroid Build Coastguard Worker archType ArchType 59*333d2b36SAndroid Build Coastguard Worker 60*333d2b36SAndroid Build Coastguard Worker // List of module names that this packaging spec overrides 61*333d2b36SAndroid Build Coastguard Worker overrides *[]string 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker // Name of the module where this packaging spec is output of 64*333d2b36SAndroid Build Coastguard Worker owner string 65*333d2b36SAndroid Build Coastguard Worker} 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Workertype packagingSpecGob struct { 68*333d2b36SAndroid Build Coastguard Worker RelPathInPackage string 69*333d2b36SAndroid Build Coastguard Worker SrcPath Path 70*333d2b36SAndroid Build Coastguard Worker SymlinkTarget string 71*333d2b36SAndroid Build Coastguard Worker Executable bool 72*333d2b36SAndroid Build Coastguard Worker EffectiveLicenseFiles *Paths 73*333d2b36SAndroid Build Coastguard Worker Partition string 74*333d2b36SAndroid Build Coastguard Worker SkipInstall bool 75*333d2b36SAndroid Build Coastguard Worker AconfigPaths *Paths 76*333d2b36SAndroid Build Coastguard Worker ArchType ArchType 77*333d2b36SAndroid Build Coastguard Worker Overrides *[]string 78*333d2b36SAndroid Build Coastguard Worker Owner string 79*333d2b36SAndroid Build Coastguard Worker} 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) ToGob() *packagingSpecGob { 82*333d2b36SAndroid Build Coastguard Worker return &packagingSpecGob{ 83*333d2b36SAndroid Build Coastguard Worker RelPathInPackage: p.relPathInPackage, 84*333d2b36SAndroid Build Coastguard Worker SrcPath: p.srcPath, 85*333d2b36SAndroid Build Coastguard Worker SymlinkTarget: p.symlinkTarget, 86*333d2b36SAndroid Build Coastguard Worker Executable: p.executable, 87*333d2b36SAndroid Build Coastguard Worker EffectiveLicenseFiles: p.effectiveLicenseFiles, 88*333d2b36SAndroid Build Coastguard Worker Partition: p.partition, 89*333d2b36SAndroid Build Coastguard Worker SkipInstall: p.skipInstall, 90*333d2b36SAndroid Build Coastguard Worker AconfigPaths: p.aconfigPaths, 91*333d2b36SAndroid Build Coastguard Worker ArchType: p.archType, 92*333d2b36SAndroid Build Coastguard Worker Overrides: p.overrides, 93*333d2b36SAndroid Build Coastguard Worker Owner: p.owner, 94*333d2b36SAndroid Build Coastguard Worker } 95*333d2b36SAndroid Build Coastguard Worker} 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) FromGob(data *packagingSpecGob) { 98*333d2b36SAndroid Build Coastguard Worker p.relPathInPackage = data.RelPathInPackage 99*333d2b36SAndroid Build Coastguard Worker p.srcPath = data.SrcPath 100*333d2b36SAndroid Build Coastguard Worker p.symlinkTarget = data.SymlinkTarget 101*333d2b36SAndroid Build Coastguard Worker p.executable = data.Executable 102*333d2b36SAndroid Build Coastguard Worker p.effectiveLicenseFiles = data.EffectiveLicenseFiles 103*333d2b36SAndroid Build Coastguard Worker p.partition = data.Partition 104*333d2b36SAndroid Build Coastguard Worker p.skipInstall = data.SkipInstall 105*333d2b36SAndroid Build Coastguard Worker p.aconfigPaths = data.AconfigPaths 106*333d2b36SAndroid Build Coastguard Worker p.archType = data.ArchType 107*333d2b36SAndroid Build Coastguard Worker p.overrides = data.Overrides 108*333d2b36SAndroid Build Coastguard Worker p.owner = data.Owner 109*333d2b36SAndroid Build Coastguard Worker} 110*333d2b36SAndroid Build Coastguard Worker 111*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) GobEncode() ([]byte, error) { 112*333d2b36SAndroid Build Coastguard Worker return gobtools.CustomGobEncode[packagingSpecGob](p) 113*333d2b36SAndroid Build Coastguard Worker} 114*333d2b36SAndroid Build Coastguard Worker 115*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) GobDecode(data []byte) error { 116*333d2b36SAndroid Build Coastguard Worker return gobtools.CustomGobDecode[packagingSpecGob](data, p) 117*333d2b36SAndroid Build Coastguard Worker} 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) Equals(other *PackagingSpec) bool { 120*333d2b36SAndroid Build Coastguard Worker if other == nil { 121*333d2b36SAndroid Build Coastguard Worker return false 122*333d2b36SAndroid Build Coastguard Worker } 123*333d2b36SAndroid Build Coastguard Worker if p.relPathInPackage != other.relPathInPackage { 124*333d2b36SAndroid Build Coastguard Worker return false 125*333d2b36SAndroid Build Coastguard Worker } 126*333d2b36SAndroid Build Coastguard Worker if p.srcPath != other.srcPath || p.symlinkTarget != other.symlinkTarget { 127*333d2b36SAndroid Build Coastguard Worker return false 128*333d2b36SAndroid Build Coastguard Worker } 129*333d2b36SAndroid Build Coastguard Worker if p.executable != other.executable { 130*333d2b36SAndroid Build Coastguard Worker return false 131*333d2b36SAndroid Build Coastguard Worker } 132*333d2b36SAndroid Build Coastguard Worker if p.partition != other.partition { 133*333d2b36SAndroid Build Coastguard Worker return false 134*333d2b36SAndroid Build Coastguard Worker } 135*333d2b36SAndroid Build Coastguard Worker return true 136*333d2b36SAndroid Build Coastguard Worker} 137*333d2b36SAndroid Build Coastguard Worker 138*333d2b36SAndroid Build Coastguard Worker// Get file name of installed package 139*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) FileName() string { 140*333d2b36SAndroid Build Coastguard Worker if p.relPathInPackage != "" { 141*333d2b36SAndroid Build Coastguard Worker return filepath.Base(p.relPathInPackage) 142*333d2b36SAndroid Build Coastguard Worker } 143*333d2b36SAndroid Build Coastguard Worker 144*333d2b36SAndroid Build Coastguard Worker return "" 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker// Path relative to the root of the package 148*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) RelPathInPackage() string { 149*333d2b36SAndroid Build Coastguard Worker return p.relPathInPackage 150*333d2b36SAndroid Build Coastguard Worker} 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) SetRelPathInPackage(relPathInPackage string) { 153*333d2b36SAndroid Build Coastguard Worker p.relPathInPackage = relPathInPackage 154*333d2b36SAndroid Build Coastguard Worker} 155*333d2b36SAndroid Build Coastguard Worker 156*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) EffectiveLicenseFiles() Paths { 157*333d2b36SAndroid Build Coastguard Worker if p.effectiveLicenseFiles == nil { 158*333d2b36SAndroid Build Coastguard Worker return Paths{} 159*333d2b36SAndroid Build Coastguard Worker } 160*333d2b36SAndroid Build Coastguard Worker return *p.effectiveLicenseFiles 161*333d2b36SAndroid Build Coastguard Worker} 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) Partition() string { 164*333d2b36SAndroid Build Coastguard Worker return p.partition 165*333d2b36SAndroid Build Coastguard Worker} 166*333d2b36SAndroid Build Coastguard Worker 167*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) SetPartition(partition string) { 168*333d2b36SAndroid Build Coastguard Worker p.partition = partition 169*333d2b36SAndroid Build Coastguard Worker} 170*333d2b36SAndroid Build Coastguard Worker 171*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) SkipInstall() bool { 172*333d2b36SAndroid Build Coastguard Worker return p.skipInstall 173*333d2b36SAndroid Build Coastguard Worker} 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Worker// Paths of aconfig files for the built artifact 176*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingSpec) GetAconfigPaths() Paths { 177*333d2b36SAndroid Build Coastguard Worker return *p.aconfigPaths 178*333d2b36SAndroid Build Coastguard Worker} 179*333d2b36SAndroid Build Coastguard Worker 180*333d2b36SAndroid Build Coastguard Workertype PackageModule interface { 181*333d2b36SAndroid Build Coastguard Worker Module 182*333d2b36SAndroid Build Coastguard Worker packagingBase() *PackagingBase 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Worker // AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator. 185*333d2b36SAndroid Build Coastguard Worker // When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to 186*333d2b36SAndroid Build Coastguard Worker // be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface. 187*333d2b36SAndroid Build Coastguard Worker AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) 188*333d2b36SAndroid Build Coastguard Worker 189*333d2b36SAndroid Build Coastguard Worker // GatherPackagingSpecs gathers PackagingSpecs of transitive dependencies. 190*333d2b36SAndroid Build Coastguard Worker GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec 191*333d2b36SAndroid Build Coastguard Worker GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec 192*333d2b36SAndroid Build Coastguard Worker GatherPackagingSpecsWithFilterAndModifier(ctx ModuleContext, filter func(PackagingSpec) bool, modifier func(*PackagingSpec)) map[string]PackagingSpec 193*333d2b36SAndroid Build Coastguard Worker 194*333d2b36SAndroid Build Coastguard Worker // CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and 195*333d2b36SAndroid Build Coastguard Worker // returns zip entries in it. This is expected to be called in GenerateAndroidBuildActions, 196*333d2b36SAndroid Build Coastguard Worker // followed by a build rule that unzips it and creates the final output (img, zip, tar.gz, 197*333d2b36SAndroid Build Coastguard Worker // etc.) from the extracted files 198*333d2b36SAndroid Build Coastguard Worker CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) []string 199*333d2b36SAndroid Build Coastguard Worker} 200*333d2b36SAndroid Build Coastguard Worker 201*333d2b36SAndroid Build Coastguard Worker// PackagingBase provides basic functionality for packaging dependencies. A module is expected to 202*333d2b36SAndroid Build Coastguard Worker// include this struct and call InitPackageModule. 203*333d2b36SAndroid Build Coastguard Workertype PackagingBase struct { 204*333d2b36SAndroid Build Coastguard Worker properties PackagingProperties 205*333d2b36SAndroid Build Coastguard Worker 206*333d2b36SAndroid Build Coastguard Worker // Allows this module to skip missing dependencies. In most cases, this is not required, but 207*333d2b36SAndroid Build Coastguard Worker // for rare cases like when there's a dependency to a module which exists in certain repo 208*333d2b36SAndroid Build Coastguard Worker // checkouts, this is needed. 209*333d2b36SAndroid Build Coastguard Worker IgnoreMissingDependencies bool 210*333d2b36SAndroid Build Coastguard Worker 211*333d2b36SAndroid Build Coastguard Worker // If this is set to true by a module type inheriting PackagingBase, the deps property 212*333d2b36SAndroid Build Coastguard Worker // collects the first target only even with compile_multilib: true. 213*333d2b36SAndroid Build Coastguard Worker DepsCollectFirstTargetOnly bool 214*333d2b36SAndroid Build Coastguard Worker 215*333d2b36SAndroid Build Coastguard Worker // If this is set to try by a module type inheriting PackagingBase, the module type is 216*333d2b36SAndroid Build Coastguard Worker // allowed to utilize High_priority_deps. 217*333d2b36SAndroid Build Coastguard Worker AllowHighPriorityDeps bool 218*333d2b36SAndroid Build Coastguard Worker} 219*333d2b36SAndroid Build Coastguard Worker 220*333d2b36SAndroid Build Coastguard Workertype DepsProperty struct { 221*333d2b36SAndroid Build Coastguard Worker // Deps that have higher priority in packaging when there is a packaging conflict. 222*333d2b36SAndroid Build Coastguard Worker // For example, if multiple files are being installed to same filepath, the install file 223*333d2b36SAndroid Build Coastguard Worker // of the module listed in this property will have a higher priority over those in other 224*333d2b36SAndroid Build Coastguard Worker // deps properties. 225*333d2b36SAndroid Build Coastguard Worker High_priority_deps []string `android:"arch_variant"` 226*333d2b36SAndroid Build Coastguard Worker 227*333d2b36SAndroid Build Coastguard Worker // Modules to include in this package 228*333d2b36SAndroid Build Coastguard Worker Deps proptools.Configurable[[]string] `android:"arch_variant"` 229*333d2b36SAndroid Build Coastguard Worker} 230*333d2b36SAndroid Build Coastguard Worker 231*333d2b36SAndroid Build Coastguard Workertype packagingMultilibProperties struct { 232*333d2b36SAndroid Build Coastguard Worker First DepsProperty `android:"arch_variant"` 233*333d2b36SAndroid Build Coastguard Worker Common DepsProperty `android:"arch_variant"` 234*333d2b36SAndroid Build Coastguard Worker Lib32 DepsProperty `android:"arch_variant"` 235*333d2b36SAndroid Build Coastguard Worker Lib64 DepsProperty `android:"arch_variant"` 236*333d2b36SAndroid Build Coastguard Worker Both DepsProperty `android:"arch_variant"` 237*333d2b36SAndroid Build Coastguard Worker Prefer32 DepsProperty `android:"arch_variant"` 238*333d2b36SAndroid Build Coastguard Worker} 239*333d2b36SAndroid Build Coastguard Worker 240*333d2b36SAndroid Build Coastguard Workertype packagingArchProperties struct { 241*333d2b36SAndroid Build Coastguard Worker Arm64 DepsProperty 242*333d2b36SAndroid Build Coastguard Worker Arm DepsProperty 243*333d2b36SAndroid Build Coastguard Worker X86_64 DepsProperty 244*333d2b36SAndroid Build Coastguard Worker X86 DepsProperty 245*333d2b36SAndroid Build Coastguard Worker} 246*333d2b36SAndroid Build Coastguard Worker 247*333d2b36SAndroid Build Coastguard Workertype PackagingProperties struct { 248*333d2b36SAndroid Build Coastguard Worker DepsProperty 249*333d2b36SAndroid Build Coastguard Worker 250*333d2b36SAndroid Build Coastguard Worker Multilib packagingMultilibProperties `android:"arch_variant"` 251*333d2b36SAndroid Build Coastguard Worker Arch packagingArchProperties 252*333d2b36SAndroid Build Coastguard Worker} 253*333d2b36SAndroid Build Coastguard Worker 254*333d2b36SAndroid Build Coastguard Workerfunc InitPackageModule(p PackageModule) { 255*333d2b36SAndroid Build Coastguard Worker base := p.packagingBase() 256*333d2b36SAndroid Build Coastguard Worker p.AddProperties(&base.properties, &base.properties.DepsProperty) 257*333d2b36SAndroid Build Coastguard Worker} 258*333d2b36SAndroid Build Coastguard Worker 259*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) packagingBase() *PackagingBase { 260*333d2b36SAndroid Build Coastguard Worker return p 261*333d2b36SAndroid Build Coastguard Worker} 262*333d2b36SAndroid Build Coastguard Worker 263*333d2b36SAndroid Build Coastguard Worker// From deps and multilib.*.deps, select the dependencies that are for the given arch deps is for 264*333d2b36SAndroid Build Coastguard Worker// the current archicture when this module is not configured for multi target. When configured for 265*333d2b36SAndroid Build Coastguard Worker// multi target, deps is selected for each of the targets and is NOT selected for the current 266*333d2b36SAndroid Build Coastguard Worker// architecture which would be Common. 267*333d2b36SAndroid Build Coastguard Worker// It returns two lists, the normal and high priority deps, respectively. 268*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) ([]string, []string) { 269*333d2b36SAndroid Build Coastguard Worker var normalDeps []string 270*333d2b36SAndroid Build Coastguard Worker var highPriorityDeps []string 271*333d2b36SAndroid Build Coastguard Worker 272*333d2b36SAndroid Build Coastguard Worker get := func(prop DepsProperty) { 273*333d2b36SAndroid Build Coastguard Worker normalDeps = append(normalDeps, prop.Deps.GetOrDefault(ctx, nil)...) 274*333d2b36SAndroid Build Coastguard Worker highPriorityDeps = append(highPriorityDeps, prop.High_priority_deps...) 275*333d2b36SAndroid Build Coastguard Worker } 276*333d2b36SAndroid Build Coastguard Worker has := func(prop DepsProperty) bool { 277*333d2b36SAndroid Build Coastguard Worker return len(prop.Deps.GetOrDefault(ctx, nil)) > 0 || len(prop.High_priority_deps) > 0 278*333d2b36SAndroid Build Coastguard Worker } 279*333d2b36SAndroid Build Coastguard Worker 280*333d2b36SAndroid Build Coastguard Worker if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 { 281*333d2b36SAndroid Build Coastguard Worker get(p.properties.DepsProperty) 282*333d2b36SAndroid Build Coastguard Worker } else if arch.Multilib == "lib32" { 283*333d2b36SAndroid Build Coastguard Worker get(p.properties.Multilib.Lib32) 284*333d2b36SAndroid Build Coastguard Worker // multilib.prefer32.deps are added for lib32 only when they support 32-bit arch 285*333d2b36SAndroid Build Coastguard Worker for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) { 286*333d2b36SAndroid Build Coastguard Worker if checkIfOtherModuleSupportsLib32(ctx, dep) { 287*333d2b36SAndroid Build Coastguard Worker normalDeps = append(normalDeps, dep) 288*333d2b36SAndroid Build Coastguard Worker } 289*333d2b36SAndroid Build Coastguard Worker } 290*333d2b36SAndroid Build Coastguard Worker for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps { 291*333d2b36SAndroid Build Coastguard Worker if checkIfOtherModuleSupportsLib32(ctx, dep) { 292*333d2b36SAndroid Build Coastguard Worker highPriorityDeps = append(highPriorityDeps, dep) 293*333d2b36SAndroid Build Coastguard Worker } 294*333d2b36SAndroid Build Coastguard Worker } 295*333d2b36SAndroid Build Coastguard Worker } else if arch.Multilib == "lib64" { 296*333d2b36SAndroid Build Coastguard Worker get(p.properties.Multilib.Lib64) 297*333d2b36SAndroid Build Coastguard Worker // multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch 298*333d2b36SAndroid Build Coastguard Worker for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) { 299*333d2b36SAndroid Build Coastguard Worker if !checkIfOtherModuleSupportsLib32(ctx, dep) { 300*333d2b36SAndroid Build Coastguard Worker normalDeps = append(normalDeps, dep) 301*333d2b36SAndroid Build Coastguard Worker } 302*333d2b36SAndroid Build Coastguard Worker } 303*333d2b36SAndroid Build Coastguard Worker for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps { 304*333d2b36SAndroid Build Coastguard Worker if !checkIfOtherModuleSupportsLib32(ctx, dep) { 305*333d2b36SAndroid Build Coastguard Worker highPriorityDeps = append(highPriorityDeps, dep) 306*333d2b36SAndroid Build Coastguard Worker } 307*333d2b36SAndroid Build Coastguard Worker } 308*333d2b36SAndroid Build Coastguard Worker } else if arch == Common { 309*333d2b36SAndroid Build Coastguard Worker get(p.properties.Multilib.Common) 310*333d2b36SAndroid Build Coastguard Worker } 311*333d2b36SAndroid Build Coastguard Worker 312*333d2b36SAndroid Build Coastguard Worker if p.DepsCollectFirstTargetOnly { 313*333d2b36SAndroid Build Coastguard Worker if has(p.properties.Multilib.First) { 314*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead") 315*333d2b36SAndroid Build Coastguard Worker } 316*333d2b36SAndroid Build Coastguard Worker for i, t := range ctx.MultiTargets() { 317*333d2b36SAndroid Build Coastguard Worker if t.Arch.ArchType == arch { 318*333d2b36SAndroid Build Coastguard Worker get(p.properties.Multilib.Both) 319*333d2b36SAndroid Build Coastguard Worker if i == 0 { 320*333d2b36SAndroid Build Coastguard Worker get(p.properties.DepsProperty) 321*333d2b36SAndroid Build Coastguard Worker } 322*333d2b36SAndroid Build Coastguard Worker } 323*333d2b36SAndroid Build Coastguard Worker } 324*333d2b36SAndroid Build Coastguard Worker } else { 325*333d2b36SAndroid Build Coastguard Worker if has(p.properties.Multilib.Both) { 326*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead") 327*333d2b36SAndroid Build Coastguard Worker } 328*333d2b36SAndroid Build Coastguard Worker for i, t := range ctx.MultiTargets() { 329*333d2b36SAndroid Build Coastguard Worker if t.Arch.ArchType == arch { 330*333d2b36SAndroid Build Coastguard Worker get(p.properties.DepsProperty) 331*333d2b36SAndroid Build Coastguard Worker if i == 0 { 332*333d2b36SAndroid Build Coastguard Worker get(p.properties.Multilib.First) 333*333d2b36SAndroid Build Coastguard Worker } 334*333d2b36SAndroid Build Coastguard Worker } 335*333d2b36SAndroid Build Coastguard Worker } 336*333d2b36SAndroid Build Coastguard Worker } 337*333d2b36SAndroid Build Coastguard Worker 338*333d2b36SAndroid Build Coastguard Worker if ctx.Arch().ArchType == Common { 339*333d2b36SAndroid Build Coastguard Worker switch arch { 340*333d2b36SAndroid Build Coastguard Worker case Arm64: 341*333d2b36SAndroid Build Coastguard Worker get(p.properties.Arch.Arm64) 342*333d2b36SAndroid Build Coastguard Worker case Arm: 343*333d2b36SAndroid Build Coastguard Worker get(p.properties.Arch.Arm) 344*333d2b36SAndroid Build Coastguard Worker case X86_64: 345*333d2b36SAndroid Build Coastguard Worker get(p.properties.Arch.X86_64) 346*333d2b36SAndroid Build Coastguard Worker case X86: 347*333d2b36SAndroid Build Coastguard Worker get(p.properties.Arch.X86) 348*333d2b36SAndroid Build Coastguard Worker } 349*333d2b36SAndroid Build Coastguard Worker } 350*333d2b36SAndroid Build Coastguard Worker 351*333d2b36SAndroid Build Coastguard Worker if len(highPriorityDeps) > 0 && !p.AllowHighPriorityDeps { 352*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Usage of high_priority_deps is not allowed for %s module type", ctx.ModuleType()) 353*333d2b36SAndroid Build Coastguard Worker } 354*333d2b36SAndroid Build Coastguard Worker 355*333d2b36SAndroid Build Coastguard Worker return FirstUniqueStrings(normalDeps), FirstUniqueStrings(highPriorityDeps) 356*333d2b36SAndroid Build Coastguard Worker} 357*333d2b36SAndroid Build Coastguard Worker 358*333d2b36SAndroid Build Coastguard Workerfunc getSupportedTargets(ctx BaseModuleContext) []Target { 359*333d2b36SAndroid Build Coastguard Worker var ret []Target 360*333d2b36SAndroid Build Coastguard Worker // The current and the common OS targets are always supported 361*333d2b36SAndroid Build Coastguard Worker ret = append(ret, ctx.Target()) 362*333d2b36SAndroid Build Coastguard Worker if ctx.Arch().ArchType != Common { 363*333d2b36SAndroid Build Coastguard Worker ret = append(ret, Target{Os: ctx.Os(), Arch: Arch{ArchType: Common}}) 364*333d2b36SAndroid Build Coastguard Worker } 365*333d2b36SAndroid Build Coastguard Worker // If this module is configured for multi targets, those should be supported as well 366*333d2b36SAndroid Build Coastguard Worker ret = append(ret, ctx.MultiTargets()...) 367*333d2b36SAndroid Build Coastguard Worker return ret 368*333d2b36SAndroid Build Coastguard Worker} 369*333d2b36SAndroid Build Coastguard Worker 370*333d2b36SAndroid Build Coastguard Worker// getLib32Target returns the 32-bit target from the list of targets this module supports. If this 371*333d2b36SAndroid Build Coastguard Worker// module doesn't support 32-bit target, nil is returned. 372*333d2b36SAndroid Build Coastguard Workerfunc getLib32Target(ctx BaseModuleContext) *Target { 373*333d2b36SAndroid Build Coastguard Worker for _, t := range getSupportedTargets(ctx) { 374*333d2b36SAndroid Build Coastguard Worker if t.Arch.ArchType.Multilib == "lib32" { 375*333d2b36SAndroid Build Coastguard Worker return &t 376*333d2b36SAndroid Build Coastguard Worker } 377*333d2b36SAndroid Build Coastguard Worker } 378*333d2b36SAndroid Build Coastguard Worker return nil 379*333d2b36SAndroid Build Coastguard Worker} 380*333d2b36SAndroid Build Coastguard Worker 381*333d2b36SAndroid Build Coastguard Worker// checkIfOtherModuleSUpportsLib32 returns true if 32-bit variant of dep exists. 382*333d2b36SAndroid Build Coastguard Workerfunc checkIfOtherModuleSupportsLib32(ctx BaseModuleContext, dep string) bool { 383*333d2b36SAndroid Build Coastguard Worker t := getLib32Target(ctx) 384*333d2b36SAndroid Build Coastguard Worker if t == nil { 385*333d2b36SAndroid Build Coastguard Worker // This packaging module doesn't support 32bit. No point of checking if dep supports 32-bit 386*333d2b36SAndroid Build Coastguard Worker // or not. 387*333d2b36SAndroid Build Coastguard Worker return false 388*333d2b36SAndroid Build Coastguard Worker } 389*333d2b36SAndroid Build Coastguard Worker return ctx.OtherModuleFarDependencyVariantExists(t.Variations(), dep) 390*333d2b36SAndroid Build Coastguard Worker} 391*333d2b36SAndroid Build Coastguard Worker 392*333d2b36SAndroid Build Coastguard Worker// PackagingItem is a marker interface for dependency tags. 393*333d2b36SAndroid Build Coastguard Worker// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip(). 394*333d2b36SAndroid Build Coastguard Workertype PackagingItem interface { 395*333d2b36SAndroid Build Coastguard Worker // IsPackagingItem returns true if the dep is to be packaged 396*333d2b36SAndroid Build Coastguard Worker IsPackagingItem() bool 397*333d2b36SAndroid Build Coastguard Worker} 398*333d2b36SAndroid Build Coastguard Worker 399*333d2b36SAndroid Build Coastguard Workervar _ PackagingItem = (*PackagingItemAlwaysDepTag)(nil) 400*333d2b36SAndroid Build Coastguard Worker 401*333d2b36SAndroid Build Coastguard Worker// DepTag provides default implementation of PackagingItem interface. 402*333d2b36SAndroid Build Coastguard Worker// PackagingBase-derived modules can define their own dependency tag by embedding this, which 403*333d2b36SAndroid Build Coastguard Worker// can be passed to AddDeps() or AddDependencies(). 404*333d2b36SAndroid Build Coastguard Workertype PackagingItemAlwaysDepTag struct { 405*333d2b36SAndroid Build Coastguard Worker} 406*333d2b36SAndroid Build Coastguard Worker 407*333d2b36SAndroid Build Coastguard Worker// IsPackagingItem returns true if the dep is to be packaged 408*333d2b36SAndroid Build Coastguard Workerfunc (PackagingItemAlwaysDepTag) IsPackagingItem() bool { 409*333d2b36SAndroid Build Coastguard Worker return true 410*333d2b36SAndroid Build Coastguard Worker} 411*333d2b36SAndroid Build Coastguard Worker 412*333d2b36SAndroid Build Coastguard Workertype highPriorityDepTag struct { 413*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 414*333d2b36SAndroid Build Coastguard Worker PackagingItemAlwaysDepTag 415*333d2b36SAndroid Build Coastguard Worker} 416*333d2b36SAndroid Build Coastguard Worker 417*333d2b36SAndroid Build Coastguard Worker// See PackageModule.AddDeps 418*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) { 419*333d2b36SAndroid Build Coastguard Worker addDep := func(t Target, dep string, highPriority bool) { 420*333d2b36SAndroid Build Coastguard Worker if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) { 421*333d2b36SAndroid Build Coastguard Worker return 422*333d2b36SAndroid Build Coastguard Worker } 423*333d2b36SAndroid Build Coastguard Worker targetVariation := t.Variations() 424*333d2b36SAndroid Build Coastguard Worker sharedVariation := blueprint.Variation{ 425*333d2b36SAndroid Build Coastguard Worker Mutator: "link", 426*333d2b36SAndroid Build Coastguard Worker Variation: "shared", 427*333d2b36SAndroid Build Coastguard Worker } 428*333d2b36SAndroid Build Coastguard Worker // If a shared variation exists, use that. Static variants do not provide any standalone files 429*333d2b36SAndroid Build Coastguard Worker // for packaging. 430*333d2b36SAndroid Build Coastguard Worker if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) { 431*333d2b36SAndroid Build Coastguard Worker targetVariation = append(targetVariation, sharedVariation) 432*333d2b36SAndroid Build Coastguard Worker } 433*333d2b36SAndroid Build Coastguard Worker depTagToUse := depTag 434*333d2b36SAndroid Build Coastguard Worker if highPriority { 435*333d2b36SAndroid Build Coastguard Worker depTagToUse = highPriorityDepTag{} 436*333d2b36SAndroid Build Coastguard Worker } 437*333d2b36SAndroid Build Coastguard Worker 438*333d2b36SAndroid Build Coastguard Worker ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep) 439*333d2b36SAndroid Build Coastguard Worker } 440*333d2b36SAndroid Build Coastguard Worker for _, t := range getSupportedTargets(ctx) { 441*333d2b36SAndroid Build Coastguard Worker normalDeps, highPriorityDeps := p.getDepsForArch(ctx, t.Arch.ArchType) 442*333d2b36SAndroid Build Coastguard Worker for _, dep := range normalDeps { 443*333d2b36SAndroid Build Coastguard Worker addDep(t, dep, false) 444*333d2b36SAndroid Build Coastguard Worker } 445*333d2b36SAndroid Build Coastguard Worker for _, dep := range highPriorityDeps { 446*333d2b36SAndroid Build Coastguard Worker addDep(t, dep, true) 447*333d2b36SAndroid Build Coastguard Worker } 448*333d2b36SAndroid Build Coastguard Worker } 449*333d2b36SAndroid Build Coastguard Worker} 450*333d2b36SAndroid Build Coastguard Worker 451*333d2b36SAndroid Build Coastguard Worker// See PackageModule.GatherPackagingSpecs 452*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) GatherPackagingSpecsWithFilterAndModifier(ctx ModuleContext, filter func(PackagingSpec) bool, modifier func(*PackagingSpec)) map[string]PackagingSpec { 453*333d2b36SAndroid Build Coastguard Worker // packaging specs gathered from the dep that are not high priorities. 454*333d2b36SAndroid Build Coastguard Worker var regularPriorities []PackagingSpec 455*333d2b36SAndroid Build Coastguard Worker 456*333d2b36SAndroid Build Coastguard Worker // all packaging specs gathered from the high priority deps. 457*333d2b36SAndroid Build Coastguard Worker var highPriorities []PackagingSpec 458*333d2b36SAndroid Build Coastguard Worker 459*333d2b36SAndroid Build Coastguard Worker // Name of the dependency which requested the packaging spec. 460*333d2b36SAndroid Build Coastguard Worker // If this dep is overridden, the packaging spec will not be installed via this dependency chain. 461*333d2b36SAndroid Build Coastguard Worker // (the packaging spec might still be installed if there are some other deps which depend on it). 462*333d2b36SAndroid Build Coastguard Worker var depNames []string 463*333d2b36SAndroid Build Coastguard Worker 464*333d2b36SAndroid Build Coastguard Worker // list of module names overridden 465*333d2b36SAndroid Build Coastguard Worker var overridden []string 466*333d2b36SAndroid Build Coastguard Worker 467*333d2b36SAndroid Build Coastguard Worker var arches []ArchType 468*333d2b36SAndroid Build Coastguard Worker for _, target := range getSupportedTargets(ctx) { 469*333d2b36SAndroid Build Coastguard Worker arches = append(arches, target.Arch.ArchType) 470*333d2b36SAndroid Build Coastguard Worker } 471*333d2b36SAndroid Build Coastguard Worker 472*333d2b36SAndroid Build Coastguard Worker // filter out packaging specs for unsupported architecture 473*333d2b36SAndroid Build Coastguard Worker filterArch := func(ps PackagingSpec) bool { 474*333d2b36SAndroid Build Coastguard Worker for _, arch := range arches { 475*333d2b36SAndroid Build Coastguard Worker if arch == ps.archType { 476*333d2b36SAndroid Build Coastguard Worker return true 477*333d2b36SAndroid Build Coastguard Worker } 478*333d2b36SAndroid Build Coastguard Worker } 479*333d2b36SAndroid Build Coastguard Worker return false 480*333d2b36SAndroid Build Coastguard Worker } 481*333d2b36SAndroid Build Coastguard Worker 482*333d2b36SAndroid Build Coastguard Worker ctx.VisitDirectDepsProxy(func(child ModuleProxy) { 483*333d2b36SAndroid Build Coastguard Worker depTag := ctx.OtherModuleDependencyTag(child) 484*333d2b36SAndroid Build Coastguard Worker if pi, ok := depTag.(PackagingItem); !ok || !pi.IsPackagingItem() { 485*333d2b36SAndroid Build Coastguard Worker return 486*333d2b36SAndroid Build Coastguard Worker } 487*333d2b36SAndroid Build Coastguard Worker for _, ps := range OtherModuleProviderOrDefault( 488*333d2b36SAndroid Build Coastguard Worker ctx, child, InstallFilesProvider).TransitivePackagingSpecs.ToList() { 489*333d2b36SAndroid Build Coastguard Worker if !filterArch(ps) { 490*333d2b36SAndroid Build Coastguard Worker continue 491*333d2b36SAndroid Build Coastguard Worker } 492*333d2b36SAndroid Build Coastguard Worker 493*333d2b36SAndroid Build Coastguard Worker if filter != nil { 494*333d2b36SAndroid Build Coastguard Worker if !filter(ps) { 495*333d2b36SAndroid Build Coastguard Worker continue 496*333d2b36SAndroid Build Coastguard Worker } 497*333d2b36SAndroid Build Coastguard Worker } 498*333d2b36SAndroid Build Coastguard Worker 499*333d2b36SAndroid Build Coastguard Worker if modifier != nil { 500*333d2b36SAndroid Build Coastguard Worker modifier(&ps) 501*333d2b36SAndroid Build Coastguard Worker } 502*333d2b36SAndroid Build Coastguard Worker 503*333d2b36SAndroid Build Coastguard Worker if _, ok := depTag.(highPriorityDepTag); ok { 504*333d2b36SAndroid Build Coastguard Worker highPriorities = append(highPriorities, ps) 505*333d2b36SAndroid Build Coastguard Worker } else { 506*333d2b36SAndroid Build Coastguard Worker regularPriorities = append(regularPriorities, ps) 507*333d2b36SAndroid Build Coastguard Worker } 508*333d2b36SAndroid Build Coastguard Worker 509*333d2b36SAndroid Build Coastguard Worker depNames = append(depNames, child.Name()) 510*333d2b36SAndroid Build Coastguard Worker if ps.overrides != nil { 511*333d2b36SAndroid Build Coastguard Worker overridden = append(overridden, *ps.overrides...) 512*333d2b36SAndroid Build Coastguard Worker } 513*333d2b36SAndroid Build Coastguard Worker } 514*333d2b36SAndroid Build Coastguard Worker }) 515*333d2b36SAndroid Build Coastguard Worker 516*333d2b36SAndroid Build Coastguard Worker filterOverridden := func(input []PackagingSpec) []PackagingSpec { 517*333d2b36SAndroid Build Coastguard Worker // input minus packaging specs that are overridden 518*333d2b36SAndroid Build Coastguard Worker var filtered []PackagingSpec 519*333d2b36SAndroid Build Coastguard Worker for index, ps := range input { 520*333d2b36SAndroid Build Coastguard Worker if ps.owner != "" && InList(ps.owner, overridden) { 521*333d2b36SAndroid Build Coastguard Worker continue 522*333d2b36SAndroid Build Coastguard Worker } 523*333d2b36SAndroid Build Coastguard Worker // The dependency which requested this packaging spec has been overridden. 524*333d2b36SAndroid Build Coastguard Worker if InList(depNames[index], overridden) { 525*333d2b36SAndroid Build Coastguard Worker continue 526*333d2b36SAndroid Build Coastguard Worker } 527*333d2b36SAndroid Build Coastguard Worker filtered = append(filtered, ps) 528*333d2b36SAndroid Build Coastguard Worker } 529*333d2b36SAndroid Build Coastguard Worker return filtered 530*333d2b36SAndroid Build Coastguard Worker } 531*333d2b36SAndroid Build Coastguard Worker 532*333d2b36SAndroid Build Coastguard Worker filteredRegularPriority := filterOverridden(regularPriorities) 533*333d2b36SAndroid Build Coastguard Worker 534*333d2b36SAndroid Build Coastguard Worker m := make(map[string]PackagingSpec) 535*333d2b36SAndroid Build Coastguard Worker for _, ps := range filteredRegularPriority { 536*333d2b36SAndroid Build Coastguard Worker dstPath := ps.relPathInPackage 537*333d2b36SAndroid Build Coastguard Worker if existingPs, ok := m[dstPath]; ok { 538*333d2b36SAndroid Build Coastguard Worker if !existingPs.Equals(&ps) { 539*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps) 540*333d2b36SAndroid Build Coastguard Worker } 541*333d2b36SAndroid Build Coastguard Worker continue 542*333d2b36SAndroid Build Coastguard Worker } 543*333d2b36SAndroid Build Coastguard Worker m[dstPath] = ps 544*333d2b36SAndroid Build Coastguard Worker } 545*333d2b36SAndroid Build Coastguard Worker 546*333d2b36SAndroid Build Coastguard Worker filteredHighPriority := filterOverridden(highPriorities) 547*333d2b36SAndroid Build Coastguard Worker highPriorityPs := make(map[string]PackagingSpec) 548*333d2b36SAndroid Build Coastguard Worker for _, ps := range filteredHighPriority { 549*333d2b36SAndroid Build Coastguard Worker dstPath := ps.relPathInPackage 550*333d2b36SAndroid Build Coastguard Worker if existingPs, ok := highPriorityPs[dstPath]; ok { 551*333d2b36SAndroid Build Coastguard Worker if !existingPs.Equals(&ps) { 552*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps) 553*333d2b36SAndroid Build Coastguard Worker } 554*333d2b36SAndroid Build Coastguard Worker continue 555*333d2b36SAndroid Build Coastguard Worker } 556*333d2b36SAndroid Build Coastguard Worker highPriorityPs[dstPath] = ps 557*333d2b36SAndroid Build Coastguard Worker m[dstPath] = ps 558*333d2b36SAndroid Build Coastguard Worker } 559*333d2b36SAndroid Build Coastguard Worker 560*333d2b36SAndroid Build Coastguard Worker return m 561*333d2b36SAndroid Build Coastguard Worker} 562*333d2b36SAndroid Build Coastguard Worker 563*333d2b36SAndroid Build Coastguard Worker// See PackageModule.GatherPackagingSpecs 564*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec { 565*333d2b36SAndroid Build Coastguard Worker return p.GatherPackagingSpecsWithFilterAndModifier(ctx, filter, nil) 566*333d2b36SAndroid Build Coastguard Worker} 567*333d2b36SAndroid Build Coastguard Worker 568*333d2b36SAndroid Build Coastguard Worker// See PackageModule.GatherPackagingSpecs 569*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec { 570*333d2b36SAndroid Build Coastguard Worker return p.GatherPackagingSpecsWithFilter(ctx, nil) 571*333d2b36SAndroid Build Coastguard Worker} 572*333d2b36SAndroid Build Coastguard Worker 573*333d2b36SAndroid Build Coastguard Worker// CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec 574*333d2b36SAndroid Build Coastguard Worker// entries into the specified directory. 575*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) { 576*333d2b36SAndroid Build Coastguard Worker dirsToSpecs := make(map[WritablePath]map[string]PackagingSpec) 577*333d2b36SAndroid Build Coastguard Worker dirsToSpecs[dir] = specs 578*333d2b36SAndroid Build Coastguard Worker return p.CopySpecsToDirs(ctx, builder, dirsToSpecs) 579*333d2b36SAndroid Build Coastguard Worker} 580*333d2b36SAndroid Build Coastguard Worker 581*333d2b36SAndroid Build Coastguard Worker// CopySpecsToDirs is a helper that will add commands to the rule builder to copy the PackagingSpec 582*333d2b36SAndroid Build Coastguard Worker// entries into corresponding directories. 583*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec) (entries []string) { 584*333d2b36SAndroid Build Coastguard Worker empty := true 585*333d2b36SAndroid Build Coastguard Worker for _, specs := range dirsToSpecs { 586*333d2b36SAndroid Build Coastguard Worker if len(specs) > 0 { 587*333d2b36SAndroid Build Coastguard Worker empty = false 588*333d2b36SAndroid Build Coastguard Worker break 589*333d2b36SAndroid Build Coastguard Worker } 590*333d2b36SAndroid Build Coastguard Worker } 591*333d2b36SAndroid Build Coastguard Worker if empty { 592*333d2b36SAndroid Build Coastguard Worker return entries 593*333d2b36SAndroid Build Coastguard Worker } 594*333d2b36SAndroid Build Coastguard Worker 595*333d2b36SAndroid Build Coastguard Worker seenDir := make(map[string]bool) 596*333d2b36SAndroid Build Coastguard Worker 597*333d2b36SAndroid Build Coastguard Worker dirs := make([]WritablePath, 0, len(dirsToSpecs)) 598*333d2b36SAndroid Build Coastguard Worker for dir, _ := range dirsToSpecs { 599*333d2b36SAndroid Build Coastguard Worker dirs = append(dirs, dir) 600*333d2b36SAndroid Build Coastguard Worker } 601*333d2b36SAndroid Build Coastguard Worker sort.Slice(dirs, func(i, j int) bool { 602*333d2b36SAndroid Build Coastguard Worker return dirs[i].String() < dirs[j].String() 603*333d2b36SAndroid Build Coastguard Worker }) 604*333d2b36SAndroid Build Coastguard Worker 605*333d2b36SAndroid Build Coastguard Worker for _, dir := range dirs { 606*333d2b36SAndroid Build Coastguard Worker specs := dirsToSpecs[dir] 607*333d2b36SAndroid Build Coastguard Worker for _, k := range SortedKeys(specs) { 608*333d2b36SAndroid Build Coastguard Worker ps := specs[k] 609*333d2b36SAndroid Build Coastguard Worker destPath := filepath.Join(dir.String(), ps.relPathInPackage) 610*333d2b36SAndroid Build Coastguard Worker destDir := filepath.Dir(destPath) 611*333d2b36SAndroid Build Coastguard Worker entries = append(entries, ps.relPathInPackage) 612*333d2b36SAndroid Build Coastguard Worker if _, ok := seenDir[destDir]; !ok { 613*333d2b36SAndroid Build Coastguard Worker seenDir[destDir] = true 614*333d2b36SAndroid Build Coastguard Worker builder.Command().Textf("mkdir -p %s", destDir) 615*333d2b36SAndroid Build Coastguard Worker } 616*333d2b36SAndroid Build Coastguard Worker if ps.symlinkTarget == "" { 617*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("cp").Input(ps.srcPath).Text(destPath) 618*333d2b36SAndroid Build Coastguard Worker } else { 619*333d2b36SAndroid Build Coastguard Worker builder.Command().Textf("ln -sf %s %s", ps.symlinkTarget, destPath) 620*333d2b36SAndroid Build Coastguard Worker } 621*333d2b36SAndroid Build Coastguard Worker if ps.executable { 622*333d2b36SAndroid Build Coastguard Worker builder.Command().Textf("chmod a+x %s", destPath) 623*333d2b36SAndroid Build Coastguard Worker } 624*333d2b36SAndroid Build Coastguard Worker } 625*333d2b36SAndroid Build Coastguard Worker } 626*333d2b36SAndroid Build Coastguard Worker 627*333d2b36SAndroid Build Coastguard Worker return entries 628*333d2b36SAndroid Build Coastguard Worker} 629*333d2b36SAndroid Build Coastguard Worker 630*333d2b36SAndroid Build Coastguard Worker// See PackageModule.CopyDepsToZip 631*333d2b36SAndroid Build Coastguard Workerfunc (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) (entries []string) { 632*333d2b36SAndroid Build Coastguard Worker builder := NewRuleBuilder(pctx, ctx) 633*333d2b36SAndroid Build Coastguard Worker 634*333d2b36SAndroid Build Coastguard Worker dir := PathForModuleOut(ctx, ".zip") 635*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("rm").Flag("-rf").Text(dir.String()) 636*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("mkdir").Flag("-p").Text(dir.String()) 637*333d2b36SAndroid Build Coastguard Worker entries = p.CopySpecsToDir(ctx, builder, specs, dir) 638*333d2b36SAndroid Build Coastguard Worker 639*333d2b36SAndroid Build Coastguard Worker builder.Command(). 640*333d2b36SAndroid Build Coastguard Worker BuiltTool("soong_zip"). 641*333d2b36SAndroid Build Coastguard Worker FlagWithOutput("-o ", zipOut). 642*333d2b36SAndroid Build Coastguard Worker FlagWithArg("-C ", dir.String()). 643*333d2b36SAndroid Build Coastguard Worker Flag("-L 0"). // no compression because this will be unzipped soon 644*333d2b36SAndroid Build Coastguard Worker FlagWithArg("-D ", dir.String()) 645*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("rm").Flag("-rf").Text(dir.String()) 646*333d2b36SAndroid Build Coastguard Worker 647*333d2b36SAndroid Build Coastguard Worker builder.Build("zip_deps", fmt.Sprintf("Zipping deps for %s", ctx.ModuleName())) 648*333d2b36SAndroid Build Coastguard Worker return entries 649*333d2b36SAndroid Build Coastguard Worker} 650