blob: 45a8e5c7a2fe6a2ea11918d5ed7369071f882955 [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 Cross69452e12023-11-15 11:20:53 -080019 "path"
20 "path/filepath"
Spandan Dasc1ded7e2024-11-01 00:52:33 +000021 "slices"
Colin Cross69452e12023-11-15 11:20:53 -080022 "strings"
Cole Faust9a346f62024-01-18 20:12:02 +000023
24 "github.com/google/blueprint"
Yu Liud3228ac2024-11-08 23:11:47 +000025 "github.com/google/blueprint/depset"
Cole Faust9a346f62024-01-18 20:12:02 +000026 "github.com/google/blueprint/proptools"
Colin Crossf0c1ede2025-01-23 13:30:36 -080027 "github.com/google/blueprint/uniquelist"
Colin Cross69452e12023-11-15 11:20:53 -080028)
29
30// BuildParameters describes the set of potential parameters to build a Ninja rule.
31// In general, these correspond to a Ninja concept.
32type BuildParams struct {
33 // A Ninja Rule that will be written to the Ninja file. This allows factoring out common code
34 // among multiple modules to reduce repetition in the Ninja file of action requirements. A rule
35 // can contain variables that should be provided in Args.
36 Rule blueprint.Rule
37 // Deps represents the depfile format. When using RuleBuilder, this defaults to GCC when depfiles
38 // are used.
39 Deps blueprint.Deps
40 // Depfile is a writeable path that allows correct incremental builds when the inputs have not
41 // been fully specified by the Ninja rule. Ninja supports a subset of the Makefile depfile syntax.
42 Depfile WritablePath
43 // A description of the build action.
44 Description string
45 // Output is an output file of the action. When using this field, references to $out in the Ninja
46 // command will refer to this file.
47 Output WritablePath
48 // Outputs is a slice of output file of the action. When using this field, references to $out in
49 // the Ninja command will refer to these files.
50 Outputs WritablePaths
Colin Cross69452e12023-11-15 11:20:53 -080051 // ImplicitOutput is an output file generated by the action. Note: references to `$out` in the
52 // Ninja command will NOT include references to this file.
53 ImplicitOutput WritablePath
54 // ImplicitOutputs is a slice of output files generated by the action. Note: references to `$out`
55 // in the Ninja command will NOT include references to these files.
56 ImplicitOutputs WritablePaths
57 // Input is an input file to the Ninja action. When using this field, references to $in in the
58 // Ninja command will refer to this file.
59 Input Path
60 // Inputs is a slice of input files to the Ninja action. When using this field, references to $in
61 // in the Ninja command will refer to these files.
62 Inputs Paths
63 // Implicit is an input file to the Ninja action. Note: references to `$in` in the Ninja command
64 // will NOT include references to this file.
65 Implicit Path
66 // Implicits is a slice of input files to the Ninja action. Note: references to `$in` in the Ninja
67 // command will NOT include references to these files.
68 Implicits Paths
69 // OrderOnly are Ninja order-only inputs to the action. When these are out of date, the output is
70 // not rebuilt until they are built, but changes in order-only dependencies alone do not cause the
71 // output to be rebuilt.
72 OrderOnly Paths
73 // Validation is an output path for a validation action. Validation outputs imply lower
74 // non-blocking priority to building non-validation outputs.
75 Validation Path
76 // Validations is a slice of output path for a validation action. Validation outputs imply lower
77 // non-blocking priority to building non-validation outputs.
78 Validations Paths
Cole Faust451912d2025-01-10 11:21:18 -080079 // Whether to output a default target statement which will be built by Ninja when no
Colin Cross69452e12023-11-15 11:20:53 -080080 // targets are specified on Ninja's command line.
81 Default bool
82 // Args is a key value mapping for replacements of variables within the Rule
83 Args map[string]string
84}
85
86type ModuleBuildParams BuildParams
87
88type ModuleContext interface {
89 BaseModuleContext
90
Colin Cross1496fb12024-09-09 16:44:10 -070091 // BlueprintModuleContext returns the blueprint.ModuleContext that the ModuleContext wraps. It may only be
92 // used by the golang module types that need to call into the bootstrap module types.
93 BlueprintModuleContext() blueprint.ModuleContext
Colin Cross69452e12023-11-15 11:20:53 -080094
95 // Deprecated: use ModuleContext.Build instead.
96 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
97
98 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
99 // be tagged with `android:"path" to support automatic source module dependency resolution.
100 //
101 // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
102 ExpandSources(srcFiles, excludes []string) Paths
103
104 // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
105 // be tagged with `android:"path" to support automatic source module dependency resolution.
106 //
107 // Deprecated: use PathForModuleSrc instead.
108 ExpandSource(srcFile, prop string) Path
109
110 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
111
112 // InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
113 // with the given additional dependencies. The file is marked executable after copying.
114 //
Yu Liubad1eef2024-08-21 22:37:35 +0000115 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
116 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
117 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
118 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800119 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800120
121 // InstallFile creates a rule to copy srcPath to name in the installPath directory,
122 // with the given additional dependencies.
123 //
Yu Liubad1eef2024-08-21 22:37:35 +0000124 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
125 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
126 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
127 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800128 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800129
Colin Crossa6182ab2024-08-21 10:47:44 -0700130 // InstallFileWithoutCheckbuild creates a rule to copy srcPath to name in the installPath directory,
131 // with the given additional dependencies, but does not add the file to the list of files to build
132 // during `m checkbuild`.
133 //
134 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
135 // installed file will be returned by PackagingSpecs() on this module or by
136 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags
137 // for which IsInstallDepNeeded returns true.
138 InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
139
Colin Cross69452e12023-11-15 11:20:53 -0800140 // InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
141 // directory, and also unzip a zip file containing extra files to install into the same
142 // directory.
143 //
Yu Liubad1eef2024-08-21 22:37:35 +0000144 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
145 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
146 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
147 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800148 InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800149
150 // InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
151 // directory.
152 //
Yu Liubad1eef2024-08-21 22:37:35 +0000153 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
154 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
155 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
156 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800157 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
158
159 // InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
160 // in the installPath directory.
161 //
Yu Liubad1eef2024-08-21 22:37:35 +0000162 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
163 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
164 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
165 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800166 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
167
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800168 // InstallTestData creates rules to install test data (e.g. data files used during a test) into
169 // the installPath directory.
170 //
Yu Liubad1eef2024-08-21 22:37:35 +0000171 // The installed files can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
172 // for the installed files can be accessed by InstallFilesInfo.PackagingSpecs on this module
173 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
174 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800175 InstallTestData(installPath InstallPath, data []DataPath) InstallPaths
176
Colin Cross69452e12023-11-15 11:20:53 -0800177 // PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
178 // the rule to copy the file. This is useful to define how a module would be packaged
179 // without installing it into the global installation directories.
180 //
Yu Liubad1eef2024-08-21 22:37:35 +0000181 // The created PackagingSpec can be accessed by InstallFilesInfo.PackagingSpecs on this module
182 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
183 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800184 PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
185
Colin Crossa6182ab2024-08-21 10:47:44 -0700186 CheckbuildFile(srcPaths ...Path)
187 UncheckedModule()
Colin Cross69452e12023-11-15 11:20:53 -0800188
189 InstallInData() bool
190 InstallInTestcases() bool
191 InstallInSanitizerDir() bool
192 InstallInRamdisk() bool
193 InstallInVendorRamdisk() bool
194 InstallInDebugRamdisk() bool
195 InstallInRecovery() bool
196 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -0800197 InstallInOdm() bool
198 InstallInProduct() bool
Colin Cross69452e12023-11-15 11:20:53 -0800199 InstallInVendor() bool
Spandan Das27ff7672024-11-06 19:23:57 +0000200 InstallInSystemDlkm() bool
201 InstallInVendorDlkm() bool
202 InstallInOdmDlkm() bool
Colin Cross69452e12023-11-15 11:20:53 -0800203 InstallForceOS() (*OsType, *ArchType)
204
Cole Fauste8a87832024-09-11 11:35:46 -0700205 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Colin Cross69452e12023-11-15 11:20:53 -0800206 HostRequiredModuleNames() []string
207 TargetRequiredModuleNames() []string
208
209 ModuleSubDir() string
Colin Cross69452e12023-11-15 11:20:53 -0800210
211 Variable(pctx PackageContext, name, value string)
212 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
213 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
214 // and performs more verification.
215 Build(pctx PackageContext, params BuildParams)
216 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
217 // phony rules or real files. Phony can be called on the same name multiple times to add
218 // additional dependencies.
219 Phony(phony string, deps ...Path)
220
221 // GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods,
222 // but do not exist.
223 GetMissingDependencies() []string
224
225 // LicenseMetadataFile returns the path where the license metadata for this module will be
226 // generated.
227 LicenseMetadataFile() Path
Colin Crossd6fd0132023-11-06 13:54:06 -0800228
229 // ModuleInfoJSON returns a pointer to the ModuleInfoJSON struct that can be filled out by
230 // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in
231 // the module-info.json generated by Make, and Make will not generate its own data for this module.
232 ModuleInfoJSON() *ModuleInfoJSON
mrziwange6c85812024-05-22 14:36:09 -0700233
Jihoon Kangd4063812025-01-24 00:25:30 +0000234 // Simiar to ModuleInfoJSON, ExtraModuleInfoJSON also returns a pointer to the ModuleInfoJSON struct.
235 // This should only be called by a module that generates multiple AndroidMkEntries struct.
236 ExtraModuleInfoJSON() *ModuleInfoJSON
237
mrziwange6c85812024-05-22 14:36:09 -0700238 // SetOutputFiles stores the outputFiles to outputFiles property, which is used
239 // to set the OutputFilesProvider later.
240 SetOutputFiles(outputFiles Paths, tag string)
Wei Lia1aa2972024-06-21 13:08:51 -0700241
Yu Liu876b7ce2024-08-21 18:20:13 +0000242 GetOutputFiles() OutputFilesInfo
243
Yu Liubad1eef2024-08-21 22:37:35 +0000244 // SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
245 // apex container for use when generation the license metadata file.
246 SetLicenseInstallMap(installMap []string)
247
Wei Lia1aa2972024-06-21 13:08:51 -0700248 // ComplianceMetadataInfo returns a ComplianceMetadataInfo instance for different module types to dump metadata,
249 // which usually happens in GenerateAndroidBuildActions() of a module type.
250 // See android.ModuleBase.complianceMetadataInfo
251 ComplianceMetadataInfo() *ComplianceMetadataInfo
Yu Liu9a993132024-08-27 23:21:06 +0000252
253 // Get the information about the containers this module belongs to.
254 getContainersInfo() ContainersInfo
255 setContainersInfo(info ContainersInfo)
256
257 setAconfigPaths(paths Paths)
Cole Faustd62a4892025-02-07 16:55:11 -0800258
259 // DistForGoals creates a rule to copy one or more Paths to the artifacts
260 // directory on the build server when any of the specified goals are built.
261 DistForGoal(goal string, paths ...Path)
262
263 // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
264 // directory on the build server with the given filename when the specified
265 // goal is built.
266 DistForGoalWithFilename(goal string, path Path, filename string)
267
268 // DistForGoals creates a rule to copy one or more Paths to the artifacts
269 // directory on the build server when any of the specified goals are built.
270 DistForGoals(goals []string, paths ...Path)
271
272 // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
273 // directory on the build server with the given filename when any of the
274 // specified goals are built.
275 DistForGoalsWithFilename(goals []string, path Path, filename string)
Colin Cross69452e12023-11-15 11:20:53 -0800276}
277
278type moduleContext struct {
279 bp blueprint.ModuleContext
280 baseModuleContext
Colin Crossa6182ab2024-08-21 10:47:44 -0700281 packagingSpecs []PackagingSpec
282 installFiles InstallPaths
283 checkbuildFiles Paths
284 checkbuildTarget Path
285 uncheckedModule bool
286 module Module
287 phonies map[string]Paths
Yu Liu876b7ce2024-08-21 18:20:13 +0000288 // outputFiles stores the output of a module by tag and is used to set
289 // the OutputFilesProvider in GenerateBuildActions
290 outputFiles OutputFilesInfo
Colin Cross69452e12023-11-15 11:20:53 -0800291
Colin Crossa14fb6a2024-10-23 16:57:06 -0700292 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liubad1eef2024-08-21 22:37:35 +0000293
294 // set of dependency module:location mappings used to populate the license metadata for
295 // apex containers.
296 licenseInstallMap []string
297
Yu Liuec810542024-08-26 18:09:15 +0000298 // The path to the generated license metadata file for the module.
299 licenseMetadataFile WritablePath
300
Yu Liud46e5ae2024-08-15 18:46:17 +0000301 katiInstalls katiInstalls
302 katiSymlinks katiInstalls
Yu Liu82a6d142024-08-27 19:02:29 +0000303 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
304 // allowed to have duplicates across modules and variants.
305 katiInitRcInstalls katiInstalls
306 katiVintfInstalls katiInstalls
307 initRcPaths Paths
308 vintfFragmentsPaths Paths
309 installedInitRcPaths InstallPaths
310 installedVintfFragmentsPaths InstallPaths
Colin Cross69452e12023-11-15 11:20:53 -0800311
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800312 testData []DataPath
313
Colin Cross69452e12023-11-15 11:20:53 -0800314 // For tests
315 buildParams []BuildParams
316 ruleParams map[blueprint.Rule]blueprint.RuleParams
317 variables map[string]string
Yu Liu4297ad92024-08-27 19:50:13 +0000318
319 // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
320 // be included in the final module-info.json produced by Make.
Jihoon Kangd4063812025-01-24 00:25:30 +0000321 moduleInfoJSON []*ModuleInfoJSON
Yu Liu9a993132024-08-27 23:21:06 +0000322
323 // containersInfo stores the information about the containers and the information of the
324 // apexes the module belongs to.
325 containersInfo ContainersInfo
326
327 // Merged Aconfig files for all transitive deps.
328 aconfigFilePaths Paths
329
330 // complianceMetadataInfo is for different module types to dump metadata.
331 // See android.ModuleContext interface.
332 complianceMetadataInfo *ComplianceMetadataInfo
Cole Faustd62a4892025-02-07 16:55:11 -0800333
334 dists []dist
Colin Cross69452e12023-11-15 11:20:53 -0800335}
336
Cole Faust02987bd2024-03-21 17:58:43 -0700337var _ ModuleContext = &moduleContext{}
338
Colin Cross69452e12023-11-15 11:20:53 -0800339func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
340 return pctx, BuildParams{
341 Rule: ErrorRule,
342 Description: params.Description,
343 Output: params.Output,
344 Outputs: params.Outputs,
345 ImplicitOutput: params.ImplicitOutput,
346 ImplicitOutputs: params.ImplicitOutputs,
347 Args: map[string]string{
348 "error": err.Error(),
349 },
350 }
351}
352
353func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
354 m.Build(pctx, BuildParams(params))
355}
356
Colin Cross69452e12023-11-15 11:20:53 -0800357// Convert build parameters from their concrete Android types into their string representations,
358// and combine the singular and plural fields of the same type (e.g. Output and Outputs).
359func convertBuildParams(params BuildParams) blueprint.BuildParams {
360 bparams := blueprint.BuildParams{
361 Rule: params.Rule,
362 Description: params.Description,
363 Deps: params.Deps,
364 Outputs: params.Outputs.Strings(),
365 ImplicitOutputs: params.ImplicitOutputs.Strings(),
Colin Cross69452e12023-11-15 11:20:53 -0800366 Inputs: params.Inputs.Strings(),
367 Implicits: params.Implicits.Strings(),
368 OrderOnly: params.OrderOnly.Strings(),
369 Validations: params.Validations.Strings(),
370 Args: params.Args,
Cole Faust451912d2025-01-10 11:21:18 -0800371 Default: params.Default,
Colin Cross69452e12023-11-15 11:20:53 -0800372 }
373
374 if params.Depfile != nil {
375 bparams.Depfile = params.Depfile.String()
376 }
377 if params.Output != nil {
378 bparams.Outputs = append(bparams.Outputs, params.Output.String())
379 }
Colin Cross69452e12023-11-15 11:20:53 -0800380 if params.ImplicitOutput != nil {
381 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
382 }
383 if params.Input != nil {
384 bparams.Inputs = append(bparams.Inputs, params.Input.String())
385 }
386 if params.Implicit != nil {
387 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
388 }
389 if params.Validation != nil {
390 bparams.Validations = append(bparams.Validations, params.Validation.String())
391 }
392
393 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
394 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
Colin Cross69452e12023-11-15 11:20:53 -0800395 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
396 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
397 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
398 bparams.Validations = proptools.NinjaEscapeList(bparams.Validations)
399 bparams.Depfile = proptools.NinjaEscape(bparams.Depfile)
400
401 return bparams
402}
403
404func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
405 if m.config.captureBuild {
406 m.variables[name] = value
407 }
408
409 m.bp.Variable(pctx.PackageContext, name, value)
410}
411
412func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
413 argNames ...string) blueprint.Rule {
414
415 if m.config.UseRemoteBuild() {
416 if params.Pool == nil {
417 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
418 // jobs to the local parallelism value
419 params.Pool = localPool
420 } else if params.Pool == remotePool {
421 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
422 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
423 // parallelism.
424 params.Pool = nil
425 }
426 }
427
428 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
429
430 if m.config.captureBuild {
431 m.ruleParams[rule] = params
432 }
433
434 return rule
435}
436
437func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
438 if params.Description != "" {
439 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
440 }
441
442 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
443 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
444 m.ModuleName(), strings.Join(missingDeps, ", ")))
445 }
446
447 if m.config.captureBuild {
448 m.buildParams = append(m.buildParams, params)
449 }
450
451 bparams := convertBuildParams(params)
Colin Cross69452e12023-11-15 11:20:53 -0800452 m.bp.Build(pctx.PackageContext, bparams)
453}
454
455func (m *moduleContext) Phony(name string, deps ...Path) {
Yu Liu54513622024-08-19 20:00:32 +0000456 m.phonies[name] = append(m.phonies[name], deps...)
Colin Cross69452e12023-11-15 11:20:53 -0800457}
458
459func (m *moduleContext) GetMissingDependencies() []string {
460 var missingDeps []string
461 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
462 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
463 missingDeps = FirstUniqueStrings(missingDeps)
464 return missingDeps
465}
466
Yu Liud3228ac2024-11-08 23:11:47 +0000467func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module {
Yu Liu3ae96652024-12-17 22:27:38 +0000468 deps := m.getDirectDepsInternal(name, tag)
469 if len(deps) == 1 {
470 return deps[0]
471 } else if len(deps) >= 2 {
472 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
473 name, m.ModuleName()))
474 } else {
475 return nil
Yu Liud3228ac2024-11-08 23:11:47 +0000476 }
Yu Liu3ae96652024-12-17 22:27:38 +0000477}
478
479func (m *moduleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy {
480 deps := m.getDirectDepsProxyInternal(name, tag)
481 if len(deps) == 1 {
482 return &deps[0]
483 } else if len(deps) >= 2 {
484 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
485 name, m.ModuleName()))
486 } else {
487 return nil
488 }
Colin Cross69452e12023-11-15 11:20:53 -0800489}
490
491func (m *moduleContext) ModuleSubDir() string {
492 return m.bp.ModuleSubDir()
493}
494
Colin Cross69452e12023-11-15 11:20:53 -0800495func (m *moduleContext) InstallInData() bool {
496 return m.module.InstallInData()
497}
498
499func (m *moduleContext) InstallInTestcases() bool {
500 return m.module.InstallInTestcases()
501}
502
503func (m *moduleContext) InstallInSanitizerDir() bool {
504 return m.module.InstallInSanitizerDir()
505}
506
507func (m *moduleContext) InstallInRamdisk() bool {
508 return m.module.InstallInRamdisk()
509}
510
511func (m *moduleContext) InstallInVendorRamdisk() bool {
512 return m.module.InstallInVendorRamdisk()
513}
514
515func (m *moduleContext) InstallInDebugRamdisk() bool {
516 return m.module.InstallInDebugRamdisk()
517}
518
519func (m *moduleContext) InstallInRecovery() bool {
520 return m.module.InstallInRecovery()
521}
522
523func (m *moduleContext) InstallInRoot() bool {
524 return m.module.InstallInRoot()
525}
526
527func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) {
528 return m.module.InstallForceOS()
529}
530
Colin Crossea30d852023-11-29 16:00:16 -0800531func (m *moduleContext) InstallInOdm() bool {
532 return m.module.InstallInOdm()
533}
534
535func (m *moduleContext) InstallInProduct() bool {
536 return m.module.InstallInProduct()
537}
538
Colin Cross69452e12023-11-15 11:20:53 -0800539func (m *moduleContext) InstallInVendor() bool {
540 return m.module.InstallInVendor()
541}
542
Spandan Das27ff7672024-11-06 19:23:57 +0000543func (m *moduleContext) InstallInSystemDlkm() bool {
544 return m.module.InstallInSystemDlkm()
545}
546
547func (m *moduleContext) InstallInVendorDlkm() bool {
548 return m.module.InstallInVendorDlkm()
549}
550
551func (m *moduleContext) InstallInOdmDlkm() bool {
552 return m.module.InstallInOdmDlkm()
553}
554
Colin Cross69452e12023-11-15 11:20:53 -0800555func (m *moduleContext) skipInstall() bool {
556 if m.module.base().commonProperties.SkipInstall {
557 return true
558 }
559
Colin Cross69452e12023-11-15 11:20:53 -0800560 // We'll need a solution for choosing which of modules with the same name in different
561 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
562 // list of namespaces to install in a Soong-only build.
563 if !m.module.base().commonProperties.NamespaceExportedToMake {
564 return true
565 }
566
567 return false
568}
569
Jiyong Park3f627e62024-05-01 16:14:38 +0900570// Tells whether this module is installed to the full install path (ex:
571// out/target/product/<name>/<partition>) or not. If this returns false, the install build rule is
572// not created and this module can only be installed to packaging modules like android_filesystem.
573func (m *moduleContext) requiresFullInstall() bool {
574 if m.skipInstall() {
575 return false
576 }
577
Spandan Das034af2c2024-10-30 21:45:09 +0000578 if m.module.base().commonProperties.HideFromMake {
579 return false
580 }
581
Jiyong Park3f627e62024-05-01 16:14:38 +0900582 if proptools.Bool(m.module.base().commonProperties.No_full_install) {
583 return false
584 }
585
586 return true
587}
588
Colin Cross69452e12023-11-15 11:20:53 -0800589func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800590 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700591 return m.installFile(installPath, name, srcPath, deps, false, true, true, nil)
592}
593
594func (m *moduleContext) InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path,
595 deps ...InstallPath) InstallPath {
596 return m.installFile(installPath, name, srcPath, deps, false, true, false, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800597}
598
599func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800600 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700601 return m.installFile(installPath, name, srcPath, deps, true, true, true, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800602}
603
604func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800605 extraZip Path, deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700606 return m.installFile(installPath, name, srcPath, deps, false, true, true, &extraFilesZip{
Colin Cross69452e12023-11-15 11:20:53 -0800607 zip: extraZip,
608 dir: installPath,
609 })
610}
611
612func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
613 fullInstallPath := installPath.Join(m, name)
Cole Faust19fbb072025-01-30 18:19:29 -0800614 return m.packageFile(fullInstallPath, srcPath, false, false)
Colin Cross69452e12023-11-15 11:20:53 -0800615}
616
Colin Crossf0c1ede2025-01-23 13:30:36 -0800617func (m *moduleContext) getAconfigPaths() Paths {
618 return m.aconfigFilePaths
Yu Liu9a993132024-08-27 23:21:06 +0000619}
620
621func (m *moduleContext) setAconfigPaths(paths Paths) {
622 m.aconfigFilePaths = paths
Justin Yun74f3f302024-05-07 14:32:14 +0900623}
624
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000625func (m *moduleContext) getOwnerAndOverrides() (string, []string) {
626 owner := m.ModuleName()
627 overrides := slices.Clone(m.Module().base().commonProperties.Overrides)
628 if b, ok := m.Module().(OverridableModule); ok {
629 if b.GetOverriddenBy() != "" {
630 // overriding variant of base module
631 overrides = append(overrides, m.ModuleName()) // com.android.foo
632 owner = m.Module().Name() // com.company.android.foo
633 }
634 }
635 return owner, overrides
636}
637
Cole Faust19fbb072025-01-30 18:19:29 -0800638func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool, requiresFullInstall bool) PackagingSpec {
Colin Cross69452e12023-11-15 11:20:53 -0800639 licenseFiles := m.Module().EffectiveLicenseFiles()
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000640 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800641 spec := PackagingSpec{
642 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
643 srcPath: srcPath,
644 symlinkTarget: "",
645 executable: executable,
Colin Crossf0c1ede2025-01-23 13:30:36 -0800646 effectiveLicenseFiles: uniquelist.Make(licenseFiles),
Colin Cross69452e12023-11-15 11:20:53 -0800647 partition: fullInstallPath.partition,
Jiyong Park4152b192024-04-30 21:24:21 +0900648 skipInstall: m.skipInstall(),
Colin Crossf0c1ede2025-01-23 13:30:36 -0800649 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900650 archType: m.target.Arch.ArchType,
Jihoon Kangd4063812025-01-24 00:25:30 +0000651 overrides: uniquelist.Make(overrides),
652 owner: owner,
Cole Faust19fbb072025-01-30 18:19:29 -0800653 requiresFullInstall: requiresFullInstall,
654 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800655 }
656 m.packagingSpecs = append(m.packagingSpecs, spec)
657 return spec
658}
659
Colin Cross09ad3a62023-11-15 12:29:33 -0800660func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []InstallPath,
Colin Crossa6182ab2024-08-21 10:47:44 -0700661 executable bool, hooks bool, checkbuild bool, extraZip *extraFilesZip) InstallPath {
Spandan Dasd718aa52025-02-04 21:18:36 +0000662 if _, ok := srcPath.(InstallPath); ok {
663 m.ModuleErrorf("Src path cannot be another installed file. Please use a path from source or intermediates instead.")
664 }
Colin Cross69452e12023-11-15 11:20:53 -0800665
666 fullInstallPath := installPath.Join(m, name)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800667 if hooks {
668 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
669 }
Colin Cross69452e12023-11-15 11:20:53 -0800670
Jiyong Park3f627e62024-05-01 16:14:38 +0900671 if m.requiresFullInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +0000672 deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
Cole Faust74d243c2024-12-11 17:57:34 -0800673 if m.config.KatiEnabled() {
674 deps = append(deps, m.installedInitRcPaths...)
675 deps = append(deps, m.installedVintfFragmentsPaths...)
676 }
Colin Cross69452e12023-11-15 11:20:53 -0800677
678 var implicitDeps, orderOnlyDeps Paths
679
680 if m.Host() {
681 // Installed host modules might be used during the build, depend directly on their
682 // dependencies so their timestamp is updated whenever their dependency is updated
Colin Cross09ad3a62023-11-15 12:29:33 -0800683 implicitDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800684 } else {
Colin Cross09ad3a62023-11-15 12:29:33 -0800685 orderOnlyDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800686 }
687
Cole Faust866ab392025-01-23 12:56:20 -0800688 // When creating the install rule in Soong but embedding in Make, write the rule to a
689 // makefile instead of directly to the ninja file so that main.mk can add the
690 // dependencies from the `required` property that are hard to resolve in Soong.
691 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
692 // such as module-info.json or compliance, but it will not be used for actually installing
693 // the file.
694 m.katiInstalls = append(m.katiInstalls, katiInstall{
695 from: srcPath,
696 to: fullInstallPath,
697 implicitDeps: implicitDeps,
698 orderOnlyDeps: orderOnlyDeps,
699 executable: executable,
700 extraFiles: extraZip,
701 })
702 if !m.Config().KatiEnabled() {
Spandan Das4d78e012025-01-22 23:25:39 +0000703 rule := CpWithBash
Colin Cross69452e12023-11-15 11:20:53 -0800704 if executable {
Spandan Das4d78e012025-01-22 23:25:39 +0000705 rule = CpExecutableWithBash
Colin Cross69452e12023-11-15 11:20:53 -0800706 }
707
708 extraCmds := ""
709 if extraZip != nil {
710 extraCmds += fmt.Sprintf(" && ( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} )",
711 extraZip.dir.String(), extraZip.zip.String())
712 extraCmds += " || ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )"
713 implicitDeps = append(implicitDeps, extraZip.zip)
714 }
715
716 m.Build(pctx, BuildParams{
717 Rule: rule,
718 Description: "install " + fullInstallPath.Base(),
719 Output: fullInstallPath,
720 Input: srcPath,
721 Implicits: implicitDeps,
722 OrderOnly: orderOnlyDeps,
Colin Cross69452e12023-11-15 11:20:53 -0800723 Args: map[string]string{
724 "extraCmds": extraCmds,
Spandan Das4d78e012025-01-22 23:25:39 +0000725 "cpFlags": "-f",
Colin Cross69452e12023-11-15 11:20:53 -0800726 },
727 })
728 }
729
730 m.installFiles = append(m.installFiles, fullInstallPath)
731 }
732
Cole Faust19fbb072025-01-30 18:19:29 -0800733 m.packageFile(fullInstallPath, srcPath, executable, m.requiresFullInstall())
Colin Cross69452e12023-11-15 11:20:53 -0800734
Colin Crossa6182ab2024-08-21 10:47:44 -0700735 if checkbuild {
736 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
737 }
Colin Cross69452e12023-11-15 11:20:53 -0800738
739 return fullInstallPath
740}
741
742func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
743 fullInstallPath := installPath.Join(m, name)
744 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true)
745
746 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
747 if err != nil {
748 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
749 }
Jiyong Park3f627e62024-05-01 16:14:38 +0900750 if m.requiresFullInstall() {
Colin Cross69452e12023-11-15 11:20:53 -0800751
Cole Faust866ab392025-01-23 12:56:20 -0800752 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
753 // makefile instead of directly to the ninja file so that main.mk can add the
754 // dependencies from the `required` property that are hard to resolve in Soong.
755 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
756 // such as module-info.json or compliance, but it will not be used for actually installing
757 // the file.
758 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
759 from: srcPath,
760 to: fullInstallPath,
761 })
762 if !m.Config().KatiEnabled() {
Colin Cross69452e12023-11-15 11:20:53 -0800763 // The symlink doesn't need updating when the target is modified, but we sometimes
764 // have a dependency on a symlink to a binary instead of to the binary directly, and
765 // the mtime of the symlink must be updated when the binary is modified, so use a
766 // normal dependency here instead of an order-only dependency.
767 m.Build(pctx, BuildParams{
Spandan Das4d78e012025-01-22 23:25:39 +0000768 Rule: SymlinkWithBash,
Colin Cross69452e12023-11-15 11:20:53 -0800769 Description: "install symlink " + fullInstallPath.Base(),
770 Output: fullInstallPath,
771 Input: srcPath,
Colin Cross69452e12023-11-15 11:20:53 -0800772 Args: map[string]string{
773 "fromPath": relPath,
774 },
775 })
776 }
777
778 m.installFiles = append(m.installFiles, fullInstallPath)
Colin Cross69452e12023-11-15 11:20:53 -0800779 }
780
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000781 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800782 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
Cole Faust19fbb072025-01-30 18:19:29 -0800783 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
784 srcPath: nil,
785 symlinkTarget: relPath,
786 executable: false,
787 partition: fullInstallPath.partition,
788 skipInstall: m.skipInstall(),
789 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
790 archType: m.target.Arch.ArchType,
791 overrides: uniquelist.Make(overrides),
792 owner: owner,
793 requiresFullInstall: m.requiresFullInstall(),
794 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800795 })
796
797 return fullInstallPath
798}
799
800// installPath/name -> absPath where absPath might be a path that is available only at runtime
801// (e.g. /apex/...)
802func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
803 fullInstallPath := installPath.Join(m, name)
804 m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
805
Jiyong Park3f627e62024-05-01 16:14:38 +0900806 if m.requiresFullInstall() {
Cole Faust866ab392025-01-23 12:56:20 -0800807 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
808 // makefile instead of directly to the ninja file so that main.mk can add the
809 // dependencies from the `required` property that are hard to resolve in Soong.
810 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
811 // such as module-info.json or compliance, but it will not be used for actually installing
812 // the file.
813 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
814 absFrom: absPath,
815 to: fullInstallPath,
816 })
817 if !m.Config().KatiEnabled() {
Colin Cross69452e12023-11-15 11:20:53 -0800818 m.Build(pctx, BuildParams{
Cole Faust2526b482025-02-12 18:23:37 -0800819 Rule: SymlinkWithBash,
Colin Cross69452e12023-11-15 11:20:53 -0800820 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
821 Output: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800822 Args: map[string]string{
823 "fromPath": absPath,
824 },
825 })
826 }
827
828 m.installFiles = append(m.installFiles, fullInstallPath)
829 }
830
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000831 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800832 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
Cole Faust19fbb072025-01-30 18:19:29 -0800833 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
834 srcPath: nil,
835 symlinkTarget: absPath,
836 executable: false,
837 partition: fullInstallPath.partition,
838 skipInstall: m.skipInstall(),
839 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
840 archType: m.target.Arch.ArchType,
841 overrides: uniquelist.Make(overrides),
842 owner: owner,
843 requiresFullInstall: m.requiresFullInstall(),
844 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800845 })
846
847 return fullInstallPath
848}
849
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800850func (m *moduleContext) InstallTestData(installPath InstallPath, data []DataPath) InstallPaths {
851 m.testData = append(m.testData, data...)
852
853 ret := make(InstallPaths, 0, len(data))
854 for _, d := range data {
855 relPath := d.ToRelativeInstallPath()
Colin Crossa6182ab2024-08-21 10:47:44 -0700856 installed := m.installFile(installPath, relPath, d.SrcPath, nil, false, false, true, nil)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800857 ret = append(ret, installed)
858 }
859
860 return ret
861}
862
Colin Crossa6182ab2024-08-21 10:47:44 -0700863// CheckbuildFile specifies the output files that should be built by checkbuild.
864func (m *moduleContext) CheckbuildFile(srcPaths ...Path) {
865 m.checkbuildFiles = append(m.checkbuildFiles, srcPaths...)
866}
867
868// UncheckedModule marks the current module has having no files that should be built by checkbuild.
869func (m *moduleContext) UncheckedModule() {
870 m.uncheckedModule = true
Colin Cross69452e12023-11-15 11:20:53 -0800871}
872
Colin Cross1496fb12024-09-09 16:44:10 -0700873func (m *moduleContext) BlueprintModuleContext() blueprint.ModuleContext {
Colin Cross69452e12023-11-15 11:20:53 -0800874 return m.bp
875}
876
877func (m *moduleContext) LicenseMetadataFile() Path {
Yu Liuec810542024-08-26 18:09:15 +0000878 return m.licenseMetadataFile
Colin Cross69452e12023-11-15 11:20:53 -0800879}
880
Colin Crossd6fd0132023-11-06 13:54:06 -0800881func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
Jihoon Kangd4063812025-01-24 00:25:30 +0000882 if len(m.moduleInfoJSON) == 0 {
883 moduleInfoJSON := &ModuleInfoJSON{}
884 m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -0800885 }
Jihoon Kangd4063812025-01-24 00:25:30 +0000886 return m.moduleInfoJSON[0]
887}
888
889func (m *moduleContext) ExtraModuleInfoJSON() *ModuleInfoJSON {
890 if len(m.moduleInfoJSON) == 0 {
891 panic("call ModuleInfoJSON() instead")
892 }
893
Colin Crossd6fd0132023-11-06 13:54:06 -0800894 moduleInfoJSON := &ModuleInfoJSON{}
Jihoon Kangd4063812025-01-24 00:25:30 +0000895 m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -0800896 return moduleInfoJSON
897}
898
mrziwange6c85812024-05-22 14:36:09 -0700899func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
Cole Faust5146e782024-11-15 14:47:49 -0800900 for _, outputFile := range outputFiles {
901 if outputFile == nil {
902 panic("outputfiles cannot be nil")
903 }
904 }
mrziwange6c85812024-05-22 14:36:09 -0700905 if tag == "" {
Yu Liu876b7ce2024-08-21 18:20:13 +0000906 if len(m.outputFiles.DefaultOutputFiles) > 0 {
mrziwange6c85812024-05-22 14:36:09 -0700907 m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
908 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000909 m.outputFiles.DefaultOutputFiles = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700910 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000911 if m.outputFiles.TaggedOutputFiles == nil {
912 m.outputFiles.TaggedOutputFiles = make(map[string]Paths)
mrziwang57768d72024-06-06 11:31:51 -0700913 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000914 if _, exists := m.outputFiles.TaggedOutputFiles[tag]; exists {
mrziwange6c85812024-05-22 14:36:09 -0700915 m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag)
916 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000917 m.outputFiles.TaggedOutputFiles[tag] = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700918 }
919 }
920}
921
Yu Liu876b7ce2024-08-21 18:20:13 +0000922func (m *moduleContext) GetOutputFiles() OutputFilesInfo {
923 return m.outputFiles
924}
925
Yu Liubad1eef2024-08-21 22:37:35 +0000926func (m *moduleContext) SetLicenseInstallMap(installMap []string) {
927 m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
928}
929
Wei Lia1aa2972024-06-21 13:08:51 -0700930func (m *moduleContext) ComplianceMetadataInfo() *ComplianceMetadataInfo {
Yu Liu9a993132024-08-27 23:21:06 +0000931 if m.complianceMetadataInfo == nil {
932 m.complianceMetadataInfo = NewComplianceMetadataInfo()
Wei Lia1aa2972024-06-21 13:08:51 -0700933 }
Yu Liu9a993132024-08-27 23:21:06 +0000934 return m.complianceMetadataInfo
Wei Lia1aa2972024-06-21 13:08:51 -0700935}
936
Colin Cross69452e12023-11-15 11:20:53 -0800937// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
938// be tagged with `android:"path" to support automatic source module dependency resolution.
939//
940// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
941func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
942 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
943}
944
945// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
946// be tagged with `android:"path" to support automatic source module dependency resolution.
947//
948// Deprecated: use PathForModuleSrc instead.
949func (m *moduleContext) ExpandSource(srcFile, _ string) Path {
950 return PathForModuleSrc(m, srcFile)
951}
952
953// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
954// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
955// dependency resolution.
956func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) OptionalPath {
957 if srcFile != nil {
958 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
959 }
960 return OptionalPath{}
961}
962
Cole Fauste8a87832024-09-11 11:35:46 -0700963func (m *moduleContext) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust43ddd082024-06-17 12:32:40 -0700964 return m.module.RequiredModuleNames(ctx)
Colin Cross69452e12023-11-15 11:20:53 -0800965}
966
967func (m *moduleContext) HostRequiredModuleNames() []string {
968 return m.module.HostRequiredModuleNames()
969}
970
971func (m *moduleContext) TargetRequiredModuleNames() []string {
972 return m.module.TargetRequiredModuleNames()
973}
Yu Liu9a993132024-08-27 23:21:06 +0000974
975func (m *moduleContext) getContainersInfo() ContainersInfo {
976 return m.containersInfo
977}
978
979func (m *moduleContext) setContainersInfo(info ContainersInfo) {
980 m.containersInfo = info
981}
Cole Faustd62a4892025-02-07 16:55:11 -0800982
983func (c *moduleContext) DistForGoal(goal string, paths ...Path) {
984 c.DistForGoals([]string{goal}, paths...)
985}
986
987func (c *moduleContext) DistForGoalWithFilename(goal string, path Path, filename string) {
988 c.DistForGoalsWithFilename([]string{goal}, path, filename)
989}
990
991func (c *moduleContext) DistForGoals(goals []string, paths ...Path) {
992 var copies distCopies
993 for _, path := range paths {
994 copies = append(copies, distCopy{
995 from: path,
996 dest: path.Base(),
997 })
998 }
999 c.dists = append(c.dists, dist{
1000 goals: slices.Clone(goals),
1001 paths: copies,
1002 })
1003}
1004
1005func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
1006 c.dists = append(c.dists, dist{
1007 goals: slices.Clone(goals),
1008 paths: distCopies{{from: path, dest: filename}},
1009 })
1010}