blob: d939e6a60a842d245e8d20bccd7c73245a4ae69e [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>)
Colin Cross8cf13342015-04-10 15:41:49 -070040 javac = pctx.StaticRule("javac",
Colin Cross2fe66872015-03-30 17:20:39 -070041 blueprint.RuleParams{
Colin Cross8cf13342015-04-10 15:41:49 -070042 Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
43 `$javacCmd -encoding UTF-8 $javacFlags $bootClasspath $classpath ` +
44 `-extdirs "" -d $outDir @$out.rsp || ( rm -rf "$outDir"; exit 41 ) && ` +
Colin Cross2fe66872015-03-30 17:20:39 -070045 `find $outDir -name "*.class" > $out`,
46 Rspfile: "$out.rsp",
47 RspfileContent: "$in",
48 Description: "javac $outDir",
49 },
50 "javacCmd", "javacFlags", "bootClasspath", "classpath", "outDir")
51
52 jar = pctx.StaticRule("jar",
53 blueprint.RuleParams{
54 Command: `$jarCmd -o $out $jarArgs`,
55 Description: "jar $out",
56 },
57 "jarCmd", "jarArgs")
58
59 dx = pctx.StaticRule("dx",
60 blueprint.RuleParams{
61 Command: "$dxCmd --dex --output=$out $dxFlags $in",
62 Description: "dex $out",
63 },
64 "outDir", "dxFlags")
Colin Crosse1d62a82015-04-03 16:53:05 -070065
Colin Cross65bf4f22015-04-03 16:54:17 -070066 jarjar = pctx.StaticRule("jarjar",
67 blueprint.RuleParams{
68 Command: "java -jar $jarjarCmd process $rulesFile $in $out",
69 Description: "jarjar $out",
70 },
71 "rulesFile")
72
Colin Crosse1d62a82015-04-03 16:53:05 -070073 extractPrebuilt = pctx.StaticRule("extractPrebuilt",
74 blueprint.RuleParams{
75 Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
76 `find $outDir -name "*.class" > $classFile && ` +
77 `find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" > $resourceFile || ` +
78 `(rm -rf $outDir; exit 42)`,
79 Description: "extract java prebuilt $outDir",
80 },
81 "outDir", "classFile", "resourceFile")
Colin Cross2fe66872015-03-30 17:20:39 -070082)
83
84func init() {
85 pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
86 pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
87 pctx.StaticVariable("jarCmd", filepath.Join(bootstrap.BinDir, "soong_jar"))
88 pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070089 return c.(common.Config).HostBinTool("dx")
Colin Cross2fe66872015-03-30 17:20:39 -070090 })
Colin Cross65bf4f22015-04-03 16:54:17 -070091 pctx.VariableFunc("jarjarCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070092 return c.(common.Config).HostJavaTool("jarjar.jar")
Colin Cross65bf4f22015-04-03 16:54:17 -070093 })
Colin Cross2fe66872015-03-30 17:20:39 -070094}
95
96type javaBuilderFlags struct {
97 javacFlags string
98 dxFlags string
99 bootClasspath string
100 classpath string
Colin Crossc0b06f12015-04-08 13:03:43 -0700101 aidlFlags string
Colin Cross2fe66872015-03-30 17:20:39 -0700102}
103
104type jarSpec struct {
105 fileList, dir string
106}
107
108func (j jarSpec) soongJarArgs() string {
109 return "-C " + j.dir + " -l " + j.fileList
110}
111
112func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
113 flags javaBuilderFlags, deps []string) jarSpec {
114
115 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
Colin Cross8cf13342015-04-10 15:41:49 -0700116 classFileList := filepath.Join(common.ModuleOutDir(ctx), "classes.list")
Colin Cross2fe66872015-03-30 17:20:39 -0700117
118 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross8cf13342015-04-10 15:41:49 -0700119 Rule: javac,
Colin Cross2fe66872015-03-30 17:20:39 -0700120 Outputs: []string{classFileList},
121 Inputs: srcFiles,
122 Implicits: deps,
123 Args: map[string]string{
124 "javacFlags": flags.javacFlags,
125 "bootClasspath": flags.bootClasspath,
126 "classpath": flags.classpath,
127 "outDir": classDir,
128 },
129 })
130
131 return jarSpec{classFileList, classDir}
132}
133
134func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
135 manifest string) string {
136
137 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
138
139 deps := []string{}
140 jarArgs := []string{}
141
142 for _, j := range classes {
143 deps = append(deps, j.fileList)
144 jarArgs = append(jarArgs, j.soongJarArgs())
145 }
146
147 if manifest != "" {
148 deps = append(deps, manifest)
149 jarArgs = append(jarArgs, "-m "+manifest)
150 }
151
152 deps = append(deps, "$jarCmd")
153
154 ctx.Build(pctx, blueprint.BuildParams{
155 Rule: jar,
156 Outputs: []string{outputFile},
157 Implicits: deps,
158 Args: map[string]string{
159 "jarArgs": strings.Join(jarArgs, " "),
160 },
161 })
162
163 return outputFile
164}
165
166func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
167 flags javaBuilderFlags) string {
168
169 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes.dex")
170
171 ctx.Build(pctx, blueprint.BuildParams{
172 Rule: dx,
173 Outputs: []string{outputFile},
174 Inputs: []string{classesJar},
175 Implicits: []string{"$dxCmd"},
176 Args: map[string]string{
177 "dxFlags": flags.dxFlags,
178 },
179 })
180
181 return outputFile
182}
183
184func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
185 dexFile string) string {
186
187 outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
188 var deps []string
189 var jarArgs []string
190
191 for _, j := range resources {
192 deps = append(deps, j.fileList)
193 jarArgs = append(jarArgs, j.soongJarArgs())
194 }
195
196 dexDir, _ := filepath.Split(dexFile)
197 jarArgs = append(jarArgs, "-C "+dexDir+" -f "+dexFile)
198
199 deps = append(deps, "$jarCmd", dexFile)
200
201 ctx.Build(pctx, blueprint.BuildParams{
202 Rule: jar,
203 Outputs: []string{outputFile},
204 Implicits: deps,
205 Args: map[string]string{
206 "jarArgs": strings.Join(jarArgs, " "),
207 },
208 })
209
210 return outputFile
211}
Colin Crosse1d62a82015-04-03 16:53:05 -0700212
Colin Cross65bf4f22015-04-03 16:54:17 -0700213func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFile string) string {
214 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-jarjar.jar")
215 ctx.Build(pctx, blueprint.BuildParams{
216 Rule: jarjar,
217 Outputs: []string{outputFile},
218 Inputs: []string{classesJar},
219 Implicits: []string{"$jarjarCmd"},
220 Args: map[string]string{
221 "rulesFile": rulesFile,
222 },
223 })
224
225 return outputFile
226}
227
Colin Crosse1d62a82015-04-03 16:53:05 -0700228func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
229 prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {
230
231 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
232 classFileList := filepath.Join(classDir, "classes.list")
233 resourceFileList := filepath.Join(classDir, "resources.list")
234
235 ctx.Build(pctx, blueprint.BuildParams{
236 Rule: extractPrebuilt,
237 Outputs: []string{classFileList, resourceFileList},
238 Inputs: []string{prebuilt},
239 Args: map[string]string{
240 "outDir": classDir,
241 "classFile": classFileList,
242 "resourceFile": resourceFileList,
243 },
244 })
245
246 return jarSpec{classFileList, classDir}, jarSpec{resourceFileList, classDir}
247}