blob: 9fa3fa315800e3837c2776707f2bcf1fe4baf91c [file] [log] [blame]
Colin Cross69452e12023-11-15 11:20:53 -08001// Copyright 2015 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
17import (
18 "fmt"
Colin Cross7ceb14a2024-10-30 11:40:21 -070019 "github.com/google/blueprint/depset"
Colin Cross69452e12023-11-15 11:20:53 -080020 "path"
21 "path/filepath"
22 "strings"
Cole Faust9a346f62024-01-18 20:12:02 +000023
24 "github.com/google/blueprint"
25 "github.com/google/blueprint/proptools"
Colin Cross69452e12023-11-15 11:20:53 -080026)
27
28// BuildParameters describes the set of potential parameters to build a Ninja rule.
29// In general, these correspond to a Ninja concept.
30type BuildParams struct {
31 // A Ninja Rule that will be written to the Ninja file. This allows factoring out common code
32 // among multiple modules to reduce repetition in the Ninja file of action requirements. A rule
33 // can contain variables that should be provided in Args.
34 Rule blueprint.Rule
35 // Deps represents the depfile format. When using RuleBuilder, this defaults to GCC when depfiles
36 // are used.
37 Deps blueprint.Deps
38 // Depfile is a writeable path that allows correct incremental builds when the inputs have not
39 // been fully specified by the Ninja rule. Ninja supports a subset of the Makefile depfile syntax.
40 Depfile WritablePath
41 // A description of the build action.
42 Description string
43 // Output is an output file of the action. When using this field, references to $out in the Ninja
44 // command will refer to this file.
45 Output WritablePath
46 // Outputs is a slice of output file of the action. When using this field, references to $out in
47 // the Ninja command will refer to these files.
48 Outputs WritablePaths
Colin Cross69452e12023-11-15 11:20:53 -080049 // ImplicitOutput is an output file generated by the action. Note: references to `$out` in the
50 // Ninja command will NOT include references to this file.
51 ImplicitOutput WritablePath
52 // ImplicitOutputs is a slice of output files generated by the action. Note: references to `$out`
53 // in the Ninja command will NOT include references to these files.
54 ImplicitOutputs WritablePaths
55 // Input is an input file to the Ninja action. When using this field, references to $in in the
56 // Ninja command will refer to this file.
57 Input Path
58 // Inputs is a slice of input files to the Ninja action. When using this field, references to $in
59 // in the Ninja command will refer to these files.
60 Inputs Paths
61 // Implicit is an input file to the Ninja action. Note: references to `$in` in the Ninja command
62 // will NOT include references to this file.
63 Implicit Path
64 // Implicits is a slice of input files to the Ninja action. Note: references to `$in` in the Ninja
65 // command will NOT include references to these files.
66 Implicits Paths
67 // OrderOnly are Ninja order-only inputs to the action. When these are out of date, the output is
68 // not rebuilt until they are built, but changes in order-only dependencies alone do not cause the
69 // output to be rebuilt.
70 OrderOnly Paths
71 // Validation is an output path for a validation action. Validation outputs imply lower
72 // non-blocking priority to building non-validation outputs.
73 Validation Path
74 // Validations is a slice of output path for a validation action. Validation outputs imply lower
75 // non-blocking priority to building non-validation outputs.
76 Validations Paths
77 // Whether to skip outputting a default target statement which will be built by Ninja when no
78 // targets are specified on Ninja's command line.
79 Default bool
80 // Args is a key value mapping for replacements of variables within the Rule
81 Args map[string]string
82}
83
84type ModuleBuildParams BuildParams
85
86type ModuleContext interface {
87 BaseModuleContext
88
Colin Cross1496fb12024-09-09 16:44:10 -070089 // BlueprintModuleContext returns the blueprint.ModuleContext that the ModuleContext wraps. It may only be
90 // used by the golang module types that need to call into the bootstrap module types.
91 BlueprintModuleContext() blueprint.ModuleContext
Colin Cross69452e12023-11-15 11:20:53 -080092
93 // Deprecated: use ModuleContext.Build instead.
94 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
95
96 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
97 // be tagged with `android:"path" to support automatic source module dependency resolution.
98 //
99 // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
100 ExpandSources(srcFiles, excludes []string) Paths
101
102 // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
103 // be tagged with `android:"path" to support automatic source module dependency resolution.
104 //
105 // Deprecated: use PathForModuleSrc instead.
106 ExpandSource(srcFile, prop string) Path
107
108 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
109
110 // InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
111 // with the given additional dependencies. The file is marked executable after copying.
112 //
Yu Liubad1eef2024-08-21 22:37:35 +0000113 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
114 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
115 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
116 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800117 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800118
119 // InstallFile creates a rule to copy srcPath to name in the installPath directory,
120 // with the given additional dependencies.
121 //
Yu Liubad1eef2024-08-21 22:37:35 +0000122 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
123 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
124 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
125 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800126 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800127
Colin Crossa6182ab2024-08-21 10:47:44 -0700128 // InstallFileWithoutCheckbuild creates a rule to copy srcPath to name in the installPath directory,
129 // with the given additional dependencies, but does not add the file to the list of files to build
130 // during `m checkbuild`.
131 //
132 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
133 // installed file will be returned by PackagingSpecs() on this module or by
134 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags
135 // for which IsInstallDepNeeded returns true.
136 InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
137
Colin Cross69452e12023-11-15 11:20:53 -0800138 // InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
139 // directory, and also unzip a zip file containing extra files to install into the same
140 // directory.
141 //
Yu Liubad1eef2024-08-21 22:37:35 +0000142 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
143 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
144 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
145 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800146 InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800147
148 // InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
149 // directory.
150 //
Yu Liubad1eef2024-08-21 22:37:35 +0000151 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
152 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
153 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
154 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800155 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
156
157 // InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
158 // in the installPath directory.
159 //
Yu Liubad1eef2024-08-21 22:37:35 +0000160 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
161 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
162 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
163 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800164 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
165
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800166 // InstallTestData creates rules to install test data (e.g. data files used during a test) into
167 // the installPath directory.
168 //
Yu Liubad1eef2024-08-21 22:37:35 +0000169 // The installed files can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
170 // for the installed files can be accessed by InstallFilesInfo.PackagingSpecs on this module
171 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
172 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800173 InstallTestData(installPath InstallPath, data []DataPath) InstallPaths
174
Colin Cross69452e12023-11-15 11:20:53 -0800175 // PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
176 // the rule to copy the file. This is useful to define how a module would be packaged
177 // without installing it into the global installation directories.
178 //
Yu Liubad1eef2024-08-21 22:37:35 +0000179 // The created PackagingSpec can be accessed by InstallFilesInfo.PackagingSpecs on this module
180 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
181 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800182 PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
183
Colin Crossa6182ab2024-08-21 10:47:44 -0700184 CheckbuildFile(srcPaths ...Path)
185 UncheckedModule()
Colin Cross69452e12023-11-15 11:20:53 -0800186
187 InstallInData() bool
188 InstallInTestcases() bool
189 InstallInSanitizerDir() bool
190 InstallInRamdisk() bool
191 InstallInVendorRamdisk() bool
192 InstallInDebugRamdisk() bool
193 InstallInRecovery() bool
194 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -0800195 InstallInOdm() bool
196 InstallInProduct() bool
Colin Cross69452e12023-11-15 11:20:53 -0800197 InstallInVendor() bool
198 InstallForceOS() (*OsType, *ArchType)
199
Cole Fauste8a87832024-09-11 11:35:46 -0700200 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Colin Cross69452e12023-11-15 11:20:53 -0800201 HostRequiredModuleNames() []string
202 TargetRequiredModuleNames() []string
203
204 ModuleSubDir() string
Colin Cross69452e12023-11-15 11:20:53 -0800205
206 Variable(pctx PackageContext, name, value string)
207 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
208 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
209 // and performs more verification.
210 Build(pctx PackageContext, params BuildParams)
211 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
212 // phony rules or real files. Phony can be called on the same name multiple times to add
213 // additional dependencies.
214 Phony(phony string, deps ...Path)
215
216 // GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods,
217 // but do not exist.
218 GetMissingDependencies() []string
219
220 // LicenseMetadataFile returns the path where the license metadata for this module will be
221 // generated.
222 LicenseMetadataFile() Path
Colin Crossd6fd0132023-11-06 13:54:06 -0800223
224 // ModuleInfoJSON returns a pointer to the ModuleInfoJSON struct that can be filled out by
225 // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in
226 // the module-info.json generated by Make, and Make will not generate its own data for this module.
227 ModuleInfoJSON() *ModuleInfoJSON
mrziwange6c85812024-05-22 14:36:09 -0700228
229 // SetOutputFiles stores the outputFiles to outputFiles property, which is used
230 // to set the OutputFilesProvider later.
231 SetOutputFiles(outputFiles Paths, tag string)
Wei Lia1aa2972024-06-21 13:08:51 -0700232
Yu Liu876b7ce2024-08-21 18:20:13 +0000233 GetOutputFiles() OutputFilesInfo
234
Yu Liubad1eef2024-08-21 22:37:35 +0000235 // SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
236 // apex container for use when generation the license metadata file.
237 SetLicenseInstallMap(installMap []string)
238
Wei Lia1aa2972024-06-21 13:08:51 -0700239 // ComplianceMetadataInfo returns a ComplianceMetadataInfo instance for different module types to dump metadata,
240 // which usually happens in GenerateAndroidBuildActions() of a module type.
241 // See android.ModuleBase.complianceMetadataInfo
242 ComplianceMetadataInfo() *ComplianceMetadataInfo
Yu Liu9a993132024-08-27 23:21:06 +0000243
244 // Get the information about the containers this module belongs to.
245 getContainersInfo() ContainersInfo
246 setContainersInfo(info ContainersInfo)
247
248 setAconfigPaths(paths Paths)
Colin Cross69452e12023-11-15 11:20:53 -0800249}
250
251type moduleContext struct {
252 bp blueprint.ModuleContext
253 baseModuleContext
Colin Crossa6182ab2024-08-21 10:47:44 -0700254 packagingSpecs []PackagingSpec
255 installFiles InstallPaths
256 checkbuildFiles Paths
257 checkbuildTarget Path
258 uncheckedModule bool
259 module Module
260 phonies map[string]Paths
Yu Liu876b7ce2024-08-21 18:20:13 +0000261 // outputFiles stores the output of a module by tag and is used to set
262 // the OutputFilesProvider in GenerateBuildActions
263 outputFiles OutputFilesInfo
Colin Cross69452e12023-11-15 11:20:53 -0800264
Colin Crossa14fb6a2024-10-23 16:57:06 -0700265 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liubad1eef2024-08-21 22:37:35 +0000266
267 // set of dependency module:location mappings used to populate the license metadata for
268 // apex containers.
269 licenseInstallMap []string
270
Yu Liuec810542024-08-26 18:09:15 +0000271 // The path to the generated license metadata file for the module.
272 licenseMetadataFile WritablePath
273
Yu Liud46e5ae2024-08-15 18:46:17 +0000274 katiInstalls katiInstalls
275 katiSymlinks katiInstalls
Yu Liu82a6d142024-08-27 19:02:29 +0000276 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
277 // allowed to have duplicates across modules and variants.
278 katiInitRcInstalls katiInstalls
279 katiVintfInstalls katiInstalls
280 initRcPaths Paths
281 vintfFragmentsPaths Paths
282 installedInitRcPaths InstallPaths
283 installedVintfFragmentsPaths InstallPaths
Colin Cross69452e12023-11-15 11:20:53 -0800284
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800285 testData []DataPath
286
Colin Cross69452e12023-11-15 11:20:53 -0800287 // For tests
288 buildParams []BuildParams
289 ruleParams map[blueprint.Rule]blueprint.RuleParams
290 variables map[string]string
Yu Liu4297ad92024-08-27 19:50:13 +0000291
292 // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
293 // be included in the final module-info.json produced by Make.
294 moduleInfoJSON *ModuleInfoJSON
Yu Liu9a993132024-08-27 23:21:06 +0000295
296 // containersInfo stores the information about the containers and the information of the
297 // apexes the module belongs to.
298 containersInfo ContainersInfo
299
300 // Merged Aconfig files for all transitive deps.
301 aconfigFilePaths Paths
302
303 // complianceMetadataInfo is for different module types to dump metadata.
304 // See android.ModuleContext interface.
305 complianceMetadataInfo *ComplianceMetadataInfo
Colin Cross69452e12023-11-15 11:20:53 -0800306}
307
Cole Faust02987bd2024-03-21 17:58:43 -0700308var _ ModuleContext = &moduleContext{}
309
Colin Cross69452e12023-11-15 11:20:53 -0800310func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
311 return pctx, BuildParams{
312 Rule: ErrorRule,
313 Description: params.Description,
314 Output: params.Output,
315 Outputs: params.Outputs,
316 ImplicitOutput: params.ImplicitOutput,
317 ImplicitOutputs: params.ImplicitOutputs,
318 Args: map[string]string{
319 "error": err.Error(),
320 },
321 }
322}
323
324func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
325 m.Build(pctx, BuildParams(params))
326}
327
Colin Cross69452e12023-11-15 11:20:53 -0800328// Convert build parameters from their concrete Android types into their string representations,
329// and combine the singular and plural fields of the same type (e.g. Output and Outputs).
330func convertBuildParams(params BuildParams) blueprint.BuildParams {
331 bparams := blueprint.BuildParams{
332 Rule: params.Rule,
333 Description: params.Description,
334 Deps: params.Deps,
335 Outputs: params.Outputs.Strings(),
336 ImplicitOutputs: params.ImplicitOutputs.Strings(),
Colin Cross69452e12023-11-15 11:20:53 -0800337 Inputs: params.Inputs.Strings(),
338 Implicits: params.Implicits.Strings(),
339 OrderOnly: params.OrderOnly.Strings(),
340 Validations: params.Validations.Strings(),
341 Args: params.Args,
342 Optional: !params.Default,
343 }
344
345 if params.Depfile != nil {
346 bparams.Depfile = params.Depfile.String()
347 }
348 if params.Output != nil {
349 bparams.Outputs = append(bparams.Outputs, params.Output.String())
350 }
Colin Cross69452e12023-11-15 11:20:53 -0800351 if params.ImplicitOutput != nil {
352 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
353 }
354 if params.Input != nil {
355 bparams.Inputs = append(bparams.Inputs, params.Input.String())
356 }
357 if params.Implicit != nil {
358 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
359 }
360 if params.Validation != nil {
361 bparams.Validations = append(bparams.Validations, params.Validation.String())
362 }
363
364 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
365 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
Colin Cross69452e12023-11-15 11:20:53 -0800366 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
367 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
368 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
369 bparams.Validations = proptools.NinjaEscapeList(bparams.Validations)
370 bparams.Depfile = proptools.NinjaEscape(bparams.Depfile)
371
372 return bparams
373}
374
375func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
376 if m.config.captureBuild {
377 m.variables[name] = value
378 }
379
380 m.bp.Variable(pctx.PackageContext, name, value)
381}
382
383func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
384 argNames ...string) blueprint.Rule {
385
386 if m.config.UseRemoteBuild() {
387 if params.Pool == nil {
388 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
389 // jobs to the local parallelism value
390 params.Pool = localPool
391 } else if params.Pool == remotePool {
392 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
393 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
394 // parallelism.
395 params.Pool = nil
396 }
397 }
398
399 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
400
401 if m.config.captureBuild {
402 m.ruleParams[rule] = params
403 }
404
405 return rule
406}
407
408func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
409 if params.Description != "" {
410 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
411 }
412
413 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
414 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
415 m.ModuleName(), strings.Join(missingDeps, ", ")))
416 }
417
418 if m.config.captureBuild {
419 m.buildParams = append(m.buildParams, params)
420 }
421
422 bparams := convertBuildParams(params)
Colin Cross69452e12023-11-15 11:20:53 -0800423 m.bp.Build(pctx.PackageContext, bparams)
424}
425
426func (m *moduleContext) Phony(name string, deps ...Path) {
Yu Liu54513622024-08-19 20:00:32 +0000427 m.phonies[name] = append(m.phonies[name], deps...)
Colin Cross69452e12023-11-15 11:20:53 -0800428}
429
430func (m *moduleContext) GetMissingDependencies() []string {
431 var missingDeps []string
432 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
433 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
434 missingDeps = FirstUniqueStrings(missingDeps)
435 return missingDeps
436}
437
438func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
439 module, _ := m.getDirectDepInternal(name, tag)
440 return module
441}
442
443func (m *moduleContext) ModuleSubDir() string {
444 return m.bp.ModuleSubDir()
445}
446
Colin Cross69452e12023-11-15 11:20:53 -0800447func (m *moduleContext) InstallInData() bool {
448 return m.module.InstallInData()
449}
450
451func (m *moduleContext) InstallInTestcases() bool {
452 return m.module.InstallInTestcases()
453}
454
455func (m *moduleContext) InstallInSanitizerDir() bool {
456 return m.module.InstallInSanitizerDir()
457}
458
459func (m *moduleContext) InstallInRamdisk() bool {
460 return m.module.InstallInRamdisk()
461}
462
463func (m *moduleContext) InstallInVendorRamdisk() bool {
464 return m.module.InstallInVendorRamdisk()
465}
466
467func (m *moduleContext) InstallInDebugRamdisk() bool {
468 return m.module.InstallInDebugRamdisk()
469}
470
471func (m *moduleContext) InstallInRecovery() bool {
472 return m.module.InstallInRecovery()
473}
474
475func (m *moduleContext) InstallInRoot() bool {
476 return m.module.InstallInRoot()
477}
478
479func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) {
480 return m.module.InstallForceOS()
481}
482
Colin Crossea30d852023-11-29 16:00:16 -0800483func (m *moduleContext) InstallInOdm() bool {
484 return m.module.InstallInOdm()
485}
486
487func (m *moduleContext) InstallInProduct() bool {
488 return m.module.InstallInProduct()
489}
490
Colin Cross69452e12023-11-15 11:20:53 -0800491func (m *moduleContext) InstallInVendor() bool {
492 return m.module.InstallInVendor()
493}
494
495func (m *moduleContext) skipInstall() bool {
496 if m.module.base().commonProperties.SkipInstall {
497 return true
498 }
499
Colin Cross69452e12023-11-15 11:20:53 -0800500 // We'll need a solution for choosing which of modules with the same name in different
501 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
502 // list of namespaces to install in a Soong-only build.
503 if !m.module.base().commonProperties.NamespaceExportedToMake {
504 return true
505 }
506
507 return false
508}
509
Jiyong Park3f627e62024-05-01 16:14:38 +0900510// Tells whether this module is installed to the full install path (ex:
511// out/target/product/<name>/<partition>) or not. If this returns false, the install build rule is
512// not created and this module can only be installed to packaging modules like android_filesystem.
513func (m *moduleContext) requiresFullInstall() bool {
514 if m.skipInstall() {
515 return false
516 }
517
Spandan Das034af2c2024-10-30 21:45:09 +0000518 if m.module.base().commonProperties.HideFromMake {
519 return false
520 }
521
Jiyong Park3f627e62024-05-01 16:14:38 +0900522 if proptools.Bool(m.module.base().commonProperties.No_full_install) {
523 return false
524 }
525
526 return true
527}
528
Colin Cross69452e12023-11-15 11:20:53 -0800529func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800530 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700531 return m.installFile(installPath, name, srcPath, deps, false, true, true, nil)
532}
533
534func (m *moduleContext) InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path,
535 deps ...InstallPath) InstallPath {
536 return m.installFile(installPath, name, srcPath, deps, false, true, false, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800537}
538
539func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800540 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700541 return m.installFile(installPath, name, srcPath, deps, true, true, true, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800542}
543
544func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800545 extraZip Path, deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700546 return m.installFile(installPath, name, srcPath, deps, false, true, true, &extraFilesZip{
Colin Cross69452e12023-11-15 11:20:53 -0800547 zip: extraZip,
548 dir: installPath,
549 })
550}
551
552func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
553 fullInstallPath := installPath.Join(m, name)
554 return m.packageFile(fullInstallPath, srcPath, false)
555}
556
Colin Cross7ceb14a2024-10-30 11:40:21 -0700557func (m *moduleContext) getAconfigPaths() *Paths {
558 return &m.aconfigFilePaths
Yu Liu9a993132024-08-27 23:21:06 +0000559}
560
561func (m *moduleContext) setAconfigPaths(paths Paths) {
562 m.aconfigFilePaths = paths
Justin Yun74f3f302024-05-07 14:32:14 +0900563}
564
Colin Cross69452e12023-11-15 11:20:53 -0800565func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
566 licenseFiles := m.Module().EffectiveLicenseFiles()
Jiyong Parka574d532024-08-28 18:06:43 +0900567 overrides := CopyOf(m.Module().base().commonProperties.Overrides)
Colin Cross69452e12023-11-15 11:20:53 -0800568 spec := PackagingSpec{
569 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
570 srcPath: srcPath,
571 symlinkTarget: "",
572 executable: executable,
Colin Cross7ceb14a2024-10-30 11:40:21 -0700573 effectiveLicenseFiles: &licenseFiles,
Colin Cross69452e12023-11-15 11:20:53 -0800574 partition: fullInstallPath.partition,
Jiyong Park4152b192024-04-30 21:24:21 +0900575 skipInstall: m.skipInstall(),
Colin Cross7ceb14a2024-10-30 11:40:21 -0700576 aconfigPaths: m.getAconfigPaths(),
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900577 archType: m.target.Arch.ArchType,
Colin Cross7ceb14a2024-10-30 11:40:21 -0700578 overrides: &overrides,
Jiyong Parka574d532024-08-28 18:06:43 +0900579 owner: m.ModuleName(),
Colin Cross69452e12023-11-15 11:20:53 -0800580 }
581 m.packagingSpecs = append(m.packagingSpecs, spec)
582 return spec
583}
584
Colin Cross09ad3a62023-11-15 12:29:33 -0800585func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []InstallPath,
Colin Crossa6182ab2024-08-21 10:47:44 -0700586 executable bool, hooks bool, checkbuild bool, extraZip *extraFilesZip) InstallPath {
Colin Cross69452e12023-11-15 11:20:53 -0800587
588 fullInstallPath := installPath.Join(m, name)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800589 if hooks {
590 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
591 }
Colin Cross69452e12023-11-15 11:20:53 -0800592
Jiyong Park3f627e62024-05-01 16:14:38 +0900593 if m.requiresFullInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +0000594 deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
Yu Liu82a6d142024-08-27 19:02:29 +0000595 deps = append(deps, m.installedInitRcPaths...)
596 deps = append(deps, m.installedVintfFragmentsPaths...)
Colin Cross69452e12023-11-15 11:20:53 -0800597
598 var implicitDeps, orderOnlyDeps Paths
599
600 if m.Host() {
601 // Installed host modules might be used during the build, depend directly on their
602 // dependencies so their timestamp is updated whenever their dependency is updated
Colin Cross09ad3a62023-11-15 12:29:33 -0800603 implicitDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800604 } else {
Colin Cross09ad3a62023-11-15 12:29:33 -0800605 orderOnlyDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800606 }
607
608 if m.Config().KatiEnabled() {
609 // When creating the install rule in Soong but embedding in Make, write the rule to a
610 // makefile instead of directly to the ninja file so that main.mk can add the
611 // dependencies from the `required` property that are hard to resolve in Soong.
612 m.katiInstalls = append(m.katiInstalls, katiInstall{
613 from: srcPath,
614 to: fullInstallPath,
615 implicitDeps: implicitDeps,
616 orderOnlyDeps: orderOnlyDeps,
617 executable: executable,
618 extraFiles: extraZip,
619 })
620 } else {
621 rule := Cp
622 if executable {
623 rule = CpExecutable
624 }
625
626 extraCmds := ""
627 if extraZip != nil {
628 extraCmds += fmt.Sprintf(" && ( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} )",
629 extraZip.dir.String(), extraZip.zip.String())
630 extraCmds += " || ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )"
631 implicitDeps = append(implicitDeps, extraZip.zip)
632 }
633
634 m.Build(pctx, BuildParams{
635 Rule: rule,
636 Description: "install " + fullInstallPath.Base(),
637 Output: fullInstallPath,
638 Input: srcPath,
639 Implicits: implicitDeps,
640 OrderOnly: orderOnlyDeps,
641 Default: !m.Config().KatiEnabled(),
642 Args: map[string]string{
643 "extraCmds": extraCmds,
644 },
645 })
646 }
647
648 m.installFiles = append(m.installFiles, fullInstallPath)
649 }
650
651 m.packageFile(fullInstallPath, srcPath, executable)
652
Colin Crossa6182ab2024-08-21 10:47:44 -0700653 if checkbuild {
654 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
655 }
Colin Cross69452e12023-11-15 11:20:53 -0800656
657 return fullInstallPath
658}
659
660func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
661 fullInstallPath := installPath.Join(m, name)
662 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true)
663
664 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
665 if err != nil {
666 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
667 }
Jiyong Park3f627e62024-05-01 16:14:38 +0900668 if m.requiresFullInstall() {
Colin Cross69452e12023-11-15 11:20:53 -0800669
670 if m.Config().KatiEnabled() {
671 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
672 // makefile instead of directly to the ninja file so that main.mk can add the
673 // dependencies from the `required` property that are hard to resolve in Soong.
674 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
675 from: srcPath,
676 to: fullInstallPath,
677 })
678 } else {
679 // The symlink doesn't need updating when the target is modified, but we sometimes
680 // have a dependency on a symlink to a binary instead of to the binary directly, and
681 // the mtime of the symlink must be updated when the binary is modified, so use a
682 // normal dependency here instead of an order-only dependency.
683 m.Build(pctx, BuildParams{
684 Rule: Symlink,
685 Description: "install symlink " + fullInstallPath.Base(),
686 Output: fullInstallPath,
687 Input: srcPath,
688 Default: !m.Config().KatiEnabled(),
689 Args: map[string]string{
690 "fromPath": relPath,
691 },
692 })
693 }
694
695 m.installFiles = append(m.installFiles, fullInstallPath)
Colin Cross69452e12023-11-15 11:20:53 -0800696 }
697
Jiyong Parka574d532024-08-28 18:06:43 +0900698 overrides := CopyOf(m.Module().base().commonProperties.Overrides)
Colin Cross69452e12023-11-15 11:20:53 -0800699 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
700 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
701 srcPath: nil,
702 symlinkTarget: relPath,
703 executable: false,
704 partition: fullInstallPath.partition,
Jiyong Park4152b192024-04-30 21:24:21 +0900705 skipInstall: m.skipInstall(),
Colin Cross7ceb14a2024-10-30 11:40:21 -0700706 aconfigPaths: m.getAconfigPaths(),
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900707 archType: m.target.Arch.ArchType,
Colin Cross7ceb14a2024-10-30 11:40:21 -0700708 overrides: &overrides,
Jiyong Parka574d532024-08-28 18:06:43 +0900709 owner: m.ModuleName(),
Colin Cross69452e12023-11-15 11:20:53 -0800710 })
711
712 return fullInstallPath
713}
714
715// installPath/name -> absPath where absPath might be a path that is available only at runtime
716// (e.g. /apex/...)
717func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
718 fullInstallPath := installPath.Join(m, name)
719 m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
720
Jiyong Park3f627e62024-05-01 16:14:38 +0900721 if m.requiresFullInstall() {
Colin Cross69452e12023-11-15 11:20:53 -0800722 if m.Config().KatiEnabled() {
723 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
724 // makefile instead of directly to the ninja file so that main.mk can add the
725 // dependencies from the `required` property that are hard to resolve in Soong.
726 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
727 absFrom: absPath,
728 to: fullInstallPath,
729 })
730 } else {
731 m.Build(pctx, BuildParams{
732 Rule: Symlink,
733 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
734 Output: fullInstallPath,
735 Default: !m.Config().KatiEnabled(),
736 Args: map[string]string{
737 "fromPath": absPath,
738 },
739 })
740 }
741
742 m.installFiles = append(m.installFiles, fullInstallPath)
743 }
744
Jiyong Parka574d532024-08-28 18:06:43 +0900745 overrides := CopyOf(m.Module().base().commonProperties.Overrides)
Colin Cross69452e12023-11-15 11:20:53 -0800746 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
747 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
748 srcPath: nil,
749 symlinkTarget: absPath,
750 executable: false,
751 partition: fullInstallPath.partition,
Jiyong Park4152b192024-04-30 21:24:21 +0900752 skipInstall: m.skipInstall(),
Colin Cross7ceb14a2024-10-30 11:40:21 -0700753 aconfigPaths: m.getAconfigPaths(),
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900754 archType: m.target.Arch.ArchType,
Colin Cross7ceb14a2024-10-30 11:40:21 -0700755 overrides: &overrides,
Jiyong Parka574d532024-08-28 18:06:43 +0900756 owner: m.ModuleName(),
Colin Cross69452e12023-11-15 11:20:53 -0800757 })
758
759 return fullInstallPath
760}
761
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800762func (m *moduleContext) InstallTestData(installPath InstallPath, data []DataPath) InstallPaths {
763 m.testData = append(m.testData, data...)
764
765 ret := make(InstallPaths, 0, len(data))
766 for _, d := range data {
767 relPath := d.ToRelativeInstallPath()
Colin Crossa6182ab2024-08-21 10:47:44 -0700768 installed := m.installFile(installPath, relPath, d.SrcPath, nil, false, false, true, nil)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800769 ret = append(ret, installed)
770 }
771
772 return ret
773}
774
Colin Crossa6182ab2024-08-21 10:47:44 -0700775// CheckbuildFile specifies the output files that should be built by checkbuild.
776func (m *moduleContext) CheckbuildFile(srcPaths ...Path) {
777 m.checkbuildFiles = append(m.checkbuildFiles, srcPaths...)
778}
779
780// UncheckedModule marks the current module has having no files that should be built by checkbuild.
781func (m *moduleContext) UncheckedModule() {
782 m.uncheckedModule = true
Colin Cross69452e12023-11-15 11:20:53 -0800783}
784
Colin Cross1496fb12024-09-09 16:44:10 -0700785func (m *moduleContext) BlueprintModuleContext() blueprint.ModuleContext {
Colin Cross69452e12023-11-15 11:20:53 -0800786 return m.bp
787}
788
789func (m *moduleContext) LicenseMetadataFile() Path {
Yu Liuec810542024-08-26 18:09:15 +0000790 return m.licenseMetadataFile
Colin Cross69452e12023-11-15 11:20:53 -0800791}
792
Colin Crossd6fd0132023-11-06 13:54:06 -0800793func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
Yu Liu4297ad92024-08-27 19:50:13 +0000794 if moduleInfoJSON := m.moduleInfoJSON; moduleInfoJSON != nil {
Colin Crossd6fd0132023-11-06 13:54:06 -0800795 return moduleInfoJSON
796 }
797 moduleInfoJSON := &ModuleInfoJSON{}
Yu Liu4297ad92024-08-27 19:50:13 +0000798 m.moduleInfoJSON = moduleInfoJSON
Colin Crossd6fd0132023-11-06 13:54:06 -0800799 return moduleInfoJSON
800}
801
mrziwange6c85812024-05-22 14:36:09 -0700802func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
803 if tag == "" {
Yu Liu876b7ce2024-08-21 18:20:13 +0000804 if len(m.outputFiles.DefaultOutputFiles) > 0 {
mrziwange6c85812024-05-22 14:36:09 -0700805 m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
806 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000807 m.outputFiles.DefaultOutputFiles = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700808 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000809 if m.outputFiles.TaggedOutputFiles == nil {
810 m.outputFiles.TaggedOutputFiles = make(map[string]Paths)
mrziwang57768d72024-06-06 11:31:51 -0700811 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000812 if _, exists := m.outputFiles.TaggedOutputFiles[tag]; exists {
mrziwange6c85812024-05-22 14:36:09 -0700813 m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag)
814 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000815 m.outputFiles.TaggedOutputFiles[tag] = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700816 }
817 }
818}
819
Yu Liu876b7ce2024-08-21 18:20:13 +0000820func (m *moduleContext) GetOutputFiles() OutputFilesInfo {
821 return m.outputFiles
822}
823
Yu Liubad1eef2024-08-21 22:37:35 +0000824func (m *moduleContext) SetLicenseInstallMap(installMap []string) {
825 m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
826}
827
Wei Lia1aa2972024-06-21 13:08:51 -0700828func (m *moduleContext) ComplianceMetadataInfo() *ComplianceMetadataInfo {
Yu Liu9a993132024-08-27 23:21:06 +0000829 if m.complianceMetadataInfo == nil {
830 m.complianceMetadataInfo = NewComplianceMetadataInfo()
Wei Lia1aa2972024-06-21 13:08:51 -0700831 }
Yu Liu9a993132024-08-27 23:21:06 +0000832 return m.complianceMetadataInfo
Wei Lia1aa2972024-06-21 13:08:51 -0700833}
834
Colin Cross69452e12023-11-15 11:20:53 -0800835// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
836// be tagged with `android:"path" to support automatic source module dependency resolution.
837//
838// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
839func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
840 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
841}
842
843// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
844// be tagged with `android:"path" to support automatic source module dependency resolution.
845//
846// Deprecated: use PathForModuleSrc instead.
847func (m *moduleContext) ExpandSource(srcFile, _ string) Path {
848 return PathForModuleSrc(m, srcFile)
849}
850
851// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
852// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
853// dependency resolution.
854func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) OptionalPath {
855 if srcFile != nil {
856 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
857 }
858 return OptionalPath{}
859}
860
Cole Fauste8a87832024-09-11 11:35:46 -0700861func (m *moduleContext) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust43ddd082024-06-17 12:32:40 -0700862 return m.module.RequiredModuleNames(ctx)
Colin Cross69452e12023-11-15 11:20:53 -0800863}
864
865func (m *moduleContext) HostRequiredModuleNames() []string {
866 return m.module.HostRequiredModuleNames()
867}
868
869func (m *moduleContext) TargetRequiredModuleNames() []string {
870 return m.module.TargetRequiredModuleNames()
871}
Yu Liu9a993132024-08-27 23:21:06 +0000872
873func (m *moduleContext) getContainersInfo() ContainersInfo {
874 return m.containersInfo
875}
876
877func (m *moduleContext) setContainersInfo(info ContainersInfo) {
878 m.containersInfo = info
879}