blob: 12e287459bf776fe27595bcfceb83336ebc5bc34 [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"
Paul Duffin3451e162021-01-20 15:16:56 +000023 "github.com/google/blueprint"
24)
25
26func init() {
27 RegisterBootImageBuildComponents(android.InitRegistrationContext)
Paul Duffinf7f65da2021-03-10 15:00:46 +000028
29 android.RegisterSdkMemberType(&bootImageMemberType{
30 SdkMemberTypeBase: android.SdkMemberTypeBase{
31 PropertyName: "boot_images",
32 SupportsSdk: true,
33 },
34 })
Paul Duffin3451e162021-01-20 15:16:56 +000035}
36
37func RegisterBootImageBuildComponents(ctx android.RegistrationContext) {
38 ctx.RegisterModuleType("boot_image", bootImageFactory)
Paul Duffinf7f65da2021-03-10 15:00:46 +000039 ctx.RegisterModuleType("prebuilt_boot_image", prebuiltBootImageFactory)
Paul Duffin3451e162021-01-20 15:16:56 +000040}
41
42type bootImageProperties struct {
43 // The name of the image this represents.
44 //
45 // Must be one of "art" or "boot".
46 Image_name string
47}
48
49type BootImageModule struct {
50 android.ModuleBase
Paul Duffina1d60252021-01-21 18:13:43 +000051 android.ApexModuleBase
Paul Duffinf7f65da2021-03-10 15:00:46 +000052 android.SdkBase
Paul Duffin3451e162021-01-20 15:16:56 +000053 properties bootImageProperties
54}
55
56func bootImageFactory() android.Module {
57 m := &BootImageModule{}
58 m.AddProperties(&m.properties)
Paul Duffin5bbfef82021-01-30 12:57:26 +000059 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffina1d60252021-01-21 18:13:43 +000060 android.InitApexModule(m)
Paul Duffinf7f65da2021-03-10 15:00:46 +000061 android.InitSdkAwareModule(m)
Paul Duffin3451e162021-01-20 15:16:56 +000062 return m
63}
64
65var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})
66
67type BootImageInfo struct {
68 // The image config, internal to this module (and the dex_bootjars singleton).
Paul Duffina1d60252021-01-21 18:13:43 +000069 //
70 // Will be nil if the BootImageInfo has not been provided for a specific module. That can occur
71 // when SkipDexpreoptBootJars(ctx) returns true.
Paul Duffin3451e162021-01-20 15:16:56 +000072 imageConfig *bootImageConfig
73}
74
75func (i BootImageInfo) Modules() android.ConfiguredJarList {
76 return i.imageConfig.modules
77}
78
Paul Duffina1d60252021-01-21 18:13:43 +000079// Get a map from ArchType to the associated boot image's contents for Android.
80//
81// Extension boot images only return their own files, not the files of the boot images they extend.
82func (i BootImageInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
83 files := map[android.ArchType]android.OutputPaths{}
84 if i.imageConfig != nil {
85 for _, variant := range i.imageConfig.variants {
86 // We also generate boot images for host (for testing), but we don't need those in the apex.
87 // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
88 if variant.target.Os == android.Android {
89 files[variant.target.Arch.ArchType] = variant.imagesDeps
90 }
91 }
92 }
93 return files
94}
95
96func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
97 tag := ctx.OtherModuleDependencyTag(dep)
98 if tag == dexpreopt.Dex2oatDepTag {
99 // The dex2oat tool is only needed for building and is not required in the apex.
100 return false
101 }
Bob Badour07065cd2021-02-05 19:59:11 -0800102 if android.IsMetaDependencyTag(tag) {
103 // Cross-cutting metadata dependencies are metadata.
104 return false
105 }
Paul Duffina1d60252021-01-21 18:13:43 +0000106 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
107}
108
109func (b *BootImageModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
110 return nil
111}
112
113func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
114 if SkipDexpreoptBootJars(ctx) {
115 return
116 }
117
118 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
119 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
120 dexpreopt.RegisterToolDeps(ctx)
121}
122
Paul Duffin3451e162021-01-20 15:16:56 +0000123func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
124 // Nothing to do if skipping the dexpreopt of boot image jars.
125 if SkipDexpreoptBootJars(ctx) {
126 return
127 }
128
Paul Duffina1d60252021-01-21 18:13:43 +0000129 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
130 // GenerateSingletonBuildActions method as it cannot create it for itself.
131 dexpreopt.GetGlobalSoongConfig(ctx)
132
Paul Duffin3451e162021-01-20 15:16:56 +0000133 // Get a map of the image configs that are supported.
134 imageConfigs := genBootImageConfigs(ctx)
135
136 // Retrieve the config for this image.
137 imageName := b.properties.Image_name
138 imageConfig := imageConfigs[imageName]
139 if imageConfig == nil {
140 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
141 return
142 }
143
144 // Construct the boot image info from the config.
145 info := BootImageInfo{imageConfig: imageConfig}
146
147 // Make it available for other modules.
148 ctx.SetProvider(BootImageInfoProvider, info)
149}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000150
151type bootImageMemberType struct {
152 android.SdkMemberTypeBase
153}
154
155func (b *bootImageMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
156 mctx.AddVariationDependencies(nil, dependencyTag, names...)
157}
158
159func (b *bootImageMemberType) IsInstance(module android.Module) bool {
160 _, ok := module.(*BootImageModule)
161 return ok
162}
163
164func (b *bootImageMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
165 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
166}
167
168func (b *bootImageMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
169 return &bootImageSdkMemberProperties{}
170}
171
172type bootImageSdkMemberProperties struct {
173 android.SdkMemberPropertiesBase
174
175 Image_name string
176}
177
178func (b *bootImageSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
179 module := variant.(*BootImageModule)
180
181 b.Image_name = module.properties.Image_name
182}
183
184func (b *bootImageSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
185 if b.Image_name != "" {
186 propertySet.AddProperty("image_name", b.Image_name)
187 }
188}
189
190var _ android.SdkMemberType = (*bootImageMemberType)(nil)
191
192// A prebuilt version of the boot image module.
193//
194// At the moment this is basically just a boot image module that can be used as a prebuilt.
195// Eventually as more functionality is migrated into the boot image module from the singleton then
196// this will diverge.
197type prebuiltBootImageModule struct {
198 BootImageModule
199 prebuilt android.Prebuilt
200}
201
202func (module *prebuiltBootImageModule) Prebuilt() *android.Prebuilt {
203 return &module.prebuilt
204}
205
206func (module *prebuiltBootImageModule) Name() string {
207 return module.prebuilt.Name(module.ModuleBase.Name())
208}
209
210func prebuiltBootImageFactory() android.Module {
211 m := &prebuiltBootImageModule{}
212 m.AddProperties(&m.properties)
213 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
214 // 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)
219 return m
220}