blob: ad2a580cf98b888d9e7fcfd170c7f6663f259568 [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 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
17import (
18 "android/soong/android"
19 "android/soong/java/config"
20 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080021 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070022 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080023 "strings"
24
25 "github.com/google/blueprint"
26)
27
28var (
29 javadoc = pctx.AndroidStaticRule("javadoc",
30 blueprint.RuleParams{
31 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070032 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhangaf322cc2018-06-19 15:15:38 -070033 `${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070034 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080035 `-d $outDir -quiet && ` +
36 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Nan Zhange2ba5d42018-07-11 15:16:55 -070037 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds`,
Nan Zhang581fd212018-01-10 16:06:12 -080038 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070039 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080040 "${config.JavadocCmd}",
41 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080042 },
43 Rspfile: "$out.rsp",
44 RspfileContent: "$in",
45 Restat: true,
46 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070047 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070048 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070049
50 apiCheck = pctx.AndroidStaticRule("apiCheck",
51 blueprint.RuleParams{
52 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
53 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090054 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070055 CommandDeps: []string{
56 "${config.ApiCheckCmd}",
57 },
58 },
59 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
60
61 updateApi = pctx.AndroidStaticRule("updateApi",
62 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070063 Command: `( ( cp -f $srcApiFile $destApiFile && cp -f $srcRemovedApiFile $destRemovedApiFile ) ` +
Nan Zhang61819ce2018-05-04 18:49:16 -070064 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
65 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070066 "srcApiFile", "destApiFile", "srcRemovedApiFile", "destRemovedApiFile")
Nan Zhang79614d12018-04-19 18:03:39 -070067
68 metalava = pctx.AndroidStaticRule("metalava",
69 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070070 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
71 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070072 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang357466b2018-04-17 17:38:36 -070073 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070074 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet ` +
75 `$opts && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070076 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
77 CommandDeps: []string{
78 "${config.ZipSyncCmd}",
79 "${config.JavaCmd}",
80 "${config.MetalavaJar}",
Nan Zhang79614d12018-04-19 18:03:39 -070081 "${config.SoongZipCmd}",
82 },
83 Rspfile: "$out.rsp",
84 RspfileContent: "$in",
85 Restat: true,
86 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070087 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
88 "classpathArgs", "sourcepathArgs", "opts")
Nan Zhang2760dfc2018-08-24 17:32:54 +000089
90 metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
91 blueprint.RuleParams{
92 Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
93 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
94 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070095 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet ` +
Nan Zhang2760dfc2018-08-24 17:32:54 +000096 `$opts && touch $out ) || ` +
97 `( echo -e "$msg" ; exit 38 )`,
98 CommandDeps: []string{
99 "${config.ZipSyncCmd}",
100 "${config.JavaCmd}",
101 "${config.MetalavaJar}",
102 },
103 Rspfile: "$out.rsp",
104 RspfileContent: "$in",
105 },
Nan Zhang1598a9e2018-09-04 17:14:32 -0700106 "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
107
108 dokka = pctx.AndroidStaticRule("dokka",
109 blueprint.RuleParams{
110 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
111 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
112 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
113 `${config.JavaCmd} -jar ${config.DokkaJar} $srcJarDir ` +
114 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
115 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
116 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
117 CommandDeps: []string{
118 "${config.ZipSyncCmd}",
119 "${config.DokkaJar}",
120 "${config.MetalavaJar}",
121 "${config.SoongZipCmd}",
122 },
123 Restat: true,
124 },
125 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -0800126)
127
128func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700130 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800131
Nan Zhang581fd212018-01-10 16:06:12 -0800132 android.RegisterModuleType("droiddoc", DroiddocFactory)
133 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -0700134 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800135 android.RegisterModuleType("javadoc", JavadocFactory)
136 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700137
138 android.RegisterModuleType("droidstubs", DroidstubsFactory)
139 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800140}
141
Colin Crossa1ce2a02018-06-20 15:19:39 -0700142var (
143 srcsLibTag = dependencyTag{name: "sources from javalib"}
144)
145
Nan Zhang581fd212018-01-10 16:06:12 -0800146type JavadocProperties struct {
147 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
148 // or .aidl files.
149 Srcs []string `android:"arch_variant"`
150
151 // list of directories rooted at the Android.bp file that will
152 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800153 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800154
155 // list of source files that should not be used to build the Java module.
156 // This is most useful in the arch/multilib variants to remove non-common files
157 // filegroup or genrule can be included within this property.
158 Exclude_srcs []string `android:"arch_variant"`
159
Nan Zhangb2b33de2018-02-23 11:18:47 -0800160 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800161 Libs []string `android:"arch_variant"`
162
Nan Zhange66c7272018-03-06 12:59:27 -0800163 // don't build against the framework libraries (legacy-test, core-junit,
164 // ext, and framework for device targets)
165 No_framework_libs *bool
166
Nan Zhangb2b33de2018-02-23 11:18:47 -0800167 // the java library (in classpath) for documentation that provides java srcs and srcjars.
168 Srcs_lib *string
169
170 // the base dirs under srcs_lib will be scanned for java srcs.
171 Srcs_lib_whitelist_dirs []string
172
173 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
174 Srcs_lib_whitelist_pkgs []string
175
Nan Zhang581fd212018-01-10 16:06:12 -0800176 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800177 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800178
179 // if not blank, set to the version of the sdk to compile against
180 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900181
182 Aidl struct {
183 // Top level directories to pass to aidl tool
184 Include_dirs []string
185
186 // Directories rooted at the Android.bp file to pass to aidl tool
187 Local_include_dirs []string
188 }
Nan Zhang357466b2018-04-17 17:38:36 -0700189
190 // If not blank, set the java version passed to javadoc as -source
191 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700192
193 // local files that are used within user customized droiddoc options.
194 Arg_files []string
195
196 // user customized droiddoc args.
197 // Available variables for substitution:
198 //
199 // $(location <label>): the path to the arg_files with name <label>
200 Args *string
201
202 // names of the output files used in args that will be generated
203 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800204}
205
Nan Zhang61819ce2018-05-04 18:49:16 -0700206type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900207 // path to the API txt file that the new API extracted from source code is checked
208 // against. The path can be local to the module or from other module (via :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700209 Api_file *string
210
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900211 // path to the API txt file that the new @removed API extractd from source code is
212 // checked against. The path can be local to the module or from other module (via
213 // :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700214 Removed_api_file *string
215
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900216 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700217 Args *string
218}
219
Nan Zhang581fd212018-01-10 16:06:12 -0800220type DroiddocProperties struct {
221 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800222 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800223
Nan Zhanga40da042018-08-01 12:48:00 -0700224 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800225 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800226
227 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800228 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800229
230 // proofread file contains all of the text content of the javadocs concatenated into one file,
231 // suitable for spell-checking and other goodness.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800232 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800233
234 // a todo file lists the program elements that are missing documentation.
235 // At some point, this might be improved to show more warnings.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800236 Todo_file *string
237
238 // directory under current module source that provide additional resources (images).
239 Resourcesdir *string
240
241 // resources output directory under out/soong/.intermediates.
242 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800243
Nan Zhange2ba5d42018-07-11 15:16:55 -0700244 // if set to true, collect the values used by the Dev tools and
245 // write them in files packaged with the SDK. Defaults to false.
246 Write_sdk_values *bool
247
248 // index.html under current module will be copied to docs out dir, if not null.
249 Static_doc_index_redirect *string
250
251 // source.properties under current module will be copied to docs out dir, if not null.
252 Static_doc_properties *string
253
Nan Zhang581fd212018-01-10 16:06:12 -0800254 // a list of files under current module source dir which contains known tags in Java sources.
255 // filegroup or genrule can be included within this property.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800256 Knowntags []string
Nan Zhang28c68b92018-03-13 16:17:01 -0700257
258 // the tag name used to distinguish if the API files belong to public/system/test.
259 Api_tag_name *string
260
261 // the generated public API filename by Doclava.
262 Api_filename *string
263
David Brazdilfbe4cc32018-05-31 13:56:46 +0100264 // the generated public Dex API filename by Doclava.
265 Dex_api_filename *string
266
Nan Zhang28c68b92018-03-13 16:17:01 -0700267 // the generated private API filename by Doclava.
268 Private_api_filename *string
269
270 // the generated private Dex API filename by Doclava.
271 Private_dex_api_filename *string
272
273 // the generated removed API filename by Doclava.
274 Removed_api_filename *string
275
David Brazdilaac0c3c2018-04-24 16:23:29 +0100276 // the generated removed Dex API filename by Doclava.
277 Removed_dex_api_filename *string
278
Mathew Inwood76c3de12018-06-22 15:28:11 +0100279 // mapping of dex signatures to source file and line number. This is a temporary property and
280 // will be deleted; you probably shouldn't be using it.
281 Dex_mapping_filename *string
282
Nan Zhang28c68b92018-03-13 16:17:01 -0700283 // the generated exact API filename by Doclava.
284 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700285
Nan Zhang66dc2362018-08-14 20:41:04 -0700286 // the generated proguard filename by Doclava.
287 Proguard_filename *string
288
Nan Zhang853f4202018-04-12 16:55:56 -0700289 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
290 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700291
292 Check_api struct {
293 Last_released ApiToCheck
294
295 Current ApiToCheck
296 }
Nan Zhang79614d12018-04-19 18:03:39 -0700297
Nan Zhang1598a9e2018-09-04 17:14:32 -0700298 // if set to true, generate docs through Dokka instead of Doclava.
299 Dokka_enabled *bool
300}
301
302type DroidstubsProperties struct {
303 // the tag name used to distinguish if the API files belong to public/system/test.
304 Api_tag_name *string
305
306 // the generated public API filename by Doclava.
307 Api_filename *string
308
309 // the generated public Dex API filename by Doclava.
310 Dex_api_filename *string
311
312 // the generated private API filename by Doclava.
313 Private_api_filename *string
314
315 // the generated private Dex API filename by Doclava.
316 Private_dex_api_filename *string
317
318 // the generated removed API filename by Doclava.
319 Removed_api_filename *string
320
321 // the generated removed Dex API filename by Doclava.
322 Removed_dex_api_filename *string
323
Nan Zhang9c69a122018-08-22 10:22:08 -0700324 // mapping of dex signatures to source file and line number. This is a temporary property and
325 // will be deleted; you probably shouldn't be using it.
326 Dex_mapping_filename *string
327
Nan Zhang1598a9e2018-09-04 17:14:32 -0700328 // the generated exact API filename by Doclava.
329 Exact_api_filename *string
330
331 Check_api struct {
332 Last_released ApiToCheck
333
334 Current ApiToCheck
335 }
Nan Zhang79614d12018-04-19 18:03:39 -0700336
337 // user can specify the version of previous released API file in order to do compatibility check.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700338 Previous_api *string
Nan Zhang79614d12018-04-19 18:03:39 -0700339
340 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700341 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700342
Pete Gillinb13a0152018-07-19 17:56:49 +0100343 // a list of top-level directories containing files to merge annotations from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700344 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700345
Nan Zhang1598a9e2018-09-04 17:14:32 -0700346 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
347 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700348
349 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
350 Api_levels_annotations_enabled *bool
351
352 // the dirs which Metalava extracts API levels annotations from.
353 Api_levels_annotations_dirs []string
354
355 // if set to true, collect the values used by the Dev tools and
356 // write them in files packaged with the SDK. Defaults to false.
357 Write_sdk_values *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800358}
359
Nan Zhanga40da042018-08-01 12:48:00 -0700360//
361// Common flags passed down to build rule
362//
363type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700364 bootClasspathArgs string
365 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700366 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700367 dokkaClasspathArgs string
368 aidlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700369
Nan Zhanga40da042018-08-01 12:48:00 -0700370 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700371 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700372 postDoclavaCmds string
373
Nan Zhang9c69a122018-08-22 10:22:08 -0700374 metalavaStubsFlags string
375 metalavaAnnotationsFlags string
376 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700377
Nan Zhang86d2d552018-08-09 15:33:27 -0700378 metalavaDokkaFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700379}
380
381func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
382 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
383 android.InitDefaultableModule(module)
384}
385
Nan Zhang1598a9e2018-09-04 17:14:32 -0700386func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
387 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
388 return true
389 } else if String(apiToCheck.Api_file) != "" {
390 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
391 } else if String(apiToCheck.Removed_api_file) != "" {
392 panic("for " + apiVersionTag + " api_file has to be non-empty!")
393 }
394
395 return false
396}
397
398type ApiFilePath interface {
399 ApiFilePath() android.Path
400}
401
402func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
403 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
404 ctx.Build(pctx, android.BuildParams{
405 Rule: updateApi,
406 Description: "Update API",
407 Output: output,
408 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
409 destApiFile, destRemovedApiFile),
410 Args: map[string]string{
411 "destApiFile": destApiFile.String(),
412 "srcApiFile": srcApiFile.String(),
413 "destRemovedApiFile": destRemovedApiFile.String(),
414 "srcRemovedApiFile": srcRemovedApiFile.String(),
415 },
416 })
417}
418
Nan Zhanga40da042018-08-01 12:48:00 -0700419//
420// Javadoc
421//
Nan Zhang581fd212018-01-10 16:06:12 -0800422type Javadoc struct {
423 android.ModuleBase
424 android.DefaultableModuleBase
425
426 properties JavadocProperties
427
428 srcJars android.Paths
429 srcFiles android.Paths
430 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700431 argFiles android.Paths
432
433 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800434
Nan Zhangccff0f72018-03-08 17:26:16 -0800435 docZip android.WritablePath
436 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800437}
438
Nan Zhangb2b33de2018-02-23 11:18:47 -0800439func (j *Javadoc) Srcs() android.Paths {
440 return android.Paths{j.stubsSrcJar}
441}
442
Nan Zhang581fd212018-01-10 16:06:12 -0800443func JavadocFactory() android.Module {
444 module := &Javadoc{}
445
446 module.AddProperties(&module.properties)
447
448 InitDroiddocModule(module, android.HostAndDeviceSupported)
449 return module
450}
451
452func JavadocHostFactory() android.Module {
453 module := &Javadoc{}
454
455 module.AddProperties(&module.properties)
456
457 InitDroiddocModule(module, android.HostSupported)
458 return module
459}
460
Nan Zhanga40da042018-08-01 12:48:00 -0700461var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800462
Colin Cross83bb3162018-06-25 15:48:06 -0700463func (j *Javadoc) sdkVersion() string {
464 return String(j.properties.Sdk_version)
465}
466
467func (j *Javadoc) minSdkVersion() string {
468 return j.sdkVersion()
469}
470
Nan Zhang581fd212018-01-10 16:06:12 -0800471func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
472 if ctx.Device() {
Colin Cross83bb3162018-06-25 15:48:06 -0700473 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800474 if sdkDep.useDefaultLibs {
Colin Cross42d48b72018-08-29 14:10:52 -0700475 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700476 if ctx.Config().TargetOpenJDK9() {
Colin Cross42d48b72018-08-29 14:10:52 -0700477 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
Nan Zhang357466b2018-04-17 17:38:36 -0700478 }
Nan Zhang9cbe6772018-03-21 17:56:39 -0700479 if !Bool(j.properties.No_framework_libs) {
Colin Cross42d48b72018-08-29 14:10:52 -0700480 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
Nan Zhange66c7272018-03-06 12:59:27 -0800481 }
Nan Zhang581fd212018-01-10 16:06:12 -0800482 } else if sdkDep.useModule {
Nan Zhang357466b2018-04-17 17:38:36 -0700483 if ctx.Config().TargetOpenJDK9() {
Colin Cross42d48b72018-08-29 14:10:52 -0700484 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Nan Zhang357466b2018-04-17 17:38:36 -0700485 }
Colin Cross42d48b72018-08-29 14:10:52 -0700486 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang581fd212018-01-10 16:06:12 -0800487 }
488 }
489
Colin Cross42d48b72018-08-29 14:10:52 -0700490 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700491 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700492 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700493 }
Nan Zhang581fd212018-01-10 16:06:12 -0800494
495 android.ExtractSourcesDeps(ctx, j.properties.Srcs)
496
497 // exclude_srcs may contain filegroup or genrule.
498 android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700499
500 // arg_files may contains filegroup or genrule.
501 android.ExtractSourcesDeps(ctx, j.properties.Arg_files)
Nan Zhang581fd212018-01-10 16:06:12 -0800502}
503
Nan Zhangb2b33de2018-02-23 11:18:47 -0800504func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
505 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
506 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900507 // convert foo.bar.baz to foo/bar/baz
508 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
509 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800510 if _, found := whitelistPathPrefixes[prefix]; !found {
511 whitelistPathPrefixes[prefix] = true
512 }
513 }
514 }
515}
516
Nan Zhanga40da042018-08-01 12:48:00 -0700517func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
518 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900519
520 // aidl flags.
521 aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
522 if len(aidlFlags) > 0 {
523 // optimization.
524 ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
525 flags.aidlFlags = "$aidlFlags"
526 }
527
528 return flags
529}
530
531func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
532 aidlIncludeDirs android.Paths) []string {
533
534 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
535 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
536
537 var flags []string
538 if aidlPreprocess.Valid() {
539 flags = append(flags, "-p"+aidlPreprocess.String())
540 } else {
541 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
542 }
543
544 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
545 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
546 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
547 flags = append(flags, "-I"+src.String())
548 }
549
550 return flags
551}
552
553func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700554 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900555
556 outSrcFiles := make(android.Paths, 0, len(srcFiles))
557
558 for _, srcFile := range srcFiles {
559 switch srcFile.Ext() {
560 case ".aidl":
561 javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
562 outSrcFiles = append(outSrcFiles, javaFile)
563 default:
564 outSrcFiles = append(outSrcFiles, srcFile)
565 }
566 }
567
568 return outSrcFiles
569}
570
Nan Zhang581fd212018-01-10 16:06:12 -0800571func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
572 var deps deps
573
Colin Cross83bb3162018-06-25 15:48:06 -0700574 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800575 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700576 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800577 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700578 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800579 }
580
581 ctx.VisitDirectDeps(func(module android.Module) {
582 otherName := ctx.OtherModuleName(module)
583 tag := ctx.OtherModuleDependencyTag(module)
584
Colin Cross2d24c1b2018-05-23 10:59:18 -0700585 switch tag {
586 case bootClasspathTag:
587 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800588 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700589 } else {
590 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
591 }
592 case libTag:
593 switch dep := module.(type) {
594 case Dependency:
Nan Zhang581fd212018-01-10 16:06:12 -0800595 deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700596 case SdkLibraryDependency:
Colin Cross83bb3162018-06-25 15:48:06 -0700597 sdkVersion := j.sdkVersion()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900598 linkType := javaSdk
599 if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
600 linkType = javaSystem
601 } else if sdkVersion == "" {
602 linkType = javaPlatform
603 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900604 deps.classpath = append(deps.classpath, dep.ImplementationJars(linkType)...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700605 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800606 checkProducesJars(ctx, dep)
607 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800608 default:
609 ctx.ModuleErrorf("depends on non-java module %q", otherName)
610 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700611 case srcsLibTag:
612 switch dep := module.(type) {
613 case Dependency:
614 srcs := dep.(SrcDependency).CompiledSrcs()
615 whitelistPathPrefixes := make(map[string]bool)
616 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
617 for _, src := range srcs {
618 if _, ok := src.(android.WritablePath); ok { // generated sources
619 deps.srcs = append(deps.srcs, src)
620 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700621 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700622 if strings.HasPrefix(src.Rel(), k) {
623 deps.srcs = append(deps.srcs, src)
624 break
625 }
626 }
627 }
628 }
629 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
630 default:
631 ctx.ModuleErrorf("depends on non-java module %q", otherName)
632 }
Nan Zhang357466b2018-04-17 17:38:36 -0700633 case systemModulesTag:
634 if deps.systemModules != nil {
635 panic("Found two system module dependencies")
636 }
637 sm := module.(*SystemModules)
638 if sm.outputFile == nil {
639 panic("Missing directory for system module dependency")
640 }
641 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800642 }
643 })
644 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
645 // may contain filegroup or genrule.
646 srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700647 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900648 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800649
650 // srcs may depend on some genrule output.
651 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800652 j.srcJars = append(j.srcJars, deps.srcJars...)
653
Nan Zhang581fd212018-01-10 16:06:12 -0800654 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800655 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800656
657 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800658 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800659
Nan Zhang9c69a122018-08-22 10:22:08 -0700660 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800661 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
662 }
663 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800664
Nan Zhang1598a9e2018-09-04 17:14:32 -0700665 j.argFiles = ctx.ExpandSources(j.properties.Arg_files, nil)
666 argFilesMap := map[string]android.Path{}
667
668 for _, f := range j.argFiles {
669 if _, exists := argFilesMap[f.Rel()]; !exists {
670 argFilesMap[f.Rel()] = f
671 } else {
672 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
673 f, argFilesMap[f.Rel()], f.Rel())
674 }
675 }
676
677 var err error
678 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
679 if strings.HasPrefix(name, "location ") {
680 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
681 if f, ok := argFilesMap[label]; ok {
682 return f.String(), nil
683 } else {
684 return "", fmt.Errorf("unknown location label %q", label)
685 }
686 } else if name == "genDir" {
687 return android.PathForModuleGen(ctx).String(), nil
688 }
689 return "", fmt.Errorf("unknown variable '$(%s)'", name)
690 })
691
692 if err != nil {
693 ctx.PropertyErrorf("args", "%s", err.Error())
694 }
695
Nan Zhang581fd212018-01-10 16:06:12 -0800696 return deps
697}
698
699func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
700 j.addDeps(ctx)
701}
702
703func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
704 deps := j.collectDeps(ctx)
705
706 var implicits android.Paths
707 implicits = append(implicits, deps.bootClasspath...)
708 implicits = append(implicits, deps.classpath...)
709
Nan Zhang1598a9e2018-09-04 17:14:32 -0700710 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700711
Colin Cross83bb3162018-06-25 15:48:06 -0700712 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700713 if len(deps.bootClasspath) > 0 {
714 var systemModules classpath
715 if deps.systemModules != nil {
716 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800717 }
Colin Cross997262f2018-06-19 22:49:39 -0700718 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
719 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800720 }
721 if len(deps.classpath.Strings()) > 0 {
722 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
723 }
724
725 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700726 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800727
Nan Zhangaf322cc2018-06-19 15:15:38 -0700728 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800729
Nan Zhang1598a9e2018-09-04 17:14:32 -0700730 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
731
Nan Zhang581fd212018-01-10 16:06:12 -0800732 ctx.Build(pctx, android.BuildParams{
733 Rule: javadoc,
734 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800735 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800736 ImplicitOutput: j.docZip,
737 Inputs: j.srcFiles,
738 Implicits: implicits,
739 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700740 "outDir": android.PathForModuleOut(ctx, "out").String(),
741 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
742 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800743 "srcJars": strings.Join(j.srcJars.Strings(), " "),
744 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700745 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800746 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700747 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800748 "docZip": j.docZip.String(),
749 },
750 })
751}
752
Nan Zhanga40da042018-08-01 12:48:00 -0700753//
754// Droiddoc
755//
756type Droiddoc struct {
757 Javadoc
758
759 properties DroiddocProperties
760 apiFile android.WritablePath
761 dexApiFile android.WritablePath
762 privateApiFile android.WritablePath
763 privateDexApiFile android.WritablePath
764 removedApiFile android.WritablePath
765 removedDexApiFile android.WritablePath
766 exactApiFile android.WritablePath
767 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700768 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700769
770 checkCurrentApiTimestamp android.WritablePath
771 updateCurrentApiTimestamp android.WritablePath
772 checkLastReleasedApiTimestamp android.WritablePath
773
Nan Zhanga40da042018-08-01 12:48:00 -0700774 apiFilePath android.Path
775}
776
Nan Zhanga40da042018-08-01 12:48:00 -0700777func DroiddocFactory() android.Module {
778 module := &Droiddoc{}
779
780 module.AddProperties(&module.properties,
781 &module.Javadoc.properties)
782
783 InitDroiddocModule(module, android.HostAndDeviceSupported)
784 return module
785}
786
787func DroiddocHostFactory() android.Module {
788 module := &Droiddoc{}
789
790 module.AddProperties(&module.properties,
791 &module.Javadoc.properties)
792
793 InitDroiddocModule(module, android.HostSupported)
794 return module
795}
796
797func (d *Droiddoc) ApiFilePath() android.Path {
798 return d.apiFilePath
799}
800
Nan Zhang581fd212018-01-10 16:06:12 -0800801func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
802 d.Javadoc.addDeps(ctx)
803
Nan Zhang79614d12018-04-19 18:03:39 -0700804 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800805 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
806 }
807
Nan Zhang581fd212018-01-10 16:06:12 -0800808 // knowntags may contain filegroup or genrule.
809 android.ExtractSourcesDeps(ctx, d.properties.Knowntags)
Nan Zhang61819ce2018-05-04 18:49:16 -0700810
Nan Zhange2ba5d42018-07-11 15:16:55 -0700811 if String(d.properties.Static_doc_index_redirect) != "" {
812 android.ExtractSourceDeps(ctx, d.properties.Static_doc_index_redirect)
813 }
814
815 if String(d.properties.Static_doc_properties) != "" {
816 android.ExtractSourceDeps(ctx, d.properties.Static_doc_properties)
817 }
818
Nan Zhang1598a9e2018-09-04 17:14:32 -0700819 if apiCheckEnabled(d.properties.Check_api.Current, "current") {
Nan Zhang61819ce2018-05-04 18:49:16 -0700820 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
821 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
822 }
823
Nan Zhang1598a9e2018-09-04 17:14:32 -0700824 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") {
Nan Zhang61819ce2018-05-04 18:49:16 -0700825 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
826 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
827 }
Nan Zhang581fd212018-01-10 16:06:12 -0800828}
829
Nan Zhang66dc2362018-08-14 20:41:04 -0700830func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
831 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700832 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800833
Nan Zhanga40da042018-08-01 12:48:00 -0700834 *implicits = append(*implicits, deps.bootClasspath...)
835 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800836
Nan Zhangc94f9d82018-06-26 10:02:26 -0700837 if len(deps.bootClasspath.Strings()) > 0 {
838 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700839 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700840 }
Nan Zhanga40da042018-08-01 12:48:00 -0700841 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700842 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700843 dokkaClasspath := classpath{}
844 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
845 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
846 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700847
Nan Zhang9c69a122018-08-22 10:22:08 -0700848 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
849 // based stubs generation.
850 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
851 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
852 // the correct package name base path.
853 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
854 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
855 } else {
856 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
857 }
Nan Zhang581fd212018-01-10 16:06:12 -0800858
Nan Zhanga40da042018-08-01 12:48:00 -0700859 return flags, nil
860}
Nan Zhang581fd212018-01-10 16:06:12 -0800861
Nan Zhanga40da042018-08-01 12:48:00 -0700862func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700863 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800864
Nan Zhanga40da042018-08-01 12:48:00 -0700865 *implicits = append(*implicits, jsilver)
866 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700867
Nan Zhang46130972018-06-04 11:28:01 -0700868 var date string
869 if runtime.GOOS == "darwin" {
870 date = `date -r`
871 } else {
872 date = `date -d`
873 }
874
Nan Zhang443fa522018-08-20 20:58:28 -0700875 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
876 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
877 // 1.9 language features.
878 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700879 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800880 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700881 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700882
Nan Zhanga40da042018-08-01 12:48:00 -0700883 if String(d.properties.Custom_template) == "" {
884 // TODO: This is almost always droiddoc-templates-sdk
885 ctx.PropertyErrorf("custom_template", "must specify a template")
886 }
887
888 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700889 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700890 *implicits = append(*implicits, t.deps...)
891 args = args + " -templatedir " + t.dir.String()
892 } else {
893 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
894 }
895 })
896
897 if len(d.properties.Html_dirs) > 0 {
898 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
899 *implicits = append(*implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
900 args = args + " -htmldir " + htmlDir.String()
901 }
902
903 if len(d.properties.Html_dirs) > 1 {
904 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
905 *implicits = append(*implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
906 args = args + " -htmldir2 " + htmlDir2.String()
907 }
908
909 if len(d.properties.Html_dirs) > 2 {
910 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
911 }
912
913 knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
914 *implicits = append(*implicits, knownTags...)
915
916 for _, kt := range knownTags {
917 args = args + " -knowntags " + kt.String()
918 }
919
920 for _, hdf := range d.properties.Hdf {
921 args = args + " -hdf " + hdf
922 }
923
924 if String(d.properties.Proofread_file) != "" {
925 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
926 args = args + " -proofread " + proofreadFile.String()
927 }
928
929 if String(d.properties.Todo_file) != "" {
930 // tricky part:
931 // we should not compute full path for todo_file through PathForModuleOut().
932 // the non-standard doclet will get the full path relative to "-o".
933 args = args + " -todo " + String(d.properties.Todo_file)
934 }
935
936 if String(d.properties.Resourcesdir) != "" {
937 // TODO: should we add files under resourcesDir to the implicits? It seems that
938 // resourcesDir is one sub dir of htmlDir
939 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
940 args = args + " -resourcesdir " + resourcesDir.String()
941 }
942
943 if String(d.properties.Resourcesoutdir) != "" {
944 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
945 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
946 }
947 return args
948}
949
Nan Zhang1598a9e2018-09-04 17:14:32 -0700950func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
951 implicitOutputs *android.WritablePaths) string {
952 var doclavaFlags string
953 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
954 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
955 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700956 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
957 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700958 *implicitOutputs = append(*implicitOutputs, d.apiFile)
959 d.apiFilePath = d.apiFile
960 }
961
Nan Zhang1598a9e2018-09-04 17:14:32 -0700962 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
963 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
964 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700965 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
966 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700967 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
968 }
969
970 if String(d.properties.Private_api_filename) != "" {
971 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
972 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700973 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
974 }
975
976 if String(d.properties.Dex_api_filename) != "" {
977 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
978 doclavaFlags += " -dexApi " + d.dexApiFile.String()
979 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
980 }
981
982 if String(d.properties.Private_dex_api_filename) != "" {
983 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
984 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700985 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
986 }
987
988 if String(d.properties.Removed_dex_api_filename) != "" {
989 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
990 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700991 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
992 }
993
994 if String(d.properties.Exact_api_filename) != "" {
995 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
996 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700997 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
998 }
999
1000 if String(d.properties.Dex_mapping_filename) != "" {
1001 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1002 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001003 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1004 }
1005
Nan Zhang66dc2362018-08-14 20:41:04 -07001006 if String(d.properties.Proguard_filename) != "" {
1007 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1008 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001009 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1010 }
1011
Nan Zhanga40da042018-08-01 12:48:00 -07001012 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001013 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001014 }
1015
1016 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001017 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001018 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001019
1020 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001021}
1022
1023func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1024 var cmds string
1025 if String(d.properties.Static_doc_index_redirect) != "" {
1026 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1027 "static_doc_index_redirect")
1028 *implicits = append(*implicits, static_doc_index_redirect)
1029 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001030 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001031 }
1032
1033 if String(d.properties.Static_doc_properties) != "" {
1034 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1035 "static_doc_properties")
1036 *implicits = append(*implicits, static_doc_properties)
1037 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001038 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001039 }
1040 return cmds
1041}
1042
Nan Zhang1598a9e2018-09-04 17:14:32 -07001043func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1044 implicitOutputs android.WritablePaths,
1045 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1046 ctx.Build(pctx, android.BuildParams{
1047 Rule: javadoc,
1048 Description: "Doclava",
1049 Output: d.Javadoc.stubsSrcJar,
1050 Inputs: d.Javadoc.srcFiles,
1051 Implicits: implicits,
1052 ImplicitOutputs: implicitOutputs,
1053 Args: map[string]string{
1054 "outDir": android.PathForModuleOut(ctx, "out").String(),
1055 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1056 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1057 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1058 "opts": opts,
1059 "bootclasspathArgs": bootclasspathArgs,
1060 "classpathArgs": classpathArgs,
1061 "sourcepathArgs": sourcepathArgs,
1062 "docZip": d.Javadoc.docZip.String(),
1063 "postDoclavaCmds": postDoclavaCmds,
1064 },
1065 })
1066}
1067
1068func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1069 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1070 ctx.Build(pctx, android.BuildParams{
1071 Rule: apiCheck,
1072 Description: "Doclava Check API",
1073 Output: output,
1074 Inputs: nil,
1075 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1076 checkApiClasspath...),
1077 Args: map[string]string{
1078 "msg": msg,
1079 "classpath": checkApiClasspath.FormJavaClassPath(""),
1080 "opts": opts,
1081 "apiFile": apiFile.String(),
1082 "apiFileToCheck": d.apiFile.String(),
1083 "removedApiFile": removedApiFile.String(),
1084 "removedApiFileToCheck": d.removedApiFile.String(),
1085 },
1086 })
1087}
1088
1089func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1090 classpathArgs, opts string) {
1091 ctx.Build(pctx, android.BuildParams{
1092 Rule: dokka,
1093 Description: "Dokka",
1094 Output: d.Javadoc.stubsSrcJar,
1095 Inputs: d.Javadoc.srcFiles,
1096 Implicits: implicits,
1097 Args: map[string]string{
1098 "outDir": android.PathForModuleOut(ctx, "out").String(),
1099 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1100 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1101 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1102 "classpathArgs": classpathArgs,
1103 "opts": opts,
1104 "docZip": d.Javadoc.docZip.String(),
1105 },
1106 })
1107}
1108
1109func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1110 deps := d.Javadoc.collectDeps(ctx)
1111
1112 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1113 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1114 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1115 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1116
1117 var implicits android.Paths
1118 implicits = append(implicits, d.Javadoc.srcJars...)
1119 implicits = append(implicits, d.Javadoc.argFiles...)
1120
1121 var implicitOutputs android.WritablePaths
1122 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1123 for _, o := range d.Javadoc.properties.Out {
1124 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1125 }
1126
1127 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1128 if err != nil {
1129 return
1130 }
1131
1132 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1133 if Bool(d.properties.Dokka_enabled) {
1134 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1135 } else {
1136 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1137 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1138 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1139 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1140 flags.postDoclavaCmds)
1141 }
1142
1143 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1144 !ctx.Config().IsPdkBuild() {
1145 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1146 "check_api.current.api_file")
1147 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1148 "check_api.current_removed_api_file")
1149
1150 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1151 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1152 fmt.Sprintf(`\n******************************\n`+
1153 `You have tried to change the API from what has been previously approved.\n\n`+
1154 `To make these errors go away, you have two choices:\n`+
1155 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1156 ` errors above.\n\n`+
1157 ` 2. You can update current.txt by executing the following command:\n`+
1158 ` make %s-update-current-api\n\n`+
1159 ` To submit the revised current.txt to the main Android repository,\n`+
1160 ` you will need approval.\n`+
1161 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1162 d.checkCurrentApiTimestamp)
1163
1164 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1165 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1166 d.updateCurrentApiTimestamp)
1167 }
1168
1169 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1170 !ctx.Config().IsPdkBuild() {
1171 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1172 "check_api.last_released.api_file")
1173 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1174 "check_api.last_released.removed_api_file")
1175
1176 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1177 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1178 `\n******************************\n`+
1179 `You have tried to change the API from what has been previously released in\n`+
1180 `an SDK. Please fix the errors listed above.\n`+
1181 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1182 d.checkLastReleasedApiTimestamp)
1183 }
1184}
1185
1186//
1187// Droidstubs
1188//
1189type Droidstubs struct {
1190 Javadoc
1191
1192 properties DroidstubsProperties
1193 apiFile android.WritablePath
1194 dexApiFile android.WritablePath
1195 privateApiFile android.WritablePath
1196 privateDexApiFile android.WritablePath
1197 removedApiFile android.WritablePath
1198 removedDexApiFile android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001199 apiMappingFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001200 exactApiFile android.WritablePath
1201
1202 checkCurrentApiTimestamp android.WritablePath
1203 updateCurrentApiTimestamp android.WritablePath
1204 checkLastReleasedApiTimestamp android.WritablePath
1205
1206 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001207 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001208
1209 apiFilePath android.Path
1210}
1211
1212func DroidstubsFactory() android.Module {
1213 module := &Droidstubs{}
1214
1215 module.AddProperties(&module.properties,
1216 &module.Javadoc.properties)
1217
1218 InitDroiddocModule(module, android.HostAndDeviceSupported)
1219 return module
1220}
1221
1222func DroidstubsHostFactory() android.Module {
1223 module := &Droidstubs{}
1224
1225 module.AddProperties(&module.properties,
1226 &module.Javadoc.properties)
1227
1228 InitDroiddocModule(module, android.HostSupported)
1229 return module
1230}
1231
1232func (d *Droidstubs) ApiFilePath() android.Path {
1233 return d.apiFilePath
1234}
1235
1236func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1237 d.Javadoc.addDeps(ctx)
1238
1239 if apiCheckEnabled(d.properties.Check_api.Current, "current") {
1240 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
1241 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
1242 }
1243
1244 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") {
1245 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
1246 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
1247 }
1248
1249 if String(d.properties.Previous_api) != "" {
1250 android.ExtractSourceDeps(ctx, d.properties.Previous_api)
1251 }
1252
1253 if len(d.properties.Merge_annotations_dirs) != 0 {
1254 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1255 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1256 }
1257 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001258
1259 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1260 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1261 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1262 }
1263 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264}
1265
1266func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1267 deps deps) (droiddocBuilderFlags, error) {
1268 var flags droiddocBuilderFlags
1269
1270 *implicits = append(*implicits, deps.bootClasspath...)
1271 *implicits = append(*implicits, deps.classpath...)
1272
1273 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1274 // since it doesn't support system modules yet.
1275 if len(deps.bootClasspath.Strings()) > 0 {
1276 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1277 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1278 }
1279 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1280
1281 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
1282
1283 return flags, nil
1284}
1285
1286func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1287 implicitOutputs *android.WritablePaths) string {
1288 var metalavaFlags string
1289 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1290 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1291 String(d.properties.Api_filename) != "" {
1292 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1293 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1294 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1295 d.apiFilePath = d.apiFile
1296 }
1297
1298 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1299 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1300 String(d.properties.Removed_api_filename) != "" {
1301 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1302 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1303 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1304 }
1305
1306 if String(d.properties.Private_api_filename) != "" {
1307 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1308 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1309 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1310 }
1311
1312 if String(d.properties.Dex_api_filename) != "" {
1313 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1314 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1315 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1316 }
1317
1318 if String(d.properties.Private_dex_api_filename) != "" {
1319 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1320 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1321 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1322 }
1323
1324 if String(d.properties.Removed_dex_api_filename) != "" {
1325 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1326 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1327 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1328 }
1329
1330 if String(d.properties.Exact_api_filename) != "" {
1331 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1332 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1333 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1334 }
1335
Nan Zhang9c69a122018-08-22 10:22:08 -07001336 if String(d.properties.Dex_mapping_filename) != "" {
1337 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1338 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1339 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1340 }
1341
1342 if Bool(d.properties.Write_sdk_values) {
1343 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1344 }
1345
Nan Zhang1598a9e2018-09-04 17:14:32 -07001346 if Bool(d.properties.Create_doc_stubs) {
1347 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1348 } else {
1349 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1350 }
1351
1352 return metalavaFlags
1353}
1354
1355func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
1356 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
Nan Zhanga40da042018-08-01 12:48:00 -07001357 var flags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001358 if Bool(d.properties.Annotations_enabled) {
1359 if String(d.properties.Previous_api) == "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001360 ctx.PropertyErrorf("metalava_previous_api",
1361 "has to be non-empty if annotations was enabled!")
1362 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001363 previousApi := ctx.ExpandSource(String(d.properties.Previous_api),
Nan Zhangde860a42018-08-08 16:32:21 -07001364 "metalava_previous_api")
1365 *implicits = append(*implicits, previousApi)
Nan Zhangde860a42018-08-08 16:32:21 -07001366
Nan Zhangd05a4362018-08-15 13:28:54 -07001367 flags += " --include-annotations --migrate-nullness " + previousApi.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001368
1369 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1370 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1371
Nan Zhangf4936b02018-08-01 15:00:28 -07001372 flags += " --extract-annotations " + d.annotationsZip.String()
1373
Nan Zhang1598a9e2018-09-04 17:14:32 -07001374 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001375 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001376 "has to be non-empty if annotations was enabled!")
1377 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001378 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1379 if t, ok := m.(*ExportedDroiddocDir); ok {
1380 *implicits = append(*implicits, t.deps...)
1381 flags += " --merge-annotations " + t.dir.String()
1382 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001383 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001384 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1385 }
1386 })
Nan Zhanga40da042018-08-01 12:48:00 -07001387 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1388 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction "
1389 }
1390
1391 return flags
1392}
1393
Nan Zhang9c69a122018-08-22 10:22:08 -07001394func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1395 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1396 var flags string
1397 if Bool(d.properties.Api_levels_annotations_enabled) {
1398 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1399 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1400
1401 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1402 ctx.PropertyErrorf("api_levels_annotations_dirs",
1403 "has to be non-empty if api levels annotations was enabled!")
1404 }
1405
1406 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1407 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1408 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1409
1410 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1411 if t, ok := m.(*ExportedDroiddocDir); ok {
1412 var androidJars android.Paths
1413 for _, dep := range t.deps {
1414 if strings.HasSuffix(dep.String(), "android.jar") {
1415 androidJars = append(androidJars, dep)
1416 }
1417 }
1418 *implicits = append(*implicits, androidJars...)
1419 flags += " --android-jar-pattern " + t.dir.String() + "/%/android.jar "
1420 } else {
1421 ctx.PropertyErrorf("api_levels_annotations_dirs",
1422 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1423 }
1424 })
1425
1426 }
1427
1428 return flags
1429}
1430
Nan Zhang1598a9e2018-09-04 17:14:32 -07001431func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1432 implicitOutputs android.WritablePaths, javaVersion,
1433 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001434
Nan Zhang86d2d552018-08-09 15:33:27 -07001435 ctx.Build(pctx, android.BuildParams{
1436 Rule: metalava,
1437 Description: "Metalava",
1438 Output: d.Javadoc.stubsSrcJar,
1439 Inputs: d.Javadoc.srcFiles,
1440 Implicits: implicits,
1441 ImplicitOutputs: implicitOutputs,
1442 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001443 "outDir": android.PathForModuleOut(ctx, "out").String(),
1444 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1445 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1446 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001447 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001448 "bootclasspathArgs": bootclasspathArgs,
1449 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001450 "sourcepathArgs": sourcepathArgs,
1451 "opts": opts,
Nan Zhang86d2d552018-08-09 15:33:27 -07001452 },
1453 })
1454}
1455
Nan Zhang1598a9e2018-09-04 17:14:32 -07001456func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
1457 apiFile, removedApiFile android.Path, implicits android.Paths,
1458 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001459 output android.WritablePath) {
1460 ctx.Build(pctx, android.BuildParams{
1461 Rule: metalavaApiCheck,
1462 Description: "Metalava Check API",
1463 Output: output,
1464 Inputs: d.Javadoc.srcFiles,
1465 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1466 implicits...),
1467 Args: map[string]string{
1468 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1469 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1470 "javaVersion": javaVersion,
1471 "bootclasspathArgs": bootclasspathArgs,
1472 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001473 "sourcepathArgs": sourcepathArgs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001474 "opts": opts,
1475 "msg": msg,
1476 },
1477 })
1478}
1479
Nan Zhang1598a9e2018-09-04 17:14:32 -07001480func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001481 deps := d.Javadoc.collectDeps(ctx)
1482
1483 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001484
Nan Zhanga40da042018-08-01 12:48:00 -07001485 var implicits android.Paths
1486 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001487 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001488
1489 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001490 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001491 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1492 }
1493
1494 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001495 metalavaCheckApiImplicits := implicits
Nan Zhanga40da042018-08-01 12:48:00 -07001496 if err != nil {
1497 return
1498 }
1499
Nan Zhang1598a9e2018-09-04 17:14:32 -07001500 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1501 flags.metalavaAnnotationsFlags = d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001502 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001503 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1504 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1505 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1506 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1507 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001508 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001509 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1510 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Nan Zhang9c69a122018-08-22 10:22:08 -07001511 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+
1512 flags.metalavaApiLevelsAnnotationsFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001513
Nan Zhang1598a9e2018-09-04 17:14:32 -07001514 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1515 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001516 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1517 "check_api.current.api_file")
1518 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1519 "check_api.current_removed_api_file")
1520
Nan Zhang2760dfc2018-08-24 17:32:54 +00001521 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001522 opts := d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1523 " --check-compatibility:removed:current " + removedApiFile.String() + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001524
Nan Zhang1598a9e2018-09-04 17:14:32 -07001525 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
1526 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
1527 fmt.Sprintf(`\n******************************\n`+
1528 `You have tried to change the API from what has been previously approved.\n\n`+
1529 `To make these errors go away, you have two choices:\n`+
1530 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1531 ` errors above.\n\n`+
1532 ` 2. You can update current.txt by executing the following command:\n`+
1533 ` make %s-update-current-api\n\n`+
1534 ` To submit the revised current.txt to the main Android repository,\n`+
1535 ` you will need approval.\n`+
1536 `******************************\n`, ctx.ModuleName()),
1537 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001538
1539 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001540 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1541 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001542 }
Nan Zhanga40da042018-08-01 12:48:00 -07001543
Nan Zhang1598a9e2018-09-04 17:14:32 -07001544 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1545 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001546 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1547 "check_api.last_released.api_file")
1548 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1549 "check_api.last_released.removed_api_file")
1550
Nan Zhang2760dfc2018-08-24 17:32:54 +00001551 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001552 opts := d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1553 " --check-compatibility:removed:released " + removedApiFile.String() + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001554
Nan Zhang1598a9e2018-09-04 17:14:32 -07001555 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
1556 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
1557 `\n******************************\n`+
1558 `You have tried to change the API from what has been previously released in\n`+
1559 `an SDK. Please fix the errors listed above.\n`+
1560 `******************************\n`,
1561 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001562 }
Nan Zhang581fd212018-01-10 16:06:12 -08001563}
Dan Willemsencc090972018-02-26 14:33:31 -08001564
Nan Zhanga40da042018-08-01 12:48:00 -07001565//
Nan Zhangf4936b02018-08-01 15:00:28 -07001566// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001567//
Dan Willemsencc090972018-02-26 14:33:31 -08001568var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001569var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001570var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001571
Nan Zhangf4936b02018-08-01 15:00:28 -07001572type ExportedDroiddocDirProperties struct {
1573 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001574 Path *string
1575}
1576
Nan Zhangf4936b02018-08-01 15:00:28 -07001577type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001578 android.ModuleBase
1579
Nan Zhangf4936b02018-08-01 15:00:28 -07001580 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001581
1582 deps android.Paths
1583 dir android.Path
1584}
1585
Nan Zhangf4936b02018-08-01 15:00:28 -07001586func ExportedDroiddocDirFactory() android.Module {
1587 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001588 module.AddProperties(&module.properties)
1589 android.InitAndroidModule(module)
1590 return module
1591}
1592
Nan Zhangf4936b02018-08-01 15:00:28 -07001593func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001594
Nan Zhangf4936b02018-08-01 15:00:28 -07001595func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Dan Willemsencc090972018-02-26 14:33:31 -08001596 path := android.PathForModuleSrc(ctx, String(d.properties.Path))
1597 d.dir = path
1598 d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
1599}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001600
1601//
1602// Defaults
1603//
1604type DocDefaults struct {
1605 android.ModuleBase
1606 android.DefaultsModuleBase
1607}
1608
1609func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1610}
1611
1612func (d *DocDefaults) DepsMutator(ctx android.BottomUpMutatorContext) {
1613}
1614
1615func DocDefaultsFactory() android.Module {
1616 module := &DocDefaults{}
1617
1618 module.AddProperties(
1619 &JavadocProperties{},
1620 &DroiddocProperties{},
1621 )
1622
1623 android.InitDefaultsModule(module)
1624
1625 return module
1626}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001627
1628func StubsDefaultsFactory() android.Module {
1629 module := &DocDefaults{}
1630
1631 module.AddProperties(
1632 &JavadocProperties{},
1633 &DroidstubsProperties{},
1634 )
1635
1636 android.InitDefaultsModule(module)
1637
1638 return module
1639}