blob: bc73c6d89aceeffdaf15968f853b053758242af7 [file] [log] [blame]
Paul Duffin3451e162021-01-20 15:16:56 +00001// Copyright (C) 2021 The Android Open Source Project
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 java
16
17import (
Paul Duffina1d60252021-01-21 18:13:43 +000018 "fmt"
Paul Duffin3451e162021-01-20 15:16:56 +000019 "strings"
20
21 "android/soong/android"
Paul Duffina1d60252021-01-21 18:13:43 +000022 "android/soong/dexpreopt"
Martin Stjernholmb79c7f12021-03-17 00:26:25 +000023
Paul Duffin3451e162021-01-20 15:16:56 +000024 "github.com/google/blueprint"
25)
26
27func init() {
28 RegisterBootImageBuildComponents(android.InitRegistrationContext)
Paul Duffinf7f65da2021-03-10 15:00:46 +000029
30 android.RegisterSdkMemberType(&bootImageMemberType{
31 SdkMemberTypeBase: android.SdkMemberTypeBase{
32 PropertyName: "boot_images",
33 SupportsSdk: true,
34 },
35 })
Paul Duffin3451e162021-01-20 15:16:56 +000036}
37
38func RegisterBootImageBuildComponents(ctx android.RegistrationContext) {
39 ctx.RegisterModuleType("boot_image", bootImageFactory)
Paul Duffinf7f65da2021-03-10 15:00:46 +000040 ctx.RegisterModuleType("prebuilt_boot_image", prebuiltBootImageFactory)
Paul Duffin3451e162021-01-20 15:16:56 +000041}
42
43type bootImageProperties struct {
44 // The name of the image this represents.
45 //
46 // Must be one of "art" or "boot".
Paul Duffin64be7bb2021-03-23 23:06:38 +000047 Image_name *string
Paul Duffin3451e162021-01-20 15:16:56 +000048}
49
50type BootImageModule struct {
51 android.ModuleBase
Paul Duffina1d60252021-01-21 18:13:43 +000052 android.ApexModuleBase
Paul Duffinf7f65da2021-03-10 15:00:46 +000053 android.SdkBase
Paul Duffin3451e162021-01-20 15:16:56 +000054 properties bootImageProperties
55}
56
57func bootImageFactory() android.Module {
58 m := &BootImageModule{}
59 m.AddProperties(&m.properties)
Paul Duffina1d60252021-01-21 18:13:43 +000060 android.InitApexModule(m)
Paul Duffinf7f65da2021-03-10 15:00:46 +000061 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +000062 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffin3451e162021-01-20 15:16:56 +000063 return m
64}
65
66var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})
67
68type BootImageInfo struct {
69 // The image config, internal to this module (and the dex_bootjars singleton).
Paul Duffina1d60252021-01-21 18:13:43 +000070 //
71 // Will be nil if the BootImageInfo has not been provided for a specific module. That can occur
72 // when SkipDexpreoptBootJars(ctx) returns true.
Paul Duffin3451e162021-01-20 15:16:56 +000073 imageConfig *bootImageConfig
74}
75
76func (i BootImageInfo) Modules() android.ConfiguredJarList {
77 return i.imageConfig.modules
78}
79
Paul Duffina1d60252021-01-21 18:13:43 +000080// Get a map from ArchType to the associated boot image's contents for Android.
81//
82// Extension boot images only return their own files, not the files of the boot images they extend.
83func (i BootImageInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
84 files := map[android.ArchType]android.OutputPaths{}
85 if i.imageConfig != nil {
86 for _, variant := range i.imageConfig.variants {
87 // We also generate boot images for host (for testing), but we don't need those in the apex.
88 // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
89 if variant.target.Os == android.Android {
90 files[variant.target.Arch.ArchType] = variant.imagesDeps
91 }
92 }
93 }
94 return files
95}
96
97func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
98 tag := ctx.OtherModuleDependencyTag(dep)
Bob Badour07065cd2021-02-05 19:59:11 -080099 if android.IsMetaDependencyTag(tag) {
100 // Cross-cutting metadata dependencies are metadata.
101 return false
102 }
Paul Duffina1d60252021-01-21 18:13:43 +0000103 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
104}
105
106func (b *BootImageModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
107 return nil
108}
109
110func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
111 if SkipDexpreoptBootJars(ctx) {
112 return
113 }
114
115 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
116 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
117 dexpreopt.RegisterToolDeps(ctx)
118}
119
Paul Duffin3451e162021-01-20 15:16:56 +0000120func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
121 // Nothing to do if skipping the dexpreopt of boot image jars.
122 if SkipDexpreoptBootJars(ctx) {
123 return
124 }
125
Paul Duffina1d60252021-01-21 18:13:43 +0000126 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
127 // GenerateSingletonBuildActions method as it cannot create it for itself.
128 dexpreopt.GetGlobalSoongConfig(ctx)
129
Paul Duffin64be7bb2021-03-23 23:06:38 +0000130 imageConfig := b.getImageConfig(ctx)
Paul Duffin3451e162021-01-20 15:16:56 +0000131 if imageConfig == nil {
Paul Duffin3451e162021-01-20 15:16:56 +0000132 return
133 }
134
135 // Construct the boot image info from the config.
136 info := BootImageInfo{imageConfig: imageConfig}
137
138 // Make it available for other modules.
139 ctx.SetProvider(BootImageInfoProvider, info)
140}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000141
Paul Duffin64be7bb2021-03-23 23:06:38 +0000142func (b *BootImageModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
143 // Get a map of the image configs that are supported.
144 imageConfigs := genBootImageConfigs(ctx)
145
146 // Retrieve the config for this image.
147 imageNamePtr := b.properties.Image_name
148 if imageNamePtr == nil {
149 return nil
150 }
151
152 imageName := *imageNamePtr
153 imageConfig := imageConfigs[imageName]
154 if imageConfig == nil {
155 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
156 return nil
157 }
158 return imageConfig
159}
160
Paul Duffinf7f65da2021-03-10 15:00:46 +0000161type bootImageMemberType struct {
162 android.SdkMemberTypeBase
163}
164
165func (b *bootImageMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
166 mctx.AddVariationDependencies(nil, dependencyTag, names...)
167}
168
169func (b *bootImageMemberType) IsInstance(module android.Module) bool {
170 _, ok := module.(*BootImageModule)
171 return ok
172}
173
174func (b *bootImageMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
175 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
176}
177
178func (b *bootImageMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
179 return &bootImageSdkMemberProperties{}
180}
181
182type bootImageSdkMemberProperties struct {
183 android.SdkMemberPropertiesBase
184
Paul Duffin64be7bb2021-03-23 23:06:38 +0000185 Image_name *string
Paul Duffinf7f65da2021-03-10 15:00:46 +0000186}
187
188func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
189 module := variant.(*BootImageModule)
190
191 b.Image_name = module.properties.Image_name
192}
193
194func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000195 if b.Image_name != nil {
196 propertySet.AddProperty("image_name", *b.Image_name)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000197 }
198}
199
200var _ android.SdkMemberType = (*bootImageMemberType)(nil)
201
202// A prebuilt version of the boot image module.
203//
204// At the moment this is basically just a boot image module that can be used as a prebuilt.
205// Eventually as more functionality is migrated into the boot image module from the singleton then
206// this will diverge.
207type prebuiltBootImageModule struct {
208 BootImageModule
209 prebuilt android.Prebuilt
210}
211
212func (module *prebuiltBootImageModule) Prebuilt() *android.Prebuilt {
213 return &module.prebuilt
214}
215
216func (module *prebuiltBootImageModule) Name() string {
217 return module.prebuilt.Name(module.ModuleBase.Name())
218}
219
220func prebuiltBootImageFactory() android.Module {
221 m := &prebuiltBootImageModule{}
222 m.AddProperties(&m.properties)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000223 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
224 // array.
225 android.InitPrebuiltModule(m, &[]string{"placeholder"})
226 android.InitApexModule(m)
227 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000228 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000229 return m
230}