blob: 42009d5afc2cb3a70f856eeb4d28ddb278b87fb8 [file] [log] [blame]
Jiyong Park073ea552020-11-09 14:08:34 +09001// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License")
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package android
16
Jiyong Parkdda8f692020-11-09 18:38:48 +090017import (
18 "fmt"
19 "path/filepath"
Inseob Kim33f95a92024-07-11 15:44:49 +090020 "sort"
Jeongik Cha76e677f2023-12-21 16:39:15 +090021 "strings"
Jiyong Parkdda8f692020-11-09 18:38:48 +090022
23 "github.com/google/blueprint"
Jiyong Park105e11c2024-05-17 14:58:24 +090024 "github.com/google/blueprint/proptools"
Jiyong Parkdda8f692020-11-09 18:38:48 +090025)
26
Jiyong Parkcc1157c2020-11-25 11:31:13 +090027// PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A
28// package can be the traditional <partition>.img, but isn't limited to those. Other examples could
29// be a new filesystem image that is a subset of system.img (e.g. for an Android-like mini OS
30// running on a VM), or a zip archive for some of the host tools.
Jiyong Park073ea552020-11-09 14:08:34 +090031type PackagingSpec struct {
32 // Path relative to the root of the package
33 relPathInPackage string
34
35 // The path to the built artifact
36 srcPath Path
37
38 // If this is not empty, then relPathInPackage should be a symlink to this target. (Then
39 // srcPath is of course ignored.)
40 symlinkTarget string
41
42 // Whether relPathInPackage should be marked as executable or not
43 executable bool
Dan Willemsen9fe14102021-07-13 21:52:04 -070044
45 effectiveLicenseFiles *Paths
Jooyung Han99c5fe62022-03-21 15:13:38 +090046
47 partition string
Jiyong Park4152b192024-04-30 21:24:21 +090048
49 // Whether this packaging spec represents an installation of the srcPath (i.e. this struct
50 // is created via InstallFile or InstallSymlink) or a simple packaging (i.e. created via
51 // PackageFile).
52 skipInstall bool
Justin Yun74f3f302024-05-07 14:32:14 +090053
54 // Paths of aconfig files for the built artifact
55 aconfigPaths *Paths
Jiyong Parkc6a773d2024-05-14 21:49:11 +090056
57 // ArchType of the module which produced this packaging spec
58 archType ArchType
Jiyong Park073ea552020-11-09 14:08:34 +090059}
Jiyong Parkdda8f692020-11-09 18:38:48 +090060
Jiyong Park16ef7ac2024-05-01 12:36:10 +000061func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
62 if other == nil {
63 return false
64 }
65 if p.relPathInPackage != other.relPathInPackage {
66 return false
67 }
68 if p.srcPath != other.srcPath || p.symlinkTarget != other.symlinkTarget {
69 return false
70 }
71 if p.executable != other.executable {
72 return false
73 }
74 if p.partition != other.partition {
75 return false
76 }
77 return true
78}
79
Kiyoung Kim24dfc1f2020-11-16 10:48:44 +090080// Get file name of installed package
81func (p *PackagingSpec) FileName() string {
82 if p.relPathInPackage != "" {
83 return filepath.Base(p.relPathInPackage)
84 }
85
86 return ""
87}
88
Jiyong Park6446b622021-02-01 20:08:28 +090089// Path relative to the root of the package
90func (p *PackagingSpec) RelPathInPackage() string {
91 return p.relPathInPackage
92}
93
Dan Willemsen9fe14102021-07-13 21:52:04 -070094func (p *PackagingSpec) SetRelPathInPackage(relPathInPackage string) {
95 p.relPathInPackage = relPathInPackage
96}
97
98func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
99 if p.effectiveLicenseFiles == nil {
100 return Paths{}
101 }
102 return *p.effectiveLicenseFiles
103}
104
Jooyung Han99c5fe62022-03-21 15:13:38 +0900105func (p *PackagingSpec) Partition() string {
106 return p.partition
107}
108
Jiyong Park4152b192024-04-30 21:24:21 +0900109func (p *PackagingSpec) SkipInstall() bool {
110 return p.skipInstall
111}
112
Justin Yun74f3f302024-05-07 14:32:14 +0900113// Paths of aconfig files for the built artifact
114func (p *PackagingSpec) GetAconfigPaths() Paths {
115 return *p.aconfigPaths
116}
117
Jiyong Parkdda8f692020-11-09 18:38:48 +0900118type PackageModule interface {
119 Module
120 packagingBase() *PackagingBase
121
122 // AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator.
Jooyung Han092ef812021-03-10 15:40:34 +0900123 // When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to
124 // be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface.
Jiyong Park65b62242020-11-25 12:44:59 +0900125 AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900126
Jooyung Hana8834282022-03-25 11:40:12 +0900127 // GatherPackagingSpecs gathers PackagingSpecs of transitive dependencies.
128 GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec
Jeongik Cha54bf8752024-02-08 10:44:37 +0900129 GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec
Jooyung Hana8834282022-03-25 11:40:12 +0900130
Jiyong Parkdda8f692020-11-09 18:38:48 +0900131 // CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900132 // returns zip entries in it. This is expected to be called in GenerateAndroidBuildActions,
Jiyong Parkdda8f692020-11-09 18:38:48 +0900133 // followed by a build rule that unzips it and creates the final output (img, zip, tar.gz,
134 // etc.) from the extracted files
Jooyung Hana8834282022-03-25 11:40:12 +0900135 CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) []string
Jiyong Parkdda8f692020-11-09 18:38:48 +0900136}
137
138// PackagingBase provides basic functionality for packaging dependencies. A module is expected to
139// include this struct and call InitPackageModule.
140type PackagingBase struct {
141 properties PackagingProperties
142
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900143 // Allows this module to skip missing dependencies. In most cases, this is not required, but
144 // for rare cases like when there's a dependency to a module which exists in certain repo
145 // checkouts, this is needed.
Jiyong Parkdda8f692020-11-09 18:38:48 +0900146 IgnoreMissingDependencies bool
Jiyong Park3ea9b652024-05-15 23:01:54 +0900147
148 // If this is set to true by a module type inheriting PackagingBase, the deps property
149 // collects the first target only even with compile_multilib: true.
150 DepsCollectFirstTargetOnly bool
Jiyong Parkdda8f692020-11-09 18:38:48 +0900151}
152
153type depsProperty struct {
154 // Modules to include in this package
Jiyong Park105e11c2024-05-17 14:58:24 +0900155 Deps proptools.Configurable[[]string] `android:"arch_variant"`
Jiyong Parkdda8f692020-11-09 18:38:48 +0900156}
157
158type packagingMultilibProperties struct {
Jiyong Parke6043782024-05-20 16:17:39 +0900159 First depsProperty `android:"arch_variant"`
160 Common depsProperty `android:"arch_variant"`
161 Lib32 depsProperty `android:"arch_variant"`
162 Lib64 depsProperty `android:"arch_variant"`
163 Both depsProperty `android:"arch_variant"`
164 Prefer32 depsProperty `android:"arch_variant"`
Jiyong Parkdda8f692020-11-09 18:38:48 +0900165}
166
Jiyong Park2136d152021-02-01 23:24:56 +0900167type packagingArchProperties struct {
168 Arm64 depsProperty
169 Arm depsProperty
170 X86_64 depsProperty
171 X86 depsProperty
172}
173
Jiyong Parkdda8f692020-11-09 18:38:48 +0900174type PackagingProperties struct {
Jiyong Park105e11c2024-05-17 14:58:24 +0900175 Deps proptools.Configurable[[]string] `android:"arch_variant"`
176 Multilib packagingMultilibProperties `android:"arch_variant"`
Jiyong Park2136d152021-02-01 23:24:56 +0900177 Arch packagingArchProperties
Jiyong Parkdda8f692020-11-09 18:38:48 +0900178}
179
Jiyong Parkdda8f692020-11-09 18:38:48 +0900180func InitPackageModule(p PackageModule) {
181 base := p.packagingBase()
182 p.AddProperties(&base.properties)
183}
184
185func (p *PackagingBase) packagingBase() *PackagingBase {
186 return p
187}
188
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900189// From deps and multilib.*.deps, select the dependencies that are for the given arch deps is for
190// the current archicture when this module is not configured for multi target. When configured for
191// multi target, deps is selected for each of the targets and is NOT selected for the current
192// architecture which would be Common.
Jiyong Parkdda8f692020-11-09 18:38:48 +0900193func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []string {
Jiyong Park105e11c2024-05-17 14:58:24 +0900194 get := func(prop proptools.Configurable[[]string]) []string {
195 return prop.GetOrDefault(ctx, nil)
196 }
197
Jiyong Parkdda8f692020-11-09 18:38:48 +0900198 var ret []string
199 if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900200 ret = append(ret, get(p.properties.Deps)...)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900201 } else if arch.Multilib == "lib32" {
Jiyong Park105e11c2024-05-17 14:58:24 +0900202 ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
Jiyong Parke6043782024-05-20 16:17:39 +0900203 // multilib.prefer32.deps are added for lib32 only when they support 32-bit arch
204 for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
205 if checkIfOtherModuleSupportsLib32(ctx, dep) {
206 ret = append(ret, dep)
207 }
208 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900209 } else if arch.Multilib == "lib64" {
Jiyong Park105e11c2024-05-17 14:58:24 +0900210 ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
Jiyong Parke6043782024-05-20 16:17:39 +0900211 // multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch
212 for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
213 if !checkIfOtherModuleSupportsLib32(ctx, dep) {
214 ret = append(ret, dep)
215 }
216 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900217 } else if arch == Common {
Jiyong Park105e11c2024-05-17 14:58:24 +0900218 ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900219 }
Jiyong Park2136d152021-02-01 23:24:56 +0900220
Jiyong Park3ea9b652024-05-15 23:01:54 +0900221 if p.DepsCollectFirstTargetOnly {
Jiyong Park105e11c2024-05-17 14:58:24 +0900222 if len(get(p.properties.Multilib.First.Deps)) > 0 {
Jiyong Park3ea9b652024-05-15 23:01:54 +0900223 ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead")
224 }
225 for i, t := range ctx.MultiTargets() {
226 if t.Arch.ArchType == arch {
Jiyong Park105e11c2024-05-17 14:58:24 +0900227 ret = append(ret, get(p.properties.Multilib.Both.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900228 if i == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900229 ret = append(ret, get(p.properties.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900230 }
231 }
232 }
233 } else {
Jiyong Park105e11c2024-05-17 14:58:24 +0900234 if len(get(p.properties.Multilib.Both.Deps)) > 0 {
Jiyong Park3ea9b652024-05-15 23:01:54 +0900235 ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead")
236 }
237 for i, t := range ctx.MultiTargets() {
238 if t.Arch.ArchType == arch {
Jiyong Park105e11c2024-05-17 14:58:24 +0900239 ret = append(ret, get(p.properties.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900240 if i == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900241 ret = append(ret, get(p.properties.Multilib.First.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900242 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900243 }
244 }
245 }
Jiyong Park2136d152021-02-01 23:24:56 +0900246
247 if ctx.Arch().ArchType == Common {
248 switch arch {
249 case Arm64:
Jiyong Park105e11c2024-05-17 14:58:24 +0900250 ret = append(ret, get(p.properties.Arch.Arm64.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900251 case Arm:
Jiyong Park105e11c2024-05-17 14:58:24 +0900252 ret = append(ret, get(p.properties.Arch.Arm.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900253 case X86_64:
Jiyong Park105e11c2024-05-17 14:58:24 +0900254 ret = append(ret, get(p.properties.Arch.X86_64.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900255 case X86:
Jiyong Park105e11c2024-05-17 14:58:24 +0900256 ret = append(ret, get(p.properties.Arch.X86.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900257 }
258 }
259
Jiyong Parkdda8f692020-11-09 18:38:48 +0900260 return FirstUniqueStrings(ret)
261}
262
Jiyong Parke6043782024-05-20 16:17:39 +0900263func getSupportedTargets(ctx BaseModuleContext) []Target {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900264 var ret []Target
265 // The current and the common OS targets are always supported
266 ret = append(ret, ctx.Target())
267 if ctx.Arch().ArchType != Common {
268 ret = append(ret, Target{Os: ctx.Os(), Arch: Arch{ArchType: Common}})
269 }
270 // If this module is configured for multi targets, those should be supported as well
271 ret = append(ret, ctx.MultiTargets()...)
272 return ret
273}
274
Jiyong Parke6043782024-05-20 16:17:39 +0900275// getLib32Target returns the 32-bit target from the list of targets this module supports. If this
276// module doesn't support 32-bit target, nil is returned.
277func getLib32Target(ctx BaseModuleContext) *Target {
278 for _, t := range getSupportedTargets(ctx) {
279 if t.Arch.ArchType.Multilib == "lib32" {
280 return &t
281 }
282 }
283 return nil
284}
285
286// checkIfOtherModuleSUpportsLib32 returns true if 32-bit variant of dep exists.
287func checkIfOtherModuleSupportsLib32(ctx BaseModuleContext, dep string) bool {
288 t := getLib32Target(ctx)
289 if t == nil {
290 // This packaging module doesn't support 32bit. No point of checking if dep supports 32-bit
291 // or not.
292 return false
293 }
294 return ctx.OtherModuleFarDependencyVariantExists(t.Variations(), dep)
295}
296
Jooyung Han092ef812021-03-10 15:40:34 +0900297// PackagingItem is a marker interface for dependency tags.
298// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip().
299type PackagingItem interface {
300 // IsPackagingItem returns true if the dep is to be packaged
301 IsPackagingItem() bool
302}
303
304// DepTag provides default implementation of PackagingItem interface.
305// PackagingBase-derived modules can define their own dependency tag by embedding this, which
306// can be passed to AddDeps() or AddDependencies().
307type PackagingItemAlwaysDepTag struct {
308}
309
310// IsPackagingItem returns true if the dep is to be packaged
311func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
312 return true
313}
314
Jiyong Parkdda8f692020-11-09 18:38:48 +0900315// See PackageModule.AddDeps
Jiyong Park65b62242020-11-25 12:44:59 +0900316func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
Jiyong Parke6043782024-05-20 16:17:39 +0900317 for _, t := range getSupportedTargets(ctx) {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900318 for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) {
319 if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
320 continue
321 }
322 ctx.AddFarVariationDependencies(t.Variations(), depTag, dep)
323 }
324 }
325}
326
Jeongik Cha54bf8752024-02-08 10:44:37 +0900327func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900328 m := make(map[string]PackagingSpec)
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900329
330 var arches []ArchType
Jiyong Parke6043782024-05-20 16:17:39 +0900331 for _, target := range getSupportedTargets(ctx) {
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900332 arches = append(arches, target.Arch.ArchType)
333 }
334
335 // filter out packaging specs for unsupported architecture
336 filterArch := func(ps PackagingSpec) bool {
337 for _, arch := range arches {
338 if arch == ps.archType {
339 return true
340 }
341 }
342 return false
343 }
344
Jooyung Han092ef812021-03-10 15:40:34 +0900345 ctx.VisitDirectDeps(func(child Module) {
346 if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
347 return
Jiyong Parkdda8f692020-11-09 18:38:48 +0900348 }
Yu Liubad1eef2024-08-21 22:37:35 +0000349 for _, ps := range OtherModuleProviderOrDefault(
350 ctx, child, InstallFilesProvider).TransitivePackagingSpecs.ToList() {
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900351 if !filterArch(ps) {
352 continue
353 }
354
Jeongik Cha54bf8752024-02-08 10:44:37 +0900355 if filter != nil {
356 if !filter(ps) {
357 continue
358 }
359 }
Jiyong Park16ef7ac2024-05-01 12:36:10 +0000360 dstPath := ps.relPathInPackage
361 if existingPs, ok := m[dstPath]; ok {
362 if !existingPs.Equals(&ps) {
363 ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
364 }
365 continue
Jiyong Parkdda8f692020-11-09 18:38:48 +0900366 }
Jiyong Park16ef7ac2024-05-01 12:36:10 +0000367
368 m[dstPath] = ps
Jiyong Parkdda8f692020-11-09 18:38:48 +0900369 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900370 })
Jooyung Handf09d172021-05-11 11:13:30 +0900371 return m
372}
Jiyong Parkdda8f692020-11-09 18:38:48 +0900373
Jeongik Cha54bf8752024-02-08 10:44:37 +0900374// See PackageModule.GatherPackagingSpecs
375func (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec {
376 return p.GatherPackagingSpecsWithFilter(ctx, nil)
377}
378
Dan Willemsen9fe14102021-07-13 21:52:04 -0700379// CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec
380// entries into the specified directory.
Peter Collingbourneff56c012023-03-15 22:24:03 -0700381func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) {
Inseob Kim33f95a92024-07-11 15:44:49 +0900382 dirsToSpecs := make(map[WritablePath]map[string]PackagingSpec)
383 dirsToSpecs[dir] = specs
384 return p.CopySpecsToDirs(ctx, builder, dirsToSpecs)
385}
386
387// CopySpecsToDirs is a helper that will add commands to the rule builder to copy the PackagingSpec
388// entries into corresponding directories.
389func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec) (entries []string) {
390 empty := true
391 for _, specs := range dirsToSpecs {
392 if len(specs) > 0 {
393 empty = false
394 break
395 }
396 }
397 if empty {
Cole Faust3b3a0112024-01-03 15:16:55 -0800398 return entries
399 }
Inseob Kim33f95a92024-07-11 15:44:49 +0900400
Jiyong Parkdda8f692020-11-09 18:38:48 +0900401 seenDir := make(map[string]bool)
Jeongik Cha76e677f2023-12-21 16:39:15 +0900402 preparerPath := PathForModuleOut(ctx, "preparer.sh")
403 cmd := builder.Command().Tool(preparerPath)
404 var sb strings.Builder
Cole Faust3b3a0112024-01-03 15:16:55 -0800405 sb.WriteString("set -e\n")
Inseob Kim33f95a92024-07-11 15:44:49 +0900406
407 dirs := make([]WritablePath, 0, len(dirsToSpecs))
408 for dir, _ := range dirsToSpecs {
409 dirs = append(dirs, dir)
410 }
411 sort.Slice(dirs, func(i, j int) bool {
412 return dirs[i].String() < dirs[j].String()
413 })
414
415 for _, dir := range dirs {
416 specs := dirsToSpecs[dir]
417 for _, k := range SortedKeys(specs) {
418 ps := specs[k]
419 destPath := filepath.Join(dir.String(), ps.relPathInPackage)
420 destDir := filepath.Dir(destPath)
421 entries = append(entries, ps.relPathInPackage)
422 if _, ok := seenDir[destDir]; !ok {
423 seenDir[destDir] = true
424 sb.WriteString(fmt.Sprintf("mkdir -p %s\n", destDir))
425 }
426 if ps.symlinkTarget == "" {
427 cmd.Implicit(ps.srcPath)
428 sb.WriteString(fmt.Sprintf("cp %s %s\n", ps.srcPath, destPath))
429 } else {
430 sb.WriteString(fmt.Sprintf("ln -sf %s %s\n", ps.symlinkTarget, destPath))
431 }
432 if ps.executable {
433 sb.WriteString(fmt.Sprintf("chmod a+x %s\n", destPath))
434 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900435 }
436 }
437
Jeongik Cha76e677f2023-12-21 16:39:15 +0900438 WriteExecutableFileRuleVerbatim(ctx, preparerPath, sb.String())
439
Dan Willemsen9fe14102021-07-13 21:52:04 -0700440 return entries
441}
442
443// See PackageModule.CopyDepsToZip
Jooyung Hana8834282022-03-25 11:40:12 +0900444func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) (entries []string) {
Dan Willemsen9fe14102021-07-13 21:52:04 -0700445 builder := NewRuleBuilder(pctx, ctx)
446
447 dir := PathForModuleOut(ctx, ".zip")
448 builder.Command().Text("rm").Flag("-rf").Text(dir.String())
449 builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
Jooyung Hana8834282022-03-25 11:40:12 +0900450 entries = p.CopySpecsToDir(ctx, builder, specs, dir)
Dan Willemsen9fe14102021-07-13 21:52:04 -0700451
Jiyong Parkdda8f692020-11-09 18:38:48 +0900452 builder.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800453 BuiltTool("soong_zip").
Jiyong Parkdda8f692020-11-09 18:38:48 +0900454 FlagWithOutput("-o ", zipOut).
455 FlagWithArg("-C ", dir.String()).
456 Flag("-L 0"). // no compression because this will be unzipped soon
457 FlagWithArg("-D ", dir.String())
458 builder.Command().Text("rm").Flag("-rf").Text(dir.String())
459
Colin Crossf1a035e2020-11-16 17:32:30 -0800460 builder.Build("zip_deps", fmt.Sprintf("Zipping deps for %s", ctx.ModuleName()))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900461 return entries
462}