blob: cb8e6841a1e05aa4396d9c7e2133c993ce85849f [file] [log] [blame]
// Copyright 2019 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package java
import (
"android/soong/android"
"fmt"
)
func init() {
android.RegisterSingletonType("platform_compat_config_singleton", platformCompatConfigSingletonFactory)
android.RegisterModuleType("platform_compat_config", PlatformCompatConfigFactory)
android.RegisterModuleType("global_compat_config", globalCompatConfigFactory)
}
func platformCompatConfigPath(ctx android.PathContext) android.OutputPath {
return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml")
}
type platformCompatConfigSingleton struct {
metadata android.Path
}
type platformCompatConfigProperties struct {
Src *string `android:"path"`
}
type platformCompatConfig struct {
android.ModuleBase
properties platformCompatConfigProperties
installDirPath android.InstallPath
configFile android.OutputPath
metadataFile android.OutputPath
}
func (p *platformCompatConfig) compatConfigMetadata() android.OutputPath {
return p.metadataFile
}
func (p *platformCompatConfig) CompatConfig() android.OutputPath {
return p.configFile
}
func (p *platformCompatConfig) SubDir() string {
return "compatconfig"
}
type PlatformCompatConfigIntf interface {
android.Module
compatConfigMetadata() android.OutputPath
CompatConfig() android.OutputPath
// Sub dir under etc dir.
SubDir() string
}
var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil)
// compat singleton rules
func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var compatConfigMetadata android.Paths
ctx.VisitAllModules(func(module android.Module) {
if c, ok := module.(PlatformCompatConfigIntf); ok {
metadata := c.compatConfigMetadata()
compatConfigMetadata = append(compatConfigMetadata, metadata)
}
})
if compatConfigMetadata == nil {
// nothing to do.
return
}
rule := android.NewRuleBuilder()
outputPath := platformCompatConfigPath(ctx)
rule.Command().
BuiltTool(ctx, "process-compat-config").
FlagForEachInput("--xml ", compatConfigMetadata).
FlagWithOutput("--merged-config ", outputPath)
rule.Build(pctx, ctx, "merged-compat-config", "Merge compat config")
p.metadata = outputPath
}
func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
if p.metadata != nil {
ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String())
}
}
func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
rule := android.NewRuleBuilder()
configFileName := p.Name() + ".xml"
metadataFileName := p.Name() + "_meta.xml"
p.configFile = android.PathForModuleOut(ctx, configFileName).OutputPath
p.metadataFile = android.PathForModuleOut(ctx, metadataFileName).OutputPath
path := android.PathForModuleSrc(ctx, String(p.properties.Src))
rule.Command().
BuiltTool(ctx, "process-compat-config").
FlagWithInput("--jar ", path).
FlagWithOutput("--device-config ", p.configFile).
FlagWithOutput("--merged-config ", p.metadataFile)
p.installDirPath = android.PathForModuleInstall(ctx, "etc", "compatconfig")
rule.Build(pctx, ctx, configFileName, "Extract compat/compat_config.xml and install it")
}
func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "ETC",
OutputFile: android.OptionalPathForPath(p.configFile),
Include: "$(BUILD_PREBUILT)",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
},
},
}}
}
func platformCompatConfigSingletonFactory() android.Singleton {
return &platformCompatConfigSingleton{}
}
func PlatformCompatConfigFactory() android.Module {
module := &platformCompatConfig{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
return module
}
//============== merged_compat_config =================
type globalCompatConfigProperties struct {
// name of the file into which the metadata will be copied.
Filename *string
}
type globalCompatConfig struct {
android.ModuleBase
properties globalCompatConfigProperties
outputFilePath android.OutputPath
}
func (c *globalCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) {
filename := String(c.properties.Filename)
inputPath := platformCompatConfigPath(ctx)
c.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
// This ensures that outputFilePath has the correct name for others to
// use, as the source file may have a different name.
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Output: c.outputFilePath,
Input: inputPath,
})
}
func (h *globalCompatConfig) OutputFiles(tag string) (android.Paths, error) {
switch tag {
case "":
return android.Paths{h.outputFilePath}, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
}
// global_compat_config provides access to the merged compat config xml file generated by the build.
func globalCompatConfigFactory() android.Module {
module := &globalCompatConfig{}
module.AddProperties(&module.properties)
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
return module
}