blob: 02d65aa204f4bc48d9a52537857b9494b30b1a17 [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 (
22 "path/filepath"
23 "strings"
24
25 "android/soong/common"
26
27 "github.com/google/blueprint"
28 "github.com/google/blueprint/bootstrap"
29)
30
31var (
32 pctx = blueprint.NewPackageContext("android/soong/java")
33
34 // Compiling java is not conducive to proper dependency tracking. The path-matches-class-name
35 // requirement leads to unpredictable generated source file names, and a single .java file
36 // will get compiled into multiple .class files if it contains inner classes. To work around
37 // this, all java rules write into separate directories and then a post-processing step lists
38 // the files in the the directory into a list file that later rules depend on (and sometimes
39 // read from directly using @<listfile>)
40 cc = pctx.StaticRule("javac",
41 blueprint.RuleParams{
42 Command: `$javacCmd -encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
43 `-extdirs "" -d $outDir @$out.rsp || ( rm -rf $outDir; exit 41 ) && ` +
44 `find $outDir -name "*.class" > $out`,
45 Rspfile: "$out.rsp",
46 RspfileContent: "$in",
47 Description: "javac $outDir",
48 },
49 "javacCmd", "javacFlags", "bootClasspath", "classpath", "outDir")
50
51 jar = pctx.StaticRule("jar",
52 blueprint.RuleParams{
53 Command: `$jarCmd -o $out $jarArgs`,
54 Description: "jar $out",
55 },
56 "jarCmd", "jarArgs")
57
58 dx = pctx.StaticRule("dx",
59 blueprint.RuleParams{
60 Command: "$dxCmd --dex --output=$out $dxFlags $in",
61 Description: "dex $out",
62 },
63 "outDir", "dxFlags")
Colin Crosse1d62a82015-04-03 16:53:05 -070064
Colin Cross65bf4f22015-04-03 16:54:17 -070065 jarjar = pctx.StaticRule("jarjar",
66 blueprint.RuleParams{
67 Command: "java -jar $jarjarCmd process $rulesFile $in $out",
68 Description: "jarjar $out",
69 },
70 "rulesFile")
71
Colin Crosse1d62a82015-04-03 16:53:05 -070072 extractPrebuilt = pctx.StaticRule("extractPrebuilt",
73 blueprint.RuleParams{
74 Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
75 `find $outDir -name "*.class" > $classFile && ` +
76 `find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" > $resourceFile || ` +
77 `(rm -rf $outDir; exit 42)`,
78 Description: "extract java prebuilt $outDir",
79 },
80 "outDir", "classFile", "resourceFile")
Colin Cross2fe66872015-03-30 17:20:39 -070081)
82
83func init() {
84 pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
85 pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
86 pctx.StaticVariable("jarCmd", filepath.Join(bootstrap.BinDir, "soong_jar"))
87 pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070088 return c.(common.Config).HostBinTool("dx")
Colin Cross2fe66872015-03-30 17:20:39 -070089 })
Colin Cross65bf4f22015-04-03 16:54:17 -070090 pctx.VariableFunc("jarjarCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070091 return c.(common.Config).HostJavaTool("jarjar.jar")
Colin Cross65bf4f22015-04-03 16:54:17 -070092 })
Colin Cross2fe66872015-03-30 17:20:39 -070093}
94
95type javaBuilderFlags struct {
96 javacFlags string
97 dxFlags string
98 bootClasspath string
99 classpath string
Colin Crossc0b06f12015-04-08 13:03:43 -0700100 aidlFlags string
Colin Cross2fe66872015-03-30 17:20:39 -0700101}
102
103type jarSpec struct {
104 fileList, dir string
105}
106
107func (j jarSpec) soongJarArgs() string {
108 return "-C " + j.dir + " -l " + j.fileList
109}
110
111func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
112 flags javaBuilderFlags, deps []string) jarSpec {
113
114 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
115 classFileList := filepath.Join(classDir, "classes.list")
116
117 ctx.Build(pctx, blueprint.BuildParams{
118 Rule: cc,
119 Outputs: []string{classFileList},
120 Inputs: srcFiles,
121 Implicits: deps,
122 Args: map[string]string{
123 "javacFlags": flags.javacFlags,
124 "bootClasspath": flags.bootClasspath,
125 "classpath": flags.classpath,
126 "outDir": classDir,
127 },
128 })
129
130 return jarSpec{classFileList, classDir}
131}
132
133func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
134 manifest string) string {
135
136 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
137
138 deps := []string{}
139 jarArgs := []string{}
140
141 for _, j := range classes {
142 deps = append(deps, j.fileList)
143 jarArgs = append(jarArgs, j.soongJarArgs())
144 }
145
146 if manifest != "" {
147 deps = append(deps, manifest)
148 jarArgs = append(jarArgs, "-m "+manifest)
149 }
150
151 deps = append(deps, "$jarCmd")
152
153 ctx.Build(pctx, blueprint.BuildParams{
154 Rule: jar,
155 Outputs: []string{outputFile},
156 Implicits: deps,
157 Args: map[string]string{
158 "jarArgs": strings.Join(jarArgs, " "),
159 },
160 })
161
162 return outputFile
163}
164
165func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
166 flags javaBuilderFlags) string {
167
168 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes.dex")
169
170 ctx.Build(pctx, blueprint.BuildParams{
171 Rule: dx,
172 Outputs: []string{outputFile},
173 Inputs: []string{classesJar},
174 Implicits: []string{"$dxCmd"},
175 Args: map[string]string{
176 "dxFlags": flags.dxFlags,
177 },
178 })
179
180 return outputFile
181}
182
183func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
184 dexFile string) string {
185
186 outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
187 var deps []string
188 var jarArgs []string
189
190 for _, j := range resources {
191 deps = append(deps, j.fileList)
192 jarArgs = append(jarArgs, j.soongJarArgs())
193 }
194
195 dexDir, _ := filepath.Split(dexFile)
196 jarArgs = append(jarArgs, "-C "+dexDir+" -f "+dexFile)
197
198 deps = append(deps, "$jarCmd", dexFile)
199
200 ctx.Build(pctx, blueprint.BuildParams{
201 Rule: jar,
202 Outputs: []string{outputFile},
203 Implicits: deps,
204 Args: map[string]string{
205 "jarArgs": strings.Join(jarArgs, " "),
206 },
207 })
208
209 return outputFile
210}
Colin Crosse1d62a82015-04-03 16:53:05 -0700211
Colin Cross65bf4f22015-04-03 16:54:17 -0700212func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFile string) string {
213 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-jarjar.jar")
214 ctx.Build(pctx, blueprint.BuildParams{
215 Rule: jarjar,
216 Outputs: []string{outputFile},
217 Inputs: []string{classesJar},
218 Implicits: []string{"$jarjarCmd"},
219 Args: map[string]string{
220 "rulesFile": rulesFile,
221 },
222 })
223
224 return outputFile
225}
226
Colin Crosse1d62a82015-04-03 16:53:05 -0700227func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
228 prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {
229
230 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
231 classFileList := filepath.Join(classDir, "classes.list")
232 resourceFileList := filepath.Join(classDir, "resources.list")
233
234 ctx.Build(pctx, blueprint.BuildParams{
235 Rule: extractPrebuilt,
236 Outputs: []string{classFileList, resourceFileList},
237 Inputs: []string{prebuilt},
238 Args: map[string]string{
239 "outDir": classDir,
240 "classFile": classFileList,
241 "resourceFile": resourceFileList,
242 },
243 })
244
245 return jarSpec{classFileList, classDir}, jarSpec{resourceFileList, classDir}
246}