blob: 124827523b44dd2345339459999d87feba55252a [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"
Jihoon Kang346a1172023-05-17 10:17:30 +000022 "android/soong/bazel"
23
Paul Duffin001b2342021-03-11 18:43:31 +000024 "github.com/google/blueprint"
Jihoon Kang346a1172023-05-17 10:17:30 +000025 "github.com/google/blueprint/proptools"
atrostdb25ac02019-08-05 12:26:07 +010026)
27
28func init() {
Paul Duffin4eb4b412021-03-09 02:59:25 +000029 registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext)
Paul Duffin001b2342021-03-11 18:43:31 +000030
Paul Duffinfcf79852022-07-20 14:18:24 +000031 android.RegisterSdkMemberType(CompatConfigSdkMemberType)
32}
33
34var CompatConfigSdkMemberType = &compatConfigMemberType{
35 SdkMemberTypeBase: android.SdkMemberTypeBase{
36 PropertyName: "compat_configs",
37 SupportsSdk: true,
38 },
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000039}
40
Paul Duffin4eb4b412021-03-09 02:59:25 +000041func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
LaMont Jones0c10e4d2023-05-16 00:58:37 +000042 ctx.RegisterParallelSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000043 ctx.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
Paul Duffin1b29e002021-03-16 15:06:54 +000044 ctx.RegisterModuleType("prebuilt_platform_compat_config", prebuiltCompatConfigFactory)
Paul Duffin4eb4b412021-03-09 02:59:25 +000045 ctx.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
46}
47
48var PrepareForTestWithPlatformCompatConfig = android.FixtureRegisterWithContext(registerPlatformCompatConfigBuildComponents)
49
Mathew Inwoodabd49ab2019-12-19 14:27:08 +000050func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
51 return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
atrostdb25ac02019-08-05 12:26:07 +010052}
53
54type platformCompatConfigProperties struct {
atrost87901b02019-08-29 12:48:43 +010055 Src *string `android:"path"`
atrostdb25ac02019-08-05 12:26:07 +010056}
57
58type platformCompatConfig struct {
59 android.ModuleBase
Jihoon Kang346a1172023-05-17 10:17:30 +000060 android.BazelModuleBase
atrostdb25ac02019-08-05 12:26:07 +010061
62 properties platformCompatConfigProperties
Colin Cross70dda7e2019-10-01 22:05:35 -070063 installDirPath android.InstallPath
atrostdb25ac02019-08-05 12:26:07 +010064 configFile android.OutputPath
Mathew Inwood0dd06f62019-12-17 11:14:42 +000065 metadataFile android.OutputPath
atrostdb25ac02019-08-05 12:26:07 +010066}
67
Paul Duffin29072a92021-03-16 10:12:49 +000068func (p *platformCompatConfig) compatConfigMetadata() android.Path {
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000069 return p.metadataFile
70}
71
atrost6e126252020-01-27 17:01:16 +000072func (p *platformCompatConfig) CompatConfig() android.OutputPath {
73 return p.configFile
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000074}
75
atrost6e126252020-01-27 17:01:16 +000076func (p *platformCompatConfig) SubDir() string {
77 return "compatconfig"
78}
79
Paul Duffin29072a92021-03-16 10:12:49 +000080type platformCompatConfigMetadataProvider interface {
81 compatConfigMetadata() android.Path
82}
83
atrost6e126252020-01-27 17:01:16 +000084type PlatformCompatConfigIntf interface {
85 android.Module
86
atrost6e126252020-01-27 17:01:16 +000087 CompatConfig() android.OutputPath
88 // Sub dir under etc dir.
89 SubDir() string
90}
91
92var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
Paul Duffin29072a92021-03-16 10:12:49 +000093var _ platformCompatConfigMetadataProvider = (*platformCompatConfig)(nil)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +000094
Paul Duffin96154332021-03-15 18:18:22 +000095func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
96 rule := android.NewRuleBuilder(pctx, ctx)
97
98 configFileName := p.Name() + ".xml"
99 metadataFileName := p.Name() + "_meta.xml"
100 p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
101 p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
102 path := android.PathForModuleSrc(ctx, String(p.properties.Src))
103
104 rule.Command().
105 BuiltTool("process-compat-config").
106 FlagWithInput("--jar ", path).
107 FlagWithOutput("--device-config ", p.configFile).
108 FlagWithOutput("--merged-config ", p.metadataFile)
109
110 p.installDirPath = android.PathForModuleInstall(ctx, "etc", "compatconfig")
111 rule.Build(configFileName, "Extract compat/compat_config.xml and install it")
112
113}
114
115func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
116 return []android.AndroidMkEntries{android.AndroidMkEntries{
117 Class: "ETC",
118 OutputFile: android.OptionalPathForPath(p.configFile),
119 Include: "$(BUILD_PREBUILT)",
120 ExtraEntries: []android.AndroidMkExtraEntriesFunc{
121 func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
Colin Crossc68db4b2021-11-11 18:59:15 -0800122 entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
Paul Duffin96154332021-03-15 18:18:22 +0000123 entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
124 },
125 },
126 }}
127}
128
Jihoon Kang346a1172023-05-17 10:17:30 +0000129type bazelPlatformCompatConfigAttributes struct {
130 Src bazel.LabelAttribute
131}
132
133func (p *platformCompatConfig) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
134 props := bazel.BazelTargetModuleProperties{
135 Rule_class: "platform_compat_config",
136 Bzl_load_location: "//build/bazel/rules/java:platform_compat_config.bzl",
137 }
138 attr := &bazelPlatformCompatConfigAttributes{
139 Src: *bazel.MakeLabelAttribute(
140 android.BazelLabelForModuleSrcSingle(ctx, proptools.String(p.properties.Src)).Label),
141 }
142 ctx.CreateBazelTargetModule(props, android.CommonAttributes{
143 Name: p.Name(),
144 }, attr)
145}
146
Paul Duffin96154332021-03-15 18:18:22 +0000147func PlatformCompatConfigFactory() android.Module {
148 module := &platformCompatConfig{}
149 module.AddProperties(&module.properties)
150 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
Jihoon Kang346a1172023-05-17 10:17:30 +0000151 android.InitBazelModule(module)
Paul Duffin96154332021-03-15 18:18:22 +0000152 return module
153}
154
Paul Duffin001b2342021-03-11 18:43:31 +0000155type compatConfigMemberType struct {
156 android.SdkMemberTypeBase
157}
158
Paul Duffin296701e2021-07-14 10:29:36 +0100159func (b *compatConfigMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
160 ctx.AddVariationDependencies(nil, dependencyTag, names...)
Paul Duffin001b2342021-03-11 18:43:31 +0000161}
162
163func (b *compatConfigMemberType) IsInstance(module android.Module) bool {
164 _, ok := module.(*platformCompatConfig)
165 return ok
166}
167
168func (b *compatConfigMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
169 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_platform_compat_config")
170}
171
172func (b *compatConfigMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
173 return &compatConfigSdkMemberProperties{}
174}
175
176type compatConfigSdkMemberProperties struct {
177 android.SdkMemberPropertiesBase
178
179 Metadata android.Path
180}
181
182func (b *compatConfigSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
183 module := variant.(*platformCompatConfig)
184 b.Metadata = module.metadataFile
185}
186
187func (b *compatConfigSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
188 builder := ctx.SnapshotBuilder()
189 if b.Metadata != nil {
190 snapshotRelativePath := filepath.Join("compat_configs", ctx.Name(), b.Metadata.Base())
191 builder.CopyToSnapshot(b.Metadata, snapshotRelativePath)
192 propertySet.AddProperty("metadata", snapshotRelativePath)
193 }
194}
195
196var _ android.SdkMemberType = (*compatConfigMemberType)(nil)
197
Paul Duffin1b29e002021-03-16 15:06:54 +0000198// A prebuilt version of the platform compat config module.
199type prebuiltCompatConfigModule struct {
200 android.ModuleBase
Paul Duffin1b29e002021-03-16 15:06:54 +0000201 prebuilt android.Prebuilt
202
203 properties prebuiltCompatConfigProperties
204
205 metadataFile android.Path
206}
207
208type prebuiltCompatConfigProperties struct {
209 Metadata *string `android:"path"`
210}
211
212func (module *prebuiltCompatConfigModule) Prebuilt() *android.Prebuilt {
213 return &module.prebuilt
214}
215
216func (module *prebuiltCompatConfigModule) Name() string {
217 return module.prebuilt.Name(module.ModuleBase.Name())
218}
219
220func (module *prebuiltCompatConfigModule) compatConfigMetadata() android.Path {
221 return module.metadataFile
222}
223
224var _ platformCompatConfigMetadataProvider = (*prebuiltCompatConfigModule)(nil)
225
226func (module *prebuiltCompatConfigModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
227 module.metadataFile = module.prebuilt.SingleSourcePath(ctx)
228}
229
230// A prebuilt version of platform_compat_config that provides the metadata.
231func prebuiltCompatConfigFactory() android.Module {
232 m := &prebuiltCompatConfigModule{}
233 m.AddProperties(&m.properties)
234 android.InitSingleSourcePrebuiltModule(m, &m.properties, "Metadata")
Paul Duffin1b29e002021-03-16 15:06:54 +0000235 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
236 return m
237}
238
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000239// compat singleton rules
Paul Duffin96154332021-03-15 18:18:22 +0000240type platformCompatConfigSingleton struct {
241 metadata android.Path
242}
243
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000244func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
245
246 var compatConfigMetadata android.Paths
247
248 ctx.VisitAllModules(func(module android.Module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000249 if !module.Enabled() {
250 return
251 }
Paul Duffin29072a92021-03-16 10:12:49 +0000252 if c, ok := module.(platformCompatConfigMetadataProvider); ok {
Paul Duffin458a15b2022-11-25 12:18:24 +0000253 if !android.IsModulePreferred(module) {
Paul Duffinbb9ff512021-03-24 12:08:53 +0000254 return
255 }
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000256 metadata := c.compatConfigMetadata()
257 compatConfigMetadata = append(compatConfigMetadata, metadata)
258 }
259 })
260
261 if compatConfigMetadata == nil {
262 // nothing to do.
263 return
264 }
265
Colin Crossf1a035e2020-11-16 17:32:30 -0800266 rule := android.NewRuleBuilder(pctx, ctx)
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000267 outputPath := platformCompatConfigPath(ctx)
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000268
269 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800270 BuiltTool("process-compat-config").
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000271 FlagForEachInput("--xml ", compatConfigMetadata).
272 FlagWithOutput("--merged-config ", outputPath)
273
Colin Crossf1a035e2020-11-16 17:32:30 -0800274 rule.Build("merged-compat-config", "Merge compat config")
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000275
276 p.metadata = outputPath
277}
278
Mathew Inwood653c78a2019-12-19 12:38:10 +0000279func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
280 if p.metadata != nil {
281 ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String())
282 }
283}
284
Mathew Inwood4d0c19c2019-12-09 11:32:29 +0000285func platformCompatConfigSingletonFactory() android.Singleton {
286 return &platformCompatConfigSingleton{}
287}
288
Colin Crossd079e0b2022-08-16 10:27:33 -0700289// ============== merged_compat_config =================
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000290type globalCompatConfigProperties struct {
291 // name of the file into which the metadata will be copied.
292 Filename *string
293}
294
295type globalCompatConfig struct {
296 android.ModuleBase
297
298 properties globalCompatConfigProperties
299
300 outputFilePath android.OutputPath
301}
302
303func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
304 filename := String(c.properties.Filename)
305
306 inputPath := platformCompatConfigPath(ctx)
307 c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
308
309 // This ensures that outputFilePath has the correct name for others to
310 // use, as the source file may have a different name.
311 ctx.Build(pctx, android.BuildParams{
312 Rule: android.Cp,
313 Output: c.outputFilePath,
314 Input: inputPath,
315 })
316}
317
318func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
319 switch tag {
320 case "":
321 return android.Paths{h.outputFilePath}, nil
322 default:
323 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
324 }
325}
326
327// global_compat_config provides access to the merged compat config xml file generated by the build.
328func globalCompatConfigFactory() android.Module {
329 module := &globalCompatConfig{}
330 module.AddProperties(&module.properties)
331 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
332 return module
333}