xref: /aosp_15_r20/build/soong/android/packaging.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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