blob: 36506ae0eb65b8a45b5eace93a1562edfba1e82d [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"
Dan Willemsen24f2f8d2015-07-15 14:34:02 -070028 _ "github.com/google/blueprint/bootstrap"
Colin Cross2fe66872015-03-30 17:20:39 -070029)
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`,
Dan Willemsenc94a7682015-11-17 15:27:28 -080055 CommandDeps: []string{"$jarCmd"},
Colin Cross2fe66872015-03-30 17:20:39 -070056 Description: "jar $out",
57 },
58 "jarCmd", "jarArgs")
59
60 dx = pctx.StaticRule("dx",
61 blueprint.RuleParams{
Colin Cross6d1e72d2015-04-10 17:44:24 -070062 Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
63 `$dxCmd --dex --output=$outDir $dxFlags $in || ( rm -rf "$outDir"; exit 41 ) && ` +
64 `find "$outDir" -name "classes*.dex" > $out`,
Dan Willemsenc94a7682015-11-17 15:27:28 -080065 CommandDeps: []string{"$dxCmd"},
Colin Cross2fe66872015-03-30 17:20:39 -070066 Description: "dex $out",
67 },
68 "outDir", "dxFlags")
Colin Crosse1d62a82015-04-03 16:53:05 -070069
Colin Cross65bf4f22015-04-03 16:54:17 -070070 jarjar = pctx.StaticRule("jarjar",
71 blueprint.RuleParams{
72 Command: "java -jar $jarjarCmd process $rulesFile $in $out",
Dan Willemsenc94a7682015-11-17 15:27:28 -080073 CommandDeps: []string{"$jarjarCmd", "$rulesFile"},
Colin Cross65bf4f22015-04-03 16:54:17 -070074 Description: "jarjar $out",
75 },
76 "rulesFile")
77
Colin Crosse1d62a82015-04-03 16:53:05 -070078 extractPrebuilt = pctx.StaticRule("extractPrebuilt",
79 blueprint.RuleParams{
80 Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
81 `find $outDir -name "*.class" > $classFile && ` +
82 `find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" > $resourceFile || ` +
83 `(rm -rf $outDir; exit 42)`,
84 Description: "extract java prebuilt $outDir",
85 },
86 "outDir", "classFile", "resourceFile")
Colin Cross2fe66872015-03-30 17:20:39 -070087)
88
89func init() {
Dan Willemsen24f2f8d2015-07-15 14:34:02 -070090 pctx.Import("github.com/google/blueprint/bootstrap")
Colin Cross2fe66872015-03-30 17:20:39 -070091 pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
92 pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
Dan Willemsen24f2f8d2015-07-15 14:34:02 -070093 pctx.StaticVariable("jarCmd", filepath.Join("${bootstrap.BinDir}", "soong_jar"))
Colin Cross2fe66872015-03-30 17:20:39 -070094 pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070095 return c.(common.Config).HostBinTool("dx")
Colin Cross2fe66872015-03-30 17:20:39 -070096 })
Colin Cross65bf4f22015-04-03 16:54:17 -070097 pctx.VariableFunc("jarjarCmd", func(c interface{}) (string, error) {
Colin Cross1332b002015-04-07 17:11:30 -070098 return c.(common.Config).HostJavaTool("jarjar.jar")
Colin Cross65bf4f22015-04-03 16:54:17 -070099 })
Colin Cross2fe66872015-03-30 17:20:39 -0700100}
101
102type javaBuilderFlags struct {
103 javacFlags string
104 dxFlags string
105 bootClasspath string
106 classpath string
Colin Crossc0b06f12015-04-08 13:03:43 -0700107 aidlFlags string
Colin Cross2fe66872015-03-30 17:20:39 -0700108}
109
110type jarSpec struct {
111 fileList, dir string
112}
113
114func (j jarSpec) soongJarArgs() string {
115 return "-C " + j.dir + " -l " + j.fileList
116}
117
Colin Crosse7a9f3f2015-04-13 14:02:52 -0700118func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string, srcFileLists []string,
Colin Cross2fe66872015-03-30 17:20:39 -0700119 flags javaBuilderFlags, deps []string) jarSpec {
120
121 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
Colin Cross8cf13342015-04-10 15:41:49 -0700122 classFileList := filepath.Join(common.ModuleOutDir(ctx), "classes.list")
Colin Cross2fe66872015-03-30 17:20:39 -0700123
Colin Crosse7a9f3f2015-04-13 14:02:52 -0700124 javacFlags := flags.javacFlags + common.JoinWithPrefix(srcFileLists, "@")
125
126 deps = append(deps, srcFileLists...)
127
Colin Cross2fe66872015-03-30 17:20:39 -0700128 ctx.Build(pctx, blueprint.BuildParams{
Colin Cross8cf13342015-04-10 15:41:49 -0700129 Rule: javac,
Colin Cross2fe66872015-03-30 17:20:39 -0700130 Outputs: []string{classFileList},
131 Inputs: srcFiles,
132 Implicits: deps,
133 Args: map[string]string{
Colin Crosse7a9f3f2015-04-13 14:02:52 -0700134 "javacFlags": javacFlags,
Colin Cross2fe66872015-03-30 17:20:39 -0700135 "bootClasspath": flags.bootClasspath,
136 "classpath": flags.classpath,
137 "outDir": classDir,
138 },
139 })
140
141 return jarSpec{classFileList, classDir}
142}
143
144func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
145 manifest string) string {
146
147 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
148
149 deps := []string{}
150 jarArgs := []string{}
151
152 for _, j := range classes {
153 deps = append(deps, j.fileList)
154 jarArgs = append(jarArgs, j.soongJarArgs())
155 }
156
157 if manifest != "" {
158 deps = append(deps, manifest)
159 jarArgs = append(jarArgs, "-m "+manifest)
160 }
161
Colin Cross2fe66872015-03-30 17:20:39 -0700162 ctx.Build(pctx, blueprint.BuildParams{
163 Rule: jar,
164 Outputs: []string{outputFile},
165 Implicits: deps,
166 Args: map[string]string{
167 "jarArgs": strings.Join(jarArgs, " "),
168 },
169 })
170
171 return outputFile
172}
173
174func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
Colin Cross6d1e72d2015-04-10 17:44:24 -0700175 flags javaBuilderFlags) jarSpec {
Colin Cross2fe66872015-03-30 17:20:39 -0700176
Colin Cross6d1e72d2015-04-10 17:44:24 -0700177 outDir := filepath.Join(common.ModuleOutDir(ctx), "dex")
178 outputFile := filepath.Join(common.ModuleOutDir(ctx), "dex.filelist")
Colin Cross2fe66872015-03-30 17:20:39 -0700179
180 ctx.Build(pctx, blueprint.BuildParams{
Dan Willemsenc94a7682015-11-17 15:27:28 -0800181 Rule: dx,
182 Outputs: []string{outputFile},
183 Inputs: []string{classesJar},
Colin Cross2fe66872015-03-30 17:20:39 -0700184 Args: map[string]string{
185 "dxFlags": flags.dxFlags,
Colin Cross6d1e72d2015-04-10 17:44:24 -0700186 "outDir": outDir,
Colin Cross2fe66872015-03-30 17:20:39 -0700187 },
188 })
189
Colin Cross6d1e72d2015-04-10 17:44:24 -0700190 return jarSpec{outputFile, outDir}
Colin Cross2fe66872015-03-30 17:20:39 -0700191}
192
193func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
Colin Cross6d1e72d2015-04-10 17:44:24 -0700194 dexJarSpec jarSpec) string {
Colin Cross2fe66872015-03-30 17:20:39 -0700195
196 outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
197 var deps []string
198 var jarArgs []string
199
200 for _, j := range resources {
201 deps = append(deps, j.fileList)
202 jarArgs = append(jarArgs, j.soongJarArgs())
203 }
204
Colin Cross6d1e72d2015-04-10 17:44:24 -0700205 deps = append(deps, dexJarSpec.fileList)
206 jarArgs = append(jarArgs, dexJarSpec.soongJarArgs())
Colin Cross2fe66872015-03-30 17:20:39 -0700207
208 ctx.Build(pctx, blueprint.BuildParams{
209 Rule: jar,
210 Outputs: []string{outputFile},
211 Implicits: deps,
212 Args: map[string]string{
213 "jarArgs": strings.Join(jarArgs, " "),
214 },
215 })
216
217 return outputFile
218}
Colin Crosse1d62a82015-04-03 16:53:05 -0700219
Colin Cross65bf4f22015-04-03 16:54:17 -0700220func TransformJarJar(ctx common.AndroidModuleContext, classesJar string, rulesFile string) string {
221 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-jarjar.jar")
222 ctx.Build(pctx, blueprint.BuildParams{
Dan Willemsenc94a7682015-11-17 15:27:28 -0800223 Rule: jarjar,
224 Outputs: []string{outputFile},
225 Inputs: []string{classesJar},
Colin Cross65bf4f22015-04-03 16:54:17 -0700226 Args: map[string]string{
227 "rulesFile": rulesFile,
228 },
229 })
230
231 return outputFile
232}
233
Colin Crosse1d62a82015-04-03 16:53:05 -0700234func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
235 prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {
236
Colin Cross11f56542015-04-24 15:21:41 -0700237 extractedDir := filepath.Join(common.ModuleOutDir(ctx), "extracted")
238 classDir := filepath.Join(extractedDir, "classes")
239 classFileList := filepath.Join(extractedDir, "classes.list")
240 resourceFileList := filepath.Join(extractedDir, "resources.list")
Colin Crosse1d62a82015-04-03 16:53:05 -0700241
242 ctx.Build(pctx, blueprint.BuildParams{
243 Rule: extractPrebuilt,
244 Outputs: []string{classFileList, resourceFileList},
245 Inputs: []string{prebuilt},
246 Args: map[string]string{
247 "outDir": classDir,
248 "classFile": classFileList,
249 "resourceFile": resourceFileList,
250 },
251 })
252
253 return jarSpec{classFileList, classDir}, jarSpec{resourceFileList, classDir}
254}