1// Copyright 2024 Google Inc. All rights reserved. 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14package systemfeatures 15 16import ( 17 "fmt" 18 "sort" 19 "strings" 20 21 "android/soong/android" 22 "android/soong/genrule" 23) 24 25var ( 26 pctx = android.NewPackageContext("android/soong/systemfeatures") 27) 28 29func init() { 30 registerSystemFeaturesComponents(android.InitRegistrationContext) 31} 32 33func registerSystemFeaturesComponents(ctx android.RegistrationContext) { 34 ctx.RegisterModuleType("java_system_features_srcs", JavaSystemFeaturesSrcsFactory) 35} 36 37type javaSystemFeaturesSrcs struct { 38 android.ModuleBase 39 properties struct { 40 // The fully qualified class name for the generated code, e.g., com.android.Foo 41 Full_class_name string 42 } 43 outputFiles android.WritablePaths 44} 45 46var _ genrule.SourceFileGenerator = (*javaSystemFeaturesSrcs)(nil) 47var _ android.SourceFileProducer = (*javaSystemFeaturesSrcs)(nil) 48 49func (m *javaSystemFeaturesSrcs) GenerateAndroidBuildActions(ctx android.ModuleContext) { 50 // Create a file name appropriate for the given fully qualified (w/ package) class name. 51 classNameParts := strings.Split(m.properties.Full_class_name, ".") 52 outputDir := android.PathForModuleGen(ctx) 53 outputFileName := classNameParts[len(classNameParts)-1] + ".java" 54 outputFile := android.PathForModuleGen(ctx, outputFileName).OutputPath 55 56 // Collect all RELEASE_SYSTEM_FEATURE_$K:$V build flags into a list of "$K:$V" pairs. 57 var features []string 58 for k, v := range ctx.Config().ProductVariables().BuildFlags { 59 if strings.HasPrefix(k, "RELEASE_SYSTEM_FEATURE_") { 60 shortFeatureName := strings.TrimPrefix(k, "RELEASE_SYSTEM_FEATURE_") 61 features = append(features, fmt.Sprintf("%s:%s", shortFeatureName, v)) 62 } 63 } 64 // Ensure sorted outputs for consistency of flag ordering in ninja outputs. 65 sort.Strings(features) 66 67 rule := android.NewRuleBuilder(pctx, ctx) 68 rule.Command().Text("rm -rf").Text(outputDir.String()) 69 rule.Command().Text("mkdir -p").Text(outputDir.String()) 70 rule.Command(). 71 BuiltTool("systemfeatures-gen-tool"). 72 Flag(m.properties.Full_class_name). 73 FlagForEachArg("--feature=", features). 74 FlagWithArg("--readonly=", fmt.Sprint(ctx.Config().ReleaseUseSystemFeatureBuildFlags())). 75 FlagWithOutput(" > ", outputFile) 76 rule.Build(ctx.ModuleName(), "Generating systemfeatures srcs filegroup") 77 78 m.outputFiles = append(m.outputFiles, outputFile) 79} 80 81func (m *javaSystemFeaturesSrcs) Srcs() android.Paths { 82 return m.outputFiles.Paths() 83} 84 85func (m *javaSystemFeaturesSrcs) GeneratedSourceFiles() android.Paths { 86 return m.outputFiles.Paths() 87} 88 89func (m *javaSystemFeaturesSrcs) GeneratedDeps() android.Paths { 90 return m.outputFiles.Paths() 91} 92 93func (m *javaSystemFeaturesSrcs) GeneratedHeaderDirs() android.Paths { 94 return nil 95} 96 97func JavaSystemFeaturesSrcsFactory() android.Module { 98 module := &javaSystemFeaturesSrcs{} 99 module.AddProperties(&module.properties) 100 android.InitAndroidModule(module) 101 return module 102} 103