blob: 304cd2764c528f7812e32f7d942f662035941a83 [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 && ` +
Colin Cross0a6e0072017-08-30 14:24:55 -070046 `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
47 CommandDeps: []string{"${config.JavacCmd}", "${config.SoongZipCmd}"},
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" && ` +
Colin Cross3a5de652017-09-11 23:10:21 -070056 `${config.ErrorProneCmd} ` +
Colin Crossc6bbef32017-08-14 14:16:06 -070057 `$javacFlags $bootClasspath $classpath ` +
58 `-source $javaVersion -target $javaVersion ` +
59 `-d $outDir -s $annoDir @$out.rsp && ` +
Colin Cross0a6e0072017-08-30 14:24:55 -070060 `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir`,
Colin Crossc6bbef32017-08-14 14:16:06 -070061 CommandDeps: []string{
62 "${config.JavaCmd}",
63 "${config.ErrorProneJavacJar}",
64 "${config.ErrorProneJar}",
Colin Cross0a6e0072017-08-30 14:24:55 -070065 "${config.SoongZipCmd}",
Colin Crossc6bbef32017-08-14 14:16:06 -070066 },
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 Cross0a6e0072017-08-30 14:24:55 -070074 Command: `${config.SoongZipCmd} -jar -o $out $jarArgs`,
75 CommandDeps: []string{"${config.SoongZipCmd}"},
Colin Cross2fe66872015-03-30 17:20:39 -070076 },
Colin Cross0a6e0072017-08-30 14:24:55 -070077 "jarArgs")
78
79 combineJar = pctx.AndroidStaticRule("combineJar",
80 blueprint.RuleParams{
Colin Cross635acc92017-09-12 22:50:46 -070081 Command: `${config.MergeZipsCmd} -j $jarArgs $out $in`,
Colin Cross0a6e0072017-08-30 14:24:55 -070082 CommandDeps: []string{"${config.MergeZipsCmd}"},
83 },
Colin Cross635acc92017-09-12 22:50:46 -070084 "jarArgs")
Colin Cross2fe66872015-03-30 17:20:39 -070085
Colin Cross6ade34f2017-09-15 13:00:47 -070086 desugar = pctx.AndroidStaticRule("desugar",
87 blueprint.RuleParams{
88 Command: `rm -rf $dumpDir && mkdir -p $dumpDir && ` +
89 `${config.JavaCmd} ` +
90 `-Djdk.internal.lambda.dumpProxyClasses=$$(cd $dumpDir && pwd) ` +
91 `$javaFlags ` +
92 `-jar ${config.DesugarJar} $classpathFlags $desugarFlags ` +
93 `-i $in -o $out`,
94 CommandDeps: []string{"${config.DesugarJar}"},
95 },
96 "javaFlags", "classpathFlags", "desugarFlags", "dumpDir")
97
Colin Cross9d45bb72016-08-29 16:14:13 -070098 dx = pctx.AndroidStaticRule("dx",
Colin Cross2fe66872015-03-30 17:20:39 -070099 blueprint.RuleParams{
Colin Cross6d1e72d2015-04-10 17:44:24 -0700100 Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
Colin Cross6ade34f2017-09-15 13:00:47 -0700101 `${config.DxCmd} --dex --output=$outDir $dxFlags $in && ` +
Colin Cross7db5d632017-10-04 17:07:09 -0700102 `${config.SoongZipCmd} -o $outDir/classes.dex.jar -C $outDir -D $outDir && ` +
103 `${config.MergeZipsCmd} -D -stripFile "*.class" $out $outDir/classes.dex.jar $in`,
Colin Cross6ade34f2017-09-15 13:00:47 -0700104 CommandDeps: []string{
105 "${config.DxCmd}",
106 "${config.SoongZipCmd}",
Colin Cross7db5d632017-10-04 17:07:09 -0700107 "${config.MergeZipsCmd}",
Colin Cross6ade34f2017-09-15 13:00:47 -0700108 },
Colin Cross2fe66872015-03-30 17:20:39 -0700109 },
110 "outDir", "dxFlags")
Colin Crosse1d62a82015-04-03 16:53:05 -0700111
Colin Cross9d45bb72016-08-29 16:14:13 -0700112 jarjar = pctx.AndroidStaticRule("jarjar",
Colin Cross65bf4f22015-04-03 16:54:17 -0700113 blueprint.RuleParams{
Colin Cross64162712017-08-08 13:17:59 -0700114 Command: "${config.JavaCmd} -jar ${config.JarjarCmd} process $rulesFile $in $out",
115 CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
Colin Cross65bf4f22015-04-03 16:54:17 -0700116 },
117 "rulesFile")
Colin Cross2fe66872015-03-30 17:20:39 -0700118)
119
120func init() {
Colin Cross64162712017-08-08 13:17:59 -0700121 pctx.Import("android/soong/java/config")
Colin Cross2fe66872015-03-30 17:20:39 -0700122}
123
124type javaBuilderFlags struct {
125 javacFlags string
126 dxFlags string
Colin Cross6ade34f2017-09-15 13:00:47 -0700127 bootClasspath classpath
128 classpath classpath
Colin Cross1369cdb2017-09-29 17:58:17 -0700129 systemModules classpath
Colin Cross6ade34f2017-09-15 13:00:47 -0700130 desugarFlags string
Colin Crossc0b06f12015-04-08 13:03:43 -0700131 aidlFlags string
Colin Cross64162712017-08-08 13:17:59 -0700132 javaVersion string
Colin Cross6af17aa2017-09-20 12:59:05 -0700133
134 protoFlags string
135 protoOutFlag string
Colin Cross2fe66872015-03-30 17:20:39 -0700136}
137
Colin Crosse9a275b2017-10-16 17:09:48 -0700138func TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
139 srcFiles, srcFileLists android.Paths,
140 flags javaBuilderFlags, deps android.Paths) {
Colin Cross2fe66872015-03-30 17:20:39 -0700141
Colin Crosse9a275b2017-10-16 17:09:48 -0700142 transformJavaToClasses(ctx, outputFile, srcFiles, srcFileLists, flags, deps,
143 "", "javac", javac)
Colin Cross2fe66872015-03-30 17:20:39 -0700144}
145
Colin Crosse9a275b2017-10-16 17:09:48 -0700146func RunErrorProne(ctx android.ModuleContext, outputFile android.WritablePath,
147 srcFiles, srcFileLists android.Paths,
148 flags javaBuilderFlags) {
Colin Crossc6bbef32017-08-14 14:16:06 -0700149
Colin Crossfee57cb2017-09-05 13:16:45 -0700150 if config.ErrorProneJar == "" {
151 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
Colin Crossfee57cb2017-09-05 13:16:45 -0700152 }
153
Colin Crosse9a275b2017-10-16 17:09:48 -0700154 transformJavaToClasses(ctx, outputFile, srcFiles, srcFileLists, flags, nil,
155 "-errorprone", "errorprone", errorprone)
Colin Cross070879e2017-10-11 11:21:07 -0700156}
157
158// transformJavaToClasses takes source files and converts them to a jar containing .class files.
159// srcFiles is a list of paths to sources, srcFileLists is a list of paths to files that contain
160// paths to sources. There is no dependency on the sources passed through srcFileLists, those
161// must be added through the deps argument, which contains a list of paths that should be added
162// as implicit dependencies. flags contains various command line flags to be passed to the
163// compiler.
164//
165// This method may be used for different compilers, including javac and Error Prone. The rule
166// argument specifies which command line to use and desc sets the description of the rule that will
167// be printed at build time. The stem argument provides the file name of the output jar, and
168// suffix will be appended to various intermediate files and directories to avoid collisions when
169// this function is called twice in the same module directory.
Colin Crosse9a275b2017-10-16 17:09:48 -0700170func transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
171 srcFiles, srcFileLists android.Paths,
172 flags javaBuilderFlags, deps android.Paths,
173 intermediatesSuffix, desc string, rule blueprint.Rule) {
Colin Crossc6bbef32017-08-14 14:16:06 -0700174
Colin Cross6af17aa2017-09-20 12:59:05 -0700175 javacFlags := flags.javacFlags
176 if len(srcFileLists) > 0 {
177 javacFlags += " " + android.JoinWithPrefix(srcFileLists.Strings(), "@")
178 }
179
Colin Crossc6bbef32017-08-14 14:16:06 -0700180 deps = append(deps, srcFileLists...)
Colin Cross1369cdb2017-09-29 17:58:17 -0700181
182 var bootClasspath string
183 if flags.javaVersion == "1.9" {
184 deps = append(deps, flags.systemModules...)
185 bootClasspath = flags.systemModules.JavaSystemModules(ctx.Device())
186 } else {
187 deps = append(deps, flags.bootClasspath...)
188 bootClasspath = flags.bootClasspath.JavaBootClasspath(ctx.Device())
189 }
190
Colin Cross6ade34f2017-09-15 13:00:47 -0700191 deps = append(deps, flags.classpath...)
Colin Crossc6bbef32017-08-14 14:16:06 -0700192
193 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross070879e2017-10-11 11:21:07 -0700194 Rule: rule,
195 Description: desc,
196 Output: outputFile,
Colin Crossc6bbef32017-08-14 14:16:06 -0700197 Inputs: srcFiles,
198 Implicits: deps,
199 Args: map[string]string{
200 "javacFlags": javacFlags,
Colin Cross1369cdb2017-09-29 17:58:17 -0700201 "bootClasspath": bootClasspath,
Colin Cross6ade34f2017-09-15 13:00:47 -0700202 "classpath": flags.classpath.JavaClasspath(),
Colin Crosse9a275b2017-10-16 17:09:48 -0700203 "outDir": android.PathForModuleOut(ctx, "classes"+intermediatesSuffix).String(),
204 "annoDir": android.PathForModuleOut(ctx, "anno"+intermediatesSuffix).String(),
Colin Crossc6bbef32017-08-14 14:16:06 -0700205 "javaVersion": flags.javaVersion,
206 },
207 })
Colin Crossc6bbef32017-08-14 14:16:06 -0700208}
209
Colin Crosse9a275b2017-10-16 17:09:48 -0700210func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.WritablePath,
211 jarArgs []string, deps android.Paths) {
Colin Cross2fe66872015-03-30 17:20:39 -0700212
Colin Cross635c3b02016-05-18 15:37:25 -0700213 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700214 Rule: jar,
215 Description: "jar",
216 Output: outputFile,
217 Implicits: deps,
Colin Cross2fe66872015-03-30 17:20:39 -0700218 Args: map[string]string{
Colin Cross0a6e0072017-08-30 14:24:55 -0700219 "jarArgs": strings.Join(jarArgs, " "),
Colin Cross2fe66872015-03-30 17:20:39 -0700220 },
221 })
Colin Cross2fe66872015-03-30 17:20:39 -0700222}
223
Colin Crosse9a275b2017-10-16 17:09:48 -0700224func TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePath,
225 jars android.Paths, manifest android.OptionalPath, stripDirs bool) {
Colin Cross0a6e0072017-08-30 14:24:55 -0700226
Colin Cross635acc92017-09-12 22:50:46 -0700227 var deps android.Paths
228
229 var jarArgs []string
230 if manifest.Valid() {
231 jarArgs = append(jarArgs, "-m "+manifest.String())
232 deps = append(deps, manifest.Path())
233 }
234
235 if stripDirs {
236 jarArgs = append(jarArgs, "-D")
237 }
238
Colin Cross0a6e0072017-08-30 14:24:55 -0700239 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
240 Rule: combineJar,
241 Description: "combine jars",
242 Output: outputFile,
243 Inputs: jars,
Colin Cross635acc92017-09-12 22:50:46 -0700244 Implicits: deps,
245 Args: map[string]string{
246 "jarArgs": strings.Join(jarArgs, " "),
247 },
Colin Cross0a6e0072017-08-30 14:24:55 -0700248 })
Colin Cross0a6e0072017-08-30 14:24:55 -0700249}
250
Colin Crosse9a275b2017-10-16 17:09:48 -0700251func TransformDesugar(ctx android.ModuleContext, outputFile android.WritablePath,
252 classesJar android.Path, flags javaBuilderFlags) {
Colin Cross6ade34f2017-09-15 13:00:47 -0700253
Colin Cross6ade34f2017-09-15 13:00:47 -0700254 dumpDir := android.PathForModuleOut(ctx, "desugar_dumped_classes")
255
256 javaFlags := ""
Colin Cross1369cdb2017-09-29 17:58:17 -0700257 if ctx.AConfig().UseOpenJDK9() {
Colin Cross6ade34f2017-09-15 13:00:47 -0700258 javaFlags = "--add-opens java.base/java.lang.invoke=ALL-UNNAMED"
259 }
260
261 var desugarFlags []string
262 desugarFlags = append(desugarFlags, flags.bootClasspath.DesugarBootClasspath()...)
263 desugarFlags = append(desugarFlags, flags.classpath.DesugarClasspath()...)
264
265 var deps android.Paths
266 deps = append(deps, flags.bootClasspath...)
267 deps = append(deps, flags.classpath...)
268
269 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
270 Rule: desugar,
271 Description: "desugar",
272 Output: outputFile,
273 Input: classesJar,
274 Implicits: deps,
275 Args: map[string]string{
276 "dumpDir": dumpDir.String(),
277 "javaFlags": javaFlags,
278 "classpathFlags": strings.Join(desugarFlags, " "),
279 "desugarFlags": flags.desugarFlags,
280 },
281 })
Colin Cross6ade34f2017-09-15 13:00:47 -0700282}
283
Colin Cross7db5d632017-10-04 17:07:09 -0700284// Converts a classes.jar file to classes*.dex, then combines the dex files with any resources
285// in the classes.jar file into a dex jar.
Colin Crosse9a275b2017-10-16 17:09:48 -0700286func TransformClassesJarToDexJar(ctx android.ModuleContext, outputFile android.WritablePath,
287 classesJar android.Path, flags javaBuilderFlags) {
Colin Cross2fe66872015-03-30 17:20:39 -0700288
Colin Cross635c3b02016-05-18 15:37:25 -0700289 outDir := android.PathForModuleOut(ctx, "dex")
Colin Cross2fe66872015-03-30 17:20:39 -0700290
Colin Cross635c3b02016-05-18 15:37:25 -0700291 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700292 Rule: dx,
293 Description: "dx",
294 Output: outputFile,
295 Input: classesJar,
Colin Cross2fe66872015-03-30 17:20:39 -0700296 Args: map[string]string{
297 "dxFlags": flags.dxFlags,
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700298 "outDir": outDir.String(),
Colin Cross2fe66872015-03-30 17:20:39 -0700299 },
300 })
Colin Cross2fe66872015-03-30 17:20:39 -0700301}
Colin Crosse1d62a82015-04-03 16:53:05 -0700302
Colin Crosse9a275b2017-10-16 17:09:48 -0700303func TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath,
304 classesJar android.Path, rulesFile android.Path) {
Colin Cross635c3b02016-05-18 15:37:25 -0700305 ctx.ModuleBuild(pctx, android.ModuleBuildParams{
Colin Cross67a5c132017-05-09 13:45:28 -0700306 Rule: jarjar,
307 Description: "jarjar",
308 Output: outputFile,
309 Input: classesJar,
310 Implicit: rulesFile,
Colin Cross65bf4f22015-04-03 16:54:17 -0700311 Args: map[string]string{
Dan Willemsen34cc69e2015-09-23 15:26:20 -0700312 "rulesFile": rulesFile.String(),
Colin Cross65bf4f22015-04-03 16:54:17 -0700313 },
314 })
Colin Cross65bf4f22015-04-03 16:54:17 -0700315}
Colin Cross6ade34f2017-09-15 13:00:47 -0700316
317type classpath []android.Path
318
319// Returns a -classpath argument in the form java or javac expects
320func (x *classpath) JavaClasspath() string {
321 if len(*x) > 0 {
322 return "-classpath " + strings.Join(x.Strings(), ":")
323 } else {
324 return ""
325 }
326}
327
328// Returns a -processorpath argument in the form java or javac expects
329func (x *classpath) JavaProcessorpath() string {
330 if len(*x) > 0 {
331 return "-processorpath " + strings.Join(x.Strings(), ":")
332 } else {
333 return ""
334 }
335}
336
337// Returns a -bootclasspath argument in the form java or javac expects. If forceEmpty is true,
338// returns -bootclasspath "" if the bootclasspath is empty to ensure javac does not fall back to the
339// default bootclasspath.
340func (x *classpath) JavaBootClasspath(forceEmpty bool) string {
341 if len(*x) > 0 {
342 return "-bootclasspath " + strings.Join(x.Strings(), ":")
343 } else if forceEmpty {
344 return `-bootclasspath ""`
345 } else {
346 return ""
347 }
348}
349
Colin Cross1369cdb2017-09-29 17:58:17 -0700350// Returns a --system argument in the form javac expects with -source 1.9. If forceEmpty is true,
351// returns --system=none if the list is empty to ensure javac does not fall back to the default
352// system modules.
353func (x *classpath) JavaSystemModules(forceEmpty bool) string {
354 if len(*x) > 1 {
355 panic("more than one system module")
356 } else if len(*x) == 1 {
357 return "--system=" + strings.TrimSuffix((*x)[0].String(), "lib/modules")
358 } else if forceEmpty {
359 return "--system=none"
360 } else {
361 return ""
362 }
363}
364
Colin Cross6ade34f2017-09-15 13:00:47 -0700365func (x *classpath) DesugarBootClasspath() []string {
366 if x == nil || *x == nil {
367 return nil
368 }
369 flags := make([]string, len(*x))
370 for i, v := range *x {
371 flags[i] = "--bootclasspath_entry " + v.String()
372 }
373
374 return flags
375}
376
377func (x *classpath) DesugarClasspath() []string {
378 if x == nil || *x == nil {
379 return nil
380 }
381 flags := make([]string, len(*x))
382 for i, v := range *x {
383 flags[i] = "--classpath_entry " + v.String()
384 }
385
386 return flags
387}
388
389// Append an android.Paths to the end of the classpath list
390func (x *classpath) AddPaths(paths android.Paths) {
391 for _, path := range paths {
392 *x = append(*x, path)
393 }
394}
395
396// Convert a classpath to an android.Paths
397func (x *classpath) Paths() android.Paths {
398 return append(android.Paths(nil), (*x)...)
399}
400
401func (x *classpath) Strings() []string {
402 if x == nil {
403 return nil
404 }
405 ret := make([]string, len(*x))
406 for i, path := range *x {
407 ret[i] = path.String()
408 }
409 return ret
410}