1// Copyright 2015 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 ( 18 "strconv" 19 "strings" 20 21 "github.com/google/blueprint" 22 "github.com/google/blueprint/pathtools" 23 24 "android/soong/android" 25) 26 27func init() { 28 pctx.SourcePathVariable("logtagsCmd", "build/make/tools/java-event-log-tags.py") 29 pctx.SourcePathVariable("mergeLogtagsCmd", "build/make/tools/merge-event-log-tags.py") 30 pctx.SourcePathVariable("logtagsLib", "build/make/tools/event_log_tags.py") 31} 32 33var ( 34 logtags = pctx.AndroidStaticRule("logtags", 35 blueprint.RuleParams{ 36 Command: "$logtagsCmd -o $out $in", 37 CommandDeps: []string{"$logtagsCmd", "$logtagsLib"}, 38 }) 39 40 mergeLogtags = pctx.AndroidStaticRule("mergeLogtags", 41 blueprint.RuleParams{ 42 Command: "$mergeLogtagsCmd -o $out $in", 43 CommandDeps: []string{"$mergeLogtagsCmd", "$logtagsLib"}, 44 }) 45) 46 47func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlFlags string, deps android.Paths) android.Paths { 48 // Shard aidl files into groups of 50 to avoid having to recompile all of them if one changes and to avoid 49 // hitting command line length limits. 50 shards := android.ShardPaths(aidlFiles, 50) 51 52 srcJarFiles := make(android.Paths, 0, len(shards)) 53 54 for i, shard := range shards { 55 srcJarFile := android.PathForModuleGen(ctx, "aidl", "aidl"+strconv.Itoa(i)+".srcjar") 56 srcJarFiles = append(srcJarFiles, srcJarFile) 57 58 outDir := srcJarFile.ReplaceExtension(ctx, "tmp") 59 60 rule := android.NewRuleBuilder() 61 62 rule.Command().Text("rm -rf").Flag(outDir.String()) 63 rule.Command().Text("mkdir -p").Flag(outDir.String()) 64 rule.Command().Text("FLAGS=' " + aidlFlags + "'") 65 66 for _, aidlFile := range shard { 67 depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d") 68 javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java")) 69 rule.Command(). 70 Tool(ctx.Config().HostToolPath(ctx, "aidl")). 71 FlagWithDepFile("-d", depFile). 72 Flag("$FLAGS"). 73 Input(aidlFile). 74 Output(javaFile). 75 Implicits(deps) 76 rule.Temporary(javaFile) 77 } 78 79 rule.Command(). 80 Tool(ctx.Config().HostToolPath(ctx, "soong_zip")). 81 // TODO(b/124333557): this can't use -srcjar for now, aidl on parcelables generates java files 82 // without a package statement, which causes -srcjar to put them in the top level of the zip file. 83 // Once aidl skips parcelables we can use -srcjar. 84 //Flag("-srcjar"). 85 Flag("-write_if_changed"). 86 FlagWithOutput("-o ", srcJarFile). 87 FlagWithArg("-C ", outDir.String()). 88 FlagWithArg("-D ", outDir.String()) 89 90 rule.Command().Text("rm -rf").Flag(outDir.String()) 91 92 rule.Restat() 93 94 ruleName := "aidl" 95 ruleDesc := "aidl" 96 if len(shards) > 1 { 97 ruleName += "_" + strconv.Itoa(i) 98 ruleDesc += " " + strconv.Itoa(i) 99 } 100 101 rule.Build(pctx, ctx, ruleName, ruleDesc) 102 } 103 104 return srcJarFiles 105} 106 107func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Path { 108 javaFile := android.GenPathWithExt(ctx, "logtags", logtagsFile, "java") 109 110 ctx.Build(pctx, android.BuildParams{ 111 Rule: logtags, 112 Description: "logtags " + logtagsFile.Rel(), 113 Output: javaFile, 114 Input: logtagsFile, 115 }) 116 117 return javaFile 118} 119 120func genAidlIncludeFlags(srcFiles android.Paths) string { 121 var baseDirs []string 122 for _, srcFile := range srcFiles { 123 if srcFile.Ext() == ".aidl" { 124 baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel()) 125 if baseDir != "" && !android.InList(baseDir, baseDirs) { 126 baseDirs = append(baseDirs, baseDir) 127 } 128 } 129 } 130 return android.JoinWithPrefix(baseDirs, " -I") 131} 132 133func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths, 134 flags javaBuilderFlags) android.Paths { 135 136 outSrcFiles := make(android.Paths, 0, len(srcFiles)) 137 var protoSrcs android.Paths 138 var aidlSrcs android.Paths 139 140 aidlIncludeFlags := genAidlIncludeFlags(srcFiles) 141 142 for _, srcFile := range srcFiles { 143 switch srcFile.Ext() { 144 case ".aidl": 145 aidlSrcs = append(aidlSrcs, srcFile) 146 case ".logtags": 147 j.logtagsSrcs = append(j.logtagsSrcs, srcFile) 148 javaFile := genLogtags(ctx, srcFile) 149 outSrcFiles = append(outSrcFiles, javaFile) 150 case ".proto": 151 protoSrcs = append(protoSrcs, srcFile) 152 default: 153 outSrcFiles = append(outSrcFiles, srcFile) 154 } 155 } 156 157 // Process all proto files together to support sharding them into one or more rules that produce srcjars. 158 if len(protoSrcs) > 0 { 159 srcJarFiles := genProto(ctx, protoSrcs, flags.proto) 160 outSrcFiles = append(outSrcFiles, srcJarFiles...) 161 } 162 163 // Process all aidl files together to support sharding them into one or more rules that produce srcjars. 164 if len(aidlSrcs) > 0 { 165 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps) 166 outSrcFiles = append(outSrcFiles, srcJarFiles...) 167 } 168 169 return outSrcFiles 170} 171 172func LogtagsSingleton() android.Singleton { 173 return &logtagsSingleton{} 174} 175 176type logtagsProducer interface { 177 logtags() android.Paths 178} 179 180type logtagsSingleton struct{} 181 182func (l *logtagsSingleton) GenerateBuildActions(ctx android.SingletonContext) { 183 var allLogtags android.Paths 184 ctx.VisitAllModules(func(module android.Module) { 185 if logtags, ok := module.(logtagsProducer); ok { 186 allLogtags = append(allLogtags, logtags.logtags()...) 187 } 188 }) 189 190 ctx.Build(pctx, android.BuildParams{ 191 Rule: mergeLogtags, 192 Description: "merge logtags", 193 Output: android.PathForIntermediates(ctx, "all-event-log-tags.txt"), 194 Inputs: allLogtags, 195 }) 196} 197