blob: ae412e1bb55b27265b4f6ed0ea626d6b9d514a91 [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"
Jeongik Cha76e677f2023-12-21 16:39:15 +090020 "strings"
Jiyong Parkdda8f692020-11-09 18:38:48 +090021
22 "github.com/google/blueprint"
Jiyong Park105e11c2024-05-17 14:58:24 +090023 "github.com/google/blueprint/proptools"
Jiyong Parkdda8f692020-11-09 18:38:48 +090024)
25
Jiyong Parkcc1157c2020-11-25 11:31:13 +090026// PackagingSpec abstracts a request to place a built artifact at a certain path in a package. A
27// package can be the traditional <partition>.img, but isn't limited to those. Other examples could
28// be a new filesystem image that is a subset of system.img (e.g. for an Android-like mini OS
29// running on a VM), or a zip archive for some of the host tools.
Jiyong Park073ea552020-11-09 14:08:34 +090030type PackagingSpec struct {
31 // Path relative to the root of the package
32 relPathInPackage string
33
34 // The path to the built artifact
35 srcPath Path
36
37 // If this is not empty, then relPathInPackage should be a symlink to this target. (Then
38 // srcPath is of course ignored.)
39 symlinkTarget string
40
41 // Whether relPathInPackage should be marked as executable or not
42 executable bool
Dan Willemsen9fe14102021-07-13 21:52:04 -070043
44 effectiveLicenseFiles *Paths
Jooyung Han99c5fe62022-03-21 15:13:38 +090045
46 partition string
Jiyong Park4152b192024-04-30 21:24:21 +090047
48 // Whether this packaging spec represents an installation of the srcPath (i.e. this struct
49 // is created via InstallFile or InstallSymlink) or a simple packaging (i.e. created via
50 // PackageFile).
51 skipInstall bool
Justin Yun74f3f302024-05-07 14:32:14 +090052
53 // Paths of aconfig files for the built artifact
54 aconfigPaths *Paths
Jiyong Parkc6a773d2024-05-14 21:49:11 +090055
56 // ArchType of the module which produced this packaging spec
57 archType ArchType
Jiyong Park073ea552020-11-09 14:08:34 +090058}
Jiyong Parkdda8f692020-11-09 18:38:48 +090059
Jiyong Park16ef7ac2024-05-01 12:36:10 +000060func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
61 if other == nil {
62 return false
63 }
64 if p.relPathInPackage != other.relPathInPackage {
65 return false
66 }
67 if p.srcPath != other.srcPath || p.symlinkTarget != other.symlinkTarget {
68 return false
69 }
70 if p.executable != other.executable {
71 return false
72 }
73 if p.partition != other.partition {
74 return false
75 }
76 return true
77}
78
Kiyoung Kim24dfc1f2020-11-16 10:48:44 +090079// Get file name of installed package
80func (p *PackagingSpec) FileName() string {
81 if p.relPathInPackage != "" {
82 return filepath.Base(p.relPathInPackage)
83 }
84
85 return ""
86}
87
Jiyong Park6446b622021-02-01 20:08:28 +090088// Path relative to the root of the package
89func (p *PackagingSpec) RelPathInPackage() string {
90 return p.relPathInPackage
91}
92
Dan Willemsen9fe14102021-07-13 21:52:04 -070093func (p *PackagingSpec) SetRelPathInPackage(relPathInPackage string) {
94 p.relPathInPackage = relPathInPackage
95}
96
97func (p *PackagingSpec) EffectiveLicenseFiles() Paths {
98 if p.effectiveLicenseFiles == nil {
99 return Paths{}
100 }
101 return *p.effectiveLicenseFiles
102}
103
Jooyung Han99c5fe62022-03-21 15:13:38 +0900104func (p *PackagingSpec) Partition() string {
105 return p.partition
106}
107
Jiyong Park4152b192024-04-30 21:24:21 +0900108func (p *PackagingSpec) SkipInstall() bool {
109 return p.skipInstall
110}
111
Justin Yun74f3f302024-05-07 14:32:14 +0900112// Paths of aconfig files for the built artifact
113func (p *PackagingSpec) GetAconfigPaths() Paths {
114 return *p.aconfigPaths
115}
116
Jiyong Parkdda8f692020-11-09 18:38:48 +0900117type PackageModule interface {
118 Module
119 packagingBase() *PackagingBase
120
121 // AddDeps adds dependencies to the `deps` modules. This should be called in DepsMutator.
Jooyung Han092ef812021-03-10 15:40:34 +0900122 // When adding the dependencies, depTag is used as the tag. If `deps` modules are meant to
123 // be copied to a zip in CopyDepsToZip, `depTag` should implement PackagingItem marker interface.
Jiyong Park65b62242020-11-25 12:44:59 +0900124 AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900125
Jooyung Hana8834282022-03-25 11:40:12 +0900126 // GatherPackagingSpecs gathers PackagingSpecs of transitive dependencies.
127 GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec
Jeongik Cha54bf8752024-02-08 10:44:37 +0900128 GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec
Jooyung Hana8834282022-03-25 11:40:12 +0900129
Jiyong Parkdda8f692020-11-09 18:38:48 +0900130 // CopyDepsToZip zips the built artifacts of the dependencies into the given zip file and
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900131 // returns zip entries in it. This is expected to be called in GenerateAndroidBuildActions,
Jiyong Parkdda8f692020-11-09 18:38:48 +0900132 // followed by a build rule that unzips it and creates the final output (img, zip, tar.gz,
133 // etc.) from the extracted files
Jooyung Hana8834282022-03-25 11:40:12 +0900134 CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) []string
Jiyong Parkdda8f692020-11-09 18:38:48 +0900135}
136
137// PackagingBase provides basic functionality for packaging dependencies. A module is expected to
138// include this struct and call InitPackageModule.
139type PackagingBase struct {
140 properties PackagingProperties
141
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900142 // Allows this module to skip missing dependencies. In most cases, this is not required, but
143 // for rare cases like when there's a dependency to a module which exists in certain repo
144 // checkouts, this is needed.
Jiyong Parkdda8f692020-11-09 18:38:48 +0900145 IgnoreMissingDependencies bool
Jiyong Park3ea9b652024-05-15 23:01:54 +0900146
147 // If this is set to true by a module type inheriting PackagingBase, the deps property
148 // collects the first target only even with compile_multilib: true.
149 DepsCollectFirstTargetOnly bool
Jiyong Parkdda8f692020-11-09 18:38:48 +0900150}
151
152type depsProperty struct {
153 // Modules to include in this package
Jiyong Park105e11c2024-05-17 14:58:24 +0900154 Deps proptools.Configurable[[]string] `android:"arch_variant"`
Jiyong Parkdda8f692020-11-09 18:38:48 +0900155}
156
157type packagingMultilibProperties struct {
Jiyong Parke6043782024-05-20 16:17:39 +0900158 First depsProperty `android:"arch_variant"`
159 Common depsProperty `android:"arch_variant"`
160 Lib32 depsProperty `android:"arch_variant"`
161 Lib64 depsProperty `android:"arch_variant"`
162 Both depsProperty `android:"arch_variant"`
163 Prefer32 depsProperty `android:"arch_variant"`
Jiyong Parkdda8f692020-11-09 18:38:48 +0900164}
165
Jiyong Park2136d152021-02-01 23:24:56 +0900166type packagingArchProperties struct {
167 Arm64 depsProperty
168 Arm depsProperty
169 X86_64 depsProperty
170 X86 depsProperty
171}
172
Jiyong Parkdda8f692020-11-09 18:38:48 +0900173type PackagingProperties struct {
Jiyong Park105e11c2024-05-17 14:58:24 +0900174 Deps proptools.Configurable[[]string] `android:"arch_variant"`
175 Multilib packagingMultilibProperties `android:"arch_variant"`
Jiyong Park2136d152021-02-01 23:24:56 +0900176 Arch packagingArchProperties
Jiyong Parkdda8f692020-11-09 18:38:48 +0900177}
178
Jiyong Parkdda8f692020-11-09 18:38:48 +0900179func InitPackageModule(p PackageModule) {
180 base := p.packagingBase()
181 p.AddProperties(&base.properties)
182}
183
184func (p *PackagingBase) packagingBase() *PackagingBase {
185 return p
186}
187
Jiyong Parkcc1157c2020-11-25 11:31:13 +0900188// From deps and multilib.*.deps, select the dependencies that are for the given arch deps is for
189// the current archicture when this module is not configured for multi target. When configured for
190// multi target, deps is selected for each of the targets and is NOT selected for the current
191// architecture which would be Common.
Jiyong Parkdda8f692020-11-09 18:38:48 +0900192func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []string {
Jiyong Park105e11c2024-05-17 14:58:24 +0900193 get := func(prop proptools.Configurable[[]string]) []string {
194 return prop.GetOrDefault(ctx, nil)
195 }
196
Jiyong Parkdda8f692020-11-09 18:38:48 +0900197 var ret []string
198 if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900199 ret = append(ret, get(p.properties.Deps)...)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900200 } else if arch.Multilib == "lib32" {
Jiyong Park105e11c2024-05-17 14:58:24 +0900201 ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
Jiyong Parke6043782024-05-20 16:17:39 +0900202 // multilib.prefer32.deps are added for lib32 only when they support 32-bit arch
203 for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
204 if checkIfOtherModuleSupportsLib32(ctx, dep) {
205 ret = append(ret, dep)
206 }
207 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900208 } else if arch.Multilib == "lib64" {
Jiyong Park105e11c2024-05-17 14:58:24 +0900209 ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
Jiyong Parke6043782024-05-20 16:17:39 +0900210 // multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch
211 for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
212 if !checkIfOtherModuleSupportsLib32(ctx, dep) {
213 ret = append(ret, dep)
214 }
215 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900216 } else if arch == Common {
Jiyong Park105e11c2024-05-17 14:58:24 +0900217 ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900218 }
Jiyong Park2136d152021-02-01 23:24:56 +0900219
Jiyong Park3ea9b652024-05-15 23:01:54 +0900220 if p.DepsCollectFirstTargetOnly {
Jiyong Park105e11c2024-05-17 14:58:24 +0900221 if len(get(p.properties.Multilib.First.Deps)) > 0 {
Jiyong Park3ea9b652024-05-15 23:01:54 +0900222 ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead")
223 }
224 for i, t := range ctx.MultiTargets() {
225 if t.Arch.ArchType == arch {
Jiyong Park105e11c2024-05-17 14:58:24 +0900226 ret = append(ret, get(p.properties.Multilib.Both.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900227 if i == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900228 ret = append(ret, get(p.properties.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900229 }
230 }
231 }
232 } else {
Jiyong Park105e11c2024-05-17 14:58:24 +0900233 if len(get(p.properties.Multilib.Both.Deps)) > 0 {
Jiyong Park3ea9b652024-05-15 23:01:54 +0900234 ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead")
235 }
236 for i, t := range ctx.MultiTargets() {
237 if t.Arch.ArchType == arch {
Jiyong Park105e11c2024-05-17 14:58:24 +0900238 ret = append(ret, get(p.properties.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900239 if i == 0 {
Jiyong Park105e11c2024-05-17 14:58:24 +0900240 ret = append(ret, get(p.properties.Multilib.First.Deps)...)
Jiyong Park3ea9b652024-05-15 23:01:54 +0900241 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900242 }
243 }
244 }
Jiyong Park2136d152021-02-01 23:24:56 +0900245
246 if ctx.Arch().ArchType == Common {
247 switch arch {
248 case Arm64:
Jiyong Park105e11c2024-05-17 14:58:24 +0900249 ret = append(ret, get(p.properties.Arch.Arm64.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900250 case Arm:
Jiyong Park105e11c2024-05-17 14:58:24 +0900251 ret = append(ret, get(p.properties.Arch.Arm.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900252 case X86_64:
Jiyong Park105e11c2024-05-17 14:58:24 +0900253 ret = append(ret, get(p.properties.Arch.X86_64.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900254 case X86:
Jiyong Park105e11c2024-05-17 14:58:24 +0900255 ret = append(ret, get(p.properties.Arch.X86.Deps)...)
Jiyong Park2136d152021-02-01 23:24:56 +0900256 }
257 }
258
Jiyong Parkdda8f692020-11-09 18:38:48 +0900259 return FirstUniqueStrings(ret)
260}
261
Jiyong Parke6043782024-05-20 16:17:39 +0900262func getSupportedTargets(ctx BaseModuleContext) []Target {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900263 var ret []Target
264 // The current and the common OS targets are always supported
265 ret = append(ret, ctx.Target())
266 if ctx.Arch().ArchType != Common {
267 ret = append(ret, Target{Os: ctx.Os(), Arch: Arch{ArchType: Common}})
268 }
269 // If this module is configured for multi targets, those should be supported as well
270 ret = append(ret, ctx.MultiTargets()...)
271 return ret
272}
273
Jiyong Parke6043782024-05-20 16:17:39 +0900274// getLib32Target returns the 32-bit target from the list of targets this module supports. If this
275// module doesn't support 32-bit target, nil is returned.
276func getLib32Target(ctx BaseModuleContext) *Target {
277 for _, t := range getSupportedTargets(ctx) {
278 if t.Arch.ArchType.Multilib == "lib32" {
279 return &t
280 }
281 }
282 return nil
283}
284
285// checkIfOtherModuleSUpportsLib32 returns true if 32-bit variant of dep exists.
286func checkIfOtherModuleSupportsLib32(ctx BaseModuleContext, dep string) bool {
287 t := getLib32Target(ctx)
288 if t == nil {
289 // This packaging module doesn't support 32bit. No point of checking if dep supports 32-bit
290 // or not.
291 return false
292 }
293 return ctx.OtherModuleFarDependencyVariantExists(t.Variations(), dep)
294}
295
Jooyung Han092ef812021-03-10 15:40:34 +0900296// PackagingItem is a marker interface for dependency tags.
297// Direct dependencies with a tag implementing PackagingItem are packaged in CopyDepsToZip().
298type PackagingItem interface {
299 // IsPackagingItem returns true if the dep is to be packaged
300 IsPackagingItem() bool
301}
302
303// DepTag provides default implementation of PackagingItem interface.
304// PackagingBase-derived modules can define their own dependency tag by embedding this, which
305// can be passed to AddDeps() or AddDependencies().
306type PackagingItemAlwaysDepTag struct {
307}
308
309// IsPackagingItem returns true if the dep is to be packaged
310func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
311 return true
312}
313
Jiyong Parkdda8f692020-11-09 18:38:48 +0900314// See PackageModule.AddDeps
Jiyong Park65b62242020-11-25 12:44:59 +0900315func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
Jiyong Parke6043782024-05-20 16:17:39 +0900316 for _, t := range getSupportedTargets(ctx) {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900317 for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) {
318 if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
319 continue
320 }
321 ctx.AddFarVariationDependencies(t.Variations(), depTag, dep)
322 }
323 }
324}
325
Jeongik Cha54bf8752024-02-08 10:44:37 +0900326func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
Jiyong Parkdda8f692020-11-09 18:38:48 +0900327 m := make(map[string]PackagingSpec)
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900328
329 var arches []ArchType
Jiyong Parke6043782024-05-20 16:17:39 +0900330 for _, target := range getSupportedTargets(ctx) {
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900331 arches = append(arches, target.Arch.ArchType)
332 }
333
334 // filter out packaging specs for unsupported architecture
335 filterArch := func(ps PackagingSpec) bool {
336 for _, arch := range arches {
337 if arch == ps.archType {
338 return true
339 }
340 }
341 return false
342 }
343
Jooyung Han092ef812021-03-10 15:40:34 +0900344 ctx.VisitDirectDeps(func(child Module) {
345 if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
346 return
Jiyong Parkdda8f692020-11-09 18:38:48 +0900347 }
Jooyung Han092ef812021-03-10 15:40:34 +0900348 for _, ps := range child.TransitivePackagingSpecs() {
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900349 if !filterArch(ps) {
350 continue
351 }
352
Jeongik Cha54bf8752024-02-08 10:44:37 +0900353 if filter != nil {
354 if !filter(ps) {
355 continue
356 }
357 }
Jiyong Park16ef7ac2024-05-01 12:36:10 +0000358 dstPath := ps.relPathInPackage
359 if existingPs, ok := m[dstPath]; ok {
360 if !existingPs.Equals(&ps) {
361 ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
362 }
363 continue
Jiyong Parkdda8f692020-11-09 18:38:48 +0900364 }
Jiyong Park16ef7ac2024-05-01 12:36:10 +0000365
366 m[dstPath] = ps
Jiyong Parkdda8f692020-11-09 18:38:48 +0900367 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900368 })
Jooyung Handf09d172021-05-11 11:13:30 +0900369 return m
370}
Jiyong Parkdda8f692020-11-09 18:38:48 +0900371
Jeongik Cha54bf8752024-02-08 10:44:37 +0900372// See PackageModule.GatherPackagingSpecs
373func (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]PackagingSpec {
374 return p.GatherPackagingSpecsWithFilter(ctx, nil)
375}
376
Dan Willemsen9fe14102021-07-13 21:52:04 -0700377// CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec
378// entries into the specified directory.
Peter Collingbourneff56c012023-03-15 22:24:03 -0700379func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) {
Cole Faust3b3a0112024-01-03 15:16:55 -0800380 if len(specs) == 0 {
381 return entries
382 }
Jiyong Parkdda8f692020-11-09 18:38:48 +0900383 seenDir := make(map[string]bool)
Jeongik Cha76e677f2023-12-21 16:39:15 +0900384 preparerPath := PathForModuleOut(ctx, "preparer.sh")
385 cmd := builder.Command().Tool(preparerPath)
386 var sb strings.Builder
Cole Faust3b3a0112024-01-03 15:16:55 -0800387 sb.WriteString("set -e\n")
Cole Faust18994c72023-02-28 16:02:16 -0800388 for _, k := range SortedKeys(specs) {
Jooyung Hana8834282022-03-25 11:40:12 +0900389 ps := specs[k]
Peter Collingbourneff56c012023-03-15 22:24:03 -0700390 destPath := filepath.Join(dir.String(), ps.relPathInPackage)
Jiyong Parkdda8f692020-11-09 18:38:48 +0900391 destDir := filepath.Dir(destPath)
392 entries = append(entries, ps.relPathInPackage)
393 if _, ok := seenDir[destDir]; !ok {
394 seenDir[destDir] = true
Jeongik Cha76e677f2023-12-21 16:39:15 +0900395 sb.WriteString(fmt.Sprintf("mkdir -p %s\n", destDir))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900396 }
397 if ps.symlinkTarget == "" {
Jeongik Cha76e677f2023-12-21 16:39:15 +0900398 cmd.Implicit(ps.srcPath)
399 sb.WriteString(fmt.Sprintf("cp %s %s\n", ps.srcPath, destPath))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900400 } else {
Jeongik Cha76e677f2023-12-21 16:39:15 +0900401 sb.WriteString(fmt.Sprintf("ln -sf %s %s\n", ps.symlinkTarget, destPath))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900402 }
403 if ps.executable {
Jeongik Cha76e677f2023-12-21 16:39:15 +0900404 sb.WriteString(fmt.Sprintf("chmod a+x %s\n", destPath))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900405 }
406 }
407
Jeongik Cha76e677f2023-12-21 16:39:15 +0900408 WriteExecutableFileRuleVerbatim(ctx, preparerPath, sb.String())
409
Dan Willemsen9fe14102021-07-13 21:52:04 -0700410 return entries
411}
412
413// See PackageModule.CopyDepsToZip
Jooyung Hana8834282022-03-25 11:40:12 +0900414func (p *PackagingBase) CopyDepsToZip(ctx ModuleContext, specs map[string]PackagingSpec, zipOut WritablePath) (entries []string) {
Dan Willemsen9fe14102021-07-13 21:52:04 -0700415 builder := NewRuleBuilder(pctx, ctx)
416
417 dir := PathForModuleOut(ctx, ".zip")
418 builder.Command().Text("rm").Flag("-rf").Text(dir.String())
419 builder.Command().Text("mkdir").Flag("-p").Text(dir.String())
Jooyung Hana8834282022-03-25 11:40:12 +0900420 entries = p.CopySpecsToDir(ctx, builder, specs, dir)
Dan Willemsen9fe14102021-07-13 21:52:04 -0700421
Jiyong Parkdda8f692020-11-09 18:38:48 +0900422 builder.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800423 BuiltTool("soong_zip").
Jiyong Parkdda8f692020-11-09 18:38:48 +0900424 FlagWithOutput("-o ", zipOut).
425 FlagWithArg("-C ", dir.String()).
426 Flag("-L 0"). // no compression because this will be unzipped soon
427 FlagWithArg("-D ", dir.String())
428 builder.Command().Text("rm").Flag("-rf").Text(dir.String())
429
Colin Crossf1a035e2020-11-16 17:32:30 -0800430 builder.Build("zip_deps", fmt.Sprintf("Zipping deps for %s", ctx.ModuleName()))
Jiyong Parkdda8f692020-11-09 18:38:48 +0900431 return entries
432}