xref: /aosp_15_r20/build/soong/java/builder.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2015 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage java
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Worker// This file generates the final rules for compiling all Java.  All properties related to
18*333d2b36SAndroid Build Coastguard Worker// compiling should have been translated into javaBuilderFlags or another argument to the Transform*
19*333d2b36SAndroid Build Coastguard Worker// functions.
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Workerimport (
22*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
23*333d2b36SAndroid Build Coastguard Worker	"strconv"
24*333d2b36SAndroid Build Coastguard Worker	"strings"
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
27*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
28*333d2b36SAndroid Build Coastguard Worker
29*333d2b36SAndroid Build Coastguard Worker	"android/soong/android"
30*333d2b36SAndroid Build Coastguard Worker	"android/soong/remoteexec"
31*333d2b36SAndroid Build Coastguard Worker)
32*333d2b36SAndroid Build Coastguard Worker
33*333d2b36SAndroid Build Coastguard Workervar (
34*333d2b36SAndroid Build Coastguard Worker	pctx = android.NewPackageContext("android/soong/java")
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Worker	// Compiling java is not conducive to proper dependency tracking.  The path-matches-class-name
37*333d2b36SAndroid Build Coastguard Worker	// requirement leads to unpredictable generated source file names, and a single .java file
38*333d2b36SAndroid Build Coastguard Worker	// will get compiled into multiple .class files if it contains inner classes.  To work around
39*333d2b36SAndroid Build Coastguard Worker	// this, all java rules write into separate directories and then are combined into a .jar file
40*333d2b36SAndroid Build Coastguard Worker	// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
41*333d2b36SAndroid Build Coastguard Worker	// .srcjar files are unzipped into a temporary directory when compiled with javac.
42*333d2b36SAndroid Build Coastguard Worker	// TODO(b/143658984): goma can't handle the --system argument to javac.
43*333d2b36SAndroid Build Coastguard Worker	javac, javacRE = pctx.MultiCommandRemoteStaticRules("javac",
44*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
45*333d2b36SAndroid Build Coastguard Worker			Command: `rm -rf "$outDir" "$annoDir" "$annoSrcJar.tmp" "$srcJarDir" "$out.tmp" && ` +
46*333d2b36SAndroid Build Coastguard Worker				`mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
47*333d2b36SAndroid Build Coastguard Worker				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
48*333d2b36SAndroid Build Coastguard Worker				`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
49*333d2b36SAndroid Build Coastguard Worker				`${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
50*333d2b36SAndroid Build Coastguard Worker				`${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` +
51*333d2b36SAndroid Build Coastguard Worker				`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
52*333d2b36SAndroid Build Coastguard Worker				`-source $javaVersion -target $javaVersion ` +
53*333d2b36SAndroid Build Coastguard Worker				`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
54*333d2b36SAndroid Build Coastguard Worker				`$annoSrcJarTemplate${config.SoongZipCmd} -jar -o $annoSrcJar.tmp -C $annoDir -D $annoDir && ` +
55*333d2b36SAndroid Build Coastguard Worker				`$zipTemplate${config.SoongZipCmd} -jar -o $out.tmp -C $outDir -D $outDir && ` +
56*333d2b36SAndroid Build Coastguard Worker				`if ! cmp -s "$out.tmp" "$out"; then mv "$out.tmp" "$out"; fi && ` +
57*333d2b36SAndroid Build Coastguard Worker				`if ! cmp -s "$annoSrcJar.tmp" "$annoSrcJar"; then mv "$annoSrcJar.tmp" "$annoSrcJar"; fi && ` +
58*333d2b36SAndroid Build Coastguard Worker				`rm -rf "$srcJarDir" "$outDir"`,
59*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{
60*333d2b36SAndroid Build Coastguard Worker				"${config.JavacCmd}",
61*333d2b36SAndroid Build Coastguard Worker				"${config.SoongZipCmd}",
62*333d2b36SAndroid Build Coastguard Worker				"${config.ZipSyncCmd}",
63*333d2b36SAndroid Build Coastguard Worker			},
64*333d2b36SAndroid Build Coastguard Worker			CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
65*333d2b36SAndroid Build Coastguard Worker			Restat:           true,
66*333d2b36SAndroid Build Coastguard Worker			Rspfile:          "$out.rsp",
67*333d2b36SAndroid Build Coastguard Worker			RspfileContent:   "$in",
68*333d2b36SAndroid Build Coastguard Worker		}, map[string]*remoteexec.REParams{
69*333d2b36SAndroid Build Coastguard Worker			"$javaTemplate": &remoteexec.REParams{
70*333d2b36SAndroid Build Coastguard Worker				Labels:       map[string]string{"type": "compile", "lang": "java", "compiler": "javac"},
71*333d2b36SAndroid Build Coastguard Worker				ExecStrategy: "${config.REJavacExecStrategy}",
72*333d2b36SAndroid Build Coastguard Worker				Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
73*333d2b36SAndroid Build Coastguard Worker			},
74*333d2b36SAndroid Build Coastguard Worker			"$zipTemplate": &remoteexec.REParams{
75*333d2b36SAndroid Build Coastguard Worker				Labels:       map[string]string{"type": "tool", "name": "soong_zip"},
76*333d2b36SAndroid Build Coastguard Worker				Inputs:       []string{"${config.SoongZipCmd}", "$outDir"},
77*333d2b36SAndroid Build Coastguard Worker				OutputFiles:  []string{"$out.tmp"},
78*333d2b36SAndroid Build Coastguard Worker				ExecStrategy: "${config.REJavacExecStrategy}",
79*333d2b36SAndroid Build Coastguard Worker				Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
80*333d2b36SAndroid Build Coastguard Worker			},
81*333d2b36SAndroid Build Coastguard Worker			"$annoSrcJarTemplate": &remoteexec.REParams{
82*333d2b36SAndroid Build Coastguard Worker				Labels:       map[string]string{"type": "tool", "name": "soong_zip"},
83*333d2b36SAndroid Build Coastguard Worker				Inputs:       []string{"${config.SoongZipCmd}", "$annoDir"},
84*333d2b36SAndroid Build Coastguard Worker				OutputFiles:  []string{"$annoSrcJar.tmp"},
85*333d2b36SAndroid Build Coastguard Worker				ExecStrategy: "${config.REJavacExecStrategy}",
86*333d2b36SAndroid Build Coastguard Worker				Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
87*333d2b36SAndroid Build Coastguard Worker			},
88*333d2b36SAndroid Build Coastguard Worker		}, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
89*333d2b36SAndroid Build Coastguard Worker			"outDir", "annoDir", "annoSrcJar", "javaVersion"}, nil)
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Worker	_ = pctx.VariableFunc("kytheCorpus",
92*333d2b36SAndroid Build Coastguard Worker		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
93*333d2b36SAndroid Build Coastguard Worker	_ = pctx.VariableFunc("kytheCuEncoding",
94*333d2b36SAndroid Build Coastguard Worker		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
95*333d2b36SAndroid Build Coastguard Worker	_ = pctx.VariableFunc("kytheCuJavaSourceMax",
96*333d2b36SAndroid Build Coastguard Worker		func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuJavaSourceMax() })
97*333d2b36SAndroid Build Coastguard Worker	_ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
98*333d2b36SAndroid Build Coastguard Worker	// Run it with several --add-exports to allow the classes in the
99*333d2b36SAndroid Build Coastguard Worker	// com.google.devtools.kythe.extractors.java.standalone package access the packages in the
100*333d2b36SAndroid Build Coastguard Worker	// jdk.compiler compiler module. Long live Java modules.
101*333d2b36SAndroid Build Coastguard Worker	kytheExtract = pctx.AndroidStaticRule("kythe",
102*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
103*333d2b36SAndroid Build Coastguard Worker			Command: `${config.ZipSyncCmd} -d $srcJarDir ` +
104*333d2b36SAndroid Build Coastguard Worker				`-l $srcJarDir/list -f "*.java" $srcJars && ` +
105*333d2b36SAndroid Build Coastguard Worker				`( [ ! -s $srcJarDir/list -a ! -s $out.rsp ] || ` +
106*333d2b36SAndroid Build Coastguard Worker				`KYTHE_ROOT_DIRECTORY=. KYTHE_OUTPUT_FILE=$out ` +
107*333d2b36SAndroid Build Coastguard Worker				`KYTHE_CORPUS=${kytheCorpus} ` +
108*333d2b36SAndroid Build Coastguard Worker				`KYTHE_VNAMES=${kytheVnames} ` +
109*333d2b36SAndroid Build Coastguard Worker				`KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
110*333d2b36SAndroid Build Coastguard Worker				`KYTHE_JAVA_SOURCE_BATCH_SIZE=${kytheCuJavaSourceMax} ` +
111*333d2b36SAndroid Build Coastguard Worker				`${config.SoongJavacWrapper} ${config.JavaCmd} ` +
112*333d2b36SAndroid Build Coastguard Worker				// Avoid JDK9's warning about "Illegal reflective access by com.google.protobuf.Utf8$UnsafeProcessor ...
113*333d2b36SAndroid Build Coastguard Worker				// to field java.nio.Buffer.address"
114*333d2b36SAndroid Build Coastguard Worker				`--add-opens=java.base/java.nio=ALL-UNNAMED ` +
115*333d2b36SAndroid Build Coastguard Worker				// Allow the classes in the com.google.devtools.kythe.extractors.java.standalone package
116*333d2b36SAndroid Build Coastguard Worker				// access the packages in the jdk.compiler compiler module
117*333d2b36SAndroid Build Coastguard Worker				`--add-opens=java.base/java.nio=ALL-UNNAMED ` +
118*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED ` +
119*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED ` +
120*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED ` +
121*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED ` +
122*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED ` +
123*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED ` +
124*333d2b36SAndroid Build Coastguard Worker				`--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED ` +
125*333d2b36SAndroid Build Coastguard Worker				`-jar ${config.JavaKytheExtractorJar} ` +
126*333d2b36SAndroid Build Coastguard Worker				`${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
127*333d2b36SAndroid Build Coastguard Worker				`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
128*333d2b36SAndroid Build Coastguard Worker				`-source $javaVersion -target $javaVersion ` +
129*333d2b36SAndroid Build Coastguard Worker				`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list)`,
130*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{
131*333d2b36SAndroid Build Coastguard Worker				"${config.JavaCmd}",
132*333d2b36SAndroid Build Coastguard Worker				"${config.JavaKytheExtractorJar}",
133*333d2b36SAndroid Build Coastguard Worker				"${kytheVnames}",
134*333d2b36SAndroid Build Coastguard Worker				"${config.ZipSyncCmd}",
135*333d2b36SAndroid Build Coastguard Worker			},
136*333d2b36SAndroid Build Coastguard Worker			CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
137*333d2b36SAndroid Build Coastguard Worker			Rspfile:          "$out.rsp",
138*333d2b36SAndroid Build Coastguard Worker			RspfileContent:   "$in",
139*333d2b36SAndroid Build Coastguard Worker		},
140*333d2b36SAndroid Build Coastguard Worker		"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
141*333d2b36SAndroid Build Coastguard Worker		"outDir", "annoDir", "javaVersion")
142*333d2b36SAndroid Build Coastguard Worker
143*333d2b36SAndroid Build Coastguard Worker	extractMatchingApks = pctx.StaticRule(
144*333d2b36SAndroid Build Coastguard Worker		"extractMatchingApks",
145*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
146*333d2b36SAndroid Build Coastguard Worker			Command: `rm -rf "$out" && ` +
147*333d2b36SAndroid Build Coastguard Worker				`${config.ExtractApksCmd} -o "${out}" -zip "${zip}" -allow-prereleased=${allow-prereleased} ` +
148*333d2b36SAndroid Build Coastguard Worker				`-sdk-version=${sdk-version} -skip-sdk-check=${skip-sdk-check} -abis=${abis} ` +
149*333d2b36SAndroid Build Coastguard Worker				`--screen-densities=${screen-densities} --stem=${stem} ` +
150*333d2b36SAndroid Build Coastguard Worker				`-apkcerts=${apkcerts} -partition=${partition} ` +
151*333d2b36SAndroid Build Coastguard Worker				`${in}`,
152*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.ExtractApksCmd}"},
153*333d2b36SAndroid Build Coastguard Worker		},
154*333d2b36SAndroid Build Coastguard Worker		"abis", "allow-prereleased", "screen-densities", "sdk-version", "skip-sdk-check", "stem", "apkcerts", "partition", "zip")
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Worker	turbine, turbineRE = pctx.RemoteStaticRules("turbine",
157*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
158*333d2b36SAndroid Build Coastguard Worker			Command: `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.TurbineJar} $outputFlags ` +
159*333d2b36SAndroid Build Coastguard Worker				`--sources @$out.rsp ` +
160*333d2b36SAndroid Build Coastguard Worker				`--javacopts ${config.CommonJdkFlags} ` +
161*333d2b36SAndroid Build Coastguard Worker				`$javacFlags -source $javaVersion -target $javaVersion -- $turbineFlags && ` +
162*333d2b36SAndroid Build Coastguard Worker				`(for o in $outputs; do if cmp -s $${o}.tmp $${o} ; then rm $${o}.tmp ; else mv $${o}.tmp $${o} ; fi; done )`,
163*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{
164*333d2b36SAndroid Build Coastguard Worker				"${config.TurbineJar}",
165*333d2b36SAndroid Build Coastguard Worker				"${config.JavaCmd}",
166*333d2b36SAndroid Build Coastguard Worker			},
167*333d2b36SAndroid Build Coastguard Worker			Rspfile:        "$out.rsp",
168*333d2b36SAndroid Build Coastguard Worker			RspfileContent: "$in",
169*333d2b36SAndroid Build Coastguard Worker			Restat:         true,
170*333d2b36SAndroid Build Coastguard Worker		},
171*333d2b36SAndroid Build Coastguard Worker		&remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "turbine"},
172*333d2b36SAndroid Build Coastguard Worker			ExecStrategy:    "${config.RETurbineExecStrategy}",
173*333d2b36SAndroid Build Coastguard Worker			Inputs:          []string{"${config.TurbineJar}", "${out}.rsp", "$rbeInputs"},
174*333d2b36SAndroid Build Coastguard Worker			RSPFiles:        []string{"$out.rsp", "$rspFiles"},
175*333d2b36SAndroid Build Coastguard Worker			OutputFiles:     []string{"$rbeOutputs"},
176*333d2b36SAndroid Build Coastguard Worker			ToolchainInputs: []string{"${config.JavaCmd}"},
177*333d2b36SAndroid Build Coastguard Worker			Platform:        map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
178*333d2b36SAndroid Build Coastguard Worker		},
179*333d2b36SAndroid Build Coastguard Worker		[]string{"javacFlags", "turbineFlags", "outputFlags", "javaVersion", "outputs", "rbeOutputs"}, []string{"rbeInputs", "rspFiles"})
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Worker	jar, jarRE = pctx.RemoteStaticRules("jar",
182*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
183*333d2b36SAndroid Build Coastguard Worker			Command:        `$reTemplate${config.SoongZipCmd} -jar -o $out @$out.rsp`,
184*333d2b36SAndroid Build Coastguard Worker			CommandDeps:    []string{"${config.SoongZipCmd}"},
185*333d2b36SAndroid Build Coastguard Worker			Rspfile:        "$out.rsp",
186*333d2b36SAndroid Build Coastguard Worker			RspfileContent: "$jarArgs",
187*333d2b36SAndroid Build Coastguard Worker		},
188*333d2b36SAndroid Build Coastguard Worker		&remoteexec.REParams{
189*333d2b36SAndroid Build Coastguard Worker			ExecStrategy: "${config.REJarExecStrategy}",
190*333d2b36SAndroid Build Coastguard Worker			Inputs:       []string{"${config.SoongZipCmd}", "${out}.rsp"},
191*333d2b36SAndroid Build Coastguard Worker			RSPFiles:     []string{"${out}.rsp"},
192*333d2b36SAndroid Build Coastguard Worker			OutputFiles:  []string{"$out"},
193*333d2b36SAndroid Build Coastguard Worker			Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
194*333d2b36SAndroid Build Coastguard Worker		}, []string{"jarArgs"}, nil)
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Worker	zip, zipRE = pctx.RemoteStaticRules("zip",
197*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
198*333d2b36SAndroid Build Coastguard Worker			Command:        `${config.SoongZipCmd} -o $out @$out.rsp`,
199*333d2b36SAndroid Build Coastguard Worker			CommandDeps:    []string{"${config.SoongZipCmd}"},
200*333d2b36SAndroid Build Coastguard Worker			Rspfile:        "$out.rsp",
201*333d2b36SAndroid Build Coastguard Worker			RspfileContent: "$jarArgs",
202*333d2b36SAndroid Build Coastguard Worker		},
203*333d2b36SAndroid Build Coastguard Worker		&remoteexec.REParams{
204*333d2b36SAndroid Build Coastguard Worker			ExecStrategy: "${config.REZipExecStrategy}",
205*333d2b36SAndroid Build Coastguard Worker			Inputs:       []string{"${config.SoongZipCmd}", "${out}.rsp", "$implicits"},
206*333d2b36SAndroid Build Coastguard Worker			RSPFiles:     []string{"${out}.rsp"},
207*333d2b36SAndroid Build Coastguard Worker			OutputFiles:  []string{"$out"},
208*333d2b36SAndroid Build Coastguard Worker			Platform:     map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
209*333d2b36SAndroid Build Coastguard Worker		}, []string{"jarArgs"}, []string{"implicits"})
210*333d2b36SAndroid Build Coastguard Worker
211*333d2b36SAndroid Build Coastguard Worker	combineJar = pctx.AndroidStaticRule("combineJar",
212*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
213*333d2b36SAndroid Build Coastguard Worker			Command:     `${config.MergeZipsCmd} --ignore-duplicates -j $jarArgs $out $in`,
214*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.MergeZipsCmd}"},
215*333d2b36SAndroid Build Coastguard Worker		},
216*333d2b36SAndroid Build Coastguard Worker		"jarArgs")
217*333d2b36SAndroid Build Coastguard Worker	combineJarRsp = pctx.AndroidStaticRule("combineJarRsp",
218*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
219*333d2b36SAndroid Build Coastguard Worker			Command:        `${config.MergeZipsCmd} --ignore-duplicates -j $jarArgs $out @$out.rsp`,
220*333d2b36SAndroid Build Coastguard Worker			CommandDeps:    []string{"${config.MergeZipsCmd}"},
221*333d2b36SAndroid Build Coastguard Worker			Rspfile:        "$out.rsp",
222*333d2b36SAndroid Build Coastguard Worker			RspfileContent: "$in",
223*333d2b36SAndroid Build Coastguard Worker		},
224*333d2b36SAndroid Build Coastguard Worker		"jarArgs")
225*333d2b36SAndroid Build Coastguard Worker
226*333d2b36SAndroid Build Coastguard Worker	jarjar = pctx.AndroidStaticRule("jarjar",
227*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
228*333d2b36SAndroid Build Coastguard Worker			Command: "" +
229*333d2b36SAndroid Build Coastguard Worker				// Jarjar doesn't exit with an error when the rules file contains a syntax error,
230*333d2b36SAndroid Build Coastguard Worker				// leading to stale or missing files later in the build.  Remove the output file
231*333d2b36SAndroid Build Coastguard Worker				// before running jarjar.
232*333d2b36SAndroid Build Coastguard Worker				"rm -f ${out} && " +
233*333d2b36SAndroid Build Coastguard Worker				"${config.JavaCmd} ${config.JavaVmFlags}" +
234*333d2b36SAndroid Build Coastguard Worker				// b/146418363 Enable Android specific jarjar transformer to drop compat annotations
235*333d2b36SAndroid Build Coastguard Worker				// for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
236*333d2b36SAndroid Build Coastguard Worker				// avoids adding new hiddenapis after jarjar'ing.
237*333d2b36SAndroid Build Coastguard Worker				" -DremoveAndroidCompatAnnotations=true" +
238*333d2b36SAndroid Build Coastguard Worker				" -jar ${config.JarjarCmd} process $rulesFile $in $out && " +
239*333d2b36SAndroid Build Coastguard Worker				// Turn a missing output file into a ninja error
240*333d2b36SAndroid Build Coastguard Worker				`[ -e ${out} ] || (echo "Missing output file"; exit 1)`,
241*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
242*333d2b36SAndroid Build Coastguard Worker		},
243*333d2b36SAndroid Build Coastguard Worker		"rulesFile")
244*333d2b36SAndroid Build Coastguard Worker
245*333d2b36SAndroid Build Coastguard Worker	packageCheck = pctx.AndroidStaticRule("packageCheck",
246*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
247*333d2b36SAndroid Build Coastguard Worker			Command: "rm -f $out && " +
248*333d2b36SAndroid Build Coastguard Worker				"${config.PackageCheckCmd} $in $packages && " +
249*333d2b36SAndroid Build Coastguard Worker				"touch $out",
250*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.PackageCheckCmd}"},
251*333d2b36SAndroid Build Coastguard Worker		},
252*333d2b36SAndroid Build Coastguard Worker		"packages")
253*333d2b36SAndroid Build Coastguard Worker
254*333d2b36SAndroid Build Coastguard Worker	jetifier = pctx.AndroidStaticRule("jetifier",
255*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
256*333d2b36SAndroid Build Coastguard Worker			Command:     "${config.JavaCmd}  ${config.JavaVmFlags} -jar ${config.JetifierJar} -l error -o $out -i $in -t epoch",
257*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.JavaCmd}", "${config.JetifierJar}"},
258*333d2b36SAndroid Build Coastguard Worker		},
259*333d2b36SAndroid Build Coastguard Worker	)
260*333d2b36SAndroid Build Coastguard Worker
261*333d2b36SAndroid Build Coastguard Worker	ravenizer = pctx.AndroidStaticRule("ravenizer",
262*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
263*333d2b36SAndroid Build Coastguard Worker			Command:     "rm -f $out && ${ravenizer} --in-jar $in --out-jar $out $ravenizerArgs",
264*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${ravenizer}"},
265*333d2b36SAndroid Build Coastguard Worker		},
266*333d2b36SAndroid Build Coastguard Worker		"ravenizerArgs")
267*333d2b36SAndroid Build Coastguard Worker
268*333d2b36SAndroid Build Coastguard Worker	apimapper = pctx.AndroidStaticRule("apimapper",
269*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
270*333d2b36SAndroid Build Coastguard Worker			Command:     "${apimapper} --in-jar $in --out-jar $out",
271*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${apimapper}"},
272*333d2b36SAndroid Build Coastguard Worker		},
273*333d2b36SAndroid Build Coastguard Worker	)
274*333d2b36SAndroid Build Coastguard Worker
275*333d2b36SAndroid Build Coastguard Worker	zipalign = pctx.AndroidStaticRule("zipalign",
276*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
277*333d2b36SAndroid Build Coastguard Worker			Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
278*333d2b36SAndroid Build Coastguard Worker				"${config.ZipAlign} -f -p 4 $in $out; " +
279*333d2b36SAndroid Build Coastguard Worker				"else " +
280*333d2b36SAndroid Build Coastguard Worker				"cp -f $in $out; " +
281*333d2b36SAndroid Build Coastguard Worker				"fi",
282*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.ZipAlign}"},
283*333d2b36SAndroid Build Coastguard Worker		},
284*333d2b36SAndroid Build Coastguard Worker	)
285*333d2b36SAndroid Build Coastguard Worker
286*333d2b36SAndroid Build Coastguard Worker	convertImplementationJarToHeaderJarRule = pctx.AndroidStaticRule("convertImplementationJarToHeaderJar",
287*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
288*333d2b36SAndroid Build Coastguard Worker			Command:     `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`,
289*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${config.Zip2ZipCmd}"},
290*333d2b36SAndroid Build Coastguard Worker		})
291*333d2b36SAndroid Build Coastguard Worker
292*333d2b36SAndroid Build Coastguard Worker	writeCombinedProguardFlagsFileRule = pctx.AndroidStaticRule("writeCombinedProguardFlagsFileRule",
293*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
294*333d2b36SAndroid Build Coastguard Worker			Command: `rm -f $out && ` +
295*333d2b36SAndroid Build Coastguard Worker				`for f in $in; do ` +
296*333d2b36SAndroid Build Coastguard Worker				` echo  && ` +
297*333d2b36SAndroid Build Coastguard Worker				` echo "# including $$f" && ` +
298*333d2b36SAndroid Build Coastguard Worker				` cat $$f; ` +
299*333d2b36SAndroid Build Coastguard Worker				`done > $out`,
300*333d2b36SAndroid Build Coastguard Worker		})
301*333d2b36SAndroid Build Coastguard Worker
302*333d2b36SAndroid Build Coastguard Worker	gatherReleasedFlaggedApisRule = pctx.AndroidStaticRule("gatherReleasedFlaggedApisRule",
303*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
304*333d2b36SAndroid Build Coastguard Worker			Command: `${aconfig} dump-cache --dedup --format='{fully_qualified_name}' ` +
305*333d2b36SAndroid Build Coastguard Worker				`--out ${out} ` +
306*333d2b36SAndroid Build Coastguard Worker				`${flags_path} ` +
307*333d2b36SAndroid Build Coastguard Worker				`${filter_args} `,
308*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${aconfig}"},
309*333d2b36SAndroid Build Coastguard Worker			Description: "aconfig_bool",
310*333d2b36SAndroid Build Coastguard Worker		}, "flags_path", "filter_args")
311*333d2b36SAndroid Build Coastguard Worker
312*333d2b36SAndroid Build Coastguard Worker	generateMetalavaRevertAnnotationsRule = pctx.AndroidStaticRule("generateMetalavaRevertAnnotationsRule",
313*333d2b36SAndroid Build Coastguard Worker		blueprint.RuleParams{
314*333d2b36SAndroid Build Coastguard Worker			Command:     `${keep-flagged-apis} ${in} > ${out}`,
315*333d2b36SAndroid Build Coastguard Worker			CommandDeps: []string{"${keep-flagged-apis}"},
316*333d2b36SAndroid Build Coastguard Worker		})
317*333d2b36SAndroid Build Coastguard Worker)
318*333d2b36SAndroid Build Coastguard Worker
319*333d2b36SAndroid Build Coastguard Workerfunc init() {
320*333d2b36SAndroid Build Coastguard Worker	pctx.Import("android/soong/android")
321*333d2b36SAndroid Build Coastguard Worker	pctx.Import("android/soong/java/config")
322*333d2b36SAndroid Build Coastguard Worker
323*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("aconfig", "aconfig")
324*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("ravenizer", "ravenizer")
325*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("apimapper", "apimapper")
326*333d2b36SAndroid Build Coastguard Worker	pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis")
327*333d2b36SAndroid Build Coastguard Worker}
328*333d2b36SAndroid Build Coastguard Worker
329*333d2b36SAndroid Build Coastguard Workertype javaBuilderFlags struct {
330*333d2b36SAndroid Build Coastguard Worker	javacFlags string
331*333d2b36SAndroid Build Coastguard Worker
332*333d2b36SAndroid Build Coastguard Worker	// bootClasspath is the list of jars that form the boot classpath (generally the java.* and
333*333d2b36SAndroid Build Coastguard Worker	// android.* classes) for tools that still use it.  javac targeting 1.9 or higher uses
334*333d2b36SAndroid Build Coastguard Worker	// systemModules and java9Classpath instead.
335*333d2b36SAndroid Build Coastguard Worker	bootClasspath classpath
336*333d2b36SAndroid Build Coastguard Worker
337*333d2b36SAndroid Build Coastguard Worker	// classpath is the list of jars that form the classpath for javac and kotlinc rules.  It
338*333d2b36SAndroid Build Coastguard Worker	// contains header jars for all static and non-static dependencies.
339*333d2b36SAndroid Build Coastguard Worker	classpath classpath
340*333d2b36SAndroid Build Coastguard Worker
341*333d2b36SAndroid Build Coastguard Worker	// dexClasspath is the list of jars that form the classpath for d8 and r8 rules.  It contains
342*333d2b36SAndroid Build Coastguard Worker	// header jars for all non-static dependencies.  Static dependencies have already been
343*333d2b36SAndroid Build Coastguard Worker	// combined into the program jar.
344*333d2b36SAndroid Build Coastguard Worker	dexClasspath classpath
345*333d2b36SAndroid Build Coastguard Worker
346*333d2b36SAndroid Build Coastguard Worker	// java9Classpath is the list of jars that will be added to the classpath when targeting
347*333d2b36SAndroid Build Coastguard Worker	// 1.9 or higher.  It generally contains the android.* classes, while the java.* classes
348*333d2b36SAndroid Build Coastguard Worker	// are provided by systemModules.
349*333d2b36SAndroid Build Coastguard Worker	java9Classpath classpath
350*333d2b36SAndroid Build Coastguard Worker
351*333d2b36SAndroid Build Coastguard Worker	processorPath classpath
352*333d2b36SAndroid Build Coastguard Worker	processors    []string
353*333d2b36SAndroid Build Coastguard Worker	systemModules *systemModules
354*333d2b36SAndroid Build Coastguard Worker	aidlFlags     string
355*333d2b36SAndroid Build Coastguard Worker	aidlDeps      android.Paths
356*333d2b36SAndroid Build Coastguard Worker	javaVersion   javaVersion
357*333d2b36SAndroid Build Coastguard Worker
358*333d2b36SAndroid Build Coastguard Worker	errorProneExtraJavacFlags string
359*333d2b36SAndroid Build Coastguard Worker	errorProneProcessorPath   classpath
360*333d2b36SAndroid Build Coastguard Worker
361*333d2b36SAndroid Build Coastguard Worker	kotlincFlags     string
362*333d2b36SAndroid Build Coastguard Worker	kotlincClasspath classpath
363*333d2b36SAndroid Build Coastguard Worker	kotlincDeps      android.Paths
364*333d2b36SAndroid Build Coastguard Worker
365*333d2b36SAndroid Build Coastguard Worker	proto android.ProtoFlags
366*333d2b36SAndroid Build Coastguard Worker}
367*333d2b36SAndroid Build Coastguard Worker
368*333d2b36SAndroid Build Coastguard Workerfunc DefaultJavaBuilderFlags() javaBuilderFlags {
369*333d2b36SAndroid Build Coastguard Worker	return javaBuilderFlags{
370*333d2b36SAndroid Build Coastguard Worker		javaVersion: JAVA_VERSION_8,
371*333d2b36SAndroid Build Coastguard Worker	}
372*333d2b36SAndroid Build Coastguard Worker}
373*333d2b36SAndroid Build Coastguard Worker
374*333d2b36SAndroid Build Coastguard Workerfunc TransformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath, shardIdx int,
375*333d2b36SAndroid Build Coastguard Worker	srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath, flags javaBuilderFlags, deps android.Paths) {
376*333d2b36SAndroid Build Coastguard Worker
377*333d2b36SAndroid Build Coastguard Worker	// Compile java sources into .class files
378*333d2b36SAndroid Build Coastguard Worker	desc := "javac"
379*333d2b36SAndroid Build Coastguard Worker	if shardIdx >= 0 {
380*333d2b36SAndroid Build Coastguard Worker		desc += strconv.Itoa(shardIdx)
381*333d2b36SAndroid Build Coastguard Worker	}
382*333d2b36SAndroid Build Coastguard Worker
383*333d2b36SAndroid Build Coastguard Worker	transformJavaToClasses(ctx, outputFile, shardIdx, srcFiles, srcJars, annoSrcJar, flags, deps, "javac", desc)
384*333d2b36SAndroid Build Coastguard Worker}
385*333d2b36SAndroid Build Coastguard Worker
386*333d2b36SAndroid Build Coastguard Worker// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
387*333d2b36SAndroid Build Coastguard Worker// to compile with given set of builder flags, etc.
388*333d2b36SAndroid Build Coastguard Workerfunc emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath, idx int,
389*333d2b36SAndroid Build Coastguard Worker	srcFiles, srcJars android.Paths,
390*333d2b36SAndroid Build Coastguard Worker	flags javaBuilderFlags, deps android.Paths) {
391*333d2b36SAndroid Build Coastguard Worker
392*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, srcJars...)
393*333d2b36SAndroid Build Coastguard Worker	classpath := flags.classpath
394*333d2b36SAndroid Build Coastguard Worker
395*333d2b36SAndroid Build Coastguard Worker	var bootClasspath string
396*333d2b36SAndroid Build Coastguard Worker	if flags.javaVersion.usesJavaModules() {
397*333d2b36SAndroid Build Coastguard Worker		var systemModuleDeps android.Paths
398*333d2b36SAndroid Build Coastguard Worker		bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device())
399*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, systemModuleDeps...)
400*333d2b36SAndroid Build Coastguard Worker		classpath = append(flags.java9Classpath, classpath...)
401*333d2b36SAndroid Build Coastguard Worker	} else {
402*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, flags.bootClasspath...)
403*333d2b36SAndroid Build Coastguard Worker		if len(flags.bootClasspath) == 0 && ctx.Device() {
404*333d2b36SAndroid Build Coastguard Worker			// explicitly specify -bootclasspath "" if the bootclasspath is empty to
405*333d2b36SAndroid Build Coastguard Worker			// ensure java does not fall back to the default bootclasspath.
406*333d2b36SAndroid Build Coastguard Worker			bootClasspath = `-bootclasspath ""`
407*333d2b36SAndroid Build Coastguard Worker		} else {
408*333d2b36SAndroid Build Coastguard Worker			bootClasspath = flags.bootClasspath.FormJavaClassPath("-bootclasspath")
409*333d2b36SAndroid Build Coastguard Worker		}
410*333d2b36SAndroid Build Coastguard Worker	}
411*333d2b36SAndroid Build Coastguard Worker
412*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, classpath...)
413*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, flags.processorPath...)
414*333d2b36SAndroid Build Coastguard Worker
415*333d2b36SAndroid Build Coastguard Worker	processor := "-proc:none"
416*333d2b36SAndroid Build Coastguard Worker	if len(flags.processors) > 0 {
417*333d2b36SAndroid Build Coastguard Worker		processor = "-processor " + strings.Join(flags.processors, ",")
418*333d2b36SAndroid Build Coastguard Worker	}
419*333d2b36SAndroid Build Coastguard Worker
420*333d2b36SAndroid Build Coastguard Worker	intermediatesDir := "xref"
421*333d2b36SAndroid Build Coastguard Worker	if idx >= 0 {
422*333d2b36SAndroid Build Coastguard Worker		intermediatesDir += strconv.Itoa(idx)
423*333d2b36SAndroid Build Coastguard Worker	}
424*333d2b36SAndroid Build Coastguard Worker
425*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx,
426*333d2b36SAndroid Build Coastguard Worker		android.BuildParams{
427*333d2b36SAndroid Build Coastguard Worker			Rule:        kytheExtract,
428*333d2b36SAndroid Build Coastguard Worker			Description: "Xref Java extractor",
429*333d2b36SAndroid Build Coastguard Worker			Output:      xrefFile,
430*333d2b36SAndroid Build Coastguard Worker			Inputs:      srcFiles,
431*333d2b36SAndroid Build Coastguard Worker			Implicits:   deps,
432*333d2b36SAndroid Build Coastguard Worker			Args: map[string]string{
433*333d2b36SAndroid Build Coastguard Worker				"annoDir":       android.PathForModuleOut(ctx, intermediatesDir, "anno").String(),
434*333d2b36SAndroid Build Coastguard Worker				"bootClasspath": bootClasspath,
435*333d2b36SAndroid Build Coastguard Worker				"classpath":     classpath.FormJavaClassPath("-classpath"),
436*333d2b36SAndroid Build Coastguard Worker				"javacFlags":    flags.javacFlags,
437*333d2b36SAndroid Build Coastguard Worker				"javaVersion":   flags.javaVersion.String(),
438*333d2b36SAndroid Build Coastguard Worker				"outDir":        android.PathForModuleOut(ctx, "javac", "classes.xref").String(),
439*333d2b36SAndroid Build Coastguard Worker				"processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
440*333d2b36SAndroid Build Coastguard Worker				"processor":     processor,
441*333d2b36SAndroid Build Coastguard Worker				"srcJarDir":     android.PathForModuleOut(ctx, intermediatesDir, "srcjars.xref").String(),
442*333d2b36SAndroid Build Coastguard Worker				"srcJars":       strings.Join(srcJars.Strings(), " "),
443*333d2b36SAndroid Build Coastguard Worker			},
444*333d2b36SAndroid Build Coastguard Worker		})
445*333d2b36SAndroid Build Coastguard Worker}
446*333d2b36SAndroid Build Coastguard Worker
447*333d2b36SAndroid Build Coastguard Workerfunc turbineFlags(ctx android.ModuleContext, flags javaBuilderFlags, dir string, srcJars android.Paths) (string, android.Paths, android.Paths, android.Paths) {
448*333d2b36SAndroid Build Coastguard Worker	var implicits android.Paths
449*333d2b36SAndroid Build Coastguard Worker	var rbeInputs android.Paths
450*333d2b36SAndroid Build Coastguard Worker	var rspFiles android.Paths
451*333d2b36SAndroid Build Coastguard Worker
452*333d2b36SAndroid Build Coastguard Worker	classpath := flags.classpath
453*333d2b36SAndroid Build Coastguard Worker
454*333d2b36SAndroid Build Coastguard Worker	srcJarArgs := strings.Join(srcJars.Strings(), " ")
455*333d2b36SAndroid Build Coastguard Worker	implicits = append(implicits, srcJars...)
456*333d2b36SAndroid Build Coastguard Worker	const srcJarArgsLimit = 32 * 1024
457*333d2b36SAndroid Build Coastguard Worker	if len(srcJarArgs) > srcJarArgsLimit {
458*333d2b36SAndroid Build Coastguard Worker		srcJarRspFile := android.PathForModuleOut(ctx, "turbine", "srcjars.rsp")
459*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRule(ctx, srcJarRspFile, srcJarArgs)
460*333d2b36SAndroid Build Coastguard Worker		srcJarArgs = "@" + srcJarRspFile.String()
461*333d2b36SAndroid Build Coastguard Worker		implicits = append(implicits, srcJarRspFile)
462*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, srcJarRspFile)
463*333d2b36SAndroid Build Coastguard Worker	} else {
464*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, srcJars...)
465*333d2b36SAndroid Build Coastguard Worker	}
466*333d2b36SAndroid Build Coastguard Worker
467*333d2b36SAndroid Build Coastguard Worker	var bootClasspathFlags string
468*333d2b36SAndroid Build Coastguard Worker	if flags.javaVersion.usesJavaModules() {
469*333d2b36SAndroid Build Coastguard Worker		var systemModuleDeps android.Paths
470*333d2b36SAndroid Build Coastguard Worker		bootClasspathFlags, systemModuleDeps = flags.systemModules.FormTurbineSystemModulesPath(ctx.Device())
471*333d2b36SAndroid Build Coastguard Worker		implicits = append(implicits, systemModuleDeps...)
472*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, systemModuleDeps...)
473*333d2b36SAndroid Build Coastguard Worker		classpath = append(flags.java9Classpath, classpath...)
474*333d2b36SAndroid Build Coastguard Worker	} else {
475*333d2b36SAndroid Build Coastguard Worker		implicits = append(implicits, flags.bootClasspath...)
476*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, flags.bootClasspath...)
477*333d2b36SAndroid Build Coastguard Worker		if len(flags.bootClasspath) == 0 && ctx.Device() {
478*333d2b36SAndroid Build Coastguard Worker			// explicitly specify -bootclasspath "" if the bootclasspath is empty to
479*333d2b36SAndroid Build Coastguard Worker			// ensure turbine does not fall back to the default bootclasspath.
480*333d2b36SAndroid Build Coastguard Worker			bootClasspathFlags = `--bootclasspath ""`
481*333d2b36SAndroid Build Coastguard Worker		} else {
482*333d2b36SAndroid Build Coastguard Worker			bootClasspathFlags = flags.bootClasspath.FormTurbineClassPath("--bootclasspath ")
483*333d2b36SAndroid Build Coastguard Worker		}
484*333d2b36SAndroid Build Coastguard Worker	}
485*333d2b36SAndroid Build Coastguard Worker
486*333d2b36SAndroid Build Coastguard Worker	classpathFlags := classpath.FormTurbineClassPath("")
487*333d2b36SAndroid Build Coastguard Worker	implicits = append(implicits, classpath...)
488*333d2b36SAndroid Build Coastguard Worker	const classpathLimit = 32 * 1024
489*333d2b36SAndroid Build Coastguard Worker	if len(classpathFlags) > classpathLimit {
490*333d2b36SAndroid Build Coastguard Worker		classpathRspFile := android.PathForModuleOut(ctx, dir, "classpath.rsp")
491*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRule(ctx, classpathRspFile, classpathFlags)
492*333d2b36SAndroid Build Coastguard Worker		classpathFlags = "@" + classpathRspFile.String()
493*333d2b36SAndroid Build Coastguard Worker		implicits = append(implicits, classpathRspFile)
494*333d2b36SAndroid Build Coastguard Worker		rspFiles = append(rspFiles, classpathRspFile)
495*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, classpathRspFile)
496*333d2b36SAndroid Build Coastguard Worker	} else {
497*333d2b36SAndroid Build Coastguard Worker		rbeInputs = append(rbeInputs, classpath...)
498*333d2b36SAndroid Build Coastguard Worker	}
499*333d2b36SAndroid Build Coastguard Worker
500*333d2b36SAndroid Build Coastguard Worker	turbineFlags := "--source_jars " + srcJarArgs + " " + bootClasspathFlags + " --classpath " + classpathFlags
501*333d2b36SAndroid Build Coastguard Worker
502*333d2b36SAndroid Build Coastguard Worker	return turbineFlags, implicits, rbeInputs, rspFiles
503*333d2b36SAndroid Build Coastguard Worker}
504*333d2b36SAndroid Build Coastguard Worker
505*333d2b36SAndroid Build Coastguard Workerfunc TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android.WritablePath,
506*333d2b36SAndroid Build Coastguard Worker	srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
507*333d2b36SAndroid Build Coastguard Worker
508*333d2b36SAndroid Build Coastguard Worker	turbineFlags, implicits, rbeInputs, rspFiles := turbineFlags(ctx, flags, "turbine", srcJars)
509*333d2b36SAndroid Build Coastguard Worker
510*333d2b36SAndroid Build Coastguard Worker	rule := turbine
511*333d2b36SAndroid Build Coastguard Worker	args := map[string]string{
512*333d2b36SAndroid Build Coastguard Worker		"javacFlags":   flags.javacFlags,
513*333d2b36SAndroid Build Coastguard Worker		"javaVersion":  flags.javaVersion.String(),
514*333d2b36SAndroid Build Coastguard Worker		"turbineFlags": turbineFlags,
515*333d2b36SAndroid Build Coastguard Worker		"outputFlags":  "--output " + outputFile.String() + ".tmp",
516*333d2b36SAndroid Build Coastguard Worker		"outputs":      outputFile.String(),
517*333d2b36SAndroid Build Coastguard Worker	}
518*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_TURBINE") {
519*333d2b36SAndroid Build Coastguard Worker		rule = turbineRE
520*333d2b36SAndroid Build Coastguard Worker		args["rbeInputs"] = strings.Join(rbeInputs.Strings(), ",")
521*333d2b36SAndroid Build Coastguard Worker		args["rbeOutputs"] = outputFile.String() + ".tmp"
522*333d2b36SAndroid Build Coastguard Worker		args["rspFiles"] = strings.Join(rspFiles.Strings(), ",")
523*333d2b36SAndroid Build Coastguard Worker	}
524*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
525*333d2b36SAndroid Build Coastguard Worker		Rule:        rule,
526*333d2b36SAndroid Build Coastguard Worker		Description: "turbine",
527*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
528*333d2b36SAndroid Build Coastguard Worker		Inputs:      srcFiles,
529*333d2b36SAndroid Build Coastguard Worker		Implicits:   implicits,
530*333d2b36SAndroid Build Coastguard Worker		Args:        args,
531*333d2b36SAndroid Build Coastguard Worker	})
532*333d2b36SAndroid Build Coastguard Worker}
533*333d2b36SAndroid Build Coastguard Worker
534*333d2b36SAndroid Build Coastguard Worker// TurbineApt produces a rule to run annotation processors using turbine.
535*333d2b36SAndroid Build Coastguard Workerfunc TurbineApt(ctx android.ModuleContext, outputSrcJar, outputResJar android.WritablePath,
536*333d2b36SAndroid Build Coastguard Worker	srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
537*333d2b36SAndroid Build Coastguard Worker
538*333d2b36SAndroid Build Coastguard Worker	turbineFlags, implicits, rbeInputs, rspFiles := turbineFlags(ctx, flags, "turbine-apt", srcJars)
539*333d2b36SAndroid Build Coastguard Worker
540*333d2b36SAndroid Build Coastguard Worker	implicits = append(implicits, flags.processorPath...)
541*333d2b36SAndroid Build Coastguard Worker	rbeInputs = append(rbeInputs, flags.processorPath...)
542*333d2b36SAndroid Build Coastguard Worker	turbineFlags += " " + flags.processorPath.FormTurbineClassPath("--processorpath ")
543*333d2b36SAndroid Build Coastguard Worker	turbineFlags += " --processors " + strings.Join(flags.processors, " ")
544*333d2b36SAndroid Build Coastguard Worker
545*333d2b36SAndroid Build Coastguard Worker	outputs := android.WritablePaths{outputSrcJar, outputResJar}
546*333d2b36SAndroid Build Coastguard Worker	outputFlags := "--gensrc_output " + outputSrcJar.String() + ".tmp " +
547*333d2b36SAndroid Build Coastguard Worker		"--resource_output " + outputResJar.String() + ".tmp"
548*333d2b36SAndroid Build Coastguard Worker
549*333d2b36SAndroid Build Coastguard Worker	rule := turbine
550*333d2b36SAndroid Build Coastguard Worker	args := map[string]string{
551*333d2b36SAndroid Build Coastguard Worker		"javacFlags":   flags.javacFlags,
552*333d2b36SAndroid Build Coastguard Worker		"javaVersion":  flags.javaVersion.String(),
553*333d2b36SAndroid Build Coastguard Worker		"turbineFlags": turbineFlags,
554*333d2b36SAndroid Build Coastguard Worker		"outputFlags":  outputFlags,
555*333d2b36SAndroid Build Coastguard Worker		"outputs":      strings.Join(outputs.Strings(), " "),
556*333d2b36SAndroid Build Coastguard Worker	}
557*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_TURBINE") {
558*333d2b36SAndroid Build Coastguard Worker		rule = turbineRE
559*333d2b36SAndroid Build Coastguard Worker		args["rbeInputs"] = strings.Join(rbeInputs.Strings(), ",")
560*333d2b36SAndroid Build Coastguard Worker		args["rbeOutputs"] = outputSrcJar.String() + ".tmp," + outputResJar.String() + ".tmp"
561*333d2b36SAndroid Build Coastguard Worker		args["rspFiles"] = strings.Join(rspFiles.Strings(), ",")
562*333d2b36SAndroid Build Coastguard Worker	}
563*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
564*333d2b36SAndroid Build Coastguard Worker		Rule:            rule,
565*333d2b36SAndroid Build Coastguard Worker		Description:     "turbine apt",
566*333d2b36SAndroid Build Coastguard Worker		Output:          outputs[0],
567*333d2b36SAndroid Build Coastguard Worker		ImplicitOutputs: outputs[1:],
568*333d2b36SAndroid Build Coastguard Worker		Inputs:          srcFiles,
569*333d2b36SAndroid Build Coastguard Worker		Implicits:       implicits,
570*333d2b36SAndroid Build Coastguard Worker		Args:            args,
571*333d2b36SAndroid Build Coastguard Worker	})
572*333d2b36SAndroid Build Coastguard Worker}
573*333d2b36SAndroid Build Coastguard Worker
574*333d2b36SAndroid Build Coastguard Worker// transformJavaToClasses takes source files and converts them to a jar containing .class files.
575*333d2b36SAndroid Build Coastguard Worker// srcFiles is a list of paths to sources, srcJars is a list of paths to jar files that contain
576*333d2b36SAndroid Build Coastguard Worker// sources.  flags contains various command line flags to be passed to the compiler.
577*333d2b36SAndroid Build Coastguard Worker//
578*333d2b36SAndroid Build Coastguard Worker// This method may be used for different compilers, including javac and Error Prone.  The rule
579*333d2b36SAndroid Build Coastguard Worker// argument specifies which command line to use and desc sets the description of the rule that will
580*333d2b36SAndroid Build Coastguard Worker// be printed at build time.  The stem argument provides the file name of the output jar, and
581*333d2b36SAndroid Build Coastguard Worker// suffix will be appended to various intermediate files and directories to avoid collisions when
582*333d2b36SAndroid Build Coastguard Worker// this function is called twice in the same module directory.
583*333d2b36SAndroid Build Coastguard Workerfunc transformJavaToClasses(ctx android.ModuleContext, outputFile android.WritablePath,
584*333d2b36SAndroid Build Coastguard Worker	shardIdx int, srcFiles, srcJars android.Paths, annoSrcJar android.WritablePath,
585*333d2b36SAndroid Build Coastguard Worker	flags javaBuilderFlags, deps android.Paths,
586*333d2b36SAndroid Build Coastguard Worker	intermediatesDir, desc string) {
587*333d2b36SAndroid Build Coastguard Worker
588*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, srcJars...)
589*333d2b36SAndroid Build Coastguard Worker
590*333d2b36SAndroid Build Coastguard Worker	javacClasspath := flags.classpath
591*333d2b36SAndroid Build Coastguard Worker
592*333d2b36SAndroid Build Coastguard Worker	var bootClasspath string
593*333d2b36SAndroid Build Coastguard Worker	if flags.javaVersion.usesJavaModules() {
594*333d2b36SAndroid Build Coastguard Worker		var systemModuleDeps android.Paths
595*333d2b36SAndroid Build Coastguard Worker		bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device())
596*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, systemModuleDeps...)
597*333d2b36SAndroid Build Coastguard Worker		javacClasspath = append(flags.java9Classpath, javacClasspath...)
598*333d2b36SAndroid Build Coastguard Worker	} else {
599*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, flags.bootClasspath...)
600*333d2b36SAndroid Build Coastguard Worker		if len(flags.bootClasspath) == 0 && ctx.Device() {
601*333d2b36SAndroid Build Coastguard Worker			// explicitly specify -bootclasspath "" if the bootclasspath is empty to
602*333d2b36SAndroid Build Coastguard Worker			// ensure java does not fall back to the default bootclasspath.
603*333d2b36SAndroid Build Coastguard Worker			bootClasspath = `-bootclasspath ""`
604*333d2b36SAndroid Build Coastguard Worker		} else {
605*333d2b36SAndroid Build Coastguard Worker			bootClasspath = flags.bootClasspath.FormJavaClassPath("-bootclasspath")
606*333d2b36SAndroid Build Coastguard Worker		}
607*333d2b36SAndroid Build Coastguard Worker	}
608*333d2b36SAndroid Build Coastguard Worker
609*333d2b36SAndroid Build Coastguard Worker	classpathArg := javacClasspath.FormJavaClassPath("-classpath")
610*333d2b36SAndroid Build Coastguard Worker
611*333d2b36SAndroid Build Coastguard Worker	// Keep the command line under the MAX_ARG_STRLEN limit by putting the classpath argument into an rsp file
612*333d2b36SAndroid Build Coastguard Worker	// if it is too long.
613*333d2b36SAndroid Build Coastguard Worker	const classpathLimit = 64 * 1024
614*333d2b36SAndroid Build Coastguard Worker	if len(classpathArg) > classpathLimit {
615*333d2b36SAndroid Build Coastguard Worker		classpathRspFile := outputFile.ReplaceExtension(ctx, "classpath")
616*333d2b36SAndroid Build Coastguard Worker		android.WriteFileRule(ctx, classpathRspFile, classpathArg)
617*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, classpathRspFile)
618*333d2b36SAndroid Build Coastguard Worker		classpathArg = "@" + classpathRspFile.String()
619*333d2b36SAndroid Build Coastguard Worker	}
620*333d2b36SAndroid Build Coastguard Worker
621*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, javacClasspath...)
622*333d2b36SAndroid Build Coastguard Worker	deps = append(deps, flags.processorPath...)
623*333d2b36SAndroid Build Coastguard Worker
624*333d2b36SAndroid Build Coastguard Worker	processor := "-proc:none"
625*333d2b36SAndroid Build Coastguard Worker	if len(flags.processors) > 0 {
626*333d2b36SAndroid Build Coastguard Worker		processor = "-processor " + strings.Join(flags.processors, ",")
627*333d2b36SAndroid Build Coastguard Worker	}
628*333d2b36SAndroid Build Coastguard Worker
629*333d2b36SAndroid Build Coastguard Worker	srcJarDir := "srcjars"
630*333d2b36SAndroid Build Coastguard Worker	outDir := "classes"
631*333d2b36SAndroid Build Coastguard Worker	annoDir := "anno"
632*333d2b36SAndroid Build Coastguard Worker	if shardIdx >= 0 {
633*333d2b36SAndroid Build Coastguard Worker		shardDir := "shard" + strconv.Itoa(shardIdx)
634*333d2b36SAndroid Build Coastguard Worker		srcJarDir = filepath.Join(shardDir, srcJarDir)
635*333d2b36SAndroid Build Coastguard Worker		outDir = filepath.Join(shardDir, outDir)
636*333d2b36SAndroid Build Coastguard Worker		annoDir = filepath.Join(shardDir, annoDir)
637*333d2b36SAndroid Build Coastguard Worker	}
638*333d2b36SAndroid Build Coastguard Worker	rule := javac
639*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_JAVAC") {
640*333d2b36SAndroid Build Coastguard Worker		rule = javacRE
641*333d2b36SAndroid Build Coastguard Worker	}
642*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
643*333d2b36SAndroid Build Coastguard Worker		Rule:           rule,
644*333d2b36SAndroid Build Coastguard Worker		Description:    desc,
645*333d2b36SAndroid Build Coastguard Worker		Output:         outputFile,
646*333d2b36SAndroid Build Coastguard Worker		ImplicitOutput: annoSrcJar,
647*333d2b36SAndroid Build Coastguard Worker		Inputs:         srcFiles,
648*333d2b36SAndroid Build Coastguard Worker		Implicits:      deps,
649*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
650*333d2b36SAndroid Build Coastguard Worker			"javacFlags":    flags.javacFlags,
651*333d2b36SAndroid Build Coastguard Worker			"bootClasspath": bootClasspath,
652*333d2b36SAndroid Build Coastguard Worker			"classpath":     classpathArg,
653*333d2b36SAndroid Build Coastguard Worker			"processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
654*333d2b36SAndroid Build Coastguard Worker			"processor":     processor,
655*333d2b36SAndroid Build Coastguard Worker			"srcJars":       strings.Join(srcJars.Strings(), " "),
656*333d2b36SAndroid Build Coastguard Worker			"srcJarDir":     android.PathForModuleOut(ctx, intermediatesDir, srcJarDir).String(),
657*333d2b36SAndroid Build Coastguard Worker			"outDir":        android.PathForModuleOut(ctx, intermediatesDir, outDir).String(),
658*333d2b36SAndroid Build Coastguard Worker			"annoDir":       android.PathForModuleOut(ctx, intermediatesDir, annoDir).String(),
659*333d2b36SAndroid Build Coastguard Worker			"annoSrcJar":    annoSrcJar.String(),
660*333d2b36SAndroid Build Coastguard Worker			"javaVersion":   flags.javaVersion.String(),
661*333d2b36SAndroid Build Coastguard Worker		},
662*333d2b36SAndroid Build Coastguard Worker	})
663*333d2b36SAndroid Build Coastguard Worker}
664*333d2b36SAndroid Build Coastguard Worker
665*333d2b36SAndroid Build Coastguard Workerfunc TransformResourcesToJar(ctx android.ModuleContext, outputFile android.WritablePath,
666*333d2b36SAndroid Build Coastguard Worker	jarArgs []string, deps android.Paths) {
667*333d2b36SAndroid Build Coastguard Worker
668*333d2b36SAndroid Build Coastguard Worker	rule := jar
669*333d2b36SAndroid Build Coastguard Worker	if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_JAR") {
670*333d2b36SAndroid Build Coastguard Worker		rule = jarRE
671*333d2b36SAndroid Build Coastguard Worker	}
672*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
673*333d2b36SAndroid Build Coastguard Worker		Rule:        rule,
674*333d2b36SAndroid Build Coastguard Worker		Description: "jar",
675*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
676*333d2b36SAndroid Build Coastguard Worker		Implicits:   deps,
677*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
678*333d2b36SAndroid Build Coastguard Worker			"jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "),
679*333d2b36SAndroid Build Coastguard Worker		},
680*333d2b36SAndroid Build Coastguard Worker	})
681*333d2b36SAndroid Build Coastguard Worker}
682*333d2b36SAndroid Build Coastguard Worker
683*333d2b36SAndroid Build Coastguard Workerfunc TransformJarsToJar(ctx android.ModuleContext, outputFile android.WritablePath, desc string,
684*333d2b36SAndroid Build Coastguard Worker	jars android.Paths, manifest android.OptionalPath, stripDirEntries bool, filesToStrip []string,
685*333d2b36SAndroid Build Coastguard Worker	dirsToStrip []string) {
686*333d2b36SAndroid Build Coastguard Worker
687*333d2b36SAndroid Build Coastguard Worker	var deps android.Paths
688*333d2b36SAndroid Build Coastguard Worker
689*333d2b36SAndroid Build Coastguard Worker	var jarArgs []string
690*333d2b36SAndroid Build Coastguard Worker	if manifest.Valid() {
691*333d2b36SAndroid Build Coastguard Worker		jarArgs = append(jarArgs, "-m ", manifest.String())
692*333d2b36SAndroid Build Coastguard Worker		deps = append(deps, manifest.Path())
693*333d2b36SAndroid Build Coastguard Worker	}
694*333d2b36SAndroid Build Coastguard Worker
695*333d2b36SAndroid Build Coastguard Worker	for _, dir := range dirsToStrip {
696*333d2b36SAndroid Build Coastguard Worker		jarArgs = append(jarArgs, "-stripDir ", dir)
697*333d2b36SAndroid Build Coastguard Worker	}
698*333d2b36SAndroid Build Coastguard Worker
699*333d2b36SAndroid Build Coastguard Worker	for _, file := range filesToStrip {
700*333d2b36SAndroid Build Coastguard Worker		jarArgs = append(jarArgs, "-stripFile ", file)
701*333d2b36SAndroid Build Coastguard Worker	}
702*333d2b36SAndroid Build Coastguard Worker
703*333d2b36SAndroid Build Coastguard Worker	// Remove any module-info.class files that may have come from prebuilt jars, they cause problems
704*333d2b36SAndroid Build Coastguard Worker	// for downstream tools like desugar.
705*333d2b36SAndroid Build Coastguard Worker	jarArgs = append(jarArgs, "-stripFile module-info.class")
706*333d2b36SAndroid Build Coastguard Worker	jarArgs = append(jarArgs, "-stripFile META-INF/versions/*/module-info.class")
707*333d2b36SAndroid Build Coastguard Worker
708*333d2b36SAndroid Build Coastguard Worker	if stripDirEntries {
709*333d2b36SAndroid Build Coastguard Worker		jarArgs = append(jarArgs, "-D")
710*333d2b36SAndroid Build Coastguard Worker	}
711*333d2b36SAndroid Build Coastguard Worker
712*333d2b36SAndroid Build Coastguard Worker	rule := combineJar
713*333d2b36SAndroid Build Coastguard Worker	// Keep the command line under the MAX_ARG_STRLEN limit by putting the list of jars into an rsp file
714*333d2b36SAndroid Build Coastguard Worker	// if it is too long.
715*333d2b36SAndroid Build Coastguard Worker	const jarsLengthLimit = 64 * 1024
716*333d2b36SAndroid Build Coastguard Worker	jarsLength := 0
717*333d2b36SAndroid Build Coastguard Worker	for i, jar := range jars {
718*333d2b36SAndroid Build Coastguard Worker		if i != 0 {
719*333d2b36SAndroid Build Coastguard Worker			jarsLength += 1
720*333d2b36SAndroid Build Coastguard Worker		}
721*333d2b36SAndroid Build Coastguard Worker		jarsLength += len(jar.String())
722*333d2b36SAndroid Build Coastguard Worker	}
723*333d2b36SAndroid Build Coastguard Worker	if jarsLength > jarsLengthLimit {
724*333d2b36SAndroid Build Coastguard Worker		rule = combineJarRsp
725*333d2b36SAndroid Build Coastguard Worker	}
726*333d2b36SAndroid Build Coastguard Worker
727*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
728*333d2b36SAndroid Build Coastguard Worker		Rule:        rule,
729*333d2b36SAndroid Build Coastguard Worker		Description: desc,
730*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
731*333d2b36SAndroid Build Coastguard Worker		Inputs:      jars,
732*333d2b36SAndroid Build Coastguard Worker		Implicits:   deps,
733*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
734*333d2b36SAndroid Build Coastguard Worker			"jarArgs": strings.Join(jarArgs, " "),
735*333d2b36SAndroid Build Coastguard Worker		},
736*333d2b36SAndroid Build Coastguard Worker	})
737*333d2b36SAndroid Build Coastguard Worker}
738*333d2b36SAndroid Build Coastguard Worker
739*333d2b36SAndroid Build Coastguard Workerfunc convertImplementationJarToHeaderJar(ctx android.ModuleContext, implementationJarFile android.Path,
740*333d2b36SAndroid Build Coastguard Worker	headerJarFile android.WritablePath) {
741*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
742*333d2b36SAndroid Build Coastguard Worker		Rule:   convertImplementationJarToHeaderJarRule,
743*333d2b36SAndroid Build Coastguard Worker		Input:  implementationJarFile,
744*333d2b36SAndroid Build Coastguard Worker		Output: headerJarFile,
745*333d2b36SAndroid Build Coastguard Worker	})
746*333d2b36SAndroid Build Coastguard Worker}
747*333d2b36SAndroid Build Coastguard Worker
748*333d2b36SAndroid Build Coastguard Workerfunc TransformJarJar(ctx android.ModuleContext, outputFile android.WritablePath,
749*333d2b36SAndroid Build Coastguard Worker	classesJar android.Path, rulesFile android.Path) {
750*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
751*333d2b36SAndroid Build Coastguard Worker		Rule:        jarjar,
752*333d2b36SAndroid Build Coastguard Worker		Description: "jarjar",
753*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
754*333d2b36SAndroid Build Coastguard Worker		Input:       classesJar,
755*333d2b36SAndroid Build Coastguard Worker		Implicit:    rulesFile,
756*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
757*333d2b36SAndroid Build Coastguard Worker			"rulesFile": rulesFile.String(),
758*333d2b36SAndroid Build Coastguard Worker		},
759*333d2b36SAndroid Build Coastguard Worker	})
760*333d2b36SAndroid Build Coastguard Worker}
761*333d2b36SAndroid Build Coastguard Worker
762*333d2b36SAndroid Build Coastguard Workerfunc CheckJarPackages(ctx android.ModuleContext, outputFile android.WritablePath,
763*333d2b36SAndroid Build Coastguard Worker	classesJar android.Path, permittedPackages []string) {
764*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
765*333d2b36SAndroid Build Coastguard Worker		Rule:        packageCheck,
766*333d2b36SAndroid Build Coastguard Worker		Description: "packageCheck",
767*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
768*333d2b36SAndroid Build Coastguard Worker		Input:       classesJar,
769*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
770*333d2b36SAndroid Build Coastguard Worker			"packages": strings.Join(permittedPackages, " "),
771*333d2b36SAndroid Build Coastguard Worker		},
772*333d2b36SAndroid Build Coastguard Worker	})
773*333d2b36SAndroid Build Coastguard Worker}
774*333d2b36SAndroid Build Coastguard Worker
775*333d2b36SAndroid Build Coastguard Workerfunc TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePath,
776*333d2b36SAndroid Build Coastguard Worker	inputFile android.Path) {
777*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
778*333d2b36SAndroid Build Coastguard Worker		Rule:        jetifier,
779*333d2b36SAndroid Build Coastguard Worker		Description: "jetifier",
780*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
781*333d2b36SAndroid Build Coastguard Worker		Input:       inputFile,
782*333d2b36SAndroid Build Coastguard Worker	})
783*333d2b36SAndroid Build Coastguard Worker}
784*333d2b36SAndroid Build Coastguard Worker
785*333d2b36SAndroid Build Coastguard Workerfunc TransformRavenizer(ctx android.ModuleContext, outputFile android.WritablePath,
786*333d2b36SAndroid Build Coastguard Worker	inputFile android.Path, ravenizerArgs string) {
787*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
788*333d2b36SAndroid Build Coastguard Worker		Rule:        ravenizer,
789*333d2b36SAndroid Build Coastguard Worker		Description: "ravenizer",
790*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
791*333d2b36SAndroid Build Coastguard Worker		Input:       inputFile,
792*333d2b36SAndroid Build Coastguard Worker		Args: map[string]string{
793*333d2b36SAndroid Build Coastguard Worker			"ravenizerArgs": ravenizerArgs,
794*333d2b36SAndroid Build Coastguard Worker		},
795*333d2b36SAndroid Build Coastguard Worker	})
796*333d2b36SAndroid Build Coastguard Worker}
797*333d2b36SAndroid Build Coastguard Worker
798*333d2b36SAndroid Build Coastguard Workerfunc GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.WritablePath, mainClass string) {
799*333d2b36SAndroid Build Coastguard Worker	android.WriteFileRule(ctx, outputFile, "Main-Class: "+mainClass+"\n")
800*333d2b36SAndroid Build Coastguard Worker}
801*333d2b36SAndroid Build Coastguard Worker
802*333d2b36SAndroid Build Coastguard Workerfunc TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePath, inputFile android.Path, validations android.Paths) {
803*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
804*333d2b36SAndroid Build Coastguard Worker		Rule:        zipalign,
805*333d2b36SAndroid Build Coastguard Worker		Description: "align",
806*333d2b36SAndroid Build Coastguard Worker		Input:       inputFile,
807*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
808*333d2b36SAndroid Build Coastguard Worker		Validations: validations,
809*333d2b36SAndroid Build Coastguard Worker	})
810*333d2b36SAndroid Build Coastguard Worker}
811*333d2b36SAndroid Build Coastguard Worker
812*333d2b36SAndroid Build Coastguard Workerfunc writeCombinedProguardFlagsFile(ctx android.ModuleContext, outputFile android.WritablePath, files android.Paths) {
813*333d2b36SAndroid Build Coastguard Worker	ctx.Build(pctx, android.BuildParams{
814*333d2b36SAndroid Build Coastguard Worker		Rule:        writeCombinedProguardFlagsFileRule,
815*333d2b36SAndroid Build Coastguard Worker		Description: "write combined proguard flags file",
816*333d2b36SAndroid Build Coastguard Worker		Inputs:      files,
817*333d2b36SAndroid Build Coastguard Worker		Output:      outputFile,
818*333d2b36SAndroid Build Coastguard Worker	})
819*333d2b36SAndroid Build Coastguard Worker}
820*333d2b36SAndroid Build Coastguard Worker
821*333d2b36SAndroid Build Coastguard Workertype classpath android.Paths
822*333d2b36SAndroid Build Coastguard Worker
823*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) formJoinedClassPath(optName string, sep string) string {
824*333d2b36SAndroid Build Coastguard Worker	if optName != "" && !strings.HasSuffix(optName, "=") && !strings.HasSuffix(optName, " ") {
825*333d2b36SAndroid Build Coastguard Worker		optName += " "
826*333d2b36SAndroid Build Coastguard Worker	}
827*333d2b36SAndroid Build Coastguard Worker	if len(*x) > 0 {
828*333d2b36SAndroid Build Coastguard Worker		return optName + strings.Join(x.Strings(), sep)
829*333d2b36SAndroid Build Coastguard Worker	} else {
830*333d2b36SAndroid Build Coastguard Worker		return ""
831*333d2b36SAndroid Build Coastguard Worker	}
832*333d2b36SAndroid Build Coastguard Worker}
833*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) FormJavaClassPath(optName string) string {
834*333d2b36SAndroid Build Coastguard Worker	return x.formJoinedClassPath(optName, ":")
835*333d2b36SAndroid Build Coastguard Worker}
836*333d2b36SAndroid Build Coastguard Worker
837*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) FormTurbineClassPath(optName string) string {
838*333d2b36SAndroid Build Coastguard Worker	return x.formJoinedClassPath(optName, " ")
839*333d2b36SAndroid Build Coastguard Worker}
840*333d2b36SAndroid Build Coastguard Worker
841*333d2b36SAndroid Build Coastguard Worker// FormRepeatedClassPath returns a list of arguments with the given optName prefixed to each element of the classpath.
842*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) FormRepeatedClassPath(optName string) []string {
843*333d2b36SAndroid Build Coastguard Worker	if x == nil || *x == nil {
844*333d2b36SAndroid Build Coastguard Worker		return nil
845*333d2b36SAndroid Build Coastguard Worker	}
846*333d2b36SAndroid Build Coastguard Worker	flags := make([]string, len(*x))
847*333d2b36SAndroid Build Coastguard Worker	for i, v := range *x {
848*333d2b36SAndroid Build Coastguard Worker		flags[i] = optName + v.String()
849*333d2b36SAndroid Build Coastguard Worker	}
850*333d2b36SAndroid Build Coastguard Worker
851*333d2b36SAndroid Build Coastguard Worker	return flags
852*333d2b36SAndroid Build Coastguard Worker}
853*333d2b36SAndroid Build Coastguard Worker
854*333d2b36SAndroid Build Coastguard Worker// Convert a classpath to an android.Paths
855*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) Paths() android.Paths {
856*333d2b36SAndroid Build Coastguard Worker	return append(android.Paths(nil), (*x)...)
857*333d2b36SAndroid Build Coastguard Worker}
858*333d2b36SAndroid Build Coastguard Worker
859*333d2b36SAndroid Build Coastguard Workerfunc (x *classpath) Strings() []string {
860*333d2b36SAndroid Build Coastguard Worker	if x == nil {
861*333d2b36SAndroid Build Coastguard Worker		return nil
862*333d2b36SAndroid Build Coastguard Worker	}
863*333d2b36SAndroid Build Coastguard Worker	ret := make([]string, len(*x))
864*333d2b36SAndroid Build Coastguard Worker	for i, path := range *x {
865*333d2b36SAndroid Build Coastguard Worker		ret[i] = path.String()
866*333d2b36SAndroid Build Coastguard Worker	}
867*333d2b36SAndroid Build Coastguard Worker	return ret
868*333d2b36SAndroid Build Coastguard Worker}
869*333d2b36SAndroid Build Coastguard Worker
870*333d2b36SAndroid Build Coastguard Workertype systemModules struct {
871*333d2b36SAndroid Build Coastguard Worker	dir  android.Path
872*333d2b36SAndroid Build Coastguard Worker	deps android.Paths
873*333d2b36SAndroid Build Coastguard Worker}
874*333d2b36SAndroid Build Coastguard Worker
875*333d2b36SAndroid Build Coastguard Worker// Returns a --system argument in the form javac expects with -source 1.9 and the list of files to
876*333d2b36SAndroid Build Coastguard Worker// depend on.  If forceEmpty is true, returns --system=none if the list is empty to ensure javac
877*333d2b36SAndroid Build Coastguard Worker// does not fall back to the default system modules.
878*333d2b36SAndroid Build Coastguard Workerfunc (x *systemModules) FormJavaSystemModulesPath(forceEmpty bool) (string, android.Paths) {
879*333d2b36SAndroid Build Coastguard Worker	if x != nil {
880*333d2b36SAndroid Build Coastguard Worker		return "--system=" + x.dir.String(), x.deps
881*333d2b36SAndroid Build Coastguard Worker	} else if forceEmpty {
882*333d2b36SAndroid Build Coastguard Worker		return "--system=none", nil
883*333d2b36SAndroid Build Coastguard Worker	} else {
884*333d2b36SAndroid Build Coastguard Worker		return "", nil
885*333d2b36SAndroid Build Coastguard Worker	}
886*333d2b36SAndroid Build Coastguard Worker}
887*333d2b36SAndroid Build Coastguard Worker
888*333d2b36SAndroid Build Coastguard Worker// Returns a --system argument in the form turbine expects with -source 1.9 and the list of files to
889*333d2b36SAndroid Build Coastguard Worker// depend on.  If forceEmpty is true, returns --bootclasspath "" if the list is empty to ensure turbine
890*333d2b36SAndroid Build Coastguard Worker// does not fall back to the default bootclasspath.
891*333d2b36SAndroid Build Coastguard Workerfunc (x *systemModules) FormTurbineSystemModulesPath(forceEmpty bool) (string, android.Paths) {
892*333d2b36SAndroid Build Coastguard Worker	if x != nil {
893*333d2b36SAndroid Build Coastguard Worker		return "--system " + x.dir.String(), x.deps
894*333d2b36SAndroid Build Coastguard Worker	} else if forceEmpty {
895*333d2b36SAndroid Build Coastguard Worker		return `--bootclasspath ""`, nil
896*333d2b36SAndroid Build Coastguard Worker	} else {
897*333d2b36SAndroid Build Coastguard Worker		return "--system ${config.JavaHome}", nil
898*333d2b36SAndroid Build Coastguard Worker	}
899*333d2b36SAndroid Build Coastguard Worker}
900