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 "path/filepath" 19 "strconv" 20 "strings" 21 22 "github.com/google/blueprint" 23 "github.com/google/blueprint/pathtools" 24 25 "android/soong/android" 26) 27 28func init() { 29 pctx.SourcePathVariable("logtagsCmd", "build/make/tools/java-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 41func genAidl(ctx android.ModuleContext, aidlFiles android.Paths, aidlGlobalFlags string, aidlIndividualFlags map[string]string, deps android.Paths) android.Paths { 42 // Shard aidl files into groups of 50 to avoid having to recompile all of them if one changes and to avoid 43 // hitting command line length limits. 44 shards := android.ShardPaths(aidlFiles, 50) 45 46 srcJarFiles := make(android.Paths, 0, len(shards)) 47 48 for i, shard := range shards { 49 srcJarFile := android.PathForModuleGen(ctx, "aidl", "aidl"+strconv.Itoa(i)+".srcjar") 50 srcJarFiles = append(srcJarFiles, srcJarFile) 51 52 outDir := srcJarFile.ReplaceExtension(ctx, "tmp") 53 54 rule := android.NewRuleBuilder(pctx, ctx) 55 56 rule.Command().Text("rm -rf").Flag(outDir.String()) 57 rule.Command().Text("mkdir -p").Flag(outDir.String()) 58 rule.Command().Text("FLAGS=' " + aidlGlobalFlags + "'") 59 60 for _, aidlFile := range shard { 61 localFlag := aidlIndividualFlags[aidlFile.String()] 62 depFile := srcJarFile.InSameDir(ctx, aidlFile.String()+".d") 63 javaFile := outDir.Join(ctx, pathtools.ReplaceExtension(aidlFile.String(), "java")) 64 rule.Command(). 65 Tool(ctx.Config().HostToolPath(ctx, "aidl")). 66 FlagWithDepFile("-d", depFile). 67 Flag("$FLAGS"). 68 Flag(localFlag). 69 Input(aidlFile). 70 Output(javaFile). 71 Implicits(deps) 72 rule.Temporary(javaFile) 73 } 74 75 rule.Command(). 76 Tool(ctx.Config().HostToolPath(ctx, "soong_zip")). 77 Flag("-srcjar"). 78 Flag("-write_if_changed"). 79 FlagWithOutput("-o ", srcJarFile). 80 FlagWithArg("-C ", outDir.String()). 81 FlagWithArg("-D ", outDir.String()) 82 83 rule.Command().Text("rm -rf").Flag(outDir.String()) 84 85 rule.Restat() 86 87 ruleName := "aidl" 88 ruleDesc := "aidl" 89 if len(shards) > 1 { 90 ruleName += "_" + strconv.Itoa(i) 91 ruleDesc += " " + strconv.Itoa(i) 92 } 93 94 rule.Build(ruleName, ruleDesc) 95 } 96 97 return srcJarFiles 98} 99 100func genLogtags(ctx android.ModuleContext, logtagsFile android.Path) android.Path { 101 javaFile := android.GenPathWithExt(ctx, "logtags", logtagsFile, "java") 102 103 ctx.Build(pctx, android.BuildParams{ 104 Rule: logtags, 105 Description: "logtags " + logtagsFile.Rel(), 106 Output: javaFile, 107 Input: logtagsFile, 108 }) 109 110 return javaFile 111} 112 113// genAidlIncludeFlags returns additional include flags based on the relative path 114// of each .aidl file passed in srcFiles. excludeDirs is a list of paths relative to 115// the Android checkout root that should not be included in the returned flags. 116func genAidlIncludeFlags(ctx android.PathContext, srcFiles android.Paths, excludeDirs android.Paths) string { 117 var baseDirs []string 118 excludeDirsStrings := excludeDirs.Strings() 119 for _, srcFile := range srcFiles { 120 if srcFile.Ext() == ".aidl" { 121 baseDir := strings.TrimSuffix(srcFile.String(), srcFile.Rel()) 122 baseDir = filepath.Clean(baseDir) 123 baseDirSeen := android.InList(baseDir, baseDirs) || android.InList(baseDir, excludeDirsStrings) 124 125 if baseDir != "" && !baseDirSeen { 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 for _, srcFile := range srcFiles { 141 switch srcFile.Ext() { 142 case ".aidl": 143 aidlSrcs = append(aidlSrcs, srcFile) 144 case ".logtags": 145 j.logtagsSrcs = append(j.logtagsSrcs, srcFile) 146 javaFile := genLogtags(ctx, srcFile) 147 outSrcFiles = append(outSrcFiles, javaFile) 148 case ".proto": 149 protoSrcs = append(protoSrcs, srcFile) 150 default: 151 outSrcFiles = append(outSrcFiles, srcFile) 152 } 153 } 154 155 // Process all proto files together to support sharding them into one or more rules that produce srcjars. 156 if len(protoSrcs) > 0 { 157 srcJarFiles := genProto(ctx, protoSrcs, flags.proto) 158 outSrcFiles = append(outSrcFiles, srcJarFiles...) 159 } 160 161 // Process all aidl files together to support sharding them into one or more rules that produce srcjars. 162 if len(aidlSrcs) > 0 { 163 individualFlags := make(map[string]string) 164 for _, aidlSrc := range aidlSrcs { 165 flags := j.individualAidlFlags(ctx, aidlSrc) 166 if flags != "" { 167 individualFlags[aidlSrc.String()] = flags 168 } 169 } 170 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags, individualFlags, flags.aidlDeps) 171 outSrcFiles = append(outSrcFiles, srcJarFiles...) 172 } 173 174 android.SetProvider(ctx, android.LogtagsProviderKey, &android.LogtagsInfo{ 175 Logtags: j.logtagsSrcs, 176 }) 177 178 return outSrcFiles 179} 180