blob: 2c72cabae183c5b66cd0a2c10fec3c98d5f59793 [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
65 extractPrebuilt = pctx.StaticRule("extractPrebuilt",
66 blueprint.RuleParams{
67 Command: `rm -rf $outDir && unzip -qo $in -d $outDir && ` +
68 `find $outDir -name "*.class" > $classFile && ` +
69 `find $outDir -type f -a \! -name "*.class" -a \! -name "MANIFEST.MF" > $resourceFile || ` +
70 `(rm -rf $outDir; exit 42)`,
71 Description: "extract java prebuilt $outDir",
72 },
73 "outDir", "classFile", "resourceFile")
Colin Cross2fe66872015-03-30 17:20:39 -070074)
75
76func init() {
77 pctx.StaticVariable("commonJdkFlags", "-source 1.7 -target 1.7 -Xmaxerrs 9999999")
78 pctx.StaticVariable("javacCmd", "javac -J-Xmx1024M $commonJdkFlags")
79 pctx.StaticVariable("jarCmd", filepath.Join(bootstrap.BinDir, "soong_jar"))
80 pctx.VariableFunc("dxCmd", func(c interface{}) (string, error) {
81 return c.(Config).HostBinTool("dx")
82 })
83}
84
85type javaBuilderFlags struct {
86 javacFlags string
87 dxFlags string
88 bootClasspath string
89 classpath string
90}
91
92type jarSpec struct {
93 fileList, dir string
94}
95
96func (j jarSpec) soongJarArgs() string {
97 return "-C " + j.dir + " -l " + j.fileList
98}
99
100func TransformJavaToClasses(ctx common.AndroidModuleContext, srcFiles []string,
101 flags javaBuilderFlags, deps []string) jarSpec {
102
103 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
104 classFileList := filepath.Join(classDir, "classes.list")
105
106 ctx.Build(pctx, blueprint.BuildParams{
107 Rule: cc,
108 Outputs: []string{classFileList},
109 Inputs: srcFiles,
110 Implicits: deps,
111 Args: map[string]string{
112 "javacFlags": flags.javacFlags,
113 "bootClasspath": flags.bootClasspath,
114 "classpath": flags.classpath,
115 "outDir": classDir,
116 },
117 })
118
119 return jarSpec{classFileList, classDir}
120}
121
122func TransformClassesToJar(ctx common.AndroidModuleContext, classes []jarSpec,
123 manifest string) string {
124
125 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes-full-debug.jar")
126
127 deps := []string{}
128 jarArgs := []string{}
129
130 for _, j := range classes {
131 deps = append(deps, j.fileList)
132 jarArgs = append(jarArgs, j.soongJarArgs())
133 }
134
135 if manifest != "" {
136 deps = append(deps, manifest)
137 jarArgs = append(jarArgs, "-m "+manifest)
138 }
139
140 deps = append(deps, "$jarCmd")
141
142 ctx.Build(pctx, blueprint.BuildParams{
143 Rule: jar,
144 Outputs: []string{outputFile},
145 Implicits: deps,
146 Args: map[string]string{
147 "jarArgs": strings.Join(jarArgs, " "),
148 },
149 })
150
151 return outputFile
152}
153
154func TransformClassesJarToDex(ctx common.AndroidModuleContext, classesJar string,
155 flags javaBuilderFlags) string {
156
157 outputFile := filepath.Join(common.ModuleOutDir(ctx), "classes.dex")
158
159 ctx.Build(pctx, blueprint.BuildParams{
160 Rule: dx,
161 Outputs: []string{outputFile},
162 Inputs: []string{classesJar},
163 Implicits: []string{"$dxCmd"},
164 Args: map[string]string{
165 "dxFlags": flags.dxFlags,
166 },
167 })
168
169 return outputFile
170}
171
172func TransformDexToJavaLib(ctx common.AndroidModuleContext, resources []jarSpec,
173 dexFile string) string {
174
175 outputFile := filepath.Join(common.ModuleOutDir(ctx), "javalib.jar")
176 var deps []string
177 var jarArgs []string
178
179 for _, j := range resources {
180 deps = append(deps, j.fileList)
181 jarArgs = append(jarArgs, j.soongJarArgs())
182 }
183
184 dexDir, _ := filepath.Split(dexFile)
185 jarArgs = append(jarArgs, "-C "+dexDir+" -f "+dexFile)
186
187 deps = append(deps, "$jarCmd", dexFile)
188
189 ctx.Build(pctx, blueprint.BuildParams{
190 Rule: jar,
191 Outputs: []string{outputFile},
192 Implicits: deps,
193 Args: map[string]string{
194 "jarArgs": strings.Join(jarArgs, " "),
195 },
196 })
197
198 return outputFile
199}
Colin Crosse1d62a82015-04-03 16:53:05 -0700200
201func TransformPrebuiltJarToClasses(ctx common.AndroidModuleContext,
202 prebuilt string) (classJarSpec, resourceJarSpec jarSpec) {
203
204 classDir := filepath.Join(common.ModuleOutDir(ctx), "classes")
205 classFileList := filepath.Join(classDir, "classes.list")
206 resourceFileList := filepath.Join(classDir, "resources.list")
207
208 ctx.Build(pctx, blueprint.BuildParams{
209 Rule: extractPrebuilt,
210 Outputs: []string{classFileList, resourceFileList},
211 Inputs: []string{prebuilt},
212 Args: map[string]string{
213 "outDir": classDir,
214 "classFile": classFileList,
215 "resourceFile": resourceFileList,
216 },
217 })
218
219 return jarSpec{classFileList, classDir}, jarSpec{resourceFileList, classDir}
220}