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