blob: 8fb893fe37d1d3cf15b8b28632a1fbe3c6cd7f99 [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
Paul Duffin4b64ba02021-03-29 11:02:53 +010030 // TODO(b/177892522): Remove after has been replaced by bootclasspath_fragments
Paul Duffinf7f65da2021-03-10 15:00:46 +000031 android.RegisterSdkMemberType(&bootImageMemberType{
32 SdkMemberTypeBase: android.SdkMemberTypeBase{
33 PropertyName: "boot_images",
34 SupportsSdk: true,
35 },
36 })
Paul Duffin4b64ba02021-03-29 11:02:53 +010037
38 android.RegisterSdkMemberType(&bootImageMemberType{
39 SdkMemberTypeBase: android.SdkMemberTypeBase{
40 PropertyName: "bootclasspath_fragments",
41 SupportsSdk: true,
42 },
43 })
Paul Duffin3451e162021-01-20 15:16:56 +000044}
45
46func RegisterBootImageBuildComponents(ctx android.RegistrationContext) {
Paul Duffin4b64ba02021-03-29 11:02:53 +010047 // TODO(b/177892522): Remove after has been replaced by bootclasspath_fragment
Paul Duffin3451e162021-01-20 15:16:56 +000048 ctx.RegisterModuleType("boot_image", bootImageFactory)
Paul Duffinf7f65da2021-03-10 15:00:46 +000049 ctx.RegisterModuleType("prebuilt_boot_image", prebuiltBootImageFactory)
Paul Duffin4b64ba02021-03-29 11:02:53 +010050
51 ctx.RegisterModuleType("bootclasspath_fragment", bootImageFactory)
52 ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootImageFactory)
Paul Duffin3451e162021-01-20 15:16:56 +000053}
54
55type bootImageProperties struct {
56 // The name of the image this represents.
57 //
58 // Must be one of "art" or "boot".
Paul Duffin64be7bb2021-03-23 23:06:38 +000059 Image_name *string
Paul Duffin3451e162021-01-20 15:16:56 +000060}
61
62type BootImageModule struct {
63 android.ModuleBase
Paul Duffina1d60252021-01-21 18:13:43 +000064 android.ApexModuleBase
Paul Duffinf7f65da2021-03-10 15:00:46 +000065 android.SdkBase
Paul Duffin3451e162021-01-20 15:16:56 +000066 properties bootImageProperties
67}
68
69func bootImageFactory() android.Module {
70 m := &BootImageModule{}
71 m.AddProperties(&m.properties)
Paul Duffina1d60252021-01-21 18:13:43 +000072 android.InitApexModule(m)
Paul Duffinf7f65da2021-03-10 15:00:46 +000073 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +000074 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffin3451e162021-01-20 15:16:56 +000075 return m
76}
77
78var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})
79
80type BootImageInfo struct {
81 // The image config, internal to this module (and the dex_bootjars singleton).
Paul Duffina1d60252021-01-21 18:13:43 +000082 //
83 // Will be nil if the BootImageInfo has not been provided for a specific module. That can occur
84 // when SkipDexpreoptBootJars(ctx) returns true.
Paul Duffin3451e162021-01-20 15:16:56 +000085 imageConfig *bootImageConfig
86}
87
88func (i BootImageInfo) Modules() android.ConfiguredJarList {
89 return i.imageConfig.modules
90}
91
Paul Duffina1d60252021-01-21 18:13:43 +000092// Get a map from ArchType to the associated boot image's contents for Android.
93//
94// Extension boot images only return their own files, not the files of the boot images they extend.
95func (i BootImageInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
96 files := map[android.ArchType]android.OutputPaths{}
97 if i.imageConfig != nil {
98 for _, variant := range i.imageConfig.variants {
99 // We also generate boot images for host (for testing), but we don't need those in the apex.
100 // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
101 if variant.target.Os == android.Android {
102 files[variant.target.Arch.ArchType] = variant.imagesDeps
103 }
104 }
105 }
106 return files
107}
108
109func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
110 tag := ctx.OtherModuleDependencyTag(dep)
Bob Badour07065cd2021-02-05 19:59:11 -0800111 if android.IsMetaDependencyTag(tag) {
112 // Cross-cutting metadata dependencies are metadata.
113 return false
114 }
Paul Duffina1d60252021-01-21 18:13:43 +0000115 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
116}
117
118func (b *BootImageModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
119 return nil
120}
121
122func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
123 if SkipDexpreoptBootJars(ctx) {
124 return
125 }
126
127 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
128 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
129 dexpreopt.RegisterToolDeps(ctx)
130}
131
Paul Duffin3451e162021-01-20 15:16:56 +0000132func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
133 // Nothing to do if skipping the dexpreopt of boot image jars.
134 if SkipDexpreoptBootJars(ctx) {
135 return
136 }
137
Paul Duffina1d60252021-01-21 18:13:43 +0000138 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
139 // GenerateSingletonBuildActions method as it cannot create it for itself.
140 dexpreopt.GetGlobalSoongConfig(ctx)
141
Paul Duffin64be7bb2021-03-23 23:06:38 +0000142 imageConfig := b.getImageConfig(ctx)
Paul Duffin3451e162021-01-20 15:16:56 +0000143 if imageConfig == nil {
Paul Duffin3451e162021-01-20 15:16:56 +0000144 return
145 }
146
147 // Construct the boot image info from the config.
148 info := BootImageInfo{imageConfig: imageConfig}
149
150 // Make it available for other modules.
151 ctx.SetProvider(BootImageInfoProvider, info)
152}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000153
Paul Duffin64be7bb2021-03-23 23:06:38 +0000154func (b *BootImageModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
155 // Get a map of the image configs that are supported.
156 imageConfigs := genBootImageConfigs(ctx)
157
158 // Retrieve the config for this image.
159 imageNamePtr := b.properties.Image_name
160 if imageNamePtr == nil {
161 return nil
162 }
163
164 imageName := *imageNamePtr
165 imageConfig := imageConfigs[imageName]
166 if imageConfig == nil {
167 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
168 return nil
169 }
170 return imageConfig
171}
172
Paul Duffinf7f65da2021-03-10 15:00:46 +0000173type bootImageMemberType struct {
174 android.SdkMemberTypeBase
175}
176
177func (b *bootImageMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
178 mctx.AddVariationDependencies(nil, dependencyTag, names...)
179}
180
181func (b *bootImageMemberType) IsInstance(module android.Module) bool {
182 _, ok := module.(*BootImageModule)
183 return ok
184}
185
186func (b *bootImageMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
Paul Duffin4b64ba02021-03-29 11:02:53 +0100187 if b.PropertyName == "boot_images" {
188 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
189 } else {
190 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_bootclasspath_fragment")
191 }
Paul Duffinf7f65da2021-03-10 15:00:46 +0000192}
193
194func (b *bootImageMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
195 return &bootImageSdkMemberProperties{}
196}
197
198type bootImageSdkMemberProperties struct {
199 android.SdkMemberPropertiesBase
200
Paul Duffin64be7bb2021-03-23 23:06:38 +0000201 Image_name *string
Paul Duffinf7f65da2021-03-10 15:00:46 +0000202}
203
204func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
205 module := variant.(*BootImageModule)
206
207 b.Image_name = module.properties.Image_name
208}
209
210func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000211 if b.Image_name != nil {
212 propertySet.AddProperty("image_name", *b.Image_name)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000213 }
214}
215
216var _ android.SdkMemberType = (*bootImageMemberType)(nil)
217
218// A prebuilt version of the boot image module.
219//
220// At the moment this is basically just a boot image module that can be used as a prebuilt.
221// Eventually as more functionality is migrated into the boot image module from the singleton then
222// this will diverge.
223type prebuiltBootImageModule struct {
224 BootImageModule
225 prebuilt android.Prebuilt
226}
227
228func (module *prebuiltBootImageModule) Prebuilt() *android.Prebuilt {
229 return &module.prebuilt
230}
231
232func (module *prebuiltBootImageModule) Name() string {
233 return module.prebuilt.Name(module.ModuleBase.Name())
234}
235
236func prebuiltBootImageFactory() android.Module {
237 m := &prebuiltBootImageModule{}
238 m.AddProperties(&m.properties)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000239 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
240 // array.
241 android.InitPrebuiltModule(m, &[]string{"placeholder"})
242 android.InitApexModule(m)
243 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000244 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000245 return m
246}