blob: 49756dd99157b29c02419454b517e649c1a0e105 [file] [log] [blame]
atrostdb25ac02019-08-05 12:26:07 +01001// Copyright 2019 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 (
Paul Duffind796f6f2022-11-23 23:06:05 +000018 "fmt"
Paul Duffin001b2342021-03-11 18:43:31 +000019 "path/filepath"
20
atrostdb25ac02019-08-05 12:26:07 +010021 "android/soong/android"
Cole Fausta963b942024-04-11 17:43:00 -070022
Paul Duffin001b2342021-03-11 18:43:31 +000023 "github.com/google/blueprint"
Spandan Dase4c911e2024-01-19 00:22:22 +000024 "github.com/google/blueprint/proptools"
atrostdb25ac02019-08-05 12:26:07 +010025)
26
27func init() {
Paul Duffin4eb4b412021-03-09 02:59:25 +000028 registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext)
Paul Duffin001b2342021-03-11 18:43:31 +000029
Paul Duffinfcf79852022-07-20 14:18:24 +000030 android.RegisterSdkMemberType(CompatConfigSdkMemberType)
31}
32
33var CompatConfigSdkMemberType = &compatConfigMemberType{
34 SdkMemberTypeBase: android.SdkMemberTypeBase{
35 PropertyName: "compat_configs",
36 SupportsSdk: true,
37 },
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000038}
39
Paul Duffin4eb4b412021-03-09 02:59:25 +000040func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
LaMont Jones0c10e4d2023-05-16 00:58:37 +000041 ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000042 ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
Paul Duffin1b29e002021-03-16 15:06:54 +000043 ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000044 ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
45}
46
47var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
48
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000049func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
50 return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
atrostdb25ac02019-08-05 12:26:07 +010051}
52
53type platformCompatConfigProperties struct {
atrost87901b02019-08-29 12:48:43 +010054 Src *string `android:"path"`
atrostdb25ac02019-08-05 12:26:07 +010055}
56
57type platformCompatConfig struct {
58 android.ModuleBase
59
60 properties platformCompatConfigProperties
Colin Cross70dda7e2019-10-01 22:05:35 -070061 installDirPath android.InstallPath
atrostdb25ac02019-08-05 12:26:07 +010062 configFile android.OutputPath
Mathew Inwood0dd06f62019-12-17 11:14:42 +000063 metadataFile android.OutputPath
atrostdb25ac02019-08-05 12:26:07 +010064}
65
Paul Duffin29072a92021-03-16 10:12:49 +000066func (p *platformCompatConfig) compatConfigMetadata() android.Path {
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000067 return p.metadataFile
68}
69
atrost6e126252020-01-27 17:01:16 +000070func (p *platformCompatConfig) CompatConfig() android.OutputPath {
71 return p.configFile
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000072}
73
atrost6e126252020-01-27 17:01:16 +000074func (p *platformCompatConfig) SubDir() string {
75 return "compatconfig"
76}
77
Paul Duffin29072a92021-03-16 10:12:49 +000078type platformCompatConfigMetadataProvider interface {
79 compatConfigMetadata() android.Path
80}
81
atrost6e126252020-01-27 17:01:16 +000082type PlatformCompatConfigIntf interface {
83 android.Module
84
atrost6e126252020-01-27 17:01:16 +000085 CompatConfig() android.OutputPath
86 // Sub dir under etc dir.
87 SubDir() string
88}
89
90var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
Paul Duffin29072a92021-03-16 10:12:49 +000091var _ platformCompatConfigMetadataProvider = (*platformCompatConfig)(nil)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000092
Paul Duffin96154332021-03-15 18:18:22 +000093func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
94 rule := android.NewRuleBuilder(pctx, ctx)
95
96 configFileName := p.Name() + ".xml"
97 metadataFileName := p.Name() + "_meta.xml"
98 p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
99 p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
100 path := android.PathForModuleSrc(ctx, String(p.properties.Src))
101
102 rule.Command().
103 BuiltTool("process-compat-config").
104 FlagWithInput("--jar ", path).
105 FlagWithOutput("--device-config ", p.configFile).
106 FlagWithOutput("--merged-config ", p.metadataFile)
107
108 p.installDirPath = android.PathForModuleInstall(ctx, "etc", "compatconfig")
109 rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
110
111}
112
113func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
114 return []android.AndroidMkEntries{android.AndroidMkEntries{
115 Class: "ETC",
116 OutputFile: android.OptionalPathForPath(p.configFile),
117 Include: "$(BUILD_PREBUILT)",
118 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
119 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800120 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
Paul Duffin96154332021-03-15 18:18:22 +0000121 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
122 },
123 },
124 }}
125}
126
127func PlatformCompatConfigFactory() android.Module {
128 module := &platformCompatConfig{}
129 module.AddProperties(&module.properties)
130 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
131 return module
132}
133
Paul Duffin001b2342021-03-11 18:43:31 +0000134type compatConfigMemberType struct {
135 android.SdkMemberTypeBase
136}
137
Paul Duffin296701e2021-07-14 10:29:36 +0100138func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
139 ctx.AddVariationDependencies(nil, dependencyTag, names...)
Paul Duffin001b2342021-03-11 18:43:31 +0000140}
141
142func (b *compatConfigMemberType) IsInstance(module android.Module) bool {
143 _, ok := module.(*platformCompatConfig)
144 return ok
145}
146
147func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
148 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_platform_compat_config")
149}
150
151func (b *compatConfigMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
152 return &compatConfigSdkMemberProperties{}
153}
154
155type compatConfigSdkMemberProperties struct {
156 android.SdkMemberPropertiesBase
157
158 Metadata android.Path
159}
160
161func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
162 module := variant.(*platformCompatConfig)
163 b.Metadata = module.metadataFile
164}
165
166func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
167 builder := ctx.SnapshotBuilder()
168 if b.Metadata != nil {
169 snapshotRelativePath := filepath.Join("compat_configs", ctx.Name(), b.Metadata.Base())
170 builder.CopyToSnapshot(b.Metadata, snapshotRelativePath)
171 propertySet.AddProperty("metadata", snapshotRelativePath)
172 }
173}
174
175var _ android.SdkMemberType = (*compatConfigMemberType)(nil)
176
Paul Duffin1b29e002021-03-16 15:06:54 +0000177// A prebuilt version of the platform compat config module.
178type prebuiltCompatConfigModule struct {
179 android.ModuleBase
Paul Duffin1b29e002021-03-16 15:06:54 +0000180 prebuilt android.Prebuilt
181
182 properties prebuiltCompatConfigProperties
183
184 metadataFile android.Path
185}
186
187type prebuiltCompatConfigProperties struct {
188 Metadata *string `android:"path"`
Spandan Dase4c911e2024-01-19 00:22:22 +0000189
190 // Name of the source soong module that gets shadowed by this prebuilt
191 // If unspecified, follows the naming convention that the source module of
192 // the prebuilt is Name() without "prebuilt_" prefix
193 Source_module_name *string
Paul Duffin1b29e002021-03-16 15:06:54 +0000194}
195
196func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
197 return &module.prebuilt
198}
199
200func (module *prebuiltCompatConfigModule) Name() string {
201 return module.prebuilt.Name(module.ModuleBase.Name())
202}
203
204func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path {
205 return module.metadataFile
206}
207
Spandan Dase4c911e2024-01-19 00:22:22 +0000208func (module *prebuiltCompatConfigModule) BaseModuleName() string {
209 return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
210}
211
Paul Duffin1b29e002021-03-16 15:06:54 +0000212var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
213
214func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
215 module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
216}
217
218// A prebuilt version of platform_compat_config that provides the metadata.
219func prebuiltCompatConfigFactory() android.Module {
220 m := &prebuiltCompatConfigModule{}
221 m.AddProperties(&m.properties)
222 android.InitSingleSourcePrebuiltModule(m, &m.properties, "Metadata")
Paul Duffin1b29e002021-03-16 15:06:54 +0000223 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
224 return m
225}
226
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000227// compat singleton rules
Paul Duffin96154332021-03-15 18:18:22 +0000228type platformCompatConfigSingleton struct {
229 metadata android.Path
230}
231
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000232func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
233
234 var compatConfigMetadata android.Paths
235
236 ctx.VisitAllModules(func(module android.Module) {
Cole Fausta963b942024-04-11 17:43:00 -0700237 if !module.Enabled(ctx) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000238 return
239 }
Paul Duffin29072a92021-03-16 10:12:49 +0000240 if c, ok := module.(platformCompatConfigMetadataProvider); ok {
Paul Duffin458a15b2022-11-25 12:18:24 +0000241 if !android.IsModulePreferred(module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000242 return
243 }
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000244 metadata := c.compatConfigMetadata()
245 compatConfigMetadata = append(compatConfigMetadata, metadata)
246 }
247 })
248
249 if compatConfigMetadata == nil {
250 // nothing to do.
251 return
252 }
253
Colin Crossf1a035e2020-11-16 17:32:30 -0800254 rule := android.NewRuleBuilder(pctx, ctx)
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000255 outputPath := platformCompatConfigPath(ctx)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000256
257 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800258 BuiltTool("process-compat-config").
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000259 FlagForEachInput("--xml ", compatConfigMetadata).
260 FlagWithOutput("--merged-config ", outputPath)
261
Colin Crossf1a035e2020-11-16 17:32:30 -0800262 rule.Build("merged-compat-config", "Merge compat config")
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000263
264 p.metadata = outputPath
265}
266
Mathew Inwood653c78a2019-12-19 12:38:10 +0000267func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
268 if p.metadata != nil {
Herbert Xue67a41bc2024-06-06 15:17:10 +0800269 ctx.DistForGoal("droidcore", p.metadata)
Mathew Inwood653c78a2019-12-19 12:38:10 +0000270 }
271}
272
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000273func platformCompatConfigSingletonFactory() android.Singleton {
274 return &platformCompatConfigSingleton{}
275}
276
Colin Crossd079e0b2022-08-16 10:27:33 -0700277// ============== merged_compat_config =================
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000278type globalCompatConfigProperties struct {
279 // name of the file into which the metadata will be copied.
280 Filename *string
281}
282
283type globalCompatConfig struct {
284 android.ModuleBase
285
286 properties globalCompatConfigProperties
287
288 outputFilePath android.OutputPath
289}
290
291func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
292 filename := String(c.properties.Filename)
293
294 inputPath := platformCompatConfigPath(ctx)
295 c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
296
297 // This ensures that outputFilePath has the correct name for others to
298 // use, as the source file may have a different name.
299 ctx.Build(pctx, android.BuildParams{
300 Rule: android.Cp,
301 Output: c.outputFilePath,
302 Input: inputPath,
303 })
304}
305
306func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
307 switch tag {
308 case "":
309 return android.Paths{h.outputFilePath}, nil
310 default:
311 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
312 }
313}
314
315// global_compat_config provides access to the merged compat config xml file generated by the build.
316func globalCompatConfigFactory() android.Module {
317 module := &globalCompatConfig{}
318 module.AddProperties(&module.properties)
319 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
320 return module
321}