blob: 33c586cd3f2fb7d25437ed2b731bdbaa5f9945b0 [file] [log] [blame]
Colin Cross3f40fa42015-01-30 17:27:36 -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 common
16
17import (
Colin Cross3f40fa42015-01-30 17:27:36 -080018 "path/filepath"
Colin Cross0af4b842015-04-30 16:36:18 -070019 "runtime"
Colin Crossf6566ed2015-03-24 11:13:38 -070020
Colin Cross8f101b42015-06-17 15:09:06 -070021 "android/soong/glob"
22
Colin Crossf6566ed2015-03-24 11:13:38 -070023 "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -080024)
25
26var (
27 DeviceSharedLibrary = "shared_library"
28 DeviceStaticLibrary = "static_library"
29 DeviceExecutable = "executable"
30 HostSharedLibrary = "host_shared_library"
31 HostStaticLibrary = "host_static_library"
32 HostExecutable = "host_executable"
33)
34
Colin Crossf6566ed2015-03-24 11:13:38 -070035type androidBaseContext interface {
36 Arch() Arch
Colin Crossd3ba0392015-05-07 14:11:29 -070037 HostOrDevice() HostOrDevice
Colin Crossf6566ed2015-03-24 11:13:38 -070038 Host() bool
39 Device() bool
Colin Cross0af4b842015-04-30 16:36:18 -070040 Darwin() bool
Colin Crossf6566ed2015-03-24 11:13:38 -070041 Debug() bool
Colin Cross1332b002015-04-07 17:11:30 -070042 AConfig() Config
Colin Crossf6566ed2015-03-24 11:13:38 -070043}
44
45type AndroidBaseContext interface {
46 blueprint.BaseModuleContext
47 androidBaseContext
48}
49
Colin Cross3f40fa42015-01-30 17:27:36 -080050type AndroidModuleContext interface {
51 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070052 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080053
Colin Cross8f101b42015-06-17 15:09:06 -070054 ExpandSources(srcFiles []string) []string
55 Glob(globPattern string, excludes []string) []string
56
Colin Cross35cec122015-04-02 14:37:16 -070057 InstallFile(installPath, srcPath string, deps ...string) string
58 InstallFileName(installPath, name, srcPath string, deps ...string) string
Colin Cross3f40fa42015-01-30 17:27:36 -080059 CheckbuildFile(srcPath string)
60}
61
62type AndroidModule interface {
63 blueprint.Module
64
65 GenerateAndroidBuildActions(AndroidModuleContext)
66
67 base() *AndroidModuleBase
68 Disabled() bool
69 HostOrDevice() HostOrDevice
70}
71
72type AndroidDynamicDepender interface {
73 AndroidDynamicDependencies(ctx AndroidDynamicDependerModuleContext) []string
74}
75
76type AndroidDynamicDependerModuleContext interface {
77 blueprint.DynamicDependerModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -070078 androidBaseContext
Colin Cross3f40fa42015-01-30 17:27:36 -080079}
80
81type commonProperties struct {
Colin Crossc77f9d12015-04-02 13:54:39 -070082 Name string
83 Deps []string
84 Tags []string
Colin Cross3f40fa42015-01-30 17:27:36 -080085
86 // disabled: don't emit any build rules for this module
87 Disabled bool `android:"arch_variant"`
88
89 // multilib: control whether this module compiles for 32-bit, 64-bit, or both. Possible values
90 // are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
91 // architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
92 // platform
93 Compile_multilib string
94
Colin Crossd3ba0392015-05-07 14:11:29 -070095 // Set by HostOrDeviceMutator
96 CompileHostOrDevice HostOrDevice `blueprint:"mutated"`
97
Colin Cross3f40fa42015-01-30 17:27:36 -080098 // Set by ArchMutator
99 CompileArch Arch `blueprint:"mutated"`
100
101 // Set by InitAndroidModule
102 HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
103}
104
105type hostAndDeviceProperties struct {
106 Host_supported bool
107 Device_supported bool
108}
109
Colin Crossc472d572015-03-17 15:06:21 -0700110type Multilib string
111
112const (
Colin Cross2fe66872015-03-30 17:20:39 -0700113 MultilibBoth Multilib = "both"
114 MultilibFirst Multilib = "first"
115 MultilibCommon Multilib = "common"
Colin Crossc472d572015-03-17 15:06:21 -0700116)
117
Colin Cross5049f022015-03-18 13:28:46 -0700118func InitAndroidModule(m AndroidModule,
Colin Cross3f40fa42015-01-30 17:27:36 -0800119 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
120
121 base := m.base()
122 base.module = m
Colin Cross28d76592015-03-26 16:14:04 -0700123 base.extendedProperties = make(map[string]struct{})
Colin Cross5049f022015-03-18 13:28:46 -0700124
125 propertyStructs = append(propertyStructs, &base.commonProperties)
126
127 return m, propertyStructs
128}
129
130func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
131 propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
132
133 _, propertyStructs = InitAndroidModule(m, propertyStructs...)
134
135 base := m.base()
Colin Cross3f40fa42015-01-30 17:27:36 -0800136 base.commonProperties.HostOrDeviceSupported = hod
137
138 if hod == HostAndDeviceSupported {
139 // Default to module to device supported, host not supported, can override in module
140 // properties
141 base.hostAndDeviceProperties.Device_supported = true
142 propertyStructs = append(propertyStructs, &base.hostAndDeviceProperties)
143 }
144
145 return InitArchModule(m, defaultMultilib, propertyStructs...)
146}
147
148// A AndroidModuleBase object contains the properties that are common to all Android
149// modules. It should be included as an anonymous field in every module
150// struct definition. InitAndroidModule should then be called from the module's
151// factory function, and the return values from InitAndroidModule should be
152// returned from the factory function.
153//
154// The AndroidModuleBase type is responsible for implementing the
155// GenerateBuildActions method to support the blueprint.Module interface. This
156// method will then call the module's GenerateAndroidBuildActions method once
157// for each build variant that is to be built. GenerateAndroidBuildActions is
158// passed a AndroidModuleContext rather than the usual blueprint.ModuleContext.
159// AndroidModuleContext exposes extra functionality specific to the Android build
160// system including details about the particular build variant that is to be
161// generated.
162//
163// For example:
164//
165// import (
166// "android/soong/common"
Colin Cross70b40592015-03-23 12:57:34 -0700167// "github.com/google/blueprint"
Colin Cross3f40fa42015-01-30 17:27:36 -0800168// )
169//
170// type myModule struct {
171// common.AndroidModuleBase
172// properties struct {
173// MyProperty string
174// }
175// }
176//
177// func NewMyModule() (blueprint.Module, []interface{}) {
178// m := &myModule{}
179// return common.InitAndroidModule(m, &m.properties)
180// }
181//
182// func (m *myModule) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
183// // Get the CPU architecture for the current build variant.
184// variantArch := ctx.Arch()
185//
186// // ...
187// }
188type AndroidModuleBase struct {
189 // Putting the curiously recurring thing pointing to the thing that contains
190 // the thing pattern to good use.
191 module AndroidModule
192
193 commonProperties commonProperties
194 hostAndDeviceProperties hostAndDeviceProperties
195 generalProperties []interface{}
196 archProperties []*archProperties
Colin Cross28d76592015-03-26 16:14:04 -0700197 extendedProperties map[string]struct{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800198
199 noAddressSanitizer bool
200 installFiles []string
201 checkbuildFiles []string
Colin Cross1f8c52b2015-06-16 16:38:17 -0700202
203 // Used by buildTargetSingleton to create checkbuild and per-directory build targets
204 // Only set on the final variant of each module
205 installTarget string
206 checkbuildTarget string
207 blueprintDir string
Colin Cross3f40fa42015-01-30 17:27:36 -0800208}
209
210func (a *AndroidModuleBase) base() *AndroidModuleBase {
211 return a
212}
213
Colin Crossd3ba0392015-05-07 14:11:29 -0700214func (a *AndroidModuleBase) SetHostOrDevice(hod HostOrDevice) {
215 a.commonProperties.CompileHostOrDevice = hod
216}
217
Colin Cross3f40fa42015-01-30 17:27:36 -0800218func (a *AndroidModuleBase) SetArch(arch Arch) {
219 a.commonProperties.CompileArch = arch
220}
221
222func (a *AndroidModuleBase) HostOrDevice() HostOrDevice {
Colin Crossd3ba0392015-05-07 14:11:29 -0700223 return a.commonProperties.CompileHostOrDevice
Colin Cross3f40fa42015-01-30 17:27:36 -0800224}
225
226func (a *AndroidModuleBase) HostSupported() bool {
227 return a.commonProperties.HostOrDeviceSupported == HostSupported ||
228 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
229 a.hostAndDeviceProperties.Host_supported
230}
231
232func (a *AndroidModuleBase) DeviceSupported() bool {
233 return a.commonProperties.HostOrDeviceSupported == DeviceSupported ||
234 a.commonProperties.HostOrDeviceSupported == HostAndDeviceSupported &&
235 a.hostAndDeviceProperties.Device_supported
236}
237
238func (a *AndroidModuleBase) Disabled() bool {
239 return a.commonProperties.Disabled
240}
241
242func (a *AndroidModuleBase) computeInstallDeps(
243 ctx blueprint.ModuleContext) []string {
244
245 result := []string{}
246 ctx.VisitDepsDepthFirstIf(isFileInstaller,
247 func(m blueprint.Module) {
248 fileInstaller := m.(fileInstaller)
249 files := fileInstaller.filesToInstall()
250 result = append(result, files...)
251 })
252
253 return result
254}
255
256func (a *AndroidModuleBase) filesToInstall() []string {
257 return a.installFiles
258}
259
260func (p *AndroidModuleBase) NoAddressSanitizer() bool {
261 return p.noAddressSanitizer
262}
263
Colin Cross3f40fa42015-01-30 17:27:36 -0800264func (a *AndroidModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
265 if a != ctx.FinalModule().(AndroidModule).base() {
266 return
267 }
268
269 allInstalledFiles := []string{}
Colin Cross9454bfa2015-03-17 13:24:18 -0700270 allCheckbuildFiles := []string{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800271 ctx.VisitAllModuleVariants(func(module blueprint.Module) {
Colin Crossc9404352015-03-26 16:10:12 -0700272 a := module.(AndroidModule).base()
273 allInstalledFiles = append(allInstalledFiles, a.installFiles...)
274 allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800275 })
276
Colin Cross9454bfa2015-03-17 13:24:18 -0700277 deps := []string{}
278
Colin Cross3f40fa42015-01-30 17:27:36 -0800279 if len(allInstalledFiles) > 0 {
Colin Cross9454bfa2015-03-17 13:24:18 -0700280 name := ctx.ModuleName() + "-install"
Colin Cross3f40fa42015-01-30 17:27:36 -0800281 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross9454bfa2015-03-17 13:24:18 -0700282 Rule: blueprint.Phony,
283 Outputs: []string{name},
284 Implicits: allInstalledFiles,
285 })
286 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700287 a.installTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700288 }
289
290 if len(allCheckbuildFiles) > 0 {
291 name := ctx.ModuleName() + "-checkbuild"
292 ctx.Build(pctx, blueprint.BuildParams{
293 Rule: blueprint.Phony,
294 Outputs: []string{name},
295 Implicits: allCheckbuildFiles,
296 Optional: true,
297 })
298 deps = append(deps, name)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700299 a.checkbuildTarget = name
Colin Cross9454bfa2015-03-17 13:24:18 -0700300 }
301
302 if len(deps) > 0 {
303 ctx.Build(pctx, blueprint.BuildParams{
304 Rule: blueprint.Phony,
305 Outputs: []string{ctx.ModuleName()},
306 Implicits: deps,
307 Optional: true,
Colin Cross3f40fa42015-01-30 17:27:36 -0800308 })
Colin Cross1f8c52b2015-06-16 16:38:17 -0700309
310 a.blueprintDir = ctx.ModuleDir()
Colin Cross3f40fa42015-01-30 17:27:36 -0800311 }
312}
313
314func (a *AndroidModuleBase) DynamicDependencies(ctx blueprint.DynamicDependerModuleContext) []string {
315 actx := &androidDynamicDependerContext{
316 DynamicDependerModuleContext: ctx,
Colin Crossf6566ed2015-03-24 11:13:38 -0700317 androidBaseContextImpl: androidBaseContextImpl{
Colin Cross1332b002015-04-07 17:11:30 -0700318 arch: a.commonProperties.CompileArch,
Colin Crossd3ba0392015-05-07 14:11:29 -0700319 hod: a.commonProperties.CompileHostOrDevice,
Colin Cross1332b002015-04-07 17:11:30 -0700320 config: ctx.Config().(Config),
Colin Crossf6566ed2015-03-24 11:13:38 -0700321 },
Colin Cross3f40fa42015-01-30 17:27:36 -0800322 }
323
324 if dynamic, ok := a.module.(AndroidDynamicDepender); ok {
325 return dynamic.AndroidDynamicDependencies(actx)
326 }
327
328 return nil
329}
330
331func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
332 androidCtx := &androidModuleContext{
333 ModuleContext: ctx,
Colin Crossf6566ed2015-03-24 11:13:38 -0700334 androidBaseContextImpl: androidBaseContextImpl{
Colin Cross1332b002015-04-07 17:11:30 -0700335 arch: a.commonProperties.CompileArch,
Colin Crossd3ba0392015-05-07 14:11:29 -0700336 hod: a.commonProperties.CompileHostOrDevice,
Colin Cross1332b002015-04-07 17:11:30 -0700337 config: ctx.Config().(Config),
Colin Crossf6566ed2015-03-24 11:13:38 -0700338 },
Colin Cross28d76592015-03-26 16:14:04 -0700339 installDeps: a.computeInstallDeps(ctx),
340 installFiles: a.installFiles,
341 extendedProperties: a.extendedProperties,
Colin Cross3f40fa42015-01-30 17:27:36 -0800342 }
343
344 if a.commonProperties.Disabled {
345 return
346 }
347
348 a.module.GenerateAndroidBuildActions(androidCtx)
349 if ctx.Failed() {
350 return
351 }
352
Colin Crossc9404352015-03-26 16:10:12 -0700353 a.installFiles = append(a.installFiles, androidCtx.installFiles...)
354 a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...)
355
Colin Cross3f40fa42015-01-30 17:27:36 -0800356 a.generateModuleTarget(ctx)
357 if ctx.Failed() {
358 return
359 }
360}
361
Colin Crossf6566ed2015-03-24 11:13:38 -0700362type androidBaseContextImpl struct {
Colin Cross1332b002015-04-07 17:11:30 -0700363 arch Arch
Colin Crossd3ba0392015-05-07 14:11:29 -0700364 hod HostOrDevice
Colin Cross1332b002015-04-07 17:11:30 -0700365 debug bool
366 config Config
Colin Crossf6566ed2015-03-24 11:13:38 -0700367}
368
Colin Cross3f40fa42015-01-30 17:27:36 -0800369type androidModuleContext struct {
370 blueprint.ModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700371 androidBaseContextImpl
Colin Cross28d76592015-03-26 16:14:04 -0700372 installDeps []string
373 installFiles []string
374 checkbuildFiles []string
375 extendedProperties map[string]struct{}
Colin Cross3f40fa42015-01-30 17:27:36 -0800376}
377
378func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
379 params.Optional = true
380 a.ModuleContext.Build(pctx, params)
381}
382
Colin Cross28d76592015-03-26 16:14:04 -0700383func (a *androidModuleContext) ContainsProperty(property string) bool {
384 if a.ModuleContext.ContainsProperty(property) {
385 return true
386 }
387 _, ok := a.extendedProperties[property]
388 return ok
389}
390
Colin Crossf6566ed2015-03-24 11:13:38 -0700391func (a *androidBaseContextImpl) Arch() Arch {
Colin Cross3f40fa42015-01-30 17:27:36 -0800392 return a.arch
393}
394
Colin Crossd3ba0392015-05-07 14:11:29 -0700395func (a *androidBaseContextImpl) HostOrDevice() HostOrDevice {
396 return a.hod
397}
398
Colin Crossf6566ed2015-03-24 11:13:38 -0700399func (a *androidBaseContextImpl) Host() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700400 return a.hod.Host()
Colin Crossf6566ed2015-03-24 11:13:38 -0700401}
402
403func (a *androidBaseContextImpl) Device() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700404 return a.hod.Device()
Colin Crossf6566ed2015-03-24 11:13:38 -0700405}
406
Colin Cross0af4b842015-04-30 16:36:18 -0700407func (a *androidBaseContextImpl) Darwin() bool {
Colin Crossd3ba0392015-05-07 14:11:29 -0700408 return a.hod.Host() && runtime.GOOS == "darwin"
Colin Cross0af4b842015-04-30 16:36:18 -0700409}
410
Colin Crossf6566ed2015-03-24 11:13:38 -0700411func (a *androidBaseContextImpl) Debug() bool {
412 return a.debug
413}
414
Colin Cross1332b002015-04-07 17:11:30 -0700415func (a *androidBaseContextImpl) AConfig() Config {
416 return a.config
417}
418
Colin Cross35cec122015-04-02 14:37:16 -0700419func (a *androidModuleContext) InstallFileName(installPath, name, srcPath string,
420 deps ...string) string {
421
Colin Cross1332b002015-04-07 17:11:30 -0700422 config := a.AConfig()
Colin Cross3f40fa42015-01-30 17:27:36 -0800423 var fullInstallPath string
Colin Crossd3ba0392015-05-07 14:11:29 -0700424 if a.hod.Device() {
Colin Cross3f40fa42015-01-30 17:27:36 -0800425 // TODO: replace unset with a device name once we have device targeting
Colin Cross35cec122015-04-02 14:37:16 -0700426 fullInstallPath = filepath.Join(config.DeviceOut(), "system",
427 installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800428 } else {
Colin Cross35cec122015-04-02 14:37:16 -0700429 fullInstallPath = filepath.Join(config.HostOut(), installPath, name)
Colin Cross3f40fa42015-01-30 17:27:36 -0800430 }
431
Colin Cross35cec122015-04-02 14:37:16 -0700432 deps = append(deps, a.installDeps...)
433
Colin Cross3f40fa42015-01-30 17:27:36 -0800434 a.ModuleContext.Build(pctx, blueprint.BuildParams{
435 Rule: Cp,
436 Outputs: []string{fullInstallPath},
437 Inputs: []string{srcPath},
Colin Cross35cec122015-04-02 14:37:16 -0700438 OrderOnly: deps,
Colin Cross3f40fa42015-01-30 17:27:36 -0800439 })
440
441 a.installFiles = append(a.installFiles, fullInstallPath)
Colin Cross1f8c52b2015-06-16 16:38:17 -0700442 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
Colin Cross35cec122015-04-02 14:37:16 -0700443 return fullInstallPath
444}
445
446func (a *androidModuleContext) InstallFile(installPath, srcPath string, deps ...string) string {
447 return a.InstallFileName(installPath, filepath.Base(srcPath), srcPath, deps...)
Colin Cross3f40fa42015-01-30 17:27:36 -0800448}
449
450func (a *androidModuleContext) CheckbuildFile(srcPath string) {
451 a.checkbuildFiles = append(a.checkbuildFiles, srcPath)
452}
453
454type androidDynamicDependerContext struct {
455 blueprint.DynamicDependerModuleContext
Colin Crossf6566ed2015-03-24 11:13:38 -0700456 androidBaseContextImpl
Colin Cross3f40fa42015-01-30 17:27:36 -0800457}
458
459type fileInstaller interface {
460 filesToInstall() []string
461}
462
463func isFileInstaller(m blueprint.Module) bool {
464 _, ok := m.(fileInstaller)
465 return ok
466}
467
468func isAndroidModule(m blueprint.Module) bool {
469 _, ok := m.(AndroidModule)
470 return ok
471}
Colin Crossfce53272015-04-08 11:21:40 -0700472
Colin Cross8f101b42015-06-17 15:09:06 -0700473func (ctx *androidModuleContext) ExpandSources(srcFiles []string) []string {
Colin Crossfce53272015-04-08 11:21:40 -0700474 prefix := ModuleSrcDir(ctx)
475 for i, srcFile := range srcFiles {
476 if srcFile[0] == '-' {
477 srcFiles[i] = "-" + filepath.Join(prefix, srcFile[1:])
478 } else {
479 srcFiles[i] = filepath.Join(prefix, srcFile)
480 }
481 }
482
Colin Cross8f101b42015-06-17 15:09:06 -0700483 if !hasGlob(srcFiles) {
484 return srcFiles
485 }
486
487 var excludes []string
488 for _, s := range srcFiles {
489 if s[0] == '-' {
490 excludes = append(excludes, s[1:])
491 }
492 }
493
494 globbedSrcFiles := make([]string, 0, len(srcFiles))
495 for _, s := range srcFiles {
496 if s[0] == '-' {
497 continue
498 } else if glob.IsGlob(s) {
499 globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(s, excludes)...)
500 } else {
501 globbedSrcFiles = append(globbedSrcFiles, s)
502 }
503 }
504
505 return globbedSrcFiles
506}
507
508func (ctx *androidModuleContext) Glob(globPattern string, excludes []string) []string {
509 ret, err := Glob(ctx, ModuleOutDir(ctx), globPattern, excludes)
510 if err != nil {
511 ctx.ModuleErrorf("glob: %s", err.Error())
512 }
513 return ret
Colin Crossfce53272015-04-08 11:21:40 -0700514}
Colin Cross1f8c52b2015-06-16 16:38:17 -0700515
516func BuildTargetSingleton() blueprint.Singleton {
517 return &buildTargetSingleton{}
518}
519
520type buildTargetSingleton struct{}
521
522func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
523 checkbuildDeps := []string{}
524
525 dirModules := make(map[string][]string)
526
527 ctx.VisitAllModules(func(module blueprint.Module) {
528 if a, ok := module.(AndroidModule); ok {
529 blueprintDir := a.base().blueprintDir
530 installTarget := a.base().installTarget
531 checkbuildTarget := a.base().checkbuildTarget
532
533 if checkbuildTarget != "" {
534 checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
535 dirModules[blueprintDir] = append(dirModules[blueprintDir], checkbuildTarget)
536 }
537
538 if installTarget != "" {
539 dirModules[blueprintDir] = append(dirModules[blueprintDir], installTarget)
540 }
541 }
542 })
543
544 // Create a top-level checkbuild target that depends on all modules
545 ctx.Build(pctx, blueprint.BuildParams{
546 Rule: blueprint.Phony,
547 Outputs: []string{"checkbuild"},
548 Implicits: checkbuildDeps,
549 // HACK: checkbuild should be an optional build, but force it enabled for now
550 //Optional: true,
551 })
552
553 // Create a mm/<directory> target that depends on all modules in a directory
554 dirs := sortedKeys(dirModules)
555 for _, dir := range dirs {
556 ctx.Build(pctx, blueprint.BuildParams{
557 Rule: blueprint.Phony,
558 Outputs: []string{filepath.Join("mm", dir)},
559 Implicits: dirModules[dir],
560 Optional: true,
561 })
562 }
563}