blob: 7cc6231ad54445a773e8c70fef26b7edeab6bcdc [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 Duffin001b2342021-03-11 18:43:31 +000018 "path/filepath"
19
atrostdb25ac02019-08-05 12:26:07 +010020 "android/soong/android"
Cole Fausta963b942024-04-11 17:43:00 -070021
Paul Duffin001b2342021-03-11 18:43:31 +000022 "github.com/google/blueprint"
Spandan Dase4c911e2024-01-19 00:22:22 +000023 "github.com/google/blueprint/proptools"
atrostdb25ac02019-08-05 12:26:07 +010024)
25
26func init() {
Paul Duffin4eb4b412021-03-09 02:59:25 +000027 registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext)
Paul Duffin001b2342021-03-11 18:43:31 +000028
Paul Duffinfcf79852022-07-20 14:18:24 +000029 android.RegisterSdkMemberType(CompatConfigSdkMemberType)
30}
31
32var CompatConfigSdkMemberType = &compatConfigMemberType{
33 SdkMemberTypeBase: android.SdkMemberTypeBase{
34 PropertyName: "compat_configs",
35 SupportsSdk: true,
36 },
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000037}
38
Paul Duffin4eb4b412021-03-09 02:59:25 +000039func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
LaMont Jones0c10e4d2023-05-16 00:58:37 +000040 ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000041 ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
Paul Duffin1b29e002021-03-16 15:06:54 +000042 ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000043 ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
44}
45
46var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
47
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000048func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
49 return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
atrostdb25ac02019-08-05 12:26:07 +010050}
51
52type platformCompatConfigProperties struct {
atrost87901b02019-08-29 12:48:43 +010053 Src *string `android:"path"`
atrostdb25ac02019-08-05 12:26:07 +010054}
55
56type platformCompatConfig struct {
57 android.ModuleBase
58
59 properties platformCompatConfigProperties
Colin Cross70dda7e2019-10-01 22:05:35 -070060 installDirPath android.InstallPath
atrostdb25ac02019-08-05 12:26:07 +010061 configFile android.OutputPath
Mathew Inwood0dd06f62019-12-17 11:14:42 +000062 metadataFile android.OutputPath
Wei Li60333152024-06-18 16:38:31 -070063
64 installConfigFile android.InstallPath
atrostdb25ac02019-08-05 12:26:07 +010065}
66
Paul Duffin29072a92021-03-16 10:12:49 +000067func (p *platformCompatConfig) compatConfigMetadata() android.Path {
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000068 return p.metadataFile
69}
70
atrost6e126252020-01-27 17:01:16 +000071func (p *platformCompatConfig) CompatConfig() android.OutputPath {
72 return p.configFile
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000073}
74
atrost6e126252020-01-27 17:01:16 +000075func (p *platformCompatConfig) SubDir() string {
76 return "compatconfig"
77}
78
Paul Duffin29072a92021-03-16 10:12:49 +000079type platformCompatConfigMetadataProvider interface {
80 compatConfigMetadata() android.Path
81}
82
atrost6e126252020-01-27 17:01:16 +000083type PlatformCompatConfigIntf interface {
84 android.Module
85
atrost6e126252020-01-27 17:01:16 +000086 CompatConfig() android.OutputPath
87 // Sub dir under etc dir.
88 SubDir() string
89}
90
91var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
Paul Duffin29072a92021-03-16 10:12:49 +000092var _ platformCompatConfigMetadataProvider = (*platformCompatConfig)(nil)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000093
Paul Duffin96154332021-03-15 18:18:22 +000094func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
95 rule := android.NewRuleBuilder(pctx, ctx)
96
97 configFileName := p.Name() + ".xml"
98 metadataFileName := p.Name() + "_meta.xml"
99 p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
100 p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
101 path := android.PathForModuleSrc(ctx, String(p.properties.Src))
102
103 rule.Command().
104 BuiltTool("process-compat-config").
105 FlagWithInput("--jar ", path).
106 FlagWithOutput("--device-config ", p.configFile).
107 FlagWithOutput("--merged-config ", p.metadataFile)
108
109 p.installDirPath = android.PathForModuleInstall(ctx, "etc", "compatconfig")
Wei Li60333152024-06-18 16:38:31 -0700110 p.installConfigFile = android.PathForModuleInstall(ctx, "etc", "compatconfig", p.configFile.Base())
Paul Duffin96154332021-03-15 18:18:22 +0000111 rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
Wei Li60333152024-06-18 16:38:31 -0700112}
Paul Duffin96154332021-03-15 18:18:22 +0000113
Wei Li60333152024-06-18 16:38:31 -0700114func (p *platformCompatConfig) FilesToInstall() android.InstallPaths {
115 return android.InstallPaths{p.installConfigFile}
Paul Duffin96154332021-03-15 18:18:22 +0000116}
117
118func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
119 return []android.AndroidMkEntries{android.AndroidMkEntries{
120 Class: "ETC",
121 OutputFile: android.OptionalPathForPath(p.configFile),
122 Include: "$(BUILD_PREBUILT)",
123 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
124 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800125 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
Paul Duffin96154332021-03-15 18:18:22 +0000126 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
127 },
128 },
129 }}
130}
131
132func PlatformCompatConfigFactory() android.Module {
133 module := &platformCompatConfig{}
134 module.AddProperties(&module.properties)
135 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
136 return module
137}
138
Paul Duffin001b2342021-03-11 18:43:31 +0000139type compatConfigMemberType struct {
140 android.SdkMemberTypeBase
141}
142
Paul Duffin296701e2021-07-14 10:29:36 +0100143func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
144 ctx.AddVariationDependencies(nil, dependencyTag, names...)
Paul Duffin001b2342021-03-11 18:43:31 +0000145}
146
147func (b *compatConfigMemberType) IsInstance(module android.Module) bool {
148 _, ok := module.(*platformCompatConfig)
149 return ok
150}
151
152func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
153 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_platform_compat_config")
154}
155
156func (b *compatConfigMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
157 return &compatConfigSdkMemberProperties{}
158}
159
160type compatConfigSdkMemberProperties struct {
161 android.SdkMemberPropertiesBase
162
163 Metadata android.Path
164}
165
166func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
167 module := variant.(*platformCompatConfig)
168 b.Metadata = module.metadataFile
169}
170
171func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
172 builder := ctx.SnapshotBuilder()
173 if b.Metadata != nil {
174 snapshotRelativePath := filepath.Join("compat_configs", ctx.Name(), b.Metadata.Base())
175 builder.CopyToSnapshot(b.Metadata, snapshotRelativePath)
176 propertySet.AddProperty("metadata", snapshotRelativePath)
177 }
178}
179
180var _ android.SdkMemberType = (*compatConfigMemberType)(nil)
181
Paul Duffin1b29e002021-03-16 15:06:54 +0000182// A prebuilt version of the platform compat config module.
183type prebuiltCompatConfigModule struct {
184 android.ModuleBase
Paul Duffin1b29e002021-03-16 15:06:54 +0000185 prebuilt android.Prebuilt
186
187 properties prebuiltCompatConfigProperties
188
189 metadataFile android.Path
190}
191
192type prebuiltCompatConfigProperties struct {
193 Metadata *string `android:"path"`
Spandan Dase4c911e2024-01-19 00:22:22 +0000194
195 // Name of the source soong module that gets shadowed by this prebuilt
196 // If unspecified, follows the naming convention that the source module of
197 // the prebuilt is Name() without "prebuilt_" prefix
198 Source_module_name *string
Paul Duffin1b29e002021-03-16 15:06:54 +0000199}
200
201func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
202 return &module.prebuilt
203}
204
205func (module *prebuiltCompatConfigModule) Name() string {
206 return module.prebuilt.Name(module.ModuleBase.Name())
207}
208
209func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path {
210 return module.metadataFile
211}
212
Spandan Dase4c911e2024-01-19 00:22:22 +0000213func (module *prebuiltCompatConfigModule) BaseModuleName() string {
214 return proptools.StringDefault(module.properties.Source_module_name, module.ModuleBase.Name())
215}
216
Paul Duffin1b29e002021-03-16 15:06:54 +0000217var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
218
219func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
220 module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
221}
222
223// A prebuilt version of platform_compat_config that provides the metadata.
224func prebuiltCompatConfigFactory() android.Module {
225 m := &prebuiltCompatConfigModule{}
226 m.AddProperties(&m.properties)
227 android.InitSingleSourcePrebuiltModule(m, &m.properties, "Metadata")
Paul Duffin1b29e002021-03-16 15:06:54 +0000228 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
229 return m
230}
231
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000232// compat singleton rules
Paul Duffin96154332021-03-15 18:18:22 +0000233type platformCompatConfigSingleton struct {
234 metadata android.Path
235}
236
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000237func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
238
239 var compatConfigMetadata android.Paths
240
241 ctx.VisitAllModules(func(module android.Module) {
Cole Fausta963b942024-04-11 17:43:00 -0700242 if !module.Enabled(ctx) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000243 return
244 }
Paul Duffin29072a92021-03-16 10:12:49 +0000245 if c, ok := module.(platformCompatConfigMetadataProvider); ok {
Paul Duffin458a15b2022-11-25 12:18:24 +0000246 if !android.IsModulePreferred(module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000247 return
248 }
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000249 metadata := c.compatConfigMetadata()
250 compatConfigMetadata = append(compatConfigMetadata, metadata)
251 }
252 })
253
254 if compatConfigMetadata == nil {
255 // nothing to do.
256 return
257 }
258
Colin Crossf1a035e2020-11-16 17:32:30 -0800259 rule := android.NewRuleBuilder(pctx, ctx)
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000260 outputPath := platformCompatConfigPath(ctx)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000261
262 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800263 BuiltTool("process-compat-config").
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000264 FlagForEachInput("--xml ", compatConfigMetadata).
265 FlagWithOutput("--merged-config ", outputPath)
266
Colin Crossf1a035e2020-11-16 17:32:30 -0800267 rule.Build("merged-compat-config", "Merge compat config")
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000268
269 p.metadata = outputPath
270}
271
Mathew Inwood653c78a2019-12-19 12:38:10 +0000272func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
273 if p.metadata != nil {
Herbert Xue67a41bc2024-06-06 15:17:10 +0800274 ctx.DistForGoal("droidcore", p.metadata)
Mathew Inwood653c78a2019-12-19 12:38:10 +0000275 }
276}
277
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000278func platformCompatConfigSingletonFactory() android.Singleton {
279 return &platformCompatConfigSingleton{}
280}
281
Colin Crossd079e0b2022-08-16 10:27:33 -0700282// ============== merged_compat_config =================
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000283type globalCompatConfigProperties struct {
284 // name of the file into which the metadata will be copied.
285 Filename *string
286}
287
288type globalCompatConfig struct {
289 android.ModuleBase
290
291 properties globalCompatConfigProperties
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000292}
293
294func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
295 filename := String(c.properties.Filename)
296
297 inputPath := platformCompatConfigPath(ctx)
mrziwang9e7127f2024-06-18 16:10:47 -0700298 outputFilePath := android.PathForModuleOut(ctx, filename).OutputPath
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000299
300 // This ensures that outputFilePath has the correct name for others to
301 // use, as the source file may have a different name.
302 ctx.Build(pctx, android.BuildParams{
303 Rule: android.Cp,
mrziwang9e7127f2024-06-18 16:10:47 -0700304 Output: outputFilePath,
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000305 Input: inputPath,
306 })
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000307
mrziwang9e7127f2024-06-18 16:10:47 -0700308 ctx.SetOutputFiles(android.Paths{outputFilePath}, "")
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000309}
310
311// global_compat_config provides access to the merged compat config xml file generated by the build.
312func globalCompatConfigFactory() android.Module {
313 module := &globalCompatConfig{}
314 module.AddProperties(&module.properties)
315 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
316 return module
317}