blob: 5272eaf77f73a774f08a8ebdb8bc8bf59aba3a1d [file] [log] [blame]
Paul Duffinbb7f1ac2021-03-29 22:18:45 +01001// Copyright 2021 Google Inc. All rights reserved.
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 (
18 "android/soong/android"
19 "android/soong/dexpreopt"
Paul Duffinb432df92021-03-22 22:09:42 +000020 "github.com/google/blueprint"
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010021)
22
23func init() {
24 registerPlatformBootclasspathBuildComponents(android.InitRegistrationContext)
25}
26
27func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
28 ctx.RegisterModuleType("platform_bootclasspath", platformBootclasspathFactory)
Paul Duffinb432df92021-03-22 22:09:42 +000029
30 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
31 ctx.BottomUp("platform_bootclasspath_deps", platformBootclasspathDepsMutator)
32 })
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010033}
34
Paul Duffinb432df92021-03-22 22:09:42 +000035type platformBootclasspathDependencyTag struct {
36 blueprint.BaseDependencyTag
37
38 name string
39}
40
41// Avoid having to make platform bootclasspath content visible to the platform bootclasspath.
42//
43// This is a temporary workaround to make it easier to migrate to platform bootclasspath with proper
44// dependencies.
45// TODO(b/177892522): Remove this and add needed visibility.
46func (t platformBootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
47}
48
49// The tag used for the dependency between the platform bootclasspath and any configured boot jars.
50var platformBootclasspathModuleDepTag = platformBootclasspathDependencyTag{name: "module"}
51
52var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDependencyTag{}
53
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010054type platformBootclasspathModule struct {
55 android.ModuleBase
Paul Duffinb432df92021-03-22 22:09:42 +000056
57 // The apex:module pairs obtained from the configured modules.
58 //
59 // Currently only for testing.
60 configuredModules []android.Module
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010061}
62
63func platformBootclasspathFactory() android.Module {
64 m := &platformBootclasspathModule{}
65 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
66 return m
67}
68
69func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
70 if SkipDexpreoptBootJars(ctx) {
71 return
72 }
73
74 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
75 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
76 dexpreopt.RegisterToolDeps(ctx)
77}
78
Paul Duffinb432df92021-03-22 22:09:42 +000079func platformBootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
80 m := ctx.Module()
81 if p, ok := m.(*platformBootclasspathModule); ok {
82 // Add dependencies on all the modules configured in the "art" boot image.
83 artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
84 addDependenciesOntoBootImageModules(ctx, artImageConfig.modules)
85
86 // Add dependencies on all the modules configured in the "boot" boot image. That does not
87 // include modules configured in the "art" boot image.
88 bootImageConfig := p.getImageConfig(ctx)
89 addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules)
90
91 // Add dependencies on all the updatable modules.
92 updatableModules := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
93 addDependenciesOntoBootImageModules(ctx, updatableModules)
94 }
95}
96
97func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
98 var variations []blueprint.Variation
99 if apex != "platform" {
100 // Pick the correct apex variant.
101 variations = []blueprint.Variation{
102 {Mutator: "apex", Variation: apex},
103 }
104 }
105
106 addedDep := false
107 if ctx.OtherModuleDependencyVariantExists(variations, name) {
108 ctx.AddFarVariationDependencies(variations, tag, name)
109 addedDep = true
110 }
111
112 // Add a dependency on the prebuilt module if it exists.
113 prebuiltName := android.PrebuiltNameFromSource(name)
114 if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
115 ctx.AddVariationDependencies(variations, tag, prebuiltName)
116 addedDep = true
117 }
118
119 // If no appropriate variant existing for this, so no dependency could be added, then it is an
120 // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
121 // dependency that will not be satisfied and the default behavior will handle it.
122 if !addedDep {
123 ctx.AddFarVariationDependencies(variations, tag, name)
124 }
125}
126
127func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList) {
128 for i := 0; i < modules.Len(); i++ {
129 apex := modules.Apex(i)
130 name := modules.Jar(i)
131
132 addDependencyOntoApexModulePair(ctx, apex, name, platformBootclasspathModuleDepTag)
133 }
134}
135
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100136func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffinb432df92021-03-22 22:09:42 +0000137 ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
138 tag := ctx.OtherModuleDependencyTag(module)
139 if tag == platformBootclasspathModuleDepTag {
140 b.configuredModules = append(b.configuredModules, module)
141 }
142 })
143
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100144 // Nothing to do if skipping the dexpreopt of boot image jars.
145 if SkipDexpreoptBootJars(ctx) {
146 return
147 }
148
149 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
150 // GenerateSingletonBuildActions method as it cannot create it for itself.
151 dexpreopt.GetGlobalSoongConfig(ctx)
152
153 imageConfig := b.getImageConfig(ctx)
154 if imageConfig == nil {
155 return
156 }
157
158 // Construct the boot image info from the config.
159 info := BootImageInfo{imageConfig: imageConfig}
160
161 // Make it available for other modules.
162 ctx.SetProvider(BootImageInfoProvider, info)
163}
164
165func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
166 return defaultBootImageConfig(ctx)
167}