blob: 25a4f17f4b6f1103a8be7356e6b0387e62e20dcd [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".
47 Image_name string
48}
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)
99 if tag == dexpreopt.Dex2oatDepTag {
100 // The dex2oat tool is only needed for building and is not required in the apex.
101 return false
102 }
Bob Badour07065cd2021-02-05 19:59:11 -0800103 if android.IsMetaDependencyTag(tag) {
104 // Cross-cutting metadata dependencies are metadata.
105 return false
106 }
Paul Duffina1d60252021-01-21 18:13:43 +0000107 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
108}
109
110func (b *BootImageModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
111 return nil
112}
113
114func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
115 if SkipDexpreoptBootJars(ctx) {
116 return
117 }
118
119 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
120 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
121 dexpreopt.RegisterToolDeps(ctx)
122}
123
Paul Duffin3451e162021-01-20 15:16:56 +0000124func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
125 // Nothing to do if skipping the dexpreopt of boot image jars.
126 if SkipDexpreoptBootJars(ctx) {
127 return
128 }
129
Paul Duffina1d60252021-01-21 18:13:43 +0000130 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
131 // GenerateSingletonBuildActions method as it cannot create it for itself.
132 dexpreopt.GetGlobalSoongConfig(ctx)
133
Paul Duffin3451e162021-01-20 15:16:56 +0000134 // Get a map of the image configs that are supported.
135 imageConfigs := genBootImageConfigs(ctx)
136
137 // Retrieve the config for this image.
138 imageName := b.properties.Image_name
139 imageConfig := imageConfigs[imageName]
140 if imageConfig == nil {
141 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
142 return
143 }
144
145 // Construct the boot image info from the config.
146 info := BootImageInfo{imageConfig: imageConfig}
147
148 // Make it available for other modules.
149 ctx.SetProvider(BootImageInfoProvider, info)
150}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000151
152type bootImageMemberType struct {
153 android.SdkMemberTypeBase
154}
155
156func (b *bootImageMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
157 mctx.AddVariationDependencies(nil, dependencyTag, names...)
158}
159
160func (b *bootImageMemberType) IsInstance(module android.Module) bool {
161 _, ok := module.(*BootImageModule)
162 return ok
163}
164
165func (b *bootImageMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
166 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
167}
168
169func (b *bootImageMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
170 return &bootImageSdkMemberProperties{}
171}
172
173type bootImageSdkMemberProperties struct {
174 android.SdkMemberPropertiesBase
175
176 Image_name string
177}
178
179func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
180 module := variant.(*BootImageModule)
181
182 b.Image_name = module.properties.Image_name
183}
184
185func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
186 if b.Image_name != "" {
187 propertySet.AddProperty("image_name", b.Image_name)
188 }
189}
190
191var _ android.SdkMemberType = (*bootImageMemberType)(nil)
192
193// A prebuilt version of the boot image module.
194//
195// At the moment this is basically just a boot image module that can be used as a prebuilt.
196// Eventually as more functionality is migrated into the boot image module from the singleton then
197// this will diverge.
198type prebuiltBootImageModule struct {
199 BootImageModule
200 prebuilt android.Prebuilt
201}
202
203func (module *prebuiltBootImageModule) Prebuilt() *android.Prebuilt {
204 return &module.prebuilt
205}
206
207func (module *prebuiltBootImageModule) Name() string {
208 return module.prebuilt.Name(module.ModuleBase.Name())
209}
210
211func prebuiltBootImageFactory() android.Module {
212 m := &prebuiltBootImageModule{}
213 m.AddProperties(&m.properties)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000214 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
215 // array.
216 android.InitPrebuiltModule(m, &[]string{"placeholder"})
217 android.InitApexModule(m)
218 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000219 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000220 return m
221}