blob: f279fd9e57e617e62f5d386f2e5808aa7478f556 [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
LaMont Jones53915542025-02-12 15:33:13 -080084 // PhonyOutput marks this build as `phony_output = true`
85 PhonyOutput bool
Colin Cross69452e12023-11-15 11:20:53 -080086}
87
88type ModuleBuildParams BuildParams
89
90type ModuleContext interface {
91 BaseModuleContext
92
Colin Cross1496fb12024-09-09 16:44:10 -070093 // BlueprintModuleContext returns the blueprint.ModuleContext that the ModuleContext wraps. It may only be
94 // used by the golang module types that need to call into the bootstrap module types.
95 BlueprintModuleContext() blueprint.ModuleContext
Colin Cross69452e12023-11-15 11:20:53 -080096
97 // Deprecated: use ModuleContext.Build instead.
98 ModuleBuild(pctx PackageContext, params ModuleBuildParams)
99
100 // Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
101 // be tagged with `android:"path" to support automatic source module dependency resolution.
102 //
103 // Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
104 ExpandSources(srcFiles, excludes []string) Paths
105
106 // Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
107 // be tagged with `android:"path" to support automatic source module dependency resolution.
108 //
109 // Deprecated: use PathForModuleSrc instead.
110 ExpandSource(srcFile, prop string) Path
111
112 ExpandOptionalSource(srcFile *string, prop string) OptionalPath
113
114 // InstallExecutable creates a rule to copy srcPath to name in the installPath directory,
115 // with the given additional dependencies. The file is marked executable after copying.
116 //
Yu Liubad1eef2024-08-21 22:37:35 +0000117 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
118 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
119 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
120 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800121 InstallExecutable(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800122
123 // InstallFile creates a rule to copy srcPath to name in the installPath directory,
124 // with the given additional dependencies.
125 //
Yu Liubad1eef2024-08-21 22:37:35 +0000126 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
127 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
128 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
129 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800130 InstallFile(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800131
Colin Crossa6182ab2024-08-21 10:47:44 -0700132 // InstallFileWithoutCheckbuild creates a rule to copy srcPath to name in the installPath directory,
133 // with the given additional dependencies, but does not add the file to the list of files to build
134 // during `m checkbuild`.
135 //
136 // The installed file will be returned by FilesToInstall(), and the PackagingSpec for the
137 // installed file will be returned by PackagingSpecs() on this module or by
138 // TransitivePackagingSpecs() on modules that depend on this module through dependency tags
139 // for which IsInstallDepNeeded returns true.
140 InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path, deps ...InstallPath) InstallPath
141
Colin Cross69452e12023-11-15 11:20:53 -0800142 // InstallFileWithExtraFilesZip creates a rule to copy srcPath to name in the installPath
143 // directory, and also unzip a zip file containing extra files to install into the same
144 // directory.
145 //
Yu Liubad1eef2024-08-21 22:37:35 +0000146 // The installed file can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
147 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
148 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
149 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross09ad3a62023-11-15 12:29:33 -0800150 InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path, extraZip Path, deps ...InstallPath) InstallPath
Colin Cross69452e12023-11-15 11:20:53 -0800151
152 // InstallSymlink creates a rule to create a symlink from src srcPath to name in the installPath
153 // directory.
154 //
Yu Liubad1eef2024-08-21 22:37:35 +0000155 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
156 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
157 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
158 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800159 InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath
160
161 // InstallAbsoluteSymlink creates a rule to create an absolute symlink from src srcPath to name
162 // in the installPath directory.
163 //
Yu Liubad1eef2024-08-21 22:37:35 +0000164 // The installed symlink can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
165 // for the installed file can be accessed by InstallFilesInfo.PackagingSpecs on this module
166 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
167 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800168 InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath
169
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800170 // InstallTestData creates rules to install test data (e.g. data files used during a test) into
171 // the installPath directory.
172 //
Yu Liubad1eef2024-08-21 22:37:35 +0000173 // The installed files can be accessed by InstallFilesInfo.InstallFiles, and the PackagingSpec
174 // for the installed files can be accessed by InstallFilesInfo.PackagingSpecs on this module
175 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
176 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800177 InstallTestData(installPath InstallPath, data []DataPath) InstallPaths
178
Colin Cross69452e12023-11-15 11:20:53 -0800179 // PackageFile creates a PackagingSpec as if InstallFile was called, but without creating
180 // the rule to copy the file. This is useful to define how a module would be packaged
181 // without installing it into the global installation directories.
182 //
Yu Liubad1eef2024-08-21 22:37:35 +0000183 // The created PackagingSpec can be accessed by InstallFilesInfo.PackagingSpecs on this module
184 // or by InstallFilesInfo.TransitivePackagingSpecs on modules that depend on this module through
185 // dependency tags for which IsInstallDepNeeded returns true.
Colin Cross69452e12023-11-15 11:20:53 -0800186 PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec
187
Colin Crossa6182ab2024-08-21 10:47:44 -0700188 CheckbuildFile(srcPaths ...Path)
189 UncheckedModule()
Colin Cross69452e12023-11-15 11:20:53 -0800190
191 InstallInData() bool
192 InstallInTestcases() bool
193 InstallInSanitizerDir() bool
194 InstallInRamdisk() bool
195 InstallInVendorRamdisk() bool
196 InstallInDebugRamdisk() bool
197 InstallInRecovery() bool
198 InstallInRoot() bool
Colin Crossea30d852023-11-29 16:00:16 -0800199 InstallInOdm() bool
200 InstallInProduct() bool
Colin Cross69452e12023-11-15 11:20:53 -0800201 InstallInVendor() bool
Spandan Das27ff7672024-11-06 19:23:57 +0000202 InstallInSystemDlkm() bool
203 InstallInVendorDlkm() bool
204 InstallInOdmDlkm() bool
Colin Cross69452e12023-11-15 11:20:53 -0800205 InstallForceOS() (*OsType, *ArchType)
206
Cole Fauste8a87832024-09-11 11:35:46 -0700207 RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
Colin Cross69452e12023-11-15 11:20:53 -0800208 HostRequiredModuleNames() []string
209 TargetRequiredModuleNames() []string
210
211 ModuleSubDir() string
Colin Cross69452e12023-11-15 11:20:53 -0800212
213 Variable(pctx PackageContext, name, value string)
214 Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
215 // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
216 // and performs more verification.
217 Build(pctx PackageContext, params BuildParams)
218 // Phony creates a Make-style phony rule, a rule with no commands that can depend on other
219 // phony rules or real files. Phony can be called on the same name multiple times to add
220 // additional dependencies.
221 Phony(phony string, deps ...Path)
222
223 // GetMissingDependencies returns the list of dependencies that were passed to AddDependencies or related methods,
224 // but do not exist.
225 GetMissingDependencies() []string
226
227 // LicenseMetadataFile returns the path where the license metadata for this module will be
228 // generated.
229 LicenseMetadataFile() Path
Colin Crossd6fd0132023-11-06 13:54:06 -0800230
231 // ModuleInfoJSON returns a pointer to the ModuleInfoJSON struct that can be filled out by
232 // GenerateAndroidBuildActions. If it is called then the struct will be written out and included in
233 // the module-info.json generated by Make, and Make will not generate its own data for this module.
234 ModuleInfoJSON() *ModuleInfoJSON
mrziwange6c85812024-05-22 14:36:09 -0700235
Jihoon Kangd4063812025-01-24 00:25:30 +0000236 // Simiar to ModuleInfoJSON, ExtraModuleInfoJSON also returns a pointer to the ModuleInfoJSON struct.
237 // This should only be called by a module that generates multiple AndroidMkEntries struct.
238 ExtraModuleInfoJSON() *ModuleInfoJSON
239
mrziwange6c85812024-05-22 14:36:09 -0700240 // SetOutputFiles stores the outputFiles to outputFiles property, which is used
241 // to set the OutputFilesProvider later.
242 SetOutputFiles(outputFiles Paths, tag string)
Wei Lia1aa2972024-06-21 13:08:51 -0700243
Yu Liu876b7ce2024-08-21 18:20:13 +0000244 GetOutputFiles() OutputFilesInfo
245
Yu Liubad1eef2024-08-21 22:37:35 +0000246 // SetLicenseInstallMap stores the set of dependency module:location mappings for files in an
247 // apex container for use when generation the license metadata file.
248 SetLicenseInstallMap(installMap []string)
249
Wei Lia1aa2972024-06-21 13:08:51 -0700250 // ComplianceMetadataInfo returns a ComplianceMetadataInfo instance for different module types to dump metadata,
251 // which usually happens in GenerateAndroidBuildActions() of a module type.
252 // See android.ModuleBase.complianceMetadataInfo
253 ComplianceMetadataInfo() *ComplianceMetadataInfo
Yu Liu9a993132024-08-27 23:21:06 +0000254
255 // Get the information about the containers this module belongs to.
256 getContainersInfo() ContainersInfo
257 setContainersInfo(info ContainersInfo)
258
259 setAconfigPaths(paths Paths)
Cole Faustd62a4892025-02-07 16:55:11 -0800260
261 // DistForGoals creates a rule to copy one or more Paths to the artifacts
262 // directory on the build server when any of the specified goals are built.
263 DistForGoal(goal string, paths ...Path)
264
265 // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
266 // directory on the build server with the given filename when the specified
267 // goal is built.
268 DistForGoalWithFilename(goal string, path Path, filename string)
269
270 // DistForGoals creates a rule to copy one or more Paths to the artifacts
271 // directory on the build server when any of the specified goals are built.
272 DistForGoals(goals []string, paths ...Path)
273
274 // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
275 // directory on the build server with the given filename when any of the
276 // specified goals are built.
277 DistForGoalsWithFilename(goals []string, path Path, filename string)
Colin Cross69452e12023-11-15 11:20:53 -0800278}
279
280type moduleContext struct {
281 bp blueprint.ModuleContext
282 baseModuleContext
Colin Crossa6182ab2024-08-21 10:47:44 -0700283 packagingSpecs []PackagingSpec
284 installFiles InstallPaths
285 checkbuildFiles Paths
286 checkbuildTarget Path
287 uncheckedModule bool
288 module Module
289 phonies map[string]Paths
Yu Liu876b7ce2024-08-21 18:20:13 +0000290 // outputFiles stores the output of a module by tag and is used to set
291 // the OutputFilesProvider in GenerateBuildActions
292 outputFiles OutputFilesInfo
Colin Cross69452e12023-11-15 11:20:53 -0800293
Colin Crossa14fb6a2024-10-23 16:57:06 -0700294 TransitiveInstallFiles depset.DepSet[InstallPath]
Yu Liubad1eef2024-08-21 22:37:35 +0000295
296 // set of dependency module:location mappings used to populate the license metadata for
297 // apex containers.
298 licenseInstallMap []string
299
Yu Liuec810542024-08-26 18:09:15 +0000300 // The path to the generated license metadata file for the module.
301 licenseMetadataFile WritablePath
302
Yu Liud46e5ae2024-08-15 18:46:17 +0000303 katiInstalls katiInstalls
304 katiSymlinks katiInstalls
Yu Liu82a6d142024-08-27 19:02:29 +0000305 // katiInitRcInstalls and katiVintfInstalls track the install rules created by Soong that are
306 // allowed to have duplicates across modules and variants.
307 katiInitRcInstalls katiInstalls
308 katiVintfInstalls katiInstalls
309 initRcPaths Paths
310 vintfFragmentsPaths Paths
311 installedInitRcPaths InstallPaths
312 installedVintfFragmentsPaths InstallPaths
Colin Cross69452e12023-11-15 11:20:53 -0800313
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800314 testData []DataPath
315
Colin Cross69452e12023-11-15 11:20:53 -0800316 // For tests
317 buildParams []BuildParams
318 ruleParams map[blueprint.Rule]blueprint.RuleParams
319 variables map[string]string
Yu Liu4297ad92024-08-27 19:50:13 +0000320
321 // moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
322 // be included in the final module-info.json produced by Make.
Jihoon Kangd4063812025-01-24 00:25:30 +0000323 moduleInfoJSON []*ModuleInfoJSON
Yu Liu9a993132024-08-27 23:21:06 +0000324
325 // containersInfo stores the information about the containers and the information of the
326 // apexes the module belongs to.
327 containersInfo ContainersInfo
328
329 // Merged Aconfig files for all transitive deps.
330 aconfigFilePaths Paths
331
332 // complianceMetadataInfo is for different module types to dump metadata.
333 // See android.ModuleContext interface.
334 complianceMetadataInfo *ComplianceMetadataInfo
Cole Faustd62a4892025-02-07 16:55:11 -0800335
336 dists []dist
Colin Cross69452e12023-11-15 11:20:53 -0800337}
338
Cole Faust02987bd2024-03-21 17:58:43 -0700339var _ ModuleContext = &moduleContext{}
340
Colin Cross69452e12023-11-15 11:20:53 -0800341func (m *moduleContext) ninjaError(params BuildParams, err error) (PackageContext, BuildParams) {
342 return pctx, BuildParams{
343 Rule: ErrorRule,
344 Description: params.Description,
345 Output: params.Output,
346 Outputs: params.Outputs,
347 ImplicitOutput: params.ImplicitOutput,
348 ImplicitOutputs: params.ImplicitOutputs,
349 Args: map[string]string{
350 "error": err.Error(),
351 },
352 }
353}
354
355func (m *moduleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
356 m.Build(pctx, BuildParams(params))
357}
358
Colin Cross69452e12023-11-15 11:20:53 -0800359// Convert build parameters from their concrete Android types into their string representations,
360// and combine the singular and plural fields of the same type (e.g. Output and Outputs).
361func convertBuildParams(params BuildParams) blueprint.BuildParams {
362 bparams := blueprint.BuildParams{
363 Rule: params.Rule,
364 Description: params.Description,
365 Deps: params.Deps,
366 Outputs: params.Outputs.Strings(),
367 ImplicitOutputs: params.ImplicitOutputs.Strings(),
Colin Cross69452e12023-11-15 11:20:53 -0800368 Inputs: params.Inputs.Strings(),
369 Implicits: params.Implicits.Strings(),
370 OrderOnly: params.OrderOnly.Strings(),
371 Validations: params.Validations.Strings(),
372 Args: params.Args,
Cole Faust451912d2025-01-10 11:21:18 -0800373 Default: params.Default,
LaMont Jones53915542025-02-12 15:33:13 -0800374 PhonyOutput: params.PhonyOutput,
Colin Cross69452e12023-11-15 11:20:53 -0800375 }
376
377 if params.Depfile != nil {
378 bparams.Depfile = params.Depfile.String()
379 }
380 if params.Output != nil {
381 bparams.Outputs = append(bparams.Outputs, params.Output.String())
382 }
Colin Cross69452e12023-11-15 11:20:53 -0800383 if params.ImplicitOutput != nil {
384 bparams.ImplicitOutputs = append(bparams.ImplicitOutputs, params.ImplicitOutput.String())
385 }
386 if params.Input != nil {
387 bparams.Inputs = append(bparams.Inputs, params.Input.String())
388 }
389 if params.Implicit != nil {
390 bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
391 }
392 if params.Validation != nil {
393 bparams.Validations = append(bparams.Validations, params.Validation.String())
394 }
395
396 bparams.Outputs = proptools.NinjaEscapeList(bparams.Outputs)
397 bparams.ImplicitOutputs = proptools.NinjaEscapeList(bparams.ImplicitOutputs)
Colin Cross69452e12023-11-15 11:20:53 -0800398 bparams.Inputs = proptools.NinjaEscapeList(bparams.Inputs)
399 bparams.Implicits = proptools.NinjaEscapeList(bparams.Implicits)
400 bparams.OrderOnly = proptools.NinjaEscapeList(bparams.OrderOnly)
401 bparams.Validations = proptools.NinjaEscapeList(bparams.Validations)
402 bparams.Depfile = proptools.NinjaEscape(bparams.Depfile)
403
404 return bparams
405}
406
407func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
408 if m.config.captureBuild {
409 m.variables[name] = value
410 }
411
412 m.bp.Variable(pctx.PackageContext, name, value)
413}
414
415func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
416 argNames ...string) blueprint.Rule {
417
418 if m.config.UseRemoteBuild() {
419 if params.Pool == nil {
420 // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
421 // jobs to the local parallelism value
422 params.Pool = localPool
423 } else if params.Pool == remotePool {
424 // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
425 // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
426 // parallelism.
427 params.Pool = nil
428 }
429 }
430
431 rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
432
433 if m.config.captureBuild {
434 m.ruleParams[rule] = params
435 }
436
437 return rule
438}
439
440func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
441 if params.Description != "" {
442 params.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
443 }
444
445 if missingDeps := m.GetMissingDependencies(); len(missingDeps) > 0 {
446 pctx, params = m.ninjaError(params, fmt.Errorf("module %s missing dependencies: %s\n",
447 m.ModuleName(), strings.Join(missingDeps, ", ")))
448 }
449
450 if m.config.captureBuild {
451 m.buildParams = append(m.buildParams, params)
452 }
453
454 bparams := convertBuildParams(params)
Colin Cross69452e12023-11-15 11:20:53 -0800455 m.bp.Build(pctx.PackageContext, bparams)
456}
457
458func (m *moduleContext) Phony(name string, deps ...Path) {
Yu Liu54513622024-08-19 20:00:32 +0000459 m.phonies[name] = append(m.phonies[name], deps...)
Colin Cross69452e12023-11-15 11:20:53 -0800460}
461
462func (m *moduleContext) GetMissingDependencies() []string {
463 var missingDeps []string
464 missingDeps = append(missingDeps, m.Module().base().commonProperties.MissingDeps...)
465 missingDeps = append(missingDeps, m.bp.GetMissingDependencies()...)
466 missingDeps = FirstUniqueStrings(missingDeps)
467 return missingDeps
468}
469
Yu Liud3228ac2024-11-08 23:11:47 +0000470func (m *moduleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) Module {
Yu Liu3ae96652024-12-17 22:27:38 +0000471 deps := m.getDirectDepsInternal(name, tag)
472 if len(deps) == 1 {
473 return deps[0]
474 } else if len(deps) >= 2 {
475 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
476 name, m.ModuleName()))
477 } else {
478 return nil
Yu Liud3228ac2024-11-08 23:11:47 +0000479 }
Yu Liu3ae96652024-12-17 22:27:38 +0000480}
481
482func (m *moduleContext) GetDirectDepProxyWithTag(name string, tag blueprint.DependencyTag) *ModuleProxy {
483 deps := m.getDirectDepsProxyInternal(name, tag)
484 if len(deps) == 1 {
485 return &deps[0]
486 } else if len(deps) >= 2 {
487 panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
488 name, m.ModuleName()))
489 } else {
490 return nil
491 }
Colin Cross69452e12023-11-15 11:20:53 -0800492}
493
494func (m *moduleContext) ModuleSubDir() string {
495 return m.bp.ModuleSubDir()
496}
497
Colin Cross69452e12023-11-15 11:20:53 -0800498func (m *moduleContext) InstallInData() bool {
499 return m.module.InstallInData()
500}
501
502func (m *moduleContext) InstallInTestcases() bool {
503 return m.module.InstallInTestcases()
504}
505
506func (m *moduleContext) InstallInSanitizerDir() bool {
507 return m.module.InstallInSanitizerDir()
508}
509
510func (m *moduleContext) InstallInRamdisk() bool {
511 return m.module.InstallInRamdisk()
512}
513
514func (m *moduleContext) InstallInVendorRamdisk() bool {
515 return m.module.InstallInVendorRamdisk()
516}
517
518func (m *moduleContext) InstallInDebugRamdisk() bool {
519 return m.module.InstallInDebugRamdisk()
520}
521
522func (m *moduleContext) InstallInRecovery() bool {
523 return m.module.InstallInRecovery()
524}
525
526func (m *moduleContext) InstallInRoot() bool {
527 return m.module.InstallInRoot()
528}
529
530func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) {
531 return m.module.InstallForceOS()
532}
533
Colin Crossea30d852023-11-29 16:00:16 -0800534func (m *moduleContext) InstallInOdm() bool {
535 return m.module.InstallInOdm()
536}
537
538func (m *moduleContext) InstallInProduct() bool {
539 return m.module.InstallInProduct()
540}
541
Colin Cross69452e12023-11-15 11:20:53 -0800542func (m *moduleContext) InstallInVendor() bool {
543 return m.module.InstallInVendor()
544}
545
Spandan Das27ff7672024-11-06 19:23:57 +0000546func (m *moduleContext) InstallInSystemDlkm() bool {
547 return m.module.InstallInSystemDlkm()
548}
549
550func (m *moduleContext) InstallInVendorDlkm() bool {
551 return m.module.InstallInVendorDlkm()
552}
553
554func (m *moduleContext) InstallInOdmDlkm() bool {
555 return m.module.InstallInOdmDlkm()
556}
557
Colin Cross69452e12023-11-15 11:20:53 -0800558func (m *moduleContext) skipInstall() bool {
559 if m.module.base().commonProperties.SkipInstall {
560 return true
561 }
562
Colin Cross69452e12023-11-15 11:20:53 -0800563 // We'll need a solution for choosing which of modules with the same name in different
564 // namespaces to install. For now, reuse the list of namespaces exported to Make as the
565 // list of namespaces to install in a Soong-only build.
566 if !m.module.base().commonProperties.NamespaceExportedToMake {
567 return true
568 }
569
570 return false
571}
572
Jiyong Park3f627e62024-05-01 16:14:38 +0900573// Tells whether this module is installed to the full install path (ex:
574// out/target/product/<name>/<partition>) or not. If this returns false, the install build rule is
575// not created and this module can only be installed to packaging modules like android_filesystem.
576func (m *moduleContext) requiresFullInstall() bool {
577 if m.skipInstall() {
578 return false
579 }
580
Spandan Das034af2c2024-10-30 21:45:09 +0000581 if m.module.base().commonProperties.HideFromMake {
582 return false
583 }
584
Jiyong Park3f627e62024-05-01 16:14:38 +0900585 if proptools.Bool(m.module.base().commonProperties.No_full_install) {
586 return false
587 }
588
589 return true
590}
591
Colin Cross69452e12023-11-15 11:20:53 -0800592func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800593 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700594 return m.installFile(installPath, name, srcPath, deps, false, true, true, nil)
595}
596
597func (m *moduleContext) InstallFileWithoutCheckbuild(installPath InstallPath, name string, srcPath Path,
598 deps ...InstallPath) InstallPath {
599 return m.installFile(installPath, name, srcPath, deps, false, true, false, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800600}
601
602func (m *moduleContext) InstallExecutable(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800603 deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700604 return m.installFile(installPath, name, srcPath, deps, true, true, true, nil)
Colin Cross69452e12023-11-15 11:20:53 -0800605}
606
607func (m *moduleContext) InstallFileWithExtraFilesZip(installPath InstallPath, name string, srcPath Path,
Colin Cross09ad3a62023-11-15 12:29:33 -0800608 extraZip Path, deps ...InstallPath) InstallPath {
Colin Crossa6182ab2024-08-21 10:47:44 -0700609 return m.installFile(installPath, name, srcPath, deps, false, true, true, &extraFilesZip{
Colin Cross69452e12023-11-15 11:20:53 -0800610 zip: extraZip,
611 dir: installPath,
612 })
613}
614
615func (m *moduleContext) PackageFile(installPath InstallPath, name string, srcPath Path) PackagingSpec {
616 fullInstallPath := installPath.Join(m, name)
Cole Faust19fbb072025-01-30 18:19:29 -0800617 return m.packageFile(fullInstallPath, srcPath, false, false)
Colin Cross69452e12023-11-15 11:20:53 -0800618}
619
Colin Crossf0c1ede2025-01-23 13:30:36 -0800620func (m *moduleContext) getAconfigPaths() Paths {
621 return m.aconfigFilePaths
Yu Liu9a993132024-08-27 23:21:06 +0000622}
623
624func (m *moduleContext) setAconfigPaths(paths Paths) {
625 m.aconfigFilePaths = paths
Justin Yun74f3f302024-05-07 14:32:14 +0900626}
627
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000628func (m *moduleContext) getOwnerAndOverrides() (string, []string) {
629 owner := m.ModuleName()
630 overrides := slices.Clone(m.Module().base().commonProperties.Overrides)
631 if b, ok := m.Module().(OverridableModule); ok {
632 if b.GetOverriddenBy() != "" {
633 // overriding variant of base module
634 overrides = append(overrides, m.ModuleName()) // com.android.foo
635 owner = m.Module().Name() // com.company.android.foo
636 }
637 }
638 return owner, overrides
639}
640
Cole Faust19fbb072025-01-30 18:19:29 -0800641func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool, requiresFullInstall bool) PackagingSpec {
Colin Cross69452e12023-11-15 11:20:53 -0800642 licenseFiles := m.Module().EffectiveLicenseFiles()
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000643 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800644 spec := PackagingSpec{
645 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
646 srcPath: srcPath,
647 symlinkTarget: "",
648 executable: executable,
Colin Crossf0c1ede2025-01-23 13:30:36 -0800649 effectiveLicenseFiles: uniquelist.Make(licenseFiles),
Colin Cross69452e12023-11-15 11:20:53 -0800650 partition: fullInstallPath.partition,
Jiyong Park4152b192024-04-30 21:24:21 +0900651 skipInstall: m.skipInstall(),
Colin Crossf0c1ede2025-01-23 13:30:36 -0800652 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
Jiyong Parkc6a773d2024-05-14 21:49:11 +0900653 archType: m.target.Arch.ArchType,
Jihoon Kangd4063812025-01-24 00:25:30 +0000654 overrides: uniquelist.Make(overrides),
655 owner: owner,
Cole Faust19fbb072025-01-30 18:19:29 -0800656 requiresFullInstall: requiresFullInstall,
657 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800658 }
659 m.packagingSpecs = append(m.packagingSpecs, spec)
660 return spec
661}
662
Colin Cross09ad3a62023-11-15 12:29:33 -0800663func (m *moduleContext) installFile(installPath InstallPath, name string, srcPath Path, deps []InstallPath,
Colin Crossa6182ab2024-08-21 10:47:44 -0700664 executable bool, hooks bool, checkbuild bool, extraZip *extraFilesZip) InstallPath {
Spandan Dasd718aa52025-02-04 21:18:36 +0000665 if _, ok := srcPath.(InstallPath); ok {
666 m.ModuleErrorf("Src path cannot be another installed file. Please use a path from source or intermediates instead.")
667 }
Colin Cross69452e12023-11-15 11:20:53 -0800668
669 fullInstallPath := installPath.Join(m, name)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800670 if hooks {
671 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
672 }
Colin Cross69452e12023-11-15 11:20:53 -0800673
Jiyong Park3f627e62024-05-01 16:14:38 +0900674 if m.requiresFullInstall() {
Yu Liubad1eef2024-08-21 22:37:35 +0000675 deps = append(deps, InstallPaths(m.TransitiveInstallFiles.ToList())...)
Cole Faust74d243c2024-12-11 17:57:34 -0800676 if m.config.KatiEnabled() {
677 deps = append(deps, m.installedInitRcPaths...)
678 deps = append(deps, m.installedVintfFragmentsPaths...)
679 }
Colin Cross69452e12023-11-15 11:20:53 -0800680
681 var implicitDeps, orderOnlyDeps Paths
682
683 if m.Host() {
684 // Installed host modules might be used during the build, depend directly on their
685 // dependencies so their timestamp is updated whenever their dependency is updated
Colin Cross09ad3a62023-11-15 12:29:33 -0800686 implicitDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800687 } else {
Colin Cross09ad3a62023-11-15 12:29:33 -0800688 orderOnlyDeps = InstallPaths(deps).Paths()
Colin Cross69452e12023-11-15 11:20:53 -0800689 }
690
Cole Faust866ab392025-01-23 12:56:20 -0800691 // When creating the install rule in Soong but embedding in Make, write the rule to a
692 // makefile instead of directly to the ninja file so that main.mk can add the
693 // dependencies from the `required` property that are hard to resolve in Soong.
694 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
695 // such as module-info.json or compliance, but it will not be used for actually installing
696 // the file.
697 m.katiInstalls = append(m.katiInstalls, katiInstall{
698 from: srcPath,
699 to: fullInstallPath,
700 implicitDeps: implicitDeps,
701 orderOnlyDeps: orderOnlyDeps,
702 executable: executable,
703 extraFiles: extraZip,
704 })
705 if !m.Config().KatiEnabled() {
Spandan Das4d78e012025-01-22 23:25:39 +0000706 rule := CpWithBash
Colin Cross69452e12023-11-15 11:20:53 -0800707 if executable {
Spandan Das4d78e012025-01-22 23:25:39 +0000708 rule = CpExecutableWithBash
Colin Cross69452e12023-11-15 11:20:53 -0800709 }
710
711 extraCmds := ""
712 if extraZip != nil {
713 extraCmds += fmt.Sprintf(" && ( unzip -qDD -d '%s' '%s' 2>&1 | grep -v \"zipfile is empty\"; exit $${PIPESTATUS[0]} )",
714 extraZip.dir.String(), extraZip.zip.String())
715 extraCmds += " || ( code=$$?; if [ $$code -ne 0 -a $$code -ne 1 ]; then exit $$code; fi )"
716 implicitDeps = append(implicitDeps, extraZip.zip)
717 }
718
Cole Fauste3845052025-02-13 12:45:35 -0800719 var cpFlags = "-f"
720
721 // If this is a device file, copy while preserving timestamps. This is to support
722 // adb sync in soong-only builds. Because soong-only builds have 2 different staging
723 // directories, the out/target/product one and the out/soong/.intermediates one,
724 // we need to ensure the files in them have the same timestamps so that adb sync doesn't
725 // update the files on device.
726 if strings.Contains(fullInstallPath.String(), "target/product") {
727 cpFlags += " -p"
728 }
729
Colin Cross69452e12023-11-15 11:20:53 -0800730 m.Build(pctx, BuildParams{
731 Rule: rule,
732 Description: "install " + fullInstallPath.Base(),
733 Output: fullInstallPath,
734 Input: srcPath,
735 Implicits: implicitDeps,
736 OrderOnly: orderOnlyDeps,
Colin Cross69452e12023-11-15 11:20:53 -0800737 Args: map[string]string{
738 "extraCmds": extraCmds,
Cole Fauste3845052025-02-13 12:45:35 -0800739 "cpFlags": cpFlags,
Colin Cross69452e12023-11-15 11:20:53 -0800740 },
741 })
742 }
743
744 m.installFiles = append(m.installFiles, fullInstallPath)
745 }
746
Cole Faust19fbb072025-01-30 18:19:29 -0800747 m.packageFile(fullInstallPath, srcPath, executable, m.requiresFullInstall())
Colin Cross69452e12023-11-15 11:20:53 -0800748
Colin Crossa6182ab2024-08-21 10:47:44 -0700749 if checkbuild {
750 m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
751 }
Colin Cross69452e12023-11-15 11:20:53 -0800752
753 return fullInstallPath
754}
755
756func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, srcPath InstallPath) InstallPath {
757 fullInstallPath := installPath.Join(m, name)
758 m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, true)
759
760 relPath, err := filepath.Rel(path.Dir(fullInstallPath.String()), srcPath.String())
761 if err != nil {
762 panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
763 }
Jiyong Park3f627e62024-05-01 16:14:38 +0900764 if m.requiresFullInstall() {
Colin Cross69452e12023-11-15 11:20:53 -0800765
Cole Faust866ab392025-01-23 12:56:20 -0800766 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
767 // makefile instead of directly to the ninja file so that main.mk can add the
768 // dependencies from the `required` property that are hard to resolve in Soong.
769 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
770 // such as module-info.json or compliance, but it will not be used for actually installing
771 // the file.
772 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
773 from: srcPath,
774 to: fullInstallPath,
775 })
776 if !m.Config().KatiEnabled() {
Colin Cross69452e12023-11-15 11:20:53 -0800777 // The symlink doesn't need updating when the target is modified, but we sometimes
778 // have a dependency on a symlink to a binary instead of to the binary directly, and
779 // the mtime of the symlink must be updated when the binary is modified, so use a
780 // normal dependency here instead of an order-only dependency.
781 m.Build(pctx, BuildParams{
Spandan Das4d78e012025-01-22 23:25:39 +0000782 Rule: SymlinkWithBash,
Colin Cross69452e12023-11-15 11:20:53 -0800783 Description: "install symlink " + fullInstallPath.Base(),
784 Output: fullInstallPath,
785 Input: srcPath,
Colin Cross69452e12023-11-15 11:20:53 -0800786 Args: map[string]string{
787 "fromPath": relPath,
788 },
789 })
790 }
791
792 m.installFiles = append(m.installFiles, fullInstallPath)
Colin Cross69452e12023-11-15 11:20:53 -0800793 }
794
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000795 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800796 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
Cole Faust19fbb072025-01-30 18:19:29 -0800797 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
798 srcPath: nil,
799 symlinkTarget: relPath,
800 executable: false,
801 partition: fullInstallPath.partition,
802 skipInstall: m.skipInstall(),
803 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
804 archType: m.target.Arch.ArchType,
805 overrides: uniquelist.Make(overrides),
806 owner: owner,
807 requiresFullInstall: m.requiresFullInstall(),
808 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800809 })
810
811 return fullInstallPath
812}
813
814// installPath/name -> absPath where absPath might be a path that is available only at runtime
815// (e.g. /apex/...)
816func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name string, absPath string) InstallPath {
817 fullInstallPath := installPath.Join(m, name)
818 m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
819
Jiyong Park3f627e62024-05-01 16:14:38 +0900820 if m.requiresFullInstall() {
Cole Faust866ab392025-01-23 12:56:20 -0800821 // When creating the symlink rule in Soong but embedding in Make, write the rule to a
822 // makefile instead of directly to the ninja file so that main.mk can add the
823 // dependencies from the `required` property that are hard to resolve in Soong.
824 // In soong-only builds, the katiInstall will still be created for semi-legacy code paths
825 // such as module-info.json or compliance, but it will not be used for actually installing
826 // the file.
827 m.katiSymlinks = append(m.katiSymlinks, katiInstall{
828 absFrom: absPath,
829 to: fullInstallPath,
830 })
831 if !m.Config().KatiEnabled() {
Colin Cross69452e12023-11-15 11:20:53 -0800832 m.Build(pctx, BuildParams{
Cole Faust2526b482025-02-12 18:23:37 -0800833 Rule: SymlinkWithBash,
Colin Cross69452e12023-11-15 11:20:53 -0800834 Description: "install symlink " + fullInstallPath.Base() + " -> " + absPath,
835 Output: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800836 Args: map[string]string{
837 "fromPath": absPath,
838 },
839 })
840 }
841
842 m.installFiles = append(m.installFiles, fullInstallPath)
843 }
844
Spandan Dasc1ded7e2024-11-01 00:52:33 +0000845 owner, overrides := m.getOwnerAndOverrides()
Colin Cross69452e12023-11-15 11:20:53 -0800846 m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
Cole Faust19fbb072025-01-30 18:19:29 -0800847 relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
848 srcPath: nil,
849 symlinkTarget: absPath,
850 executable: false,
851 partition: fullInstallPath.partition,
852 skipInstall: m.skipInstall(),
853 aconfigPaths: uniquelist.Make(m.getAconfigPaths()),
854 archType: m.target.Arch.ArchType,
855 overrides: uniquelist.Make(overrides),
856 owner: owner,
857 requiresFullInstall: m.requiresFullInstall(),
858 fullInstallPath: fullInstallPath,
Colin Cross69452e12023-11-15 11:20:53 -0800859 })
860
861 return fullInstallPath
862}
863
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800864func (m *moduleContext) InstallTestData(installPath InstallPath, data []DataPath) InstallPaths {
865 m.testData = append(m.testData, data...)
866
867 ret := make(InstallPaths, 0, len(data))
868 for _, d := range data {
869 relPath := d.ToRelativeInstallPath()
Colin Crossa6182ab2024-08-21 10:47:44 -0700870 installed := m.installFile(installPath, relPath, d.SrcPath, nil, false, false, true, nil)
Colin Cross5c1d5fb2023-11-15 12:39:40 -0800871 ret = append(ret, installed)
872 }
873
874 return ret
875}
876
Colin Crossa6182ab2024-08-21 10:47:44 -0700877// CheckbuildFile specifies the output files that should be built by checkbuild.
878func (m *moduleContext) CheckbuildFile(srcPaths ...Path) {
879 m.checkbuildFiles = append(m.checkbuildFiles, srcPaths...)
880}
881
882// UncheckedModule marks the current module has having no files that should be built by checkbuild.
883func (m *moduleContext) UncheckedModule() {
884 m.uncheckedModule = true
Colin Cross69452e12023-11-15 11:20:53 -0800885}
886
Colin Cross1496fb12024-09-09 16:44:10 -0700887func (m *moduleContext) BlueprintModuleContext() blueprint.ModuleContext {
Colin Cross69452e12023-11-15 11:20:53 -0800888 return m.bp
889}
890
891func (m *moduleContext) LicenseMetadataFile() Path {
Yu Liuec810542024-08-26 18:09:15 +0000892 return m.licenseMetadataFile
Colin Cross69452e12023-11-15 11:20:53 -0800893}
894
Colin Crossd6fd0132023-11-06 13:54:06 -0800895func (m *moduleContext) ModuleInfoJSON() *ModuleInfoJSON {
Jihoon Kangd4063812025-01-24 00:25:30 +0000896 if len(m.moduleInfoJSON) == 0 {
897 moduleInfoJSON := &ModuleInfoJSON{}
898 m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -0800899 }
Jihoon Kangd4063812025-01-24 00:25:30 +0000900 return m.moduleInfoJSON[0]
901}
902
903func (m *moduleContext) ExtraModuleInfoJSON() *ModuleInfoJSON {
904 if len(m.moduleInfoJSON) == 0 {
905 panic("call ModuleInfoJSON() instead")
906 }
907
Colin Crossd6fd0132023-11-06 13:54:06 -0800908 moduleInfoJSON := &ModuleInfoJSON{}
Jihoon Kangd4063812025-01-24 00:25:30 +0000909 m.moduleInfoJSON = append(m.moduleInfoJSON, moduleInfoJSON)
Colin Crossd6fd0132023-11-06 13:54:06 -0800910 return moduleInfoJSON
911}
912
mrziwange6c85812024-05-22 14:36:09 -0700913func (m *moduleContext) SetOutputFiles(outputFiles Paths, tag string) {
Cole Faust5146e782024-11-15 14:47:49 -0800914 for _, outputFile := range outputFiles {
915 if outputFile == nil {
916 panic("outputfiles cannot be nil")
917 }
918 }
mrziwange6c85812024-05-22 14:36:09 -0700919 if tag == "" {
Yu Liu876b7ce2024-08-21 18:20:13 +0000920 if len(m.outputFiles.DefaultOutputFiles) > 0 {
mrziwange6c85812024-05-22 14:36:09 -0700921 m.ModuleErrorf("Module %s default OutputFiles cannot be overwritten", m.ModuleName())
922 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000923 m.outputFiles.DefaultOutputFiles = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700924 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000925 if m.outputFiles.TaggedOutputFiles == nil {
926 m.outputFiles.TaggedOutputFiles = make(map[string]Paths)
mrziwang57768d72024-06-06 11:31:51 -0700927 }
Yu Liu876b7ce2024-08-21 18:20:13 +0000928 if _, exists := m.outputFiles.TaggedOutputFiles[tag]; exists {
mrziwange6c85812024-05-22 14:36:09 -0700929 m.ModuleErrorf("Module %s OutputFiles at tag %s cannot be overwritten", m.ModuleName(), tag)
930 } else {
Yu Liu876b7ce2024-08-21 18:20:13 +0000931 m.outputFiles.TaggedOutputFiles[tag] = outputFiles
mrziwange6c85812024-05-22 14:36:09 -0700932 }
933 }
934}
935
Yu Liu876b7ce2024-08-21 18:20:13 +0000936func (m *moduleContext) GetOutputFiles() OutputFilesInfo {
937 return m.outputFiles
938}
939
Yu Liubad1eef2024-08-21 22:37:35 +0000940func (m *moduleContext) SetLicenseInstallMap(installMap []string) {
941 m.licenseInstallMap = append(m.licenseInstallMap, installMap...)
942}
943
Wei Lia1aa2972024-06-21 13:08:51 -0700944func (m *moduleContext) ComplianceMetadataInfo() *ComplianceMetadataInfo {
Yu Liu9a993132024-08-27 23:21:06 +0000945 if m.complianceMetadataInfo == nil {
946 m.complianceMetadataInfo = NewComplianceMetadataInfo()
Wei Lia1aa2972024-06-21 13:08:51 -0700947 }
Yu Liu9a993132024-08-27 23:21:06 +0000948 return m.complianceMetadataInfo
Wei Lia1aa2972024-06-21 13:08:51 -0700949}
950
Colin Cross69452e12023-11-15 11:20:53 -0800951// Returns a list of paths expanded from globs and modules referenced using ":module" syntax. The property must
952// be tagged with `android:"path" to support automatic source module dependency resolution.
953//
954// Deprecated: use PathsForModuleSrc or PathsForModuleSrcExcludes instead.
955func (m *moduleContext) ExpandSources(srcFiles, excludes []string) Paths {
956 return PathsForModuleSrcExcludes(m, srcFiles, excludes)
957}
958
959// Returns a single path expanded from globs and modules referenced using ":module" syntax. The property must
960// be tagged with `android:"path" to support automatic source module dependency resolution.
961//
962// Deprecated: use PathForModuleSrc instead.
963func (m *moduleContext) ExpandSource(srcFile, _ string) Path {
964 return PathForModuleSrc(m, srcFile)
965}
966
967// Returns an optional single path expanded from globs and modules referenced using ":module" syntax if
968// the srcFile is non-nil. The property must be tagged with `android:"path" to support automatic source module
969// dependency resolution.
970func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) OptionalPath {
971 if srcFile != nil {
972 return OptionalPathForPath(PathForModuleSrc(m, *srcFile))
973 }
974 return OptionalPath{}
975}
976
Cole Fauste8a87832024-09-11 11:35:46 -0700977func (m *moduleContext) RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string {
Cole Faust43ddd082024-06-17 12:32:40 -0700978 return m.module.RequiredModuleNames(ctx)
Colin Cross69452e12023-11-15 11:20:53 -0800979}
980
981func (m *moduleContext) HostRequiredModuleNames() []string {
982 return m.module.HostRequiredModuleNames()
983}
984
985func (m *moduleContext) TargetRequiredModuleNames() []string {
986 return m.module.TargetRequiredModuleNames()
987}
Yu Liu9a993132024-08-27 23:21:06 +0000988
989func (m *moduleContext) getContainersInfo() ContainersInfo {
990 return m.containersInfo
991}
992
993func (m *moduleContext) setContainersInfo(info ContainersInfo) {
994 m.containersInfo = info
995}
Cole Faustd62a4892025-02-07 16:55:11 -0800996
997func (c *moduleContext) DistForGoal(goal string, paths ...Path) {
998 c.DistForGoals([]string{goal}, paths...)
999}
1000
1001func (c *moduleContext) DistForGoalWithFilename(goal string, path Path, filename string) {
1002 c.DistForGoalsWithFilename([]string{goal}, path, filename)
1003}
1004
1005func (c *moduleContext) DistForGoals(goals []string, paths ...Path) {
1006 var copies distCopies
1007 for _, path := range paths {
1008 copies = append(copies, distCopy{
1009 from: path,
1010 dest: path.Base(),
1011 })
1012 }
1013 c.dists = append(c.dists, dist{
1014 goals: slices.Clone(goals),
1015 paths: copies,
1016 })
1017}
1018
1019func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
1020 c.dists = append(c.dists, dist{
1021 goals: slices.Clone(goals),
1022 paths: distCopies{{from: path, dest: filename}},
1023 })
1024}