blob: 44803a9ec05c81a2e261ef09300cc0a7e4c196b1 [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
Paul Duffina10bd3c2021-05-12 13:46:54 +010064// they were specified using java_boot_libs or java_sdk_libs.
65func (b bootclasspathFragmentContentDependencyTag) SdkMemberType(child android.Module) android.SdkMemberType {
66 // If the module is a java_sdk_library then treat it as if it was specified in the java_sdk_libs
67 // property, otherwise treat if it was specified in the java_boot_libs property.
68 if javaSdkLibrarySdkMemberType.IsInstance(child) {
69 return javaSdkLibrarySdkMemberType
70 }
71
Paul Duffine95b53a2021-04-23 20:41:23 +010072 return javaBootLibsSdkMemberType
73}
74
75func (b bootclasspathFragmentContentDependencyTag) ExportMember() bool {
76 return true
77}
78
Paul Duffin7771eba2021-04-23 14:25:28 +010079// The tag used for the dependency between the bootclasspath_fragment module and its contents.
Paul Duffin65898052021-04-20 22:47:03 +010080var bootclasspathFragmentContentDepTag = bootclasspathFragmentContentDependencyTag{}
Paul Duffinc7ef9892021-03-23 23:21:59 +000081
Paul Duffin65898052021-04-20 22:47:03 +010082var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathFragmentContentDepTag
83var _ android.ReplaceSourceWithPrebuilt = bootclasspathFragmentContentDepTag
Paul Duffine95b53a2021-04-23 20:41:23 +010084var _ android.SdkMemberTypeDependencyTag = bootclasspathFragmentContentDepTag
Paul Duffinc7ef9892021-03-23 23:21:59 +000085
Paul Duffin65898052021-04-20 22:47:03 +010086func IsBootclasspathFragmentContentDepTag(tag blueprint.DependencyTag) bool {
87 return tag == bootclasspathFragmentContentDepTag
Paul Duffin4d101b62021-03-24 15:42:20 +000088}
89
Paul Duffinc7d16442021-04-23 13:55:49 +010090// Properties that can be different when coverage is enabled.
91type BootclasspathFragmentCoverageAffectedProperties struct {
92 // The contents of this bootclasspath_fragment, could be either java_library, or java_sdk_library.
93 //
Paul Duffin34827d42021-05-13 21:25:05 +010094 // A java_sdk_library specified here will also be treated as if it was specified on the stub_libs
95 // property.
96 //
Paul Duffinc7d16442021-04-23 13:55:49 +010097 // The order of this list matters as it is the order that is used in the bootclasspath.
98 Contents []string
Paul Duffin10931582021-04-25 10:13:54 +010099
100 // The properties for specifying the API stubs provided by this fragment.
101 BootclasspathAPIProperties
Paul Duffinc7d16442021-04-23 13:55:49 +0100102}
103
Paul Duffin7771eba2021-04-23 14:25:28 +0100104type bootclasspathFragmentProperties struct {
Paul Duffin3451e162021-01-20 15:16:56 +0000105 // The name of the image this represents.
106 //
Paul Duffin82886d62021-03-24 01:34:57 +0000107 // If specified then it must be one of "art" or "boot".
Paul Duffin64be7bb2021-03-23 23:06:38 +0000108 Image_name *string
Paul Duffinc7ef9892021-03-23 23:21:59 +0000109
Paul Duffinc7d16442021-04-23 13:55:49 +0100110 // Properties whose values need to differ with and without coverage.
111 BootclasspathFragmentCoverageAffectedProperties
112 Coverage BootclasspathFragmentCoverageAffectedProperties
Paul Duffin9b381ef2021-04-08 23:01:37 +0100113
114 Hidden_api HiddenAPIFlagFileProperties
Paul Duffin70cfdff2021-05-15 09:10:42 +0100115
116 // Properties that allow a fragment to depend on other fragments. This is needed for hidden API
117 // processing as it needs access to all the classes used by a fragment including those provided
118 // by other fragments.
119 BootclasspathFragmentsDepsProperties
Paul Duffin3451e162021-01-20 15:16:56 +0000120}
121
Paul Duffin7771eba2021-04-23 14:25:28 +0100122type BootclasspathFragmentModule struct {
Paul Duffin3451e162021-01-20 15:16:56 +0000123 android.ModuleBase
Paul Duffina1d60252021-01-21 18:13:43 +0000124 android.ApexModuleBase
Paul Duffinf7f65da2021-03-10 15:00:46 +0000125 android.SdkBase
satayev3db35472021-05-06 23:59:58 +0100126 ClasspathFragmentBase
127
Paul Duffin7771eba2021-04-23 14:25:28 +0100128 properties bootclasspathFragmentProperties
Paul Duffin3451e162021-01-20 15:16:56 +0000129}
130
Paul Duffin2fef1362021-04-15 13:32:00 +0100131// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
132// bootclasspath fragment modules.
133type commonBootclasspathFragment interface {
134 // produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
135 //
Paul Duffin1352f7c2021-05-21 22:18:49 +0100136 // Updates the supplied hiddenAPIInfo with the paths to the generated files set.
137 produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput
Paul Duffin2fef1362021-04-15 13:32:00 +0100138}
139
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100140var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
141
Paul Duffin7771eba2021-04-23 14:25:28 +0100142func bootclasspathFragmentFactory() android.Module {
143 m := &BootclasspathFragmentModule{}
Paul Duffin3451e162021-01-20 15:16:56 +0000144 m.AddProperties(&m.properties)
Paul Duffina1d60252021-01-21 18:13:43 +0000145 android.InitApexModule(m)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000146 android.InitSdkAwareModule(m)
satayev3db35472021-05-06 23:59:58 +0100147 initClasspathFragment(m, BOOTCLASSPATH)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000148 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000149
Paul Duffinc7ef9892021-03-23 23:21:59 +0000150 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
Paul Duffinc7d16442021-04-23 13:55:49 +0100151 // If code coverage has been enabled for the framework then append the properties with
152 // coverage specific properties.
153 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
154 err := proptools.AppendProperties(&m.properties.BootclasspathFragmentCoverageAffectedProperties, &m.properties.Coverage, nil)
155 if err != nil {
156 ctx.PropertyErrorf("coverage", "error trying to append coverage specific properties: %s", err)
157 return
158 }
159 }
160
161 // Initialize the contents property from the image_name.
Paul Duffin7771eba2021-04-23 14:25:28 +0100162 bootclasspathFragmentInitContentsFromImage(ctx, m)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000163 })
Paul Duffin3451e162021-01-20 15:16:56 +0000164 return m
165}
166
Paul Duffin7771eba2021-04-23 14:25:28 +0100167// bootclasspathFragmentInitContentsFromImage will initialize the contents property from the image_name if
168// necessary.
169func bootclasspathFragmentInitContentsFromImage(ctx android.EarlyModuleContext, m *BootclasspathFragmentModule) {
Paul Duffin82886d62021-03-24 01:34:57 +0000170 contents := m.properties.Contents
Paul Duffin8018e502021-05-21 19:28:09 +0100171 if len(contents) == 0 {
172 ctx.PropertyErrorf("contents", "required property is missing")
173 return
174 }
175
176 if m.properties.Image_name == nil {
177 // Nothing to do.
178 return
Paul Duffin82886d62021-03-24 01:34:57 +0000179 }
Paul Duffinba6afd02019-11-19 19:44:10 +0000180
Paul Duffinc7ef9892021-03-23 23:21:59 +0000181 imageName := proptools.String(m.properties.Image_name)
Paul Duffin8018e502021-05-21 19:28:09 +0100182 if imageName != "art" {
183 ctx.PropertyErrorf("image_name", `unknown image name %q, expected "art"`, imageName)
184 return
Paul Duffinba6afd02019-11-19 19:44:10 +0000185 }
Paul Duffin8018e502021-05-21 19:28:09 +0100186
187 // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
188 if android.IsModuleInVersionedSdk(m) {
189 // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
190 // 1. There is no way to use this at the moment so ignoring it is safe.
191 // 2. Attempting to initialize the contents property from the configuration will end up having
192 // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
193 // as the unversioned prebuilt could end up with an APEX variant created for the source
194 // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
195 // turn will prevent it from accessing the dex implementation jar from that which will
196 // break hidden API processing, amongst others.
197 return
198 }
199
200 // Get the configuration for the art apex jars. Do not use getImageConfig(ctx) here as this is
201 // too early in the Soong processing for that to work.
202 global := dexpreopt.GetGlobalConfig(ctx)
203 modules := global.ArtApexJars
204
205 // Make sure that the apex specified in the configuration is consistent and is one for which
206 // this boot image is available.
207 commonApex := ""
208 for i := 0; i < modules.Len(); i++ {
209 apex := modules.Apex(i)
210 jar := modules.Jar(i)
211 if apex == "platform" {
212 ctx.ModuleErrorf("ArtApexJars is invalid as it requests a platform variant of %q", jar)
213 continue
214 }
215 if !m.AvailableFor(apex) {
216 ctx.ModuleErrorf("ArtApexJars configuration incompatible with this module, ArtApexJars expects this to be in apex %q but this is only in apexes %q",
217 apex, m.ApexAvailable())
218 continue
219 }
220 if commonApex == "" {
221 commonApex = apex
222 } else if commonApex != apex {
223 ctx.ModuleErrorf("ArtApexJars configuration is inconsistent, expected all jars to be in the same apex but it specifies apex %q and %q",
224 commonApex, apex)
225 }
226 }
227
228 if len(contents) != 0 {
229 // Nothing to do.
230 return
231 }
232
233 // Store the jars in the Contents property so that they can be used to add dependencies.
234 m.properties.Contents = modules.CopyOfJars()
Paul Duffinba6afd02019-11-19 19:44:10 +0000235}
236
237// bootclasspathImageNameContentsConsistencyCheck checks that the configuration that applies to this
238// module (if any) matches the contents.
239//
240// This should be a noop as if image_name="art" then the contents will be set from the ArtApexJars
241// config by bootclasspathFragmentInitContentsFromImage so it will be guaranteed to match. However,
242// in future this will not be the case.
243func (b *BootclasspathFragmentModule) bootclasspathImageNameContentsConsistencyCheck(ctx android.BaseModuleContext) {
244 imageName := proptools.String(b.properties.Image_name)
245 if imageName == "art" {
246 // TODO(b/177892522): Prebuilts (versioned or not) should not use the image_name property.
Paul Duffin0c2e0832021-04-28 00:39:52 +0100247 if android.IsModuleInVersionedSdk(b) {
Paul Duffinba6afd02019-11-19 19:44:10 +0000248 // The module is a versioned prebuilt so ignore it. This is done for a couple of reasons:
249 // 1. There is no way to use this at the moment so ignoring it is safe.
250 // 2. Attempting to initialize the contents property from the configuration will end up having
251 // the versioned prebuilt depending on the unversioned prebuilt. That will cause problems
252 // as the unversioned prebuilt could end up with an APEX variant created for the source
253 // APEX which will prevent it from having an APEX variant for the prebuilt APEX which in
254 // turn will prevent it from accessing the dex implementation jar from that which will
255 // break hidden API processing, amongst others.
256 return
257 }
258
259 // Get the configuration for the art apex jars.
260 modules := b.getImageConfig(ctx).modules
261 configuredJars := modules.CopyOfJars()
262
263 // Skip the check if the configured jars list is empty as that is a common configuration when
264 // building targets that do not result in a system image.
265 if len(configuredJars) == 0 {
266 return
267 }
268
269 contents := b.properties.Contents
270 if !reflect.DeepEqual(configuredJars, contents) {
271 ctx.ModuleErrorf("inconsistency in specification of contents. ArtApexJars configuration specifies %#v, contents property specifies %#v",
272 configuredJars, contents)
273 }
Paul Duffinc7ef9892021-03-23 23:21:59 +0000274 }
275}
276
Paul Duffine946b322021-04-25 23:04:00 +0100277var BootclasspathFragmentApexContentInfoProvider = blueprint.NewProvider(BootclasspathFragmentApexContentInfo{})
Paul Duffin3451e162021-01-20 15:16:56 +0000278
Paul Duffine946b322021-04-25 23:04:00 +0100279// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
280// apex contents.
281type BootclasspathFragmentApexContentInfo struct {
Paul Duffin58e0e762021-05-21 19:27:58 +0100282 // The configured modules, will be empty if this is from a bootclasspath_fragment that does not
283 // set image_name: "art".
284 modules android.ConfiguredJarList
285
286 // Map from arch type to the boot image files.
287 bootImageFilesByArch map[android.ArchType]android.OutputPaths
Paul Duffin1a8010a2021-05-15 12:39:23 +0100288
289 // Map from the name of the context module (as returned by Name()) to the hidden API encoded dex
290 // jar path.
291 contentModuleDexJarPaths map[string]android.Path
Paul Duffin3451e162021-01-20 15:16:56 +0000292}
293
Paul Duffine946b322021-04-25 23:04:00 +0100294func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
Paul Duffin58e0e762021-05-21 19:27:58 +0100295 return i.modules
Paul Duffin3451e162021-01-20 15:16:56 +0000296}
297
Paul Duffina1d60252021-01-21 18:13:43 +0000298// Get a map from ArchType to the associated boot image's contents for Android.
299//
300// Extension boot images only return their own files, not the files of the boot images they extend.
Paul Duffine946b322021-04-25 23:04:00 +0100301func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
Paul Duffin58e0e762021-05-21 19:27:58 +0100302 return i.bootImageFilesByArch
Paul Duffina1d60252021-01-21 18:13:43 +0000303}
304
Paul Duffin190fdef2021-04-26 10:33:59 +0100305// DexBootJarPathForContentModule returns the path to the dex boot jar for specified module.
306//
307// The dex boot jar is one which has had hidden API encoding performed on it.
Paul Duffin1a8010a2021-05-15 12:39:23 +0100308func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) {
309 name := module.Name()
310 if dexJar, ok := i.contentModuleDexJarPaths[name]; ok {
311 return dexJar, nil
312 } else {
313 return nil, fmt.Errorf("unknown bootclasspath_fragment content module %s, expected one of %s",
314 name, strings.Join(android.SortedStringKeys(i.contentModuleDexJarPaths), ", "))
315 }
Paul Duffin190fdef2021-04-26 10:33:59 +0100316}
317
Paul Duffin7771eba2021-04-23 14:25:28 +0100318func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
Paul Duffina1d60252021-01-21 18:13:43 +0000319 tag := ctx.OtherModuleDependencyTag(dep)
Paul Duffin65898052021-04-20 22:47:03 +0100320 if IsBootclasspathFragmentContentDepTag(tag) {
Paul Duffin4d101b62021-03-24 15:42:20 +0000321 // Boot image contents are automatically added to apex.
322 return true
Paul Duffinc7ef9892021-03-23 23:21:59 +0000323 }
Bob Badour07065cd2021-02-05 19:59:11 -0800324 if android.IsMetaDependencyTag(tag) {
325 // Cross-cutting metadata dependencies are metadata.
326 return false
327 }
Paul Duffina1d60252021-01-21 18:13:43 +0000328 panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
329}
330
Paul Duffin7771eba2021-04-23 14:25:28 +0100331func (b *BootclasspathFragmentModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
Paul Duffina1d60252021-01-21 18:13:43 +0000332 return nil
333}
334
Paul Duffin65898052021-04-20 22:47:03 +0100335// ComponentDepsMutator adds dependencies onto modules before any prebuilt modules without a
336// corresponding source module are renamed. This means that adding a dependency using a name without
337// a prebuilt_ prefix will always resolve to a source module and when using a name with that prefix
338// it will always resolve to a prebuilt module.
Paul Duffin7771eba2021-04-23 14:25:28 +0100339func (b *BootclasspathFragmentModule) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin65898052021-04-20 22:47:03 +0100340 module := ctx.Module()
Paul Duffin7771eba2021-04-23 14:25:28 +0100341 _, isSourceModule := module.(*BootclasspathFragmentModule)
Paul Duffin65898052021-04-20 22:47:03 +0100342
343 for _, name := range b.properties.Contents {
344 // A bootclasspath_fragment must depend only on other source modules, while the
345 // prebuilt_bootclasspath_fragment must only depend on other prebuilt modules.
Paul Duffina9dd6fa2021-04-22 17:25:57 +0100346 //
347 // TODO(b/177892522) - avoid special handling of jacocoagent.
348 if !isSourceModule && name != "jacocoagent" {
Paul Duffin65898052021-04-20 22:47:03 +0100349 name = android.PrebuiltNameFromSource(name)
350 }
351 ctx.AddDependency(module, bootclasspathFragmentContentDepTag, name)
352 }
353
354}
355
Paul Duffin7771eba2021-04-23 14:25:28 +0100356func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin10931582021-04-25 10:13:54 +0100357 // Add dependencies onto all the modules that provide the API stubs for classes on this
358 // bootclasspath fragment.
359 hiddenAPIAddStubLibDependencies(ctx, b.properties.sdkKindToStubLibs())
Paul Duffinc7ef9892021-03-23 23:21:59 +0000360
Paul Duffina1d60252021-01-21 18:13:43 +0000361 if SkipDexpreoptBootJars(ctx) {
362 return
363 }
364
365 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
366 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
367 dexpreopt.RegisterToolDeps(ctx)
368}
369
Paul Duffinf1b358c2021-05-17 07:38:47 +0100370func (b *BootclasspathFragmentModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
371 // Add dependencies on all the fragments.
372 b.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
373}
374
Paul Duffin7771eba2021-04-23 14:25:28 +0100375func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffinba6afd02019-11-19 19:44:10 +0000376 // Only perform a consistency check if this module is the active module. That will prevent an
377 // unused prebuilt that was created without instrumentation from breaking an instrumentation
378 // build.
379 if isActiveModule(ctx.Module()) {
380 b.bootclasspathImageNameContentsConsistencyCheck(ctx)
381 }
382
satayev3db35472021-05-06 23:59:58 +0100383 // Generate classpaths.proto config
384 b.generateClasspathProtoBuildActions(ctx)
385
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100386 // Gather the bootclasspath fragment's contents.
387 var contents []android.Module
388 ctx.VisitDirectDeps(func(module android.Module) {
389 tag := ctx.OtherModuleDependencyTag(module)
390 if IsBootclasspathFragmentContentDepTag(tag) {
Paul Duffin79fd3d72021-05-14 16:14:17 +0100391 contents = append(contents, module)
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100392 }
393 })
394
Paul Duffinf1b358c2021-05-17 07:38:47 +0100395 fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
396
Paul Duffin9b381ef2021-04-08 23:01:37 +0100397 // Perform hidden API processing.
Paul Duffinf1b358c2021-05-17 07:38:47 +0100398 hiddenAPIFlagOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
Paul Duffin9b381ef2021-04-08 23:01:37 +0100399
Paul Duffin1a8010a2021-05-15 12:39:23 +0100400 // Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
401 // prebuilt which will not use the image config.
402 imageConfig := b.getImageConfig(ctx)
403
404 // A prebuilt fragment cannot contribute to the apex.
405 if !android.IsModulePrebuilt(ctx.Module()) {
406 // Provide the apex content info.
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100407 b.provideApexContentInfo(ctx, imageConfig, contents, hiddenAPIFlagOutput)
Paul Duffin1a8010a2021-05-15 12:39:23 +0100408 }
409}
410
411// provideApexContentInfo creates, initializes and stores the apex content info for use by other
412// modules.
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100413func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
Paul Duffin1a8010a2021-05-15 12:39:23 +0100414 // Construct the apex content info from the config.
Paul Duffin58e0e762021-05-21 19:27:58 +0100415 info := BootclasspathFragmentApexContentInfo{}
Paul Duffin1a8010a2021-05-15 12:39:23 +0100416
417 // Populate the apex content info with paths to the dex jars.
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100418 b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIFlagOutput)
Paul Duffin1a8010a2021-05-15 12:39:23 +0100419
Paul Duffin58e0e762021-05-21 19:27:58 +0100420 if imageConfig != nil {
421 info.modules = imageConfig.modules
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100422
Paul Duffin58e0e762021-05-21 19:27:58 +0100423 if !SkipDexpreoptBootJars(ctx) {
424 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
425 // GenerateSingletonBuildActions method as it cannot create it for itself.
426 dexpreopt.GetGlobalSoongConfig(ctx)
427
428 // Only generate the boot image if the configuration does not skip it.
429 if b.generateBootImageBuildActions(ctx, contents, imageConfig) {
430 // Allow the apex to access the boot image files.
431 files := map[android.ArchType]android.OutputPaths{}
432 for _, variant := range imageConfig.variants {
433 // We also generate boot images for host (for testing), but we don't need those in the apex.
434 // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
435 if variant.target.Os == android.Android {
436 files[variant.target.Arch.ArchType] = variant.imagesDeps
437 }
438 }
439 info.bootImageFilesByArch = files
440 }
441 }
Paul Duffin1a8010a2021-05-15 12:39:23 +0100442 }
Paul Duffin3451e162021-01-20 15:16:56 +0000443
Paul Duffin1a8010a2021-05-15 12:39:23 +0100444 // Make the apex content info available for other modules.
445 ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
446}
447
448// populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the
449// apex content info.
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100450func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
Paul Duffin54c98f52021-05-15 08:54:30 +0100451
Paul Duffin1a8010a2021-05-15 12:39:23 +0100452 info.contentModuleDexJarPaths = map[string]android.Path{}
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100453 if hiddenAPIFlagOutput != nil {
Paul Duffin54c98f52021-05-15 08:54:30 +0100454 // Hidden API encoding has been performed.
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100455 flags := hiddenAPIFlagOutput.AllFlagsPath
Paul Duffin54c98f52021-05-15 08:54:30 +0100456 for _, m := range contents {
457 h := m.(hiddenAPIModule)
458 unencodedDex := h.bootDexJar()
459 if unencodedDex == nil {
460 // This is an error. Sometimes Soong will report the error directly, other times it will
461 // defer the error reporting to happen only when trying to use the missing file in ninja.
462 // Either way it is handled by extractBootDexJarsFromHiddenAPIModules which must have been
463 // called before this as it generates the flags that are used to encode these files.
464 continue
465 }
466
467 outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
468 encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, flags, *h.uncompressDex(), outputDir)
469 info.contentModuleDexJarPaths[m.Name()] = encodedDex
470 }
471 } else {
472 for _, m := range contents {
473 j := m.(UsesLibraryDependency)
474 dexJar := j.DexJarBuildPath()
475 info.contentModuleDexJarPaths[m.Name()] = dexJar
476 }
satayev14e49132021-05-17 21:03:07 +0100477 }
Paul Duffin3451e162021-01-20 15:16:56 +0000478}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000479
satayev3db35472021-05-06 23:59:58 +0100480// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
481func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
482 var classpathJars []classpathJar
483 if "art" == proptools.String(b.properties.Image_name) {
484 // ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
485 classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
486 } else {
487 classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), b.classpathType)
488 }
489 b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
490}
491
492func (b *BootclasspathFragmentModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
satayev8fab6f82021-05-07 00:10:33 +0100493 if "art" == proptools.String(b.properties.Image_name) {
494 return b.getImageConfig(ctx).modules
495 }
496
497 global := dexpreopt.GetGlobalConfig(ctx)
498
satayev1c564cc2021-05-25 19:50:30 +0100499 // Convert content names to their appropriate stems, in case a test library is overriding an actual boot jar
500 var stems []string
501 for _, name := range b.properties.Contents {
502 dep := ctx.GetDirectDepWithTag(name, bootclasspathFragmentContentDepTag)
503 if m, ok := dep.(ModuleWithStem); ok {
504 stems = append(stems, m.Stem())
505 } else {
506 ctx.PropertyErrorf("contents", "%v is not a ModuleWithStem", name)
507 }
508 }
509
satayev8fab6f82021-05-07 00:10:33 +0100510 // Only create configs for updatable boot jars. Non-updatable boot jars must be part of the
511 // platform_bootclasspath's classpath proto config to guarantee that they come before any
512 // updatable jars at runtime.
satayev1c564cc2021-05-25 19:50:30 +0100513 return global.UpdatableBootJars.Filter(stems)
satayev3db35472021-05-06 23:59:58 +0100514}
515
Paul Duffin7771eba2021-04-23 14:25:28 +0100516func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000517 // Get a map of the image configs that are supported.
518 imageConfigs := genBootImageConfigs(ctx)
519
520 // Retrieve the config for this image.
521 imageNamePtr := b.properties.Image_name
522 if imageNamePtr == nil {
523 return nil
524 }
525
526 imageName := *imageNamePtr
527 imageConfig := imageConfigs[imageName]
528 if imageConfig == nil {
529 ctx.PropertyErrorf("image_name", "Unknown image name %q, expected one of %s", imageName, strings.Join(android.SortedStringKeys(imageConfigs), ", "))
530 return nil
531 }
532 return imageConfig
533}
534
Paul Duffin9b381ef2021-04-08 23:01:37 +0100535// generateHiddenAPIBuildActions generates all the hidden API related build rules.
Paul Duffinf1b358c2021-05-17 07:38:47 +0100536func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIFlagOutput {
Paul Duffin10931582021-04-25 10:13:54 +0100537
Paul Duffin1352f7c2021-05-21 22:18:49 +0100538 // Create hidden API input structure.
Paul Duffinf1b358c2021-05-17 07:38:47 +0100539 input := b.createHiddenAPIFlagInput(ctx, contents, fragments)
Paul Duffin10931582021-04-25 10:13:54 +0100540
Paul Duffin62370922021-05-23 16:55:37 +0100541 var output *HiddenAPIFlagOutput
Paul Duffin537ea3d2021-05-14 10:38:00 +0100542
Paul Duffin62370922021-05-23 16:55:37 +0100543 // Hidden API processing is conditional as a temporary workaround as not all
544 // bootclasspath_fragments provide the appropriate information needed for hidden API processing
545 // which leads to breakages of the build.
546 // TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment
547 // modules have been updated to support it.
548 if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
549 // Get the content modules that contribute to the hidden API processing.
550 hiddenAPIModules := gatherHiddenAPIModuleFromContents(ctx, contents)
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100551
Paul Duffin62370922021-05-23 16:55:37 +0100552 // Delegate the production of the hidden API all-flags.csv file to a module type specific method.
553 common := ctx.Module().(commonBootclasspathFragment)
554 output = common.produceHiddenAPIAllFlagsFile(ctx, hiddenAPIModules, input)
555 }
556
557 // Initialize a HiddenAPIInfo structure.
Paul Duffinaf99afa2021-05-21 22:18:56 +0100558 hiddenAPIInfo := HiddenAPIInfo{
Paul Duffin62370922021-05-23 16:55:37 +0100559 // The monolithic hidden API processing needs access to the flag files that override the default
560 // flags from all the fragments whether or not they actually perform their own hidden API flag
561 // generation. That is because the monolithic hidden API processing uses those flag files to
562 // perform its own flag generation.
Paul Duffin1352f7c2021-05-21 22:18:49 +0100563 FlagFilesByCategory: input.FlagFilesByCategory,
Paul Duffin18cf1972021-05-21 22:46:59 +0100564
Paul Duffinf1b358c2021-05-17 07:38:47 +0100565 // Other bootclasspath_fragments that depend on this need the transitive set of stub dex jars
566 // from this to resolve any references from their code to classes provided by this fragment
567 // and the fragments this depends upon.
568 TransitiveStubDexJarsByKind: input.transitiveStubDexJarsByKind(),
Paul Duffin62370922021-05-23 16:55:37 +0100569 }
Paul Duffin2fef1362021-04-15 13:32:00 +0100570
Paul Duffin62370922021-05-23 16:55:37 +0100571 if output != nil {
Paul Duffin1352f7c2021-05-21 22:18:49 +0100572 // The monolithic hidden API processing also needs access to all the output files produced by
573 // hidden API processing of this fragment.
Paul Duffin62370922021-05-23 16:55:37 +0100574 hiddenAPIInfo.HiddenAPIFlagOutput = *output
Paul Duffin1352f7c2021-05-21 22:18:49 +0100575 }
Paul Duffin62370922021-05-23 16:55:37 +0100576
577 // Provide it for use by other modules.
Paul Duffinaf99afa2021-05-21 22:18:56 +0100578 ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)
Paul Duffin54c98f52021-05-15 08:54:30 +0100579
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100580 return output
Paul Duffin2fef1362021-04-15 13:32:00 +0100581}
582
Paul Duffin1352f7c2021-05-21 22:18:49 +0100583// createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived
584// from the properties on this module and its dependencies.
Paul Duffinf1b358c2021-05-17 07:38:47 +0100585func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) HiddenAPIFlagInput {
586
587 // Merge the HiddenAPIInfo from all the fragment dependencies.
588 dependencyHiddenApiInfo := newHiddenAPIInfo()
589 dependencyHiddenApiInfo.mergeFromFragmentDeps(ctx, fragments)
590
591 // Create hidden API flag input structure.
Paul Duffin1352f7c2021-05-21 22:18:49 +0100592 input := newHiddenAPIFlagInput()
593
594 // Update the input structure with information obtained from the stub libraries.
595 input.gatherStubLibInfo(ctx, contents)
596
597 // Populate with flag file paths from the properties.
598 input.extractFlagFilesFromProperties(ctx, &b.properties.Hidden_api)
599
Paul Duffinf1b358c2021-05-17 07:38:47 +0100600 // Store the stub dex jars from this module's fragment dependencies.
601 input.DependencyStubDexJarsByKind = dependencyHiddenApiInfo.TransitiveStubDexJarsByKind
602
Paul Duffin1352f7c2021-05-21 22:18:49 +0100603 return input
604}
605
Paul Duffin2fef1362021-04-15 13:32:00 +0100606// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
607// for the fragment.
Paul Duffin1352f7c2021-05-21 22:18:49 +0100608func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
609 // Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
Paul Duffin2fef1362021-04-15 13:32:00 +0100610 // paths to the created files.
Paul Duffin1352f7c2021-05-21 22:18:49 +0100611 return hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, input)
Paul Duffin9b381ef2021-04-08 23:01:37 +0100612}
613
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100614// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
615// module.
Paul Duffin58e0e762021-05-21 19:27:58 +0100616//
617// Returns true if the boot image is created, false otherwise.
618func (b *BootclasspathFragmentModule) generateBootImageBuildActions(ctx android.ModuleContext, contents []android.Module, imageConfig *bootImageConfig) bool {
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100619 global := dexpreopt.GetGlobalConfig(ctx)
620 if !shouldBuildBootImages(ctx.Config(), global) {
Paul Duffin58e0e762021-05-21 19:27:58 +0100621 return false
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100622 }
623
624 // Bootclasspath fragment modules that are for the platform do not produce a boot image.
625 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
626 if apexInfo.IsForPlatform() {
Paul Duffin58e0e762021-05-21 19:27:58 +0100627 return false
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100628 }
629
630 // Bootclasspath fragment modules that are versioned do not produce a boot image.
631 if android.IsModuleInVersionedSdk(ctx.Module()) {
Paul Duffin58e0e762021-05-21 19:27:58 +0100632 return false
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100633 }
634
635 // Copy the dex jars of this fragment's content modules to their predefined locations.
636 copyBootJarsToPredefinedLocations(ctx, contents, imageConfig.modules, imageConfig.dexPaths)
Paul Duffin2fc82ad2021-04-29 23:36:12 +0100637
638 // Build a profile for the image config and then use that to build the boot image.
639 profile := bootImageProfileRule(ctx, imageConfig)
640 buildBootImage(ctx, imageConfig, profile)
Paul Duffin58e0e762021-05-21 19:27:58 +0100641
642 return true
Paul Duffin7ebebfd2021-04-27 19:36:57 +0100643}
644
Paul Duffin7771eba2021-04-23 14:25:28 +0100645type bootclasspathFragmentMemberType struct {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000646 android.SdkMemberTypeBase
647}
648
Paul Duffin7771eba2021-04-23 14:25:28 +0100649func (b *bootclasspathFragmentMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000650 mctx.AddVariationDependencies(nil, dependencyTag, names...)
651}
652
Paul Duffin7771eba2021-04-23 14:25:28 +0100653func (b *bootclasspathFragmentMemberType) IsInstance(module android.Module) bool {
654 _, ok := module.(*BootclasspathFragmentModule)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000655 return ok
656}
657
Paul Duffin7771eba2021-04-23 14:25:28 +0100658func (b *bootclasspathFragmentMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
Paul Duffin4b64ba02021-03-29 11:02:53 +0100659 if b.PropertyName == "boot_images" {
660 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_boot_image")
661 } else {
662 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_bootclasspath_fragment")
663 }
Paul Duffinf7f65da2021-03-10 15:00:46 +0000664}
665
Paul Duffin7771eba2021-04-23 14:25:28 +0100666func (b *bootclasspathFragmentMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
667 return &bootclasspathFragmentSdkMemberProperties{}
Paul Duffinf7f65da2021-03-10 15:00:46 +0000668}
669
Paul Duffin7771eba2021-04-23 14:25:28 +0100670type bootclasspathFragmentSdkMemberProperties struct {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000671 android.SdkMemberPropertiesBase
672
Paul Duffina57835e2021-04-19 13:23:06 +0100673 // The image name
Paul Duffin64be7bb2021-03-23 23:06:38 +0000674 Image_name *string
Paul Duffina57835e2021-04-19 13:23:06 +0100675
676 // Contents of the bootclasspath fragment
677 Contents []string
Paul Duffin7c955552021-04-19 13:23:53 +0100678
Paul Duffin895c7142021-04-25 13:40:15 +0100679 // Stub_libs properties.
680 Stub_libs []string
681 Core_platform_stub_libs []string
682
Paul Duffin7c955552021-04-19 13:23:53 +0100683 // Flag files by *hiddenAPIFlagFileCategory
Paul Duffin438eb572021-05-21 16:58:23 +0100684 Flag_files_by_category FlagFilesByCategory
Paul Duffin2fef1362021-04-15 13:32:00 +0100685
686 // The path to the generated stub-flags.csv file.
687 Stub_flags_path android.OptionalPath
688
689 // The path to the generated annotation-flags.csv file.
690 Annotation_flags_path android.OptionalPath
691
692 // The path to the generated metadata.csv file.
693 Metadata_path android.OptionalPath
694
695 // The path to the generated index.csv file.
696 Index_path android.OptionalPath
697
698 // The path to the generated all-flags.csv file.
699 All_flags_path android.OptionalPath
700}
701
Paul Duffin7771eba2021-04-23 14:25:28 +0100702func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
703 module := variant.(*BootclasspathFragmentModule)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000704
705 b.Image_name = module.properties.Image_name
Paul Duffin2dc665b2021-04-23 16:58:51 +0100706 b.Contents = module.properties.Contents
Paul Duffin7c955552021-04-19 13:23:53 +0100707
Paul Duffinaf99afa2021-05-21 22:18:56 +0100708 // Get the hidden API information from the module.
Paul Duffin7c955552021-04-19 13:23:53 +0100709 mctx := ctx.SdkModuleContext()
Paul Duffinaf99afa2021-05-21 22:18:56 +0100710 hiddenAPIInfo := mctx.OtherModuleProvider(module, HiddenAPIInfoProvider).(HiddenAPIInfo)
711 b.Flag_files_by_category = hiddenAPIInfo.FlagFilesByCategory
Paul Duffin895c7142021-04-25 13:40:15 +0100712
Paul Duffin2fef1362021-04-15 13:32:00 +0100713 // Copy all the generated file paths.
Paul Duffinaf99afa2021-05-21 22:18:56 +0100714 b.Stub_flags_path = android.OptionalPathForPath(hiddenAPIInfo.StubFlagsPath)
715 b.Annotation_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AnnotationFlagsPath)
716 b.Metadata_path = android.OptionalPathForPath(hiddenAPIInfo.MetadataPath)
717 b.Index_path = android.OptionalPathForPath(hiddenAPIInfo.IndexPath)
718 b.All_flags_path = android.OptionalPathForPath(hiddenAPIInfo.AllFlagsPath)
Paul Duffin2fef1362021-04-15 13:32:00 +0100719
Paul Duffin895c7142021-04-25 13:40:15 +0100720 // Copy stub_libs properties.
721 b.Stub_libs = module.properties.Api.Stub_libs
722 b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
Paul Duffinf7f65da2021-03-10 15:00:46 +0000723}
724
Paul Duffin7771eba2021-04-23 14:25:28 +0100725func (b *bootclasspathFragmentSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
Paul Duffin64be7bb2021-03-23 23:06:38 +0000726 if b.Image_name != nil {
727 propertySet.AddProperty("image_name", *b.Image_name)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000728 }
Paul Duffina57835e2021-04-19 13:23:06 +0100729
Paul Duffin895c7142021-04-25 13:40:15 +0100730 builder := ctx.SnapshotBuilder()
731 requiredMemberDependency := builder.SdkMemberReferencePropertyTag(true)
732
Paul Duffina57835e2021-04-19 13:23:06 +0100733 if len(b.Contents) > 0 {
Paul Duffin895c7142021-04-25 13:40:15 +0100734 propertySet.AddPropertyWithTag("contents", b.Contents, requiredMemberDependency)
Paul Duffina57835e2021-04-19 13:23:06 +0100735 }
Paul Duffin7c955552021-04-19 13:23:53 +0100736
Paul Duffin895c7142021-04-25 13:40:15 +0100737 if len(b.Stub_libs) > 0 {
738 apiPropertySet := propertySet.AddPropertySet("api")
739 apiPropertySet.AddPropertyWithTag("stub_libs", b.Stub_libs, requiredMemberDependency)
740 }
741 if len(b.Core_platform_stub_libs) > 0 {
742 corePlatformApiPropertySet := propertySet.AddPropertySet("core_platform_api")
743 corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
744 }
745
Paul Duffin2fef1362021-04-15 13:32:00 +0100746 hiddenAPISet := propertySet.AddPropertySet("hidden_api")
747 hiddenAPIDir := "hiddenapi"
748
749 // Copy manually curated flag files specified on the bootclasspath_fragment.
Paul Duffin7c955552021-04-19 13:23:53 +0100750 if b.Flag_files_by_category != nil {
Paul Duffin7c955552021-04-19 13:23:53 +0100751 for _, category := range hiddenAPIFlagFileCategories {
752 paths := b.Flag_files_by_category[category]
753 if len(paths) > 0 {
754 dests := []string{}
755 for _, p := range paths {
Paul Duffin2fef1362021-04-15 13:32:00 +0100756 dest := filepath.Join(hiddenAPIDir, p.Base())
Paul Duffin7c955552021-04-19 13:23:53 +0100757 builder.CopyToSnapshot(p, dest)
758 dests = append(dests, dest)
759 }
760 hiddenAPISet.AddProperty(category.propertyName, dests)
761 }
762 }
763 }
Paul Duffin2fef1362021-04-15 13:32:00 +0100764
765 copyOptionalPath := func(path android.OptionalPath, property string) {
766 if path.Valid() {
767 p := path.Path()
768 dest := filepath.Join(hiddenAPIDir, p.Base())
769 builder.CopyToSnapshot(p, dest)
770 hiddenAPISet.AddProperty(property, dest)
771 }
772 }
773
774 // Copy all the generated files, if available.
775 copyOptionalPath(b.Stub_flags_path, "stub_flags")
776 copyOptionalPath(b.Annotation_flags_path, "annotation_flags")
777 copyOptionalPath(b.Metadata_path, "metadata")
778 copyOptionalPath(b.Index_path, "index")
779 copyOptionalPath(b.All_flags_path, "all_flags")
Paul Duffinf7f65da2021-03-10 15:00:46 +0000780}
781
Paul Duffin7771eba2021-04-23 14:25:28 +0100782var _ android.SdkMemberType = (*bootclasspathFragmentMemberType)(nil)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000783
Paul Duffin2fef1362021-04-15 13:32:00 +0100784// prebuiltBootclasspathFragmentProperties contains additional prebuilt_bootclasspath_fragment
785// specific properties.
786type prebuiltBootclasspathFragmentProperties struct {
787 Hidden_api struct {
788 // The path to the stub-flags.csv file created by the bootclasspath_fragment.
789 Stub_flags *string `android:"path"`
790
791 // The path to the annotation-flags.csv file created by the bootclasspath_fragment.
792 Annotation_flags *string `android:"path"`
793
794 // The path to the metadata.csv file created by the bootclasspath_fragment.
795 Metadata *string `android:"path"`
796
797 // The path to the index.csv file created by the bootclasspath_fragment.
798 Index *string `android:"path"`
799
800 // The path to the all-flags.csv file created by the bootclasspath_fragment.
801 All_flags *string `android:"path"`
802 }
803}
804
Paul Duffin7771eba2021-04-23 14:25:28 +0100805// A prebuilt version of the bootclasspath_fragment module.
Paul Duffinf7f65da2021-03-10 15:00:46 +0000806//
Paul Duffin7771eba2021-04-23 14:25:28 +0100807// At the moment this is basically just a bootclasspath_fragment module that can be used as a
808// prebuilt. Eventually as more functionality is migrated into the bootclasspath_fragment module
809// type from the various singletons then this will diverge.
810type prebuiltBootclasspathFragmentModule struct {
811 BootclasspathFragmentModule
Paul Duffinf7f65da2021-03-10 15:00:46 +0000812 prebuilt android.Prebuilt
Paul Duffin2fef1362021-04-15 13:32:00 +0100813
814 // Additional prebuilt specific properties.
815 prebuiltProperties prebuiltBootclasspathFragmentProperties
Paul Duffinf7f65da2021-03-10 15:00:46 +0000816}
817
Paul Duffin7771eba2021-04-23 14:25:28 +0100818func (module *prebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000819 return &module.prebuilt
820}
821
Paul Duffin7771eba2021-04-23 14:25:28 +0100822func (module *prebuiltBootclasspathFragmentModule) Name() string {
Paul Duffinf7f65da2021-03-10 15:00:46 +0000823 return module.prebuilt.Name(module.ModuleBase.Name())
824}
825
Paul Duffin2fef1362021-04-15 13:32:00 +0100826// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
827// specified.
Paul Duffin1352f7c2021-05-21 22:18:49 +0100828func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []hiddenAPIModule, _ HiddenAPIFlagInput) *HiddenAPIFlagOutput {
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100829 pathForOptionalSrc := func(src *string) android.Path {
Paul Duffin2fef1362021-04-15 13:32:00 +0100830 if src == nil {
831 // TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
832 return nil
833 }
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100834 return android.PathForModuleSrc(ctx, *src)
Paul Duffin2fef1362021-04-15 13:32:00 +0100835 }
836
Paul Duffin1e6f5c42021-05-21 16:15:31 +0100837 output := HiddenAPIFlagOutput{
838 StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags),
839 AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags),
840 MetadataPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata),
841 IndexPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index),
842 AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags),
843 }
844
845 return &output
Paul Duffin2fef1362021-04-15 13:32:00 +0100846}
847
848var _ commonBootclasspathFragment = (*prebuiltBootclasspathFragmentModule)(nil)
849
Paul Duffin7771eba2021-04-23 14:25:28 +0100850func prebuiltBootclasspathFragmentFactory() android.Module {
851 m := &prebuiltBootclasspathFragmentModule{}
Paul Duffin2fef1362021-04-15 13:32:00 +0100852 m.AddProperties(&m.properties, &m.prebuiltProperties)
Paul Duffinf7f65da2021-03-10 15:00:46 +0000853 // This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
854 // array.
855 android.InitPrebuiltModule(m, &[]string{"placeholder"})
856 android.InitApexModule(m)
857 android.InitSdkAwareModule(m)
Martin Stjernholmb79c7f12021-03-17 00:26:25 +0000858 android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000859
Paul Duffin7771eba2021-04-23 14:25:28 +0100860 // Initialize the contents property from the image_name.
Paul Duffinc7ef9892021-03-23 23:21:59 +0000861 android.AddLoadHook(m, func(ctx android.LoadHookContext) {
Paul Duffin7771eba2021-04-23 14:25:28 +0100862 bootclasspathFragmentInitContentsFromImage(ctx, &m.BootclasspathFragmentModule)
Paul Duffinc7ef9892021-03-23 23:21:59 +0000863 })
Paul Duffinf7f65da2021-03-10 15:00:46 +0000864 return m
865}