blob: e359529a51df757b715114ac6a1b1857775de563 [file] [log] [blame]
Colin Cross2fe66872015-03-30 17:20:39 -07001// 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
17// This file generates the final rules for compiling all Java. All properties related to
18// compiling should have been translated into javaBuilderFlags or another argument to the Transform*
19// functions.
20
21import (
Colin Cross2fe66872015-03-30 17:20:39 -070022 "strings"
23
Colin Cross2fe66872015-03-30 17:20:39 -070024 "github.com/google/blueprint"
Colin Crossfee57cb2017-09-05 13:16:45 -070025
26 "android/soong/android"
27 "android/soong/java/config"
Colin Cross2fe66872015-03-30 17:20:39 -070028)
29
30var (
Colin Cross635c3b02016-05-18 15:37:25 -070031 pctx = android.NewPackageContext("android/soong/java")
Colin Cross2fe66872015-03-30 17:20:39 -070032
33 // Compiling java is not conducive to proper dependency tracking. The path-matches-class-name
34 // requirement leads to unpredictable generated source file names, and a single .java file
35 // will get compiled into multiple .class files if it contains inner classes. To work around
36 // this, all java rules write into separate directories and then a post-processing step lists
37 // the files in the the directory into a list file that later rules depend on (and sometimes
38 // read from directly using @<listfile>)
Yoshisato Yanagisawa572324a2017-06-05 17:41:50 +090039 javac = pctx.AndroidGomaStaticRule("javac",
Colin Cross2fe66872015-03-30 17:20:39 -070040 blueprint.RuleParams{
Colin Cross64162712017-08-08 13:17:59 -070041 Command: `rm -rf "$outDir" "$annoDir" && mkdir -p "$outDir" "$annoDir" && ` +
Colin Cross3203dde2017-08-28 17:23:21 -070042 `${config.JavacWrapper}${config.JavacCmd} ${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
Colin Cross64162712017-08-08 13:17:59 -070043 `$javacFlags $bootClasspath $classpath ` +
44 `-source $javaVersion -target $javaVersion ` +
Colin Crossb852a582017-08-10 17:58:12 -070045 `-d $outDir -s $annoDir @$out.rsp && ` +
46 `find $outDir -type f | sort | ${config.JarArgsCmd} $outDir > $out`,
47 CommandDeps: []string{"${config.JavacCmd}", "${config.JarArgsCmd}"},
Colin Cross2fe66872015-03-30 17:20:39 -070048 Rspfile: "$out.rsp",
49 RspfileContent: "$in",
Colin Cross2fe66872015-03-30 17:20:39 -070050 },
Colin Cross64162712017-08-08 13:17:59 -070051 "javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
Colin Cross2fe66872015-03-30 17:20:39 -070052
Colin Crossc6bbef32017-08-14 14:16:06 -070053 errorprone = pctx.AndroidStaticRule("errorprone",
54 blueprint.RuleParams{
55 Command: `rm -rf "$outDir" "$annoDir" && mkdir -p "$outDir" "$annoDir" && ` +
56 `${config.ErrorProneCmd}` +
57 `$javacFlags $bootClasspath $classpath ` +
58 `-source $javaVersion -target $javaVersion ` +
59 `-d $outDir -s $annoDir @$out.rsp && ` +
60 `find $outDir -type f | sort | ${config.JarArgsCmd} $outDir > $out`,
61 CommandDeps: []string{
62 "${config.JavaCmd}",
63 "${config.ErrorProneJavacJar}",
64 "${config.ErrorProneJar}",
65 "${config.JarArgsCmd}",
66 },
67 Rspfile: "$out.rsp",
68 RspfileContent: "$in",
69 },
70 "javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
71
Colin Cross9d45bb72016-08-29 16:14:13 -070072 jar = pctx.AndroidStaticRule("jar",
Colin Cross2fe66872015-03-30 17:20:39 -070073 blueprint.RuleParams{
Colin Crossb852a582017-08-10 17:58:12 -070074 Command: `${config.JarCmd} $operation ${out}.tmp $manifest $jarArgs && ${config.Zip2ZipCmd} -t -i ${out}.tmp -o ${out} && rm ${out}.tmp`,
75 CommandDeps: []string{"${config.JarCmd}"},
Colin Cross2fe66872015-03-30 17:20:39 -070076 },
Colin Crossb852a582017-08-10 17:58:12 -070077 "operation", "manifest", "jarArgs")
Colin Cross2fe66872015-03-30 17:20:39 -070078
Colin Cross9d45bb72016-08-29 16:14:13 -070079 dx = pctx.AndroidStaticRule("dx",
Colin Cross2fe66872015-03-30 17:20:39 -070080 blueprint.RuleParams{
Colin Cross6d1e72d2015-04-10 17:44:24 -070081 Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
Colin Crossb852a582017-08-10 17:58:12 -070082 `${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` +
83 `find "$outDir" -name "classes*.dex" | sort | ${config.JarArgsCmd} ${outDir} > $out`,
84 CommandDeps: []string{"${config.DxCmd}", "${config.JarArgsCmd}"},
Colin Cross2fe66872015-03-30 17:20:39 -070085 },
86 "outDir", "dxFlags")
Colin Crosse1d62a82015-04-03 16:53:05 -070087
Colin Cross9d45bb72016-08-29 16:14:13 -070088 jarjar = pctx.AndroidStaticRule("jarjar",
Colin Cross65bf4f22015-04-03 16:54:17 -070089 blueprint.RuleParams{
Colin Cross64162712017-08-08 13:17:59 -070090 Command: "${config.JavaCmd} -jar ${config.JarjarCmd} process $rulesFile $in $out",
91 CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
Colin Cross65bf4f22015-04-03 16:54:17 -070092 },
93 "rulesFile")
94
Colin Cross9d45bb72016-08-29 16:14:13 -070095 extractPrebuilt = pctx.AndroidStaticRule("extractPrebuilt",
Colin Crosse1d62a82015-04-03 16:53:05 -070096 blueprint.RuleParams{
97 Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
Colin Crossb852a582017-08-10 17:58:12 -070098 `find $outDir -name "*.class" | sort | ${config.JarArgsCmd} ${outDir} > $classFile && ` +
99 `find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" | sort | ${config.JarArgsCmd} ${outDir} > $resourceFile`,
100 CommandDeps: []string{"${config.JarArgsCmd}"},
Colin Crosse1d62a82015-04-03 16:53:05 -0700101 },
102 "outDir", "classFile", "resourceFile")
Colin Crossb852a582017-08-10 17:58:12 -0700103
104 fileListToJarArgs = pctx.AndroidStaticRule("fileListToJarArgs",
105 blueprint.RuleParams{
106 Command: `${config.JarArgsCmd} -f $in -p ${outDir} -o $out`,
107 CommandDeps: []string{"${config.JarjarCmd}"},
108 },
109 "outDir")
Colin Cross2fe66872015-03-30 17:20:39 -0700110)
111
112func init() {
Colin Cross64162712017-08-08 13:17:59 -0700113 pctx.Import("android/soong/java/config")
Colin Cross2fe66872015-03-30 17:20:39 -0700114}
115
116type javaBuilderFlags struct {
117 javacFlags string
118 dxFlags string
119 bootClasspath string
120 classpath string
Colin Crossc0b06f12015-04-08 13:03:43 -0700121 aidlFlags string
Colin Cross64162712017-08-08 13:17:59 -0700122 javaVersion string
Colin Cross2fe66872015-03-30 17:20:39 -0700123}
124
125type jarSpec struct {
Colin Crossb852a582017-08-10 17:58:12 -0700126 android.ModuleOutPath
Colin Cross2fe66872015-03-30 17:20:39 -0700127}
128
Colin Crossb852a582017-08-10 17:58:12 -0700129func (j jarSpec) jarArgs() string {
130 return "@" + j.String()
131}
132
133func (j jarSpec) path() android.Path {
134 return j.ModuleOutPath
Colin Cross2fe66872015-03-30 17:20:39 -0700135}
136
Colin Cross635c3b02016-05-18 15:37:25 -0700137func TransformJavaToClasses(ctx android.ModuleContext, srcFiles android.Paths, srcFileLists android.Paths,
138 flags javaBuilderFlags, deps android.Paths) jarSpec {
Colin Cross2fe66872015-03-30 17:20:39 -0700139
Colin Cross635c3b02016-05-18 15:37:25 -0700140 classDir := android.PathForModuleOut(ctx, "classes")
Colin Cross64162712017-08-08 13:17:59 -0700141 annoDir := android.PathForModuleOut(ctx, "anno")
Colin Cross635c3b02016-05-18 15:37:25 -0700142 classFileList := android.PathForModuleOut(ctx, "classes.list")
Colin Cross2fe66872015-03-30 17:20:39 -0700143
Colin Cross635c3b02016-05-18 15:37:25 -0700144 javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
Colin Crosse7a9f3f2015-04-13 14:02:52 -0700145
146 deps = append(deps, srcFileLists...)
147
Colin Cross635c3b02016-05-18 15:37:25 -0700148 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700149 Rule: javac,
150 Description: "javac",
151 Output: classFileList,
152 Inputs: srcFiles,
153 Implicits: deps,
Colin Cross2fe66872015-03-30 17:20:39 -0700154 Args: map[string]string{
Colin Crosse7a9f3f2015-04-13 14:02:52 -0700155 "javacFlags": javacFlags,
Colin Cross2fe66872015-03-30 17:20:39 -0700156 "bootClasspath": flags.bootClasspath,
157 "classpath": flags.classpath,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700158 "outDir": classDir.String(),
Colin Cross64162712017-08-08 13:17:59 -0700159 "annoDir": annoDir.String(),
160 "javaVersion": flags.javaVersion,
Colin Cross2fe66872015-03-30 17:20:39 -0700161 },
162 })
163
Colin Crossb852a582017-08-10 17:58:12 -0700164 return jarSpec{classFileList}
Colin Cross2fe66872015-03-30 17:20:39 -0700165}
166
Colin Crossc6bbef32017-08-14 14:16:06 -0700167func RunErrorProne(ctx android.ModuleContext, srcFiles android.Paths, srcFileLists android.Paths,
168 flags javaBuilderFlags, deps android.Paths) android.Path {
169
Colin Crossfee57cb2017-09-05 13:16:45 -0700170 if config.ErrorProneJar == "" {
171 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
172 return nil
173 }
174
Colin Crossc6bbef32017-08-14 14:16:06 -0700175 classDir := android.PathForModuleOut(ctx, "classes-errorprone")
176 annoDir := android.PathForModuleOut(ctx, "anno-errorprone")
177 classFileList := android.PathForModuleOut(ctx, "classes-errorprone.list")
178
179 javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
180
181 deps = append(deps, srcFileLists...)
182
183 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
184 Rule: errorprone,
185 Description: "errorprone",
186 Output: classFileList,
187 Inputs: srcFiles,
188 Implicits: deps,
189 Args: map[string]string{
190 "javacFlags": javacFlags,
191 "bootClasspath": flags.bootClasspath,
192 "classpath": flags.classpath,
193 "outDir": classDir.String(),
194 "annoDir": annoDir.String(),
195 "javaVersion": flags.javaVersion,
196 },
197 })
198
199 return classFileList
200}
201
Colin Cross635c3b02016-05-18 15:37:25 -0700202func TransformClassesToJar(ctx android.ModuleContext, classes []jarSpec,
Colin Crossc6bbef32017-08-14 14:16:06 -0700203 manifest android.OptionalPath, deps android.Paths) android.Path {
Colin Cross2fe66872015-03-30 17:20:39 -0700204
Colin Cross635c3b02016-05-18 15:37:25 -0700205 outputFile := android.PathForModuleOut(ctx, "classes-full-debug.jar")
Colin Cross2fe66872015-03-30 17:20:39 -0700206
Colin Cross2fe66872015-03-30 17:20:39 -0700207 jarArgs := []string{}
208
209 for _, j := range classes {
Colin Crossb852a582017-08-10 17:58:12 -0700210 deps = append(deps, j.path())
211 jarArgs = append(jarArgs, j.jarArgs())
Colin Cross2fe66872015-03-30 17:20:39 -0700212 }
213
Colin Crossb852a582017-08-10 17:58:12 -0700214 operation := "cf"
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700215 if manifest.Valid() {
Colin Crossb852a582017-08-10 17:58:12 -0700216 operation = "cfm"
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700217 deps = append(deps, manifest.Path())
Colin Cross2fe66872015-03-30 17:20:39 -0700218 }
219
Colin Cross635c3b02016-05-18 15:37:25 -0700220 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700221 Rule: jar,
222 Description: "jar",
223 Output: outputFile,
224 Implicits: deps,
Colin Cross2fe66872015-03-30 17:20:39 -0700225 Args: map[string]string{
Colin Crossb852a582017-08-10 17:58:12 -0700226 "jarArgs": strings.Join(jarArgs, " "),
227 "operation": operation,
228 "manifest": manifest.String(),
Colin Cross2fe66872015-03-30 17:20:39 -0700229 },
230 })
231
232 return outputFile
233}
234
Colin Cross635c3b02016-05-18 15:37:25 -0700235func TransformClassesJarToDex(ctx android.ModuleContext, classesJar android.Path,
Colin Cross6d1e72d2015-04-10 17:44:24 -0700236 flags javaBuilderFlags) jarSpec {
Colin Cross2fe66872015-03-30 17:20:39 -0700237
Colin Cross635c3b02016-05-18 15:37:25 -0700238 outDir := android.PathForModuleOut(ctx, "dex")
239 outputFile := android.PathForModuleOut(ctx, "dex.filelist")
Colin Cross2fe66872015-03-30 17:20:39 -0700240
Colin Cross635c3b02016-05-18 15:37:25 -0700241 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700242 Rule: dx,
243 Description: "dx",
244 Output: outputFile,
245 Input: classesJar,
Colin Cross2fe66872015-03-30 17:20:39 -0700246 Args: map[string]string{
247 "dxFlags": flags.dxFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700248 "outDir": outDir.String(),
Colin Cross2fe66872015-03-30 17:20:39 -0700249 },
250 })
251
Colin Crossb852a582017-08-10 17:58:12 -0700252 return jarSpec{outputFile}
Colin Cross2fe66872015-03-30 17:20:39 -0700253}
254
Colin Cross635c3b02016-05-18 15:37:25 -0700255func TransformDexToJavaLib(ctx android.ModuleContext, resources []jarSpec,
256 dexJarSpec jarSpec) android.Path {
Colin Cross2fe66872015-03-30 17:20:39 -0700257
Colin Cross635c3b02016-05-18 15:37:25 -0700258 outputFile := android.PathForModuleOut(ctx, "javalib.jar")
259 var deps android.Paths
Colin Cross2fe66872015-03-30 17:20:39 -0700260 var jarArgs []string
261
262 for _, j := range resources {
Colin Crossb852a582017-08-10 17:58:12 -0700263 deps = append(deps, j.path())
264 jarArgs = append(jarArgs, j.jarArgs())
Colin Cross2fe66872015-03-30 17:20:39 -0700265 }
266
Colin Crossb852a582017-08-10 17:58:12 -0700267 deps = append(deps, dexJarSpec.path())
268 jarArgs = append(jarArgs, dexJarSpec.jarArgs())
Colin Cross2fe66872015-03-30 17:20:39 -0700269
Colin Cross635c3b02016-05-18 15:37:25 -0700270 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700271 Rule: jar,
272 Description: "jar",
273 Output: outputFile,
274 Implicits: deps,
Colin Cross2fe66872015-03-30 17:20:39 -0700275 Args: map[string]string{
Colin Crossb852a582017-08-10 17:58:12 -0700276 "operation": "cf",
277 "jarArgs": strings.Join(jarArgs, " "),
Colin Cross2fe66872015-03-30 17:20:39 -0700278 },
279 })
280
281 return outputFile
282}
Colin Crosse1d62a82015-04-03 16:53:05 -0700283
Colin Cross635c3b02016-05-18 15:37:25 -0700284func TransformJarJar(ctx android.ModuleContext, classesJar android.Path, rulesFile android.Path) android.Path {
285 outputFile := android.PathForModuleOut(ctx, "classes-jarjar.jar")
286 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700287 Rule: jarjar,
288 Description: "jarjar",
289 Output: outputFile,
290 Input: classesJar,
291 Implicit: rulesFile,
Colin Cross65bf4f22015-04-03 16:54:17 -0700292 Args: map[string]string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700293 "rulesFile": rulesFile.String(),
Colin Cross65bf4f22015-04-03 16:54:17 -0700294 },
295 })
296
297 return outputFile
298}
299
Colin Cross635c3b02016-05-18 15:37:25 -0700300func TransformPrebuiltJarToClasses(ctx android.ModuleContext,
Colin Cross74d73e22017-08-02 11:05:49 -0700301 subdir string, prebuilt android.Path) (classJarSpec, resourceJarSpec jarSpec) {
Colin Crosse1d62a82015-04-03 16:53:05 -0700302
Colin Cross74d73e22017-08-02 11:05:49 -0700303 classDir := android.PathForModuleOut(ctx, subdir, "classes")
304 classFileList := android.PathForModuleOut(ctx, subdir, "classes.list")
305 resourceFileList := android.PathForModuleOut(ctx, subdir, "resources.list")
Colin Crosse1d62a82015-04-03 16:53:05 -0700306
Colin Cross635c3b02016-05-18 15:37:25 -0700307 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700308 Rule: extractPrebuilt,
309 Description: "extract classes",
310 Outputs: android.WritablePaths{classFileList, resourceFileList},
311 Input: prebuilt,
Colin Crosse1d62a82015-04-03 16:53:05 -0700312 Args: map[string]string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700313 "outDir": classDir.String(),
314 "classFile": classFileList.String(),
315 "resourceFile": resourceFileList.String(),
Colin Crosse1d62a82015-04-03 16:53:05 -0700316 },
317 })
318
Colin Crossb852a582017-08-10 17:58:12 -0700319 return jarSpec{classFileList}, jarSpec{resourceFileList}
320}
321
322func TransformFileListToJarSpec(ctx android.ModuleContext, dir, fileListFile android.Path) jarSpec {
323 outputFile := android.PathForModuleOut(ctx, fileListFile.Base()+".jarArgs")
324
325 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
326 Rule: fileListToJarArgs,
327 Description: "file list to jar args",
328 Output: outputFile,
329 Input: fileListFile,
330 Args: map[string]string{
331 "outDir": dir.String(),
332 },
333 })
334
335 return jarSpec{outputFile}
Colin Crosse1d62a82015-04-03 16:53:05 -0700336}