blob: 7e8614031a5d68951d3c957752aafa45616cc044 [file] [log] [blame]
Dan Willemsen218f6562015-07-08 18:13:11 -07001// 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
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Dan Willemsen218f6562015-07-08 18:13:11 -070016
17import (
18 "bytes"
Dan Willemsen97750522016-02-09 17:43:51 -080019 "fmt"
Dan Willemsen218f6562015-07-08 18:13:11 -070020 "io"
21 "io/ioutil"
22 "os"
23 "path/filepath"
24 "sort"
Dan Willemsen0fda89f2016-06-01 15:25:32 -070025 "strings"
Dan Willemsen218f6562015-07-08 18:13:11 -070026
Dan Willemsen218f6562015-07-08 18:13:11 -070027 "github.com/google/blueprint"
Colin Cross2465c3d2018-09-28 10:19:18 -070028 "github.com/google/blueprint/bootstrap"
Dan Willemsen218f6562015-07-08 18:13:11 -070029)
30
31func init() {
Paul Duffin8c3fec42020-03-04 20:15:08 +000032 RegisterAndroidMkBuildComponents(InitRegistrationContext)
33}
34
35func RegisterAndroidMkBuildComponents(ctx RegistrationContext) {
36 ctx.RegisterSingletonType("androidmk", AndroidMkSingleton)
Dan Willemsen218f6562015-07-08 18:13:11 -070037}
38
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070039// Deprecated: consider using AndroidMkEntriesProvider instead, especially if you're not going to
40// use the Custom function.
Dan Willemsen218f6562015-07-08 18:13:11 -070041type AndroidMkDataProvider interface {
Colin Crossa18e9cf2017-08-10 17:00:19 -070042 AndroidMk() AndroidMkData
Colin Crossce75d2c2016-10-06 16:12:58 -070043 BaseModuleName() string
Dan Willemsen218f6562015-07-08 18:13:11 -070044}
45
46type AndroidMkData struct {
Sasha Smundakb6d23052019-04-01 18:37:36 -070047 Class string
48 SubName string
Jingwen Chen40fd90a2020-06-15 05:24:19 +000049 DistFiles TaggedDistFiles
Sasha Smundakb6d23052019-04-01 18:37:36 -070050 OutputFile OptionalPath
51 Disabled bool
52 Include string
53 Required []string
54 Host_required []string
55 Target_required []string
Dan Willemsen218f6562015-07-08 18:13:11 -070056
Colin Cross0f86d182017-08-10 17:07:28 -070057 Custom func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData)
Dan Willemsen218f6562015-07-08 18:13:11 -070058
Colin Cross27a4b052017-08-10 16:32:23 -070059 Extra []AndroidMkExtraFunc
Colin Cross0f86d182017-08-10 17:07:28 -070060
Jooyung Han2ed99d02020-06-24 23:26:26 +090061 Entries AndroidMkEntries
Dan Willemsen218f6562015-07-08 18:13:11 -070062}
63
Colin Cross27a4b052017-08-10 16:32:23 -070064type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
65
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070066// Allows modules to customize their Android*.mk output.
67type AndroidMkEntriesProvider interface {
Jiyong Park0b0e1b92019-12-03 13:24:29 +090068 AndroidMkEntries() []AndroidMkEntries
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070069 BaseModuleName() string
70}
71
72type AndroidMkEntries struct {
73 Class string
74 SubName string
Jingwen Chen40fd90a2020-06-15 05:24:19 +000075 DistFiles TaggedDistFiles
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070076 OutputFile OptionalPath
77 Disabled bool
78 Include string
79 Required []string
80 Host_required []string
81 Target_required []string
82
83 header bytes.Buffer
84 footer bytes.Buffer
85
Jaewoong Junge0dc8df2019-08-27 17:33:16 -070086 ExtraEntries []AndroidMkExtraEntriesFunc
Jaewoong Jungb0c127c2019-08-29 14:56:03 -070087 ExtraFooters []AndroidMkExtraFootersFunc
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070088
89 EntryMap map[string][]string
90 entryOrder []string
91}
92
Jaewoong Junge0dc8df2019-08-27 17:33:16 -070093type AndroidMkExtraEntriesFunc func(entries *AndroidMkEntries)
Jaewoong Jungb0c127c2019-08-29 14:56:03 -070094type AndroidMkExtraFootersFunc func(w io.Writer, name, prefix, moduleDir string, entries *AndroidMkEntries)
Jaewoong Junge0dc8df2019-08-27 17:33:16 -070095
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -070096func (a *AndroidMkEntries) SetString(name, value string) {
97 if _, ok := a.EntryMap[name]; !ok {
98 a.entryOrder = append(a.entryOrder, name)
99 }
100 a.EntryMap[name] = []string{value}
101}
102
Jaewoong Jung9a1e8bd2019-09-04 20:17:54 -0700103func (a *AndroidMkEntries) SetPath(name string, path Path) {
104 if _, ok := a.EntryMap[name]; !ok {
105 a.entryOrder = append(a.entryOrder, name)
106 }
107 a.EntryMap[name] = []string{path.String()}
108}
109
Colin Crossc0efd1d2020-07-03 11:56:24 -0700110func (a *AndroidMkEntries) SetOptionalPath(name string, path OptionalPath) {
111 if path.Valid() {
112 a.SetPath(name, path.Path())
113 }
114}
115
116func (a *AndroidMkEntries) AddPath(name string, path Path) {
117 if _, ok := a.EntryMap[name]; !ok {
118 a.entryOrder = append(a.entryOrder, name)
119 }
120 a.EntryMap[name] = append(a.EntryMap[name], path.String())
121}
122
123func (a *AndroidMkEntries) AddOptionalPath(name string, path OptionalPath) {
124 if path.Valid() {
125 a.AddPath(name, path.Path())
126 }
127}
128
Colin Cross08dca382020-07-21 20:31:17 -0700129func (a *AndroidMkEntries) SetPaths(name string, paths Paths) {
130 if _, ok := a.EntryMap[name]; !ok {
131 a.entryOrder = append(a.entryOrder, name)
132 }
133 a.EntryMap[name] = paths.Strings()
134}
135
136func (a *AndroidMkEntries) SetOptionalPaths(name string, paths Paths) {
137 if len(paths) > 0 {
138 a.SetPaths(name, paths)
139 }
140}
141
142func (a *AndroidMkEntries) AddPaths(name string, paths Paths) {
143 if _, ok := a.EntryMap[name]; !ok {
144 a.entryOrder = append(a.entryOrder, name)
145 }
146 a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
147}
148
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700149func (a *AndroidMkEntries) SetBoolIfTrue(name string, flag bool) {
150 if flag {
151 if _, ok := a.EntryMap[name]; !ok {
152 a.entryOrder = append(a.entryOrder, name)
153 }
154 a.EntryMap[name] = []string{"true"}
155 }
156}
157
Jaewoong Jung9a1e8bd2019-09-04 20:17:54 -0700158func (a *AndroidMkEntries) SetBool(name string, flag bool) {
159 if _, ok := a.EntryMap[name]; !ok {
160 a.entryOrder = append(a.entryOrder, name)
161 }
162 if flag {
163 a.EntryMap[name] = []string{"true"}
164 } else {
165 a.EntryMap[name] = []string{"false"}
166 }
167}
168
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700169func (a *AndroidMkEntries) AddStrings(name string, value ...string) {
170 if len(value) == 0 {
171 return
172 }
173 if _, ok := a.EntryMap[name]; !ok {
174 a.entryOrder = append(a.entryOrder, name)
175 }
176 a.EntryMap[name] = append(a.EntryMap[name], value...)
177}
178
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000179// Compute the list of Make strings to declare phone goals and dist-for-goals
180// calls from the module's dist and dists properties.
181func (a *AndroidMkEntries) GetDistForGoals(mod blueprint.Module) []string {
182 amod := mod.(Module).base()
183 name := amod.BaseModuleName()
184
185 var ret []string
186
187 availableTaggedDists := TaggedDistFiles{}
Jingwen Chen84811862020-07-21 11:32:19 +0000188 if a.DistFiles != nil {
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000189 availableTaggedDists = a.DistFiles
190 } else if a.OutputFile.Valid() {
191 availableTaggedDists = MakeDefaultDistFiles(a.OutputFile.Path())
192 }
193
194 // Iterate over this module's dist structs, merged from the dist and dists properties.
195 for _, dist := range amod.Dists() {
196 // Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
197 goals := strings.Join(dist.Targets, " ")
198
199 // Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
200 var tag string
201 if dist.Tag == nil {
202 // If the dist struct does not specify a tag, use the default output files tag.
203 tag = ""
204 } else {
205 tag = *dist.Tag
206 }
207
208 // Get the paths of the output files to be dist'd, represented by the tag.
209 // Can be an empty list.
210 tagPaths := availableTaggedDists[tag]
211 if len(tagPaths) == 0 {
212 // Nothing to dist for this tag, continue to the next dist.
213 continue
214 }
215
216 if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
217 errorMessage := "Cannot apply dest/suffix for more than one dist " +
218 "file for %s goals in module %s. The list of dist files, " +
219 "which should have a single element, is:\n%s"
220 panic(fmt.Errorf(errorMessage, goals, name, tagPaths))
221 }
222
223 ret = append(ret, fmt.Sprintf(".PHONY: %s\n", goals))
224
225 // Create dist-for-goals calls for each path in the dist'd files.
226 for _, path := range tagPaths {
227 // It's possible that the Path is nil from errant modules. Be defensive here.
228 if path == nil {
229 tagName := "default" // for error message readability
230 if dist.Tag != nil {
231 tagName = *dist.Tag
232 }
233 panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
234 }
235
236 dest := filepath.Base(path.String())
237
238 if dist.Dest != nil {
239 var err error
240 if dest, err = validateSafePath(*dist.Dest); err != nil {
241 // This was checked in ModuleBase.GenerateBuildActions
242 panic(err)
243 }
244 }
245
246 if dist.Suffix != nil {
247 ext := filepath.Ext(dest)
248 suffix := *dist.Suffix
249 dest = strings.TrimSuffix(dest, ext) + suffix + ext
250 }
251
252 if dist.Dir != nil {
253 var err error
254 if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
255 // This was checked in ModuleBase.GenerateBuildActions
256 panic(err)
257 }
258 }
259
260 ret = append(
261 ret,
262 fmt.Sprintf("$(call dist-for-goals,%s,%s:%s)\n", goals, path.String(), dest))
263 }
264 }
265
266 return ret
267}
268
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700269func (a *AndroidMkEntries) fillInEntries(config Config, bpPath string, mod blueprint.Module) {
270 a.EntryMap = make(map[string][]string)
271 amod := mod.(Module).base()
272 name := amod.BaseModuleName()
273
274 if a.Include == "" {
275 a.Include = "$(BUILD_PREBUILT)"
276 }
277 a.Required = append(a.Required, amod.commonProperties.Required...)
278 a.Host_required = append(a.Host_required, amod.commonProperties.Host_required...)
279 a.Target_required = append(a.Target_required, amod.commonProperties.Target_required...)
280
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000281 for _, distString := range a.GetDistForGoals(mod) {
282 fmt.Fprintf(&a.header, distString)
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700283 }
284
285 fmt.Fprintln(&a.header, "\ninclude $(CLEAR_VARS)")
286
287 // Collect make variable assignment entries.
288 a.SetString("LOCAL_PATH", filepath.Dir(bpPath))
289 a.SetString("LOCAL_MODULE", name+a.SubName)
290 a.SetString("LOCAL_MODULE_CLASS", a.Class)
291 a.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
292 a.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
293 a.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
294 a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
295
Jiyong Park89e850a2020-04-07 16:37:39 +0900296 if am, ok := mod.(ApexModule); ok {
297 a.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
298 }
299
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700300 archStr := amod.Arch().ArchType.String()
301 host := false
302 switch amod.Os().Class {
303 case Host:
304 // Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700305 if amod.Arch().ArchType != Common {
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700306 a.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
307 }
308 host = true
309 case HostCross:
310 // Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700311 if amod.Arch().ArchType != Common {
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700312 a.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
313 }
314 host = true
315 case Device:
316 // Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
Colin Cross0f7d2ef2019-10-16 11:03:10 -0700317 if amod.Arch().ArchType != Common {
dimitry1f33e402019-03-26 12:39:31 +0100318 if amod.Target().NativeBridge {
dimitry8d6dde82019-07-11 10:23:53 +0200319 hostArchStr := amod.Target().NativeBridgeHostArchName
dimitry1f33e402019-03-26 12:39:31 +0100320 if hostArchStr != "" {
321 a.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
322 }
323 } else {
324 a.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
325 }
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700326 }
327
328 a.AddStrings("LOCAL_INIT_RC", amod.commonProperties.Init_rc...)
329 a.AddStrings("LOCAL_VINTF_FRAGMENTS", amod.commonProperties.Vintf_fragments...)
330 a.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(amod.commonProperties.Proprietary))
331 if Bool(amod.commonProperties.Vendor) || Bool(amod.commonProperties.Soc_specific) {
332 a.SetString("LOCAL_VENDOR_MODULE", "true")
333 }
334 a.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(amod.commonProperties.Device_specific))
335 a.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(amod.commonProperties.Product_specific))
Justin Yund5f6c822019-06-25 16:47:17 +0900336 a.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(amod.commonProperties.System_ext_specific))
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700337 if amod.commonProperties.Owner != nil {
338 a.SetString("LOCAL_MODULE_OWNER", *amod.commonProperties.Owner)
339 }
340 }
341
Bob Badoura75b0572020-02-18 20:21:55 -0800342 if len(amod.noticeFiles) > 0 {
343 a.SetString("LOCAL_NOTICE_FILE", strings.Join(amod.noticeFiles.Strings(), " "))
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700344 }
345
346 if host {
347 makeOs := amod.Os().String()
348 if amod.Os() == Linux || amod.Os() == LinuxBionic {
349 makeOs = "linux"
350 }
351 a.SetString("LOCAL_MODULE_HOST_OS", makeOs)
352 a.SetString("LOCAL_IS_HOST_MODULE", "true")
353 }
354
355 prefix := ""
356 if amod.ArchSpecific() {
357 switch amod.Os().Class {
358 case Host:
359 prefix = "HOST_"
360 case HostCross:
361 prefix = "HOST_CROSS_"
362 case Device:
363 prefix = "TARGET_"
364
365 }
366
367 if amod.Arch().ArchType != config.Targets[amod.Os()][0].Arch.ArchType {
368 prefix = "2ND_" + prefix
369 }
370 }
Jaewoong Junge0dc8df2019-08-27 17:33:16 -0700371 for _, extra := range a.ExtraEntries {
372 extra(a)
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700373 }
374
375 // Write to footer.
376 fmt.Fprintln(&a.footer, "include "+a.Include)
Jaewoong Jungb0c127c2019-08-29 14:56:03 -0700377 blueprintDir := filepath.Dir(bpPath)
378 for _, footerFunc := range a.ExtraFooters {
379 footerFunc(&a.footer, name, prefix, blueprintDir, a)
380 }
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700381}
382
383func (a *AndroidMkEntries) write(w io.Writer) {
Jaewoong Jungb0c127c2019-08-29 14:56:03 -0700384 if a.Disabled {
385 return
386 }
387
388 if !a.OutputFile.Valid() {
389 return
390 }
391
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700392 w.Write(a.header.Bytes())
393 for _, name := range a.entryOrder {
394 fmt.Fprintln(w, name+" := "+strings.Join(a.EntryMap[name], " "))
395 }
396 w.Write(a.footer.Bytes())
397}
398
Jaewoong Jungb0c127c2019-08-29 14:56:03 -0700399func (a *AndroidMkEntries) FooterLinesForTests() []string {
400 return strings.Split(string(a.footer.Bytes()), "\n")
401}
402
Colin Cross0875c522017-11-28 17:34:01 -0800403func AndroidMkSingleton() Singleton {
Dan Willemsen218f6562015-07-08 18:13:11 -0700404 return &androidMkSingleton{}
405}
406
407type androidMkSingleton struct{}
408
Colin Cross0875c522017-11-28 17:34:01 -0800409func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
Colin Crossaabf6792017-11-29 00:27:14 -0800410 if !ctx.Config().EmbeddedInMake() {
Dan Willemsen5ba07e82015-12-11 13:51:06 -0800411 return
412 }
413
Colin Cross2465c3d2018-09-28 10:19:18 -0700414 var androidMkModulesList []blueprint.Module
Colin Cross4f6e4e62016-01-11 12:55:55 -0800415
Colin Cross2465c3d2018-09-28 10:19:18 -0700416 ctx.VisitAllModulesBlueprint(func(module blueprint.Module) {
Colin Cross0875c522017-11-28 17:34:01 -0800417 androidMkModulesList = append(androidMkModulesList, module)
Colin Cross4f6e4e62016-01-11 12:55:55 -0800418 })
Dan Willemsen218f6562015-07-08 18:13:11 -0700419
Colin Cross1ad81422019-01-14 12:47:35 -0800420 sort.SliceStable(androidMkModulesList, func(i, j int) bool {
421 return ctx.ModuleName(androidMkModulesList[i]) < ctx.ModuleName(androidMkModulesList[j])
422 })
Colin Crossd779da42015-12-17 18:00:23 -0800423
Dan Willemsen45133ac2018-03-09 21:22:06 -0800424 transMk := PathForOutput(ctx, "Android"+String(ctx.Config().productVariables.Make_suffix)+".mk")
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700425 if ctx.Failed() {
426 return
427 }
Dan Willemsen218f6562015-07-08 18:13:11 -0700428
Colin Cross988414c2020-01-11 01:11:46 +0000429 err := translateAndroidMk(ctx, absolutePath(transMk.String()), androidMkModulesList)
Dan Willemsen218f6562015-07-08 18:13:11 -0700430 if err != nil {
431 ctx.Errorf(err.Error())
432 }
433
Colin Cross0875c522017-11-28 17:34:01 -0800434 ctx.Build(pctx, BuildParams{
435 Rule: blueprint.Phony,
436 Output: transMk,
Dan Willemsen218f6562015-07-08 18:13:11 -0700437 })
438}
439
Colin Cross2465c3d2018-09-28 10:19:18 -0700440func translateAndroidMk(ctx SingletonContext, mkFile string, mods []blueprint.Module) error {
Dan Willemsen218f6562015-07-08 18:13:11 -0700441 buf := &bytes.Buffer{}
442
Dan Willemsen97750522016-02-09 17:43:51 -0800443 fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))")
Dan Willemsen218f6562015-07-08 18:13:11 -0700444
Dan Willemsen70e17fa2016-07-25 16:00:20 -0700445 type_stats := make(map[string]int)
Dan Willemsen218f6562015-07-08 18:13:11 -0700446 for _, mod := range mods {
447 err := translateAndroidMkModule(ctx, buf, mod)
448 if err != nil {
449 os.Remove(mkFile)
450 return err
451 }
Dan Willemsen70e17fa2016-07-25 16:00:20 -0700452
Colin Cross2465c3d2018-09-28 10:19:18 -0700453 if amod, ok := mod.(Module); ok && ctx.PrimaryModule(amod) == amod {
454 type_stats[ctx.ModuleType(amod)] += 1
Dan Willemsen70e17fa2016-07-25 16:00:20 -0700455 }
456 }
457
458 keys := []string{}
459 fmt.Fprintln(buf, "\nSTATS.SOONG_MODULE_TYPE :=")
460 for k := range type_stats {
461 keys = append(keys, k)
462 }
463 sort.Strings(keys)
464 for _, mod_type := range keys {
465 fmt.Fprintln(buf, "STATS.SOONG_MODULE_TYPE +=", mod_type)
466 fmt.Fprintf(buf, "STATS.SOONG_MODULE_TYPE.%s := %d\n", mod_type, type_stats[mod_type])
Dan Willemsen218f6562015-07-08 18:13:11 -0700467 }
468
469 // Don't write to the file if it hasn't changed
Colin Cross988414c2020-01-11 01:11:46 +0000470 if _, err := os.Stat(absolutePath(mkFile)); !os.IsNotExist(err) {
471 if data, err := ioutil.ReadFile(absolutePath(mkFile)); err == nil {
Dan Willemsen218f6562015-07-08 18:13:11 -0700472 matches := buf.Len() == len(data)
473
474 if matches {
475 for i, value := range buf.Bytes() {
476 if value != data[i] {
477 matches = false
478 break
479 }
480 }
481 }
482
483 if matches {
484 return nil
485 }
486 }
487 }
488
Colin Cross988414c2020-01-11 01:11:46 +0000489 return ioutil.WriteFile(absolutePath(mkFile), buf.Bytes(), 0666)
Dan Willemsen218f6562015-07-08 18:13:11 -0700490}
491
Colin Cross0875c522017-11-28 17:34:01 -0800492func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
Colin Cross953d3a22018-09-05 16:23:54 -0700493 defer func() {
494 if r := recover(); r != nil {
495 panic(fmt.Errorf("%s in translateAndroidMkModule for module %s variant %s",
496 r, ctx.ModuleName(mod), ctx.ModuleSubDir(mod)))
497 }
498 }()
499
Colin Cross2465c3d2018-09-28 10:19:18 -0700500 switch x := mod.(type) {
501 case AndroidMkDataProvider:
502 return translateAndroidModule(ctx, w, mod, x)
503 case bootstrap.GoBinaryTool:
504 return translateGoBinaryModule(ctx, w, mod, x)
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700505 case AndroidMkEntriesProvider:
506 return translateAndroidMkEntriesModule(ctx, w, mod, x)
Colin Cross2465c3d2018-09-28 10:19:18 -0700507 default:
Dan Willemsen218f6562015-07-08 18:13:11 -0700508 return nil
509 }
Colin Cross2465c3d2018-09-28 10:19:18 -0700510}
511
512func translateGoBinaryModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
513 goBinary bootstrap.GoBinaryTool) error {
514
515 name := ctx.ModuleName(mod)
516 fmt.Fprintln(w, ".PHONY:", name)
517 fmt.Fprintln(w, name+":", goBinary.InstallPath())
518 fmt.Fprintln(w, "")
519
520 return nil
521}
522
Jooyung Han12df5fb2019-07-11 16:18:47 +0900523func (data *AndroidMkData) fillInData(config Config, bpPath string, mod blueprint.Module) {
524 // Get the preamble content through AndroidMkEntries logic.
Jooyung Han2ed99d02020-06-24 23:26:26 +0900525 data.Entries = AndroidMkEntries{
Jooyung Han12df5fb2019-07-11 16:18:47 +0900526 Class: data.Class,
527 SubName: data.SubName,
Jingwen Chen40fd90a2020-06-15 05:24:19 +0000528 DistFiles: data.DistFiles,
Jooyung Han12df5fb2019-07-11 16:18:47 +0900529 OutputFile: data.OutputFile,
530 Disabled: data.Disabled,
531 Include: data.Include,
532 Required: data.Required,
533 Host_required: data.Host_required,
534 Target_required: data.Target_required,
535 }
Jooyung Han2ed99d02020-06-24 23:26:26 +0900536 data.Entries.fillInEntries(config, bpPath, mod)
Jooyung Han12df5fb2019-07-11 16:18:47 +0900537
538 // copy entries back to data since it is used in Custom
Jooyung Han2ed99d02020-06-24 23:26:26 +0900539 data.Required = data.Entries.Required
540 data.Host_required = data.Entries.Host_required
541 data.Target_required = data.Entries.Target_required
Jooyung Han12df5fb2019-07-11 16:18:47 +0900542}
543
Colin Cross2465c3d2018-09-28 10:19:18 -0700544func translateAndroidModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
545 provider AndroidMkDataProvider) error {
Dan Willemsen218f6562015-07-08 18:13:11 -0700546
Colin Cross635c3b02016-05-18 15:37:25 -0700547 amod := mod.(Module).base()
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700548 if shouldSkipAndroidMkProcessing(amod) {
Jeff Gaston088e29e2017-11-29 16:47:17 -0800549 return nil
550 }
551
Colin Cross91825d22017-08-10 16:59:47 -0700552 data := provider.AndroidMk()
Colin Cross53499412017-09-07 13:20:25 -0700553 if data.Include == "" {
554 data.Include = "$(BUILD_PREBUILT)"
555 }
556
Jooyung Han12df5fb2019-07-11 16:18:47 +0900557 data.fillInData(ctx.Config(), ctx.BlueprintFile(mod), mod)
Dan Willemsen01a405a2016-06-13 17:19:03 -0700558
Colin Cross0f86d182017-08-10 17:07:28 -0700559 prefix := ""
560 if amod.ArchSpecific() {
561 switch amod.Os().Class {
562 case Host:
563 prefix = "HOST_"
564 case HostCross:
565 prefix = "HOST_CROSS_"
566 case Device:
567 prefix = "TARGET_"
Colin Crossa2344662016-03-24 13:14:12 -0700568
Dan Willemsen218f6562015-07-08 18:13:11 -0700569 }
570
Dan Willemsen0ef639b2018-10-10 17:02:29 -0700571 if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
Colin Cross0f86d182017-08-10 17:07:28 -0700572 prefix = "2ND_" + prefix
573 }
Dan Willemsen218f6562015-07-08 18:13:11 -0700574 }
575
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700576 name := provider.BaseModuleName()
Colin Cross0f86d182017-08-10 17:07:28 -0700577 blueprintDir := filepath.Dir(ctx.BlueprintFile(mod))
578
579 if data.Custom != nil {
580 data.Custom(w, name, prefix, blueprintDir, data)
581 } else {
582 WriteAndroidMkData(w, data)
583 }
584
585 return nil
586}
587
588func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
589 if data.Disabled {
590 return
591 }
592
593 if !data.OutputFile.Valid() {
594 return
595 }
596
Jooyung Han2ed99d02020-06-24 23:26:26 +0900597 // write preamble via Entries
598 data.Entries.footer = bytes.Buffer{}
599 data.Entries.write(w)
Colin Cross0f86d182017-08-10 17:07:28 -0700600
Colin Crossca860ac2016-01-04 14:34:37 -0800601 for _, extra := range data.Extra {
Colin Cross27a4b052017-08-10 16:32:23 -0700602 extra(w, data.OutputFile.Path())
Dan Willemsen97750522016-02-09 17:43:51 -0800603 }
604
Colin Cross53499412017-09-07 13:20:25 -0700605 fmt.Fprintln(w, "include "+data.Include)
Dan Willemsen218f6562015-07-08 18:13:11 -0700606}
Sasha Smundakb6d23052019-04-01 18:37:36 -0700607
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700608func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, mod blueprint.Module,
609 provider AndroidMkEntriesProvider) error {
610 if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
611 return nil
Sasha Smundakb6d23052019-04-01 18:37:36 -0700612 }
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700613
Jiyong Park0b0e1b92019-12-03 13:24:29 +0900614 for _, entries := range provider.AndroidMkEntries() {
615 entries.fillInEntries(ctx.Config(), ctx.BlueprintFile(mod), mod)
616 entries.write(w)
617 }
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700618
619 return nil
620}
621
622func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
623 if !module.commonProperties.NamespaceExportedToMake {
624 // TODO(jeffrygaston) do we want to validate that there are no modules being
625 // exported to Kati that depend on this module?
626 return true
Sasha Smundakb6d23052019-04-01 18:37:36 -0700627 }
Jaewoong Jung9aa3ab12019-04-03 15:47:29 -0700628
629 return !module.Enabled() ||
630 module.commonProperties.SkipInstall ||
631 // Make does not understand LinuxBionic
632 module.Os() == LinuxBionic
Sasha Smundakb6d23052019-04-01 18:37:36 -0700633}