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, aidlGlobalFlags string, aidlIndividualFlags map[string]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(pctx, ctx) 61 62 rule.Command().Text("rm -rf").Flag(outDir.String()) 63 rule.Command().Text("mkdir -p").Flag(outDir.String()) 64 rule.Command().Text("FLAGS=' " + aidlGlobalFlags + "'") 65 66 for _, aidlFile := range shard { 67 localFlag := aidlIndividualFlags[aidlFile.String()] 68 depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d") 69 javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java")) 70 rule.Command(). 71 Tool(ctx.Config().HostToolPath(ctx, "aidl")). 72 FlagWithDepFile("-d", depFile). 73 Flag("$FLAGS"). 74 Flag(localFlag). 75 Input(aidlFile). 76 Output(javaFile). 77 Implicits(deps) 78 rule.Temporary(javaFile) 79 } 80 81 rule.Command(). 82 Tool(ctx.Config().HostToolPath(ctx, "soong_zip")). 83 Flag("-srcjar"). 84 Flag("-write_if_changed"). 85 FlagWithOutput("-o ", srcJarFile). 86 FlagWithArg("-C ", outDir.String()). 87 FlagWithArg("-D ", outDir.String()) 88 89 rule.Command().Text("rm -rf").Flag(outDir.String()) 90 91 rule.Restat() 92 93 ruleName := "aidl" 94 ruleDesc := "aidl" 95 if len(shards) > 1 { 96 ruleName += "_" + strconv.Itoa(i) 97 ruleDesc += " " + strconv.Itoa(i) 98 } 99 100 rule.Build(ruleName, ruleDesc) 101 } 102 103 return srcJarFiles 104} 105 106func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Path { 107 javaFile := android.GenPathWithExt(ctx, "logtags", logtagsFile, "java") 108 109 ctx.Build(pctx, android.BuildParams{ 110 Rule: logtags, 111 Description: "logtags " + logtagsFile.Rel(), 112 Output: javaFile, 113 Input: logtagsFile, 114 }) 115 116 return javaFile 117} 118 119func genAidlIncludeFlags(srcFiles android.Paths) string { 120 var baseDirs []string 121 for _, srcFile := range srcFiles { 122 if srcFile.Ext() == ".aidl" { 123 baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel()) 124 if baseDir != "" && !android.InList(baseDir, baseDirs) { 125 baseDirs = append(baseDirs, baseDir) 126 } 127 } 128 } 129 return android.JoinWithPrefix(baseDirs, " -I") 130} 131 132func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths, 133 flags javaBuilderFlags) android.Paths { 134 135 outSrcFiles := make(android.Paths, 0, len(srcFiles)) 136 var protoSrcs android.Paths 137 var aidlSrcs android.Paths 138 139 aidlIncludeFlags := genAidlIncludeFlags(srcFiles) 140 141 for _, srcFile := range srcFiles { 142 switch srcFile.Ext() { 143 case ".aidl": 144 aidlSrcs = append(aidlSrcs, srcFile) 145 case ".logtags": 146 j.logtagsSrcs = append(j.logtagsSrcs, srcFile) 147 javaFile := genLogtags(ctx, srcFile) 148 outSrcFiles = append(outSrcFiles, javaFile) 149 case ".proto": 150 protoSrcs = append(protoSrcs, srcFile) 151 default: 152 outSrcFiles = append(outSrcFiles, srcFile) 153 } 154 } 155 156 // Process all proto files together to support sharding them into one or more rules that produce srcjars. 157 if len(protoSrcs) > 0 { 158 srcJarFiles := genProto(ctx, protoSrcs, flags.proto) 159 outSrcFiles = append(outSrcFiles, srcJarFiles...) 160 } 161 162 // Process all aidl files together to support sharding them into one or more rules that produce srcjars. 163 if len(aidlSrcs) > 0 { 164 individualFlags := make(map[string]string) 165 for _, aidlSrc := range aidlSrcs { 166 flags := j.individualAidlFlags(ctx, aidlSrc) 167 if flags != "" { 168 individualFlags[aidlSrc.String()] = flags 169 } 170 } 171 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, individualFlags, flags.aidlDeps) 172 outSrcFiles = append(outSrcFiles, srcJarFiles...) 173 } 174 175 return outSrcFiles 176} 177 178func LogtagsSingleton() android.Singleton { 179 return &logtagsSingleton{} 180} 181 182type logtagsProducer interface { 183 logtags() android.Paths 184} 185 186func (j *Module) logtags() android.Paths { 187 return j.logtagsSrcs 188} 189 190var _ logtagsProducer = (*Module)(nil) 191 192type logtagsSingleton struct{} 193 194func (l *logtagsSingleton) GenerateBuildActions(ctx android.SingletonContext) { 195 var allLogtags android.Paths 196 ctx.VisitAllModules(func(module android.Module) { 197 if logtags, ok := module.(logtagsProducer); ok { 198 allLogtags = append(allLogtags, logtags.logtags()...) 199 } 200 }) 201 202 ctx.Build(pctx, android.BuildParams{ 203 Rule: mergeLogtags, 204 Description: "merge logtags", 205 Output: android.PathForIntermediates(ctx, "all-event-log-tags.txt"), 206 Inputs: allLogtags, 207 }) 208} 209