blob: bed629da340fd67e3369e73f5d9aa2660e2b8a96 [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 Duffin7c955552021-04-19 13:23:53 +010019 "path/filepath"
Paul Duffinba6afd02019-11-19 19:44:10 +000020 "reflect"
Paul Duffin3451e162021-01-20 15:16:56 +000021 "strings"
22
23 "android/soong/android"
Paul Duffina1d60252021-01-21 18:13:43 +000024 "android/soong/dexpreopt"
Paul Duffinc7ef9892021-03-23 23:21:59 +000025 "github.com/google/blueprint/proptools"
Martin Stjernholmb79c7f12021-03-17 00:26:25 +000026
Paul Duffin3451e162021-01-20 15:16:56 +000027 "github.com/google/blueprint"
28)
29
30func init() {
Paul Duffin7771eba2021-04-23 14:25:28 +010031 registerBootclasspathFragmentBuildComponents(android.InitRegistrationContext)
Paul Duffinf7f65da2021-03-10 15:00:46 +000032
Paul Duffin7771eba2021-04-23 14:25:28 +010033 android.RegisterSdkMemberType(&bootclasspathFragmentMemberType{
Paul Duffin4b64ba02021-03-29 11:02:53 +010034 SdkMemberTypeBase: android.SdkMemberTypeBase{
Paul Duffin2d3da312021-05-06 12:02:27 +010035 PropertyName: "bootclasspath_fragments",
36 SupportsSdk: true,
Paul Duffin4b64ba02021-03-29 11:02:53 +010037 },
38 })
Paul Duffin3451e162021-01-20 15:16:56 +000039}
40
Paul Duffin7771eba2021-04-23 14:25:28 +010041func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContext) {
Paul Duffin7771eba2021-04-23 14:25:28 +010042 ctx.RegisterModuleType("bootclasspath_fragment", bootclasspathFragmentFactory)
43 ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory)
Paul Duffin3451e162021-01-20 15:16:56 +000044}
45
Paul Duffin65898052021-04-20 22:47:03 +010046type bootclasspathFragmentContentDependencyTag struct {
Paul Duffinc7ef9892021-03-23 23:21:59 +000047 blueprint.BaseDependencyTag
48}
49
Paul Duffin7771eba2021-04-23 14:25:28 +010050// Avoid having to make bootclasspath_fragment content visible to the bootclasspath_fragment.
Paul Duffinc7ef9892021-03-23 23:21:59 +000051//
Paul Duffin7771eba2021-04-23 14:25:28 +010052// This is a temporary workaround to make it easier to migrate to bootclasspath_fragment modules
53// with proper dependencies.
Paul Duffinc7ef9892021-03-23 23:21:59 +000054// TODO(b/177892522): Remove this and add needed visibility.
Paul Duffin65898052021-04-20 22:47:03 +010055func (b bootclasspathFragmentContentDependencyTag) ExcludeFromVisibilityEnforcement() {
56}
57
58// The bootclasspath_fragment contents must never depend on prebuilts.
59func (b bootclasspathFragmentContentDependencyTag) ReplaceSourceWithPrebuilt() bool {
60 return false
Paul Duffinc7ef9892021-03-23 23:21:59 +000061}
62
Paul Duffine95b53a2021-04-23 20:41:23 +010063// SdkMemberType causes dependencies added with this tag to be automatically added to the sdk as if
64// they were specified using java_boot_libs.
Paul Duffineee466e2021-04-27 23:17:56 +010065func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType {
Paul Duffine95b53a2021-04-23 20:41:23 +010066 return javaBootLibsSdkMemberType
67}
68
69func (b bootclasspathFragmentContentDependencyTag) ExportMember() bool {
70 return true
71}
72
Paul Duffin7771eba2021-04-23 14:25:28 +010073// The tag used for the dependency between the bootclasspath_fragment module and its contents.
Paul Duffin65898052021-04-20 22:47:03 +010074var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
Paul Duffinc7ef9892021-03-23 23:21:59 +000075
Paul Duffin65898052021-04-20 22:47:03 +010076var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
77var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
Paul Duffine95b53a2021-04-23 20:41:23 +010078var _ android.SdkMemberTypeDependencyTag = bootclasspathFragmentContentDepTag
Paul Duffinc7ef9892021-03-23 23:21:59 +000079
Paul Duffin65898052021-04-20 22:47:03 +010080func IsBootclasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
81 return tag == bootclasspathFragmentContentDepTag
Paul Duffin4d101b62021-03-24 15:42:20 +000082}
83
Paul Duffinc7d16442021-04-23 13:55:49 +010084// Properties that can be different when coverage is enabled.
85type BootclasspathFragmentCoverageAffectedProperties struct {
86 // The contents of this bootclasspath_fragment, could be either java_library, or java_sdk_library.
87 //
88 // The order of this list matters as it is the order that is used in the bootclasspath.
89 Contents []string
Paul Duffin10931582021-04-25 10:13:54 +010090
91 // The properties for specifying the API stubs provided by this fragment.
92 BootclasspathAPIProperties
Paul Duffinc7d16442021-04-23 13:55:49 +010093}
94
Paul Duffin7771eba2021-04-23 14:25:28 +010095type bootclasspathFragmentProperties struct {
Paul Duffin3451e162021-01-20 15:16:56 +000096 // The name of the image this represents.
97 //
Paul Duffin82886d62021-03-24 01:34:57 +000098 // If specified then it must be one of "art" or "boot".
Paul Duffin64be7bb2021-03-23 23:06:38 +000099 Image_name *string
Paul Duffinc7ef9892021-03-23 23:21:59 +0000100
Paul Duffinc7d16442021-04-23 13:55:49 +0100101 // Properties whose values need to differ with and without coverage.
102 BootclasspathFragmentCoverageAffectedProperties
103 Coverage BootclasspathFragmentCoverageAffectedProperties
Paul Duffin9b381ef2021-04-08 23:01:37 +0100104
105 Hidden_api HiddenAPIFlagFileProperties
Paul Duffin3451e162021-01-20 15:16:56 +0000106}
107
Paul Duffin7771eba2021-04-23 14:25:28 +0100108type BootclasspathFragmentModule struct {
Paul Duffin3451e162021-01-20 15:16:56 +0000109 android.ModuleBase
Paul Duffina1d60252021-01-21 18:13:43 +0000110 android.ApexModuleBase
Paul Duffinf7f65da2021-03-10 15:00:46 +0000111 android.SdkBase
satayev3db35472021-05-06 23:59:58 +0100112 ClasspathFragmentBase
113
Paul Duffin7771eba2021-04-23 14:25:28 +0100114 properties bootclasspathFragmentProperties
Paul Duffin3451e162021-01-20 15:16:56 +0000115}
116
Paul Duffin7771eba2021-04-23 14:25:28 +0100117func bootclasspathFragmentFactory() android.Module {
118 m := &BootclasspathFragmentModule{}
Paul Duffin3451e162021-01-20 15:16:56 +0000119 m.AddProperties(&m.properties)
Paul Duffina1d60252021-01-21 18:13:43 +0000120 android.InitApexModule(m)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000121 android.InitSdkAwareModule(m)
satayev3db35472021-05-06 23:59:58 +0100122 initClasspathFragment(m, BOOTCLASSPATH)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000123 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000124
Paul Duffinc7ef9892021-03-23 23:21:59 +0000125 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
Paul Duffinc7d16442021-04-23 13:55:49 +0100126 // If code coverage has been enabled for the framework then append the properties with
127 // coverage specific properties.
128 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
129 err := proptools.AppendProperties(&m.properties.BootclasspathFragmentCoverageAffectedProperties, &m.properties.Coverage, nil)
130 if err != nil {
131 ctx.PropertyErrorf("coverage", "error trying to append coverage specific properties: %s", err)
132 return
133 }
134 }
135
136 // Initialize the contents property from the image_name.
Paul Duffin7771eba2021-04-23 14:25:28 +0100137 bootclasspathFragmentInitContentsFromImage(ctx, m)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000138 })
Paul Duffin3451e162021-01-20 15:16:56 +0000139 return m
140}
141
Paul Duffin7771eba2021-04-23 14:25:28 +0100142// bootclasspathFragmentInitContentsFromImage will initialize the contents property from the image_name if
143// necessary.
144func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, m *BootclasspathFragmentModule) {
Paul Duffin82886d62021-03-24 01:34:57 +0000145 contents := m.properties.Contents
146 if m.properties.Image_name == nil && len(contents) == 0 {
147 ctx.ModuleErrorf(`neither of the "image_name" and "contents" properties have been supplied, please supply exactly one`)
148 }
Paul Duffinba6afd02019-11-19 19:44:10 +0000149
Paul Duffinc7ef9892021-03-23 23:21:59 +0000150 imageName := proptools.String(m.properties.Image_name)
151 if imageName == "art" {
Paul Duffin023dba02021-04-22 01:45:29 +0100152 // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
Paul Duffin0c2e0832021-04-28 00:39:52 +0100153 if android.IsModuleInVersionedSdk(m) {
Paul Duffin023dba02021-04-22 01:45:29 +0100154 // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
155 // 1. There is no way to use this at the moment so ignoring it is safe.
156 // 2. Attempting to initialize the contents property from the configuration will end up having
157 // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
158 // as the unversioned prebuilt could end up with an APEX variant created for the source
159 // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
160 // turn will prevent it from accessing the dex implementation jar from that which will
161 // break hidden API processing, amongst others.
162 return
163 }
164
Paul Duffinc7ef9892021-03-23 23:21:59 +0000165 // Get the configuration for the art apex jars. Do not use getImageConfig(ctx) here as this is
166 // too early in the Soong processing for that to work.
167 global := dexpreopt.GetGlobalConfig(ctx)
168 modules := global.ArtApexJars
169
170 // Make sure that the apex specified in the configuration is consistent and is one for which
171 // this boot image is available.
Paul Duffinc7ef9892021-03-23 23:21:59 +0000172 commonApex := ""
173 for i := 0; i < modules.Len(); i++ {
174 apex := modules.Apex(i)
175 jar := modules.Jar(i)
176 if apex == "platform" {
177 ctx.ModuleErrorf("ArtApexJars is invalid as it requests a platform variant of %q", jar)
178 continue
179 }
180 if !m.AvailableFor(apex) {
Paul Duffinf23bc472021-04-27 12:42:20 +0100181 ctx.ModuleErrorf("ArtApexJars configuration incompatible with this module, ArtApexJars expects this to be in apex %q but this is only in apexes %q",
Paul Duffinc7ef9892021-03-23 23:21:59 +0000182 apex, m.ApexAvailable())
183 continue
184 }
185 if commonApex == "" {
186 commonApex = apex
187 } else if commonApex != apex {
188 ctx.ModuleErrorf("ArtApexJars configuration is inconsistent, expected all jars to be in the same apex but it specifies apex %q and %q",
189 commonApex, apex)
190 }
Paul Duffinc7ef9892021-03-23 23:21:59 +0000191 }
192
Paul Duffinf23bc472021-04-27 12:42:20 +0100193 if len(contents) != 0 {
194 // Nothing to do.
195 return
196 }
197
Paul Duffinc7ef9892021-03-23 23:21:59 +0000198 // Store the jars in the Contents property so that they can be used to add dependencies.
Paul Duffinba6afd02019-11-19 19:44:10 +0000199 m.properties.Contents = modules.CopyOfJars()
200 }
201}
202
203// bootclasspathImageNameContentsConsistencyCheck checks that the configuration that applies to this
204// module (if any) matches the contents.
205//
206// This should be a noop as if image_name="art" then the contents will be set from the ArtApexJars
207// config by bootclasspathFragmentInitContentsFromImage so it will be guaranteed to match. However,
208// in future this will not be the case.
209func (b *BootclasspathFragmentModule) bootclasspathImageNameContentsConsistencyCheck(ctx android.BaseModuleContext) {
210 imageName := proptools.String(b.properties.Image_name)
211 if imageName == "art" {
212 // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
Paul Duffin0c2e0832021-04-28 00:39:52 +0100213 if android.IsModuleInVersionedSdk(b) {
Paul Duffinba6afd02019-11-19 19:44:10 +0000214 // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
215 // 1. There is no way to use this at the moment so ignoring it is safe.
216 // 2. Attempting to initialize the contents property from the configuration will end up having
217 // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
218 // as the unversioned prebuilt could end up with an APEX variant created for the source
219 // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
220 // turn will prevent it from accessing the dex implementation jar from that which will
221 // break hidden API processing, amongst others.
222 return
223 }
224
225 // Get the configuration for the art apex jars.
226 modules := b.getImageConfig(ctx).modules
227 configuredJars := modules.CopyOfJars()
228
229 // Skip the check if the configured jars list is empty as that is a common configuration when
230 // building targets that do not result in a system image.
231 if len(configuredJars) == 0 {
232 return
233 }
234
235 contents := b.properties.Contents
236 if !reflect.DeepEqual(configuredJars, contents) {
237 ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
238 configuredJars, contents)
239 }
Paul Duffinc7ef9892021-03-23 23:21:59 +0000240 }
241}
242
Paul Duffine946b322021-04-25 23:04:00 +0100243var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{})
Paul Duffin3451e162021-01-20 15:16:56 +0000244
Paul Duffine946b322021-04-25 23:04:00 +0100245// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
246// apex contents.
247type BootclasspathFragmentApexContentInfo struct {
satayev3db35472021-05-06 23:59:58 +0100248 // ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
249 //
250 // The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
251 // for more details.
252 ClasspathFragmentProtoOutput android.OutputPath
253
254 // ClasspathFragmentProtoInstallDir contains information about on device location for the generated classpaths.proto file.
255 //
256 // The path encodes expected sub-location within partitions, i.e. etc/classpaths/<proto-file>,
257 // for ClasspathFragmentProtoOutput. To get sub-location, instead of the full output / make path
258 // use android.InstallPath#Rel().
259 //
260 // This is only relevant for APEX modules as they perform their own installation; while regular
261 // system files are installed via ClasspathFragmentBase#androidMkEntries().
262 ClasspathFragmentProtoInstallDir android.InstallPath
263
Paul Duffin3451e162021-01-20 15:16:56 +0000264 // The image config, internal to this module (and the dex_bootjars singleton).
Paul Duffina1d60252021-01-21 18:13:43 +0000265 //
Paul Duffine946b322021-04-25 23:04:00 +0100266 // Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur
Paul Duffina1d60252021-01-21 18:13:43 +0000267 // when SkipDexpreoptBootJars(ctx) returns true.
Paul Duffin3451e162021-01-20 15:16:56 +0000268 imageConfig *bootImageConfig
269}
270
Paul Duffine946b322021-04-25 23:04:00 +0100271func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
Paul Duffin3451e162021-01-20 15:16:56 +0000272 return i.imageConfig.modules
273}
274
Paul Duffina1d60252021-01-21 18:13:43 +0000275// Get a map from ArchType to the associated boot image's contents for Android.
276//
277// Extension boot images only return their own files, not the files of the boot images they extend.
Paul Duffine946b322021-04-25 23:04:00 +0100278func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
Paul Duffina1d60252021-01-21 18:13:43 +0000279 files := map[android.ArchType]android.OutputPaths{}
280 if i.imageConfig != nil {
281 for _, variant := range i.imageConfig.variants {
282 // We also generate boot images for host (for testing), but we don't need those in the apex.
283 // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
284 if variant.target.Os == android.Android {
285 files[variant.target.Arch.ArchType] = variant.imagesDeps
286 }
287 }
288 }
289 return files
290}
291
Paul Duffin190fdef2021-04-26 10:33:59 +0100292// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
293//
294// The dex boot jar is one which has had hidden API encoding performed on it.
295func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) android.Path {
296 j := module.(UsesLibraryDependency)
297 dexJar := j.DexJarBuildPath()
298 return dexJar
299}
300
Paul Duffin7771eba2021-04-23 14:25:28 +0100301func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
Paul Duffina1d60252021-01-21 18:13:43 +0000302 tag := ctx.OtherModuleDependencyTag(dep)
Paul Duffin65898052021-04-20 22:47:03 +0100303 if IsBootclasspathFragmentContentDepTag(tag) {
Paul Duffin4d101b62021-03-24 15:42:20 +0000304 // Boot image contents are automatically added to apex.
305 return true
Paul Duffinc7ef9892021-03-23 23:21:59 +0000306 }
Bob Badour07065cd2021-02-05 19:59:11 -0800307 if android.IsMetaDependencyTag(tag) {
308 // Cross-cutting metadata dependencies are metadata.
309 return false
310 }
Paul Duffina1d60252021-01-21 18:13:43 +0000311 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
312}
313
Paul Duffin7771eba2021-04-23 14:25:28 +0100314func (b *BootclasspathFragmentModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
Paul Duffina1d60252021-01-21 18:13:43 +0000315 return nil
316}
317
Paul Duffin65898052021-04-20 22:47:03 +0100318// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
319// corresponding source module are renamed. This means that adding a dependency using a name without
320// a prebuilt_ prefix will always resolve to a source module and when using a name with that prefix
321// it will always resolve to a prebuilt module.
Paul Duffin7771eba2021-04-23 14:25:28 +0100322func (b *BootclasspathFragmentModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin65898052021-04-20 22:47:03 +0100323 module := ctx.Module()
Paul Duffin7771eba2021-04-23 14:25:28 +0100324 _, isSourceModule := module.(*BootclasspathFragmentModule)
Paul Duffin65898052021-04-20 22:47:03 +0100325
326 for _, name := range b.properties.Contents {
327 // A bootclasspath_fragment must depend only on other source modules, while the
328 // prebuilt_bootclasspath_fragment must only depend on other prebuilt modules.
Paul Duffina9dd6fa2021-04-22 17:25:57 +0100329 //
330 // TODO(b/177892522) - avoid special handling of jacocoagent.
331 if !isSourceModule && name != "jacocoagent" {
Paul Duffin65898052021-04-20 22:47:03 +0100332 name = android.PrebuiltNameFromSource(name)
333 }
334 ctx.AddDependency(module, bootclasspathFragmentContentDepTag, name)
335 }
336
337}
338
Paul Duffin7771eba2021-04-23 14:25:28 +0100339func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin10931582021-04-25 10:13:54 +0100340 // Add dependencies onto all the modules that provide the API stubs for classes on this
341 // bootclasspath fragment.
342 hiddenAPIAddStubLibDependencies(ctx, b.properties.sdkKindToStubLibs())
Paul Duffinc7ef9892021-03-23 23:21:59 +0000343
Paul Duffina1d60252021-01-21 18:13:43 +0000344 if SkipDexpreoptBootJars(ctx) {
345 return
346 }
347
348 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
349 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
350 dexpreopt.RegisterToolDeps(ctx)
351}
352
Paul Duffin7771eba2021-04-23 14:25:28 +0100353func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffinba6afd02019-11-19 19:44:10 +0000354 // Only perform a consistency check if this module is the active module. That will prevent an
355 // unused prebuilt that was created without instrumentation from breaking an instrumentation
356 // build.
357 if isActiveModule(ctx.Module()) {
358 b.bootclasspathImageNameContentsConsistencyCheck(ctx)
359 }
360
satayev3db35472021-05-06 23:59:58 +0100361 // Generate classpaths.proto config
362 b.generateClasspathProtoBuildActions(ctx)
363
Paul Duffin9b381ef2021-04-08 23:01:37 +0100364 // Perform hidden API processing.
365 b.generateHiddenAPIBuildActions(ctx)
366
Paul Duffin3451e162021-01-20 15:16:56 +0000367 // Construct the boot image info from the config.
satayev3db35472021-05-06 23:59:58 +0100368 info := BootclasspathFragmentApexContentInfo{
369 ClasspathFragmentProtoInstallDir: b.classpathFragmentBase().installDirPath,
370 ClasspathFragmentProtoOutput: b.classpathFragmentBase().outputFilepath,
371 imageConfig: nil,
372 }
373
374 if !SkipDexpreoptBootJars(ctx) {
375 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
376 // GenerateSingletonBuildActions method as it cannot create it for itself.
377 dexpreopt.GetGlobalSoongConfig(ctx)
378 info.imageConfig = b.getImageConfig(ctx)
379 }
Paul Duffin3451e162021-01-20 15:16:56 +0000380
381 // Make it available for other modules.
Paul Duffine946b322021-04-25 23:04:00 +0100382 ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
Paul Duffin3451e162021-01-20 15:16:56 +0000383}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000384
satayev3db35472021-05-06 23:59:58 +0100385// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
386func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
387 var classpathJars []classpathJar
388 if "art" == proptools.String(b.properties.Image_name) {
389 // ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
390 classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
391 } else {
392 classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), b.classpathType)
393 }
394 b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
395}
396
397func (b *BootclasspathFragmentModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
398 // TODO(satayev): populate with actual content
399 return android.EmptyConfiguredJarList()
400}
401
Paul Duffin7771eba2021-04-23 14:25:28 +0100402func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000403 // Get a map of the image configs that are supported.
404 imageConfigs := genBootImageConfigs(ctx)
405
406 // Retrieve the config for this image.
407 imageNamePtr := b.properties.Image_name
408 if imageNamePtr == nil {
409 return nil
410 }
411
412 imageName := *imageNamePtr
413 imageConfig := imageConfigs[imageName]
414 if imageConfig == nil {
415 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
416 return nil
417 }
418 return imageConfig
419}
420
Paul Duffin9b381ef2021-04-08 23:01:37 +0100421// generateHiddenAPIBuildActions generates all the hidden API related build rules.
Paul Duffin7771eba2021-04-23 14:25:28 +0100422func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext) {
Paul Duffin9b381ef2021-04-08 23:01:37 +0100423 // Resolve the properties to paths.
424 flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
425
426 // Store the information for use by platform_bootclasspath.
427 ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
Paul Duffin10931582021-04-25 10:13:54 +0100428
429 // Convert the kind specific lists of modules into kind specific lists of jars.
430 stubJarsByKind := hiddenAPIGatherStubLibDexJarPaths(ctx)
431
432 // Store the information for use by other modules.
433 bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: stubJarsByKind}
434 ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
Paul Duffin9b381ef2021-04-08 23:01:37 +0100435}
436
Paul Duffin7771eba2021-04-23 14:25:28 +0100437type bootclasspathFragmentMemberType struct {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000438 android.SdkMemberTypeBase
439}
440
Paul Duffin7771eba2021-04-23 14:25:28 +0100441func (b *bootclasspathFragmentMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000442 mctx.AddVariationDependencies(nil, dependencyTag, names...)
443}
444
Paul Duffin7771eba2021-04-23 14:25:28 +0100445func (b *bootclasspathFragmentMemberType) IsInstance(module android.Module) bool {
446 _, ok := module.(*BootclasspathFragmentModule)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000447 return ok
448}
449
Paul Duffin7771eba2021-04-23 14:25:28 +0100450func (b *bootclasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
Paul Duffin4b64ba02021-03-29 11:02:53 +0100451 if b.PropertyName == "boot_images" {
452 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
453 } else {
454 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_bootclasspath_fragment")
455 }
Paul Duffinf7f65da2021-03-10 15:00:46 +0000456}
457
Paul Duffin7771eba2021-04-23 14:25:28 +0100458func (b *bootclasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
459 return &bootclasspathFragmentSdkMemberProperties{}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000460}
461
Paul Duffin7771eba2021-04-23 14:25:28 +0100462type bootclasspathFragmentSdkMemberProperties struct {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000463 android.SdkMemberPropertiesBase
464
Paul Duffina57835e2021-04-19 13:23:06 +0100465 // The image name
Paul Duffin64be7bb2021-03-23 23:06:38 +0000466 Image_name *string
Paul Duffina57835e2021-04-19 13:23:06 +0100467
468 // Contents of the bootclasspath fragment
469 Contents []string
Paul Duffin7c955552021-04-19 13:23:53 +0100470
Paul Duffin895c7142021-04-25 13:40:15 +0100471 // Stub_libs properties.
472 Stub_libs []string
473 Core_platform_stub_libs []string
474
Paul Duffin7c955552021-04-19 13:23:53 +0100475 // Flag files by *hiddenAPIFlagFileCategory
476 Flag_files_by_category map[*hiddenAPIFlagFileCategory]android.Paths
Paul Duffinf7f65da2021-03-10 15:00:46 +0000477}
478
Paul Duffin7771eba2021-04-23 14:25:28 +0100479func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
480 module := variant.(*BootclasspathFragmentModule)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000481
482 b.Image_name = module.properties.Image_name
Paul Duffin2dc665b2021-04-23 16:58:51 +0100483 b.Contents = module.properties.Contents
Paul Duffin7c955552021-04-19 13:23:53 +0100484
485 // Get the flag file information from the module.
486 mctx := ctx.SdkModuleContext()
487 flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
488 b.Flag_files_by_category = flagFileInfo.categoryToPaths
Paul Duffin895c7142021-04-25 13:40:15 +0100489
490 // Copy stub_libs properties.
491 b.Stub_libs = module.properties.Api.Stub_libs
492 b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
Paul Duffinf7f65da2021-03-10 15:00:46 +0000493}
494
Paul Duffin7771eba2021-04-23 14:25:28 +0100495func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000496 if b.Image_name != nil {
497 propertySet.AddProperty("image_name", *b.Image_name)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000498 }
Paul Duffina57835e2021-04-19 13:23:06 +0100499
Paul Duffin895c7142021-04-25 13:40:15 +0100500 builder := ctx.SnapshotBuilder()
501 requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true)
502
Paul Duffina57835e2021-04-19 13:23:06 +0100503 if len(b.Contents) > 0 {
Paul Duffin895c7142021-04-25 13:40:15 +0100504 propertySet.AddPropertyWithTag("contents", b.Contents, requiredMemberDependency)
Paul Duffina57835e2021-04-19 13:23:06 +0100505 }
Paul Duffin7c955552021-04-19 13:23:53 +0100506
Paul Duffin895c7142021-04-25 13:40:15 +0100507 if len(b.Stub_libs) > 0 {
508 apiPropertySet := propertySet.AddPropertySet("api")
509 apiPropertySet.AddPropertyWithTag("stub_libs", b.Stub_libs, requiredMemberDependency)
510 }
511 if len(b.Core_platform_stub_libs) > 0 {
512 corePlatformApiPropertySet := propertySet.AddPropertySet("core_platform_api")
513 corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
514 }
515
Paul Duffin7c955552021-04-19 13:23:53 +0100516 if b.Flag_files_by_category != nil {
517 hiddenAPISet := propertySet.AddPropertySet("hidden_api")
518 for _, category := range hiddenAPIFlagFileCategories {
519 paths := b.Flag_files_by_category[category]
520 if len(paths) > 0 {
521 dests := []string{}
522 for _, p := range paths {
523 dest := filepath.Join("hiddenapi", p.Base())
524 builder.CopyToSnapshot(p, dest)
525 dests = append(dests, dest)
526 }
527 hiddenAPISet.AddProperty(category.propertyName, dests)
528 }
529 }
530 }
Paul Duffinf7f65da2021-03-10 15:00:46 +0000531}
532
Paul Duffin7771eba2021-04-23 14:25:28 +0100533var _ android.SdkMemberType = (*bootclasspathFragmentMemberType)(nil)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000534
Paul Duffin7771eba2021-04-23 14:25:28 +0100535// A prebuilt version of the bootclasspath_fragment module.
Paul Duffinf7f65da2021-03-10 15:00:46 +0000536//
Paul Duffin7771eba2021-04-23 14:25:28 +0100537// At the moment this is basically just a bootclasspath_fragment module that can be used as a
538// prebuilt. Eventually as more functionality is migrated into the bootclasspath_fragment module
539// type from the various singletons then this will diverge.
540type prebuiltBootclasspathFragmentModule struct {
541 BootclasspathFragmentModule
Paul Duffinf7f65da2021-03-10 15:00:46 +0000542 prebuilt android.Prebuilt
543}
544
Paul Duffin7771eba2021-04-23 14:25:28 +0100545func (module *prebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000546 return &module.prebuilt
547}
548
Paul Duffin7771eba2021-04-23 14:25:28 +0100549func (module *prebuiltBootclasspathFragmentModule) Name() string {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000550 return module.prebuilt.Name(module.ModuleBase.Name())
551}
552
Paul Duffin7771eba2021-04-23 14:25:28 +0100553func prebuiltBootclasspathFragmentFactory() android.Module {
554 m := &prebuiltBootclasspathFragmentModule{}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000555 m.AddProperties(&m.properties)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000556 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
557 // array.
558 android.InitPrebuiltModule(m, &[]string{"placeholder"})
559 android.InitApexModule(m)
560 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000561 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000562
Paul Duffin7771eba2021-04-23 14:25:28 +0100563 // Initialize the contents property from the image_name.
Paul Duffinc7ef9892021-03-23 23:21:59 +0000564 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
Paul Duffin7771eba2021-04-23 14:25:28 +0100565 bootclasspathFragmentInitContentsFromImage(ctx, &m.BootclasspathFragmentModule)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000566 })
Paul Duffinf7f65da2021-03-10 15:00:46 +0000567 return m
568}