blob: 2197304a53337b0f1ea0b64e666c8a2745d0c6b4 [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"
Paul Duffin001b2342021-03-11 18:43:31 +000022 "github.com/google/blueprint"
atrostdb25ac02019-08-05 12:26:07 +010023)
24
25func init() {
Paul Duffin4eb4b412021-03-09 02:59:25 +000026 registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext)
Paul Duffin001b2342021-03-11 18:43:31 +000027
Paul Duffinfcf79852022-07-20 14:18:24 +000028 android.RegisterSdkMemberType(CompatConfigSdkMemberType)
29}
30
31var CompatConfigSdkMemberType = &compatConfigMemberType{
32 SdkMemberTypeBase: android.SdkMemberTypeBase{
33 PropertyName: "compat_configs",
34 SupportsSdk: true,
35 },
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000036}
37
Paul Duffin4eb4b412021-03-09 02:59:25 +000038func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
LaMont Jones0c10e4d2023-05-16 00:58:37 +000039 ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000040 ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
Paul Duffin1b29e002021-03-16 15:06:54 +000041 ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000042 ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
43}
44
45var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
46
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000047func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
48 return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
atrostdb25ac02019-08-05 12:26:07 +010049}
50
51type platformCompatConfigProperties struct {
atrost87901b02019-08-29 12:48:43 +010052 Src *string `android:"path"`
atrostdb25ac02019-08-05 12:26:07 +010053}
54
55type platformCompatConfig struct {
56 android.ModuleBase
57
58 properties platformCompatConfigProperties
Colin Cross70dda7e2019-10-01 22:05:35 -070059 installDirPath android.InstallPath
atrostdb25ac02019-08-05 12:26:07 +010060 configFile android.OutputPath
Mathew Inwood0dd06f62019-12-17 11:14:42 +000061 metadataFile android.OutputPath
atrostdb25ac02019-08-05 12:26:07 +010062}
63
Paul Duffin29072a92021-03-16 10:12:49 +000064func (p *platformCompatConfig) compatConfigMetadata() android.Path {
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000065 return p.metadataFile
66}
67
atrost6e126252020-01-27 17:01:16 +000068func (p *platformCompatConfig) CompatConfig() android.OutputPath {
69 return p.configFile
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000070}
71
atrost6e126252020-01-27 17:01:16 +000072func (p *platformCompatConfig) SubDir() string {
73 return "compatconfig"
74}
75
Paul Duffin29072a92021-03-16 10:12:49 +000076type platformCompatConfigMetadataProvider interface {
77 compatConfigMetadata() android.Path
78}
79
atrost6e126252020-01-27 17:01:16 +000080type PlatformCompatConfigIntf interface {
81 android.Module
82
atrost6e126252020-01-27 17:01:16 +000083 CompatConfig() android.OutputPath
84 // Sub dir under etc dir.
85 SubDir() string
86}
87
88var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
Paul Duffin29072a92021-03-16 10:12:49 +000089var _ platformCompatConfigMetadataProvider = (*platformCompatConfig)(nil)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000090
Paul Duffin96154332021-03-15 18:18:22 +000091func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
92 rule := android.NewRuleBuilder(pctx, ctx)
93
94 configFileName := p.Name() + ".xml"
95 metadataFileName := p.Name() + "_meta.xml"
96 p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
97 p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
98 path := android.PathForModuleSrc(ctx, String(p.properties.Src))
99
100 rule.Command().
101 BuiltTool("process-compat-config").
102 FlagWithInput("--jar ", path).
103 FlagWithOutput("--device-config ", p.configFile).
104 FlagWithOutput("--merged-config ", p.metadataFile)
105
106 p.installDirPath = android.PathForModuleInstall(ctx, "etc", "compatconfig")
107 rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
108
109}
110
111func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
112 return []android.AndroidMkEntries{android.AndroidMkEntries{
113 Class: "ETC",
114 OutputFile: android.OptionalPathForPath(p.configFile),
115 Include: "$(BUILD_PREBUILT)",
116 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
117 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800118 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
Paul Duffin96154332021-03-15 18:18:22 +0000119 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
120 },
121 },
122 }}
123}
124
125func PlatformCompatConfigFactory() android.Module {
126 module := &platformCompatConfig{}
127 module.AddProperties(&module.properties)
128 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
129 return module
130}
131
Paul Duffin001b2342021-03-11 18:43:31 +0000132type compatConfigMemberType struct {
133 android.SdkMemberTypeBase
134}
135
Paul Duffin296701e2021-07-14 10:29:36 +0100136func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
137 ctx.AddVariationDependencies(nil, dependencyTag, names...)
Paul Duffin001b2342021-03-11 18:43:31 +0000138}
139
140func (b *compatConfigMemberType) IsInstance(module android.Module) bool {
141 _, ok := module.(*platformCompatConfig)
142 return ok
143}
144
145func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
146 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_platform_compat_config")
147}
148
149func (b *compatConfigMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
150 return &compatConfigSdkMemberProperties{}
151}
152
153type compatConfigSdkMemberProperties struct {
154 android.SdkMemberPropertiesBase
155
156 Metadata android.Path
157}
158
159func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
160 module := variant.(*platformCompatConfig)
161 b.Metadata = module.metadataFile
162}
163
164func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
165 builder := ctx.SnapshotBuilder()
166 if b.Metadata != nil {
167 snapshotRelativePath := filepath.Join("compat_configs", ctx.Name(), b.Metadata.Base())
168 builder.CopyToSnapshot(b.Metadata, snapshotRelativePath)
169 propertySet.AddProperty("metadata", snapshotRelativePath)
170 }
171}
172
173var _ android.SdkMemberType = (*compatConfigMemberType)(nil)
174
Paul Duffin1b29e002021-03-16 15:06:54 +0000175// A prebuilt version of the platform compat config module.
176type prebuiltCompatConfigModule struct {
177 android.ModuleBase
Paul Duffin1b29e002021-03-16 15:06:54 +0000178 prebuilt android.Prebuilt
179
180 properties prebuiltCompatConfigProperties
181
182 metadataFile android.Path
183}
184
185type prebuiltCompatConfigProperties struct {
186 Metadata *string `android:"path"`
187}
188
189func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
190 return &module.prebuilt
191}
192
193func (module *prebuiltCompatConfigModule) Name() string {
194 return module.prebuilt.Name(module.ModuleBase.Name())
195}
196
197func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path {
198 return module.metadataFile
199}
200
201var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
202
203func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
204 module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
205}
206
207// A prebuilt version of platform_compat_config that provides the metadata.
208func prebuiltCompatConfigFactory() android.Module {
209 m := &prebuiltCompatConfigModule{}
210 m.AddProperties(&m.properties)
211 android.InitSingleSourcePrebuiltModule(m, &m.properties, "Metadata")
Paul Duffin1b29e002021-03-16 15:06:54 +0000212 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
213 return m
214}
215
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000216// compat singleton rules
Paul Duffin96154332021-03-15 18:18:22 +0000217type platformCompatConfigSingleton struct {
218 metadata android.Path
219}
220
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000221func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
222
223 var compatConfigMetadata android.Paths
224
225 ctx.VisitAllModules(func(module android.Module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000226 if !module.Enabled() {
227 return
228 }
Paul Duffin29072a92021-03-16 10:12:49 +0000229 if c, ok := module.(platformCompatConfigMetadataProvider); ok {
Paul Duffin458a15b2022-11-25 12:18:24 +0000230 if !android.IsModulePreferred(module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000231 return
232 }
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000233 metadata := c.compatConfigMetadata()
234 compatConfigMetadata = append(compatConfigMetadata, metadata)
235 }
236 })
237
238 if compatConfigMetadata == nil {
239 // nothing to do.
240 return
241 }
242
Colin Crossf1a035e2020-11-16 17:32:30 -0800243 rule := android.NewRuleBuilder(pctx, ctx)
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000244 outputPath := platformCompatConfigPath(ctx)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000245
246 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800247 BuiltTool("process-compat-config").
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000248 FlagForEachInput("--xml ", compatConfigMetadata).
249 FlagWithOutput("--merged-config ", outputPath)
250
Colin Crossf1a035e2020-11-16 17:32:30 -0800251 rule.Build("merged-compat-config", "Merge compat config")
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000252
253 p.metadata = outputPath
254}
255
Mathew Inwood653c78a2019-12-19 12:38:10 +0000256func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
257 if p.metadata != nil {
258 ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String())
259 }
260}
261
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000262func platformCompatConfigSingletonFactory() android.Singleton {
263 return &platformCompatConfigSingleton{}
264}
265
Colin Crossd079e0b2022-08-16 10:27:33 -0700266// ============== merged_compat_config =================
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000267type globalCompatConfigProperties struct {
268 // name of the file into which the metadata will be copied.
269 Filename *string
270}
271
272type globalCompatConfig struct {
273 android.ModuleBase
274
275 properties globalCompatConfigProperties
276
277 outputFilePath android.OutputPath
278}
279
280func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
281 filename := String(c.properties.Filename)
282
283 inputPath := platformCompatConfigPath(ctx)
284 c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
285
286 // This ensures that outputFilePath has the correct name for others to
287 // use, as the source file may have a different name.
288 ctx.Build(pctx, android.BuildParams{
289 Rule: android.Cp,
290 Output: c.outputFilePath,
291 Input: inputPath,
292 })
293}
294
295func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
296 switch tag {
297 case "":
298 return android.Paths{h.outputFilePath}, nil
299 default:
300 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
301 }
302}
303
304// global_compat_config provides access to the merged compat config xml file generated by the build.
305func globalCompatConfigFactory() android.Module {
306 module := &globalCompatConfig{}
307 module.AddProperties(&module.properties)
308 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
309 return module
310}