blob: 6de2ddf2e47f640f1ba2a366b74c0c213ae84ca6 [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"
Jeongik Cha6bd33c12019-06-25 16:26:18 +090026 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29var (
30 javadoc = pctx.AndroidStaticRule("javadoc",
31 blueprint.RuleParams{
32 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070033 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang40b41b42018-10-02 16:11:17 -070034 `${config.SoongJavacWrapper} ${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070035 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080036 `-d $outDir -quiet && ` +
37 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080038 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
39 `rm -rf "$srcJarDir"`,
40
Nan Zhang581fd212018-01-10 16:06:12 -080041 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070042 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080043 "${config.JavadocCmd}",
44 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080045 },
Nan Zhang40b41b42018-10-02 16:11:17 -070046 CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
47 Rspfile: "$out.rsp",
48 RspfileContent: "$in",
49 Restat: true,
Nan Zhang581fd212018-01-10 16:06:12 -080050 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070051 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070052 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070053
54 apiCheck = pctx.AndroidStaticRule("apiCheck",
55 blueprint.RuleParams{
56 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
57 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090058 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070059 CommandDeps: []string{
60 "${config.ApiCheckCmd}",
61 },
62 },
63 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
64
65 updateApi = pctx.AndroidStaticRule("updateApi",
66 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070067 Command: `( ( cp -f $srcApiFile $destApiFile && cp -f $srcRemovedApiFile $destRemovedApiFile ) ` +
Nan Zhang61819ce2018-05-04 18:49:16 -070068 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
69 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070070 "srcApiFile", "destApiFile", "srcRemovedApiFile", "destRemovedApiFile")
Nan Zhang79614d12018-04-19 18:03:39 -070071
72 metalava = pctx.AndroidStaticRule("metalava",
73 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070074 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
75 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070076 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070077 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -080078 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070079 `$opts && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080080 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
81 `rm -rf "$srcJarDir"`,
Nan Zhang79614d12018-04-19 18:03:39 -070082 CommandDeps: []string{
83 "${config.ZipSyncCmd}",
84 "${config.JavaCmd}",
85 "${config.MetalavaJar}",
Nan Zhang79614d12018-04-19 18:03:39 -070086 "${config.SoongZipCmd}",
87 },
88 Rspfile: "$out.rsp",
89 RspfileContent: "$in",
90 Restat: true,
91 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070092 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
93 "classpathArgs", "sourcepathArgs", "opts")
Nan Zhang2760dfc2018-08-24 17:32:54 +000094
95 metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
96 blueprint.RuleParams{
97 Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
98 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070099 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -0800100 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800101 `$opts && touch $out && rm -rf "$srcJarDir") || ` +
Nan Zhang2760dfc2018-08-24 17:32:54 +0000102 `( echo -e "$msg" ; exit 38 )`,
103 CommandDeps: []string{
104 "${config.ZipSyncCmd}",
105 "${config.JavaCmd}",
106 "${config.MetalavaJar}",
107 },
108 Rspfile: "$out.rsp",
109 RspfileContent: "$in",
110 },
Nan Zhang1598a9e2018-09-04 17:14:32 -0700111 "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
112
Pete Gillin581d6082018-10-22 15:55:04 +0100113 nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
114 blueprint.RuleParams{
115 Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
116 },
117 "expected", "actual", "msg")
118
Nan Zhang1598a9e2018-09-04 17:14:32 -0700119 dokka = pctx.AndroidStaticRule("dokka",
120 blueprint.RuleParams{
121 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
122 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
123 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -0700124 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.DokkaJar} $srcJarDir ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -0700125 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
126 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800127 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
128 `rm -rf "$srcJarDir"`,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700129 CommandDeps: []string{
130 "${config.ZipSyncCmd}",
131 "${config.DokkaJar}",
132 "${config.MetalavaJar}",
133 "${config.SoongZipCmd}",
134 },
135 Restat: true,
136 },
137 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -0800138)
139
140func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -0800141 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700142 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800143
Nan Zhang581fd212018-01-10 16:06:12 -0800144 android.RegisterModuleType("droiddoc", DroiddocFactory)
145 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -0700146 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800147 android.RegisterModuleType("javadoc", JavadocFactory)
148 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700149
150 android.RegisterModuleType("droidstubs", DroidstubsFactory)
151 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800152}
153
Colin Crossa1ce2a02018-06-20 15:19:39 -0700154var (
155 srcsLibTag = dependencyTag{name: "sources from javalib"}
156)
157
Nan Zhang581fd212018-01-10 16:06:12 -0800158type JavadocProperties struct {
159 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
160 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -0800161 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800162
163 // list of directories rooted at the Android.bp file that will
164 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800165 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800166
167 // list of source files that should not be used to build the Java module.
168 // This is most useful in the arch/multilib variants to remove non-common files
169 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800170 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800171
Nan Zhangb2b33de2018-02-23 11:18:47 -0800172 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800173 Libs []string `android:"arch_variant"`
174
Nan Zhangb2b33de2018-02-23 11:18:47 -0800175 // the java library (in classpath) for documentation that provides java srcs and srcjars.
176 Srcs_lib *string
177
178 // the base dirs under srcs_lib will be scanned for java srcs.
179 Srcs_lib_whitelist_dirs []string
180
181 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
182 Srcs_lib_whitelist_pkgs []string
183
Nan Zhang581fd212018-01-10 16:06:12 -0800184 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800185 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800186
187 // if not blank, set to the version of the sdk to compile against
188 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900189
190 Aidl struct {
191 // Top level directories to pass to aidl tool
192 Include_dirs []string
193
194 // Directories rooted at the Android.bp file to pass to aidl tool
195 Local_include_dirs []string
196 }
Nan Zhang357466b2018-04-17 17:38:36 -0700197
198 // If not blank, set the java version passed to javadoc as -source
199 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700200
201 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800202 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203
204 // user customized droiddoc args.
205 // Available variables for substitution:
206 //
207 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700208 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Args *string
210
211 // names of the output files used in args that will be generated
212 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800213}
214
Nan Zhang61819ce2018-05-04 18:49:16 -0700215type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900216 // path to the API txt file that the new API extracted from source code is checked
217 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800218 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700219
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900220 // path to the API txt file that the new @removed API extractd from source code is
221 // checked against. The path can be local to the module or from other module (via
222 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800223 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700224
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900225 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700226 Args *string
227}
228
Nan Zhang581fd212018-01-10 16:06:12 -0800229type DroiddocProperties struct {
230 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800231 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800232
Nan Zhanga40da042018-08-01 12:48:00 -0700233 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800234 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800235
236 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800237 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800238
239 // proofread file contains all of the text content of the javadocs concatenated into one file,
240 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800241 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800242
243 // a todo file lists the program elements that are missing documentation.
244 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800245 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800246
247 // directory under current module source that provide additional resources (images).
248 Resourcesdir *string
249
250 // resources output directory under out/soong/.intermediates.
251 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800252
Nan Zhange2ba5d42018-07-11 15:16:55 -0700253 // if set to true, collect the values used by the Dev tools and
254 // write them in files packaged with the SDK. Defaults to false.
255 Write_sdk_values *bool
256
257 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800258 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700259
260 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800261 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700262
Nan Zhang581fd212018-01-10 16:06:12 -0800263 // a list of files under current module source dir which contains known tags in Java sources.
264 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800265 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700266
267 // the tag name used to distinguish if the API files belong to public/system/test.
268 Api_tag_name *string
269
270 // the generated public API filename by Doclava.
271 Api_filename *string
272
David Brazdilfbe4cc32018-05-31 13:56:46 +0100273 // the generated public Dex API filename by Doclava.
274 Dex_api_filename *string
275
Nan Zhang28c68b92018-03-13 16:17:01 -0700276 // the generated private API filename by Doclava.
277 Private_api_filename *string
278
279 // the generated private Dex API filename by Doclava.
280 Private_dex_api_filename *string
281
282 // the generated removed API filename by Doclava.
283 Removed_api_filename *string
284
David Brazdilaac0c3c2018-04-24 16:23:29 +0100285 // the generated removed Dex API filename by Doclava.
286 Removed_dex_api_filename *string
287
Mathew Inwood76c3de12018-06-22 15:28:11 +0100288 // mapping of dex signatures to source file and line number. This is a temporary property and
289 // will be deleted; you probably shouldn't be using it.
290 Dex_mapping_filename *string
291
Nan Zhang28c68b92018-03-13 16:17:01 -0700292 // the generated exact API filename by Doclava.
293 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700294
Nan Zhang66dc2362018-08-14 20:41:04 -0700295 // the generated proguard filename by Doclava.
296 Proguard_filename *string
297
Nan Zhang853f4202018-04-12 16:55:56 -0700298 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
299 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700300
301 Check_api struct {
302 Last_released ApiToCheck
303
304 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900305
306 // do not perform API check against Last_released, in the case that both two specified API
307 // files by Last_released are modules which don't exist.
308 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700309 }
Nan Zhang79614d12018-04-19 18:03:39 -0700310
Nan Zhang1598a9e2018-09-04 17:14:32 -0700311 // if set to true, generate docs through Dokka instead of Doclava.
312 Dokka_enabled *bool
313}
314
315type DroidstubsProperties struct {
316 // the tag name used to distinguish if the API files belong to public/system/test.
317 Api_tag_name *string
318
Nan Zhang199645c2018-09-19 12:40:06 -0700319 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700320 Api_filename *string
321
Nan Zhang199645c2018-09-19 12:40:06 -0700322 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700323 Dex_api_filename *string
324
Nan Zhang199645c2018-09-19 12:40:06 -0700325 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700326 Private_api_filename *string
327
Nan Zhang199645c2018-09-19 12:40:06 -0700328 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700329 Private_dex_api_filename *string
330
Nan Zhang199645c2018-09-19 12:40:06 -0700331 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700332 Removed_api_filename *string
333
Nan Zhang199645c2018-09-19 12:40:06 -0700334 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700335 Removed_dex_api_filename *string
336
Nan Zhang9c69a122018-08-22 10:22:08 -0700337 // mapping of dex signatures to source file and line number. This is a temporary property and
338 // will be deleted; you probably shouldn't be using it.
339 Dex_mapping_filename *string
340
Nan Zhang199645c2018-09-19 12:40:06 -0700341 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700342 Exact_api_filename *string
343
Nan Zhang199645c2018-09-19 12:40:06 -0700344 // the generated proguard filename by Metalava.
345 Proguard_filename *string
346
Nan Zhang1598a9e2018-09-04 17:14:32 -0700347 Check_api struct {
348 Last_released ApiToCheck
349
350 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900351
352 // do not perform API check against Last_released, in the case that both two specified API
353 // files by Last_released are modules which don't exist.
354 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700355 }
Nan Zhang79614d12018-04-19 18:03:39 -0700356
357 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800358 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700359
360 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700361 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700362
Pete Gillin77167902018-09-19 18:16:26 +0100363 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700364 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700365
Pete Gillin77167902018-09-19 18:16:26 +0100366 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
367 Merge_inclusion_annotations_dirs []string
368
Pete Gillinc382a562018-11-14 18:45:46 +0000369 // a file containing a list of classes to do nullability validation for.
370 Validate_nullability_from_list *string
371
Pete Gillin581d6082018-10-22 15:55:04 +0100372 // a file containing expected warnings produced by validation of nullability annotations.
373 Check_nullability_warnings *string
374
Nan Zhang1598a9e2018-09-04 17:14:32 -0700375 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
376 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700377
378 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
379 Api_levels_annotations_enabled *bool
380
381 // the dirs which Metalava extracts API levels annotations from.
382 Api_levels_annotations_dirs []string
383
384 // if set to true, collect the values used by the Dev tools and
385 // write them in files packaged with the SDK. Defaults to false.
386 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700387
388 // If set to true, .xml based public API file will be also generated, and
389 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
390 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800391}
392
Nan Zhanga40da042018-08-01 12:48:00 -0700393//
394// Common flags passed down to build rule
395//
396type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700397 bootClasspathArgs string
398 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700399 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700400 dokkaClasspathArgs string
401 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700402 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700403
Nan Zhanga40da042018-08-01 12:48:00 -0700404 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700405 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700406 postDoclavaCmds string
407
Nan Zhang9c69a122018-08-22 10:22:08 -0700408 metalavaStubsFlags string
409 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800410 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100411 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700412 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700413
Nan Zhang71bbe632018-09-17 14:32:21 -0700414 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700415}
416
417func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
418 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
419 android.InitDefaultableModule(module)
420}
421
Nan Zhang1598a9e2018-09-04 17:14:32 -0700422func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
423 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
424 return true
425 } else if String(apiToCheck.Api_file) != "" {
426 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
427 } else if String(apiToCheck.Removed_api_file) != "" {
428 panic("for " + apiVersionTag + " api_file has to be non-empty!")
429 }
430
431 return false
432}
433
Inseob Kim38449af2019-02-28 14:24:05 +0900434func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
435 api_file := String(apiToCheck.Api_file)
436 removed_api_file := String(apiToCheck.Removed_api_file)
437
438 api_module := android.SrcIsModule(api_file)
439 removed_api_module := android.SrcIsModule(removed_api_file)
440
441 if api_module == "" || removed_api_module == "" {
442 return
443 }
444
445 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
446 return
447 }
448
449 apiToCheck.Api_file = nil
450 apiToCheck.Removed_api_file = nil
451}
452
Nan Zhang1598a9e2018-09-04 17:14:32 -0700453type ApiFilePath interface {
454 ApiFilePath() android.Path
455}
456
457func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
458 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
459 ctx.Build(pctx, android.BuildParams{
460 Rule: updateApi,
461 Description: "Update API",
462 Output: output,
463 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
464 destApiFile, destRemovedApiFile),
465 Args: map[string]string{
466 "destApiFile": destApiFile.String(),
467 "srcApiFile": srcApiFile.String(),
468 "destRemovedApiFile": destRemovedApiFile.String(),
469 "srcRemovedApiFile": srcRemovedApiFile.String(),
470 },
471 })
472}
473
Nan Zhanga40da042018-08-01 12:48:00 -0700474//
475// Javadoc
476//
Nan Zhang581fd212018-01-10 16:06:12 -0800477type Javadoc struct {
478 android.ModuleBase
479 android.DefaultableModuleBase
480
481 properties JavadocProperties
482
483 srcJars android.Paths
484 srcFiles android.Paths
485 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700486 argFiles android.Paths
487
488 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800489
Nan Zhangccff0f72018-03-08 17:26:16 -0800490 docZip android.WritablePath
491 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800492}
493
Colin Cross41955e82019-05-29 14:40:35 -0700494func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
495 switch tag {
496 case "":
497 return android.Paths{j.stubsSrcJar}, nil
498 default:
499 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
500 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800501}
502
Colin Crossa3002fc2019-07-08 16:48:04 -0700503// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800504func JavadocFactory() android.Module {
505 module := &Javadoc{}
506
507 module.AddProperties(&module.properties)
508
509 InitDroiddocModule(module, android.HostAndDeviceSupported)
510 return module
511}
512
Colin Crossa3002fc2019-07-08 16:48:04 -0700513// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800514func JavadocHostFactory() android.Module {
515 module := &Javadoc{}
516
517 module.AddProperties(&module.properties)
518
519 InitDroiddocModule(module, android.HostSupported)
520 return module
521}
522
Colin Cross41955e82019-05-29 14:40:35 -0700523var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800524
Colin Cross83bb3162018-06-25 15:48:06 -0700525func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900526 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700527}
528
529func (j *Javadoc) minSdkVersion() string {
530 return j.sdkVersion()
531}
532
Dan Willemsen419290a2018-10-31 15:28:47 -0700533func (j *Javadoc) targetSdkVersion() string {
534 return j.sdkVersion()
535}
536
Nan Zhang581fd212018-01-10 16:06:12 -0800537func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
538 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100539 sdkDep := decodeSdkDep(ctx, sdkContext(j))
540 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700541 if sdkDep.useDefaultLibs {
542 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
543 if ctx.Config().TargetOpenJDK9() {
544 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
545 }
Paul Duffin250e6192019-06-07 10:44:37 +0100546 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700547 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
548 }
549 } else if sdkDep.useModule {
550 if ctx.Config().TargetOpenJDK9() {
551 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
552 }
553 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700554 }
Nan Zhang581fd212018-01-10 16:06:12 -0800555 }
556 }
557
Colin Cross42d48b72018-08-29 14:10:52 -0700558 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700559 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700560 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700561 }
Nan Zhang581fd212018-01-10 16:06:12 -0800562}
563
Nan Zhangb2b33de2018-02-23 11:18:47 -0800564func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
565 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
566 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900567 // convert foo.bar.baz to foo/bar/baz
568 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
569 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800570 if _, found := whitelistPathPrefixes[prefix]; !found {
571 whitelistPathPrefixes[prefix] = true
572 }
573 }
574 }
575}
576
Nan Zhanga40da042018-08-01 12:48:00 -0700577func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
578 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900579
Colin Cross3047fa22019-04-18 10:56:44 -0700580 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900581
582 return flags
583}
584
585func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700586 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900587
588 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
589 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
590
591 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700592 var deps android.Paths
593
Jiyong Park1e440682018-05-23 18:42:04 +0900594 if aidlPreprocess.Valid() {
595 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700596 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900597 } else {
598 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
599 }
600
601 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
602 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
603 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
604 flags = append(flags, "-I"+src.String())
605 }
606
Colin Cross3047fa22019-04-18 10:56:44 -0700607 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900608}
609
610func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700611 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900612
613 outSrcFiles := make(android.Paths, 0, len(srcFiles))
614
615 for _, srcFile := range srcFiles {
616 switch srcFile.Ext() {
617 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700618 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900619 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900620 case ".sysprop":
621 javaFile := genSysprop(ctx, srcFile)
622 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900623 default:
624 outSrcFiles = append(outSrcFiles, srcFile)
625 }
626 }
627
628 return outSrcFiles
629}
630
Nan Zhang581fd212018-01-10 16:06:12 -0800631func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
632 var deps deps
633
Colin Cross83bb3162018-06-25 15:48:06 -0700634 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800635 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700636 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800637 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700638 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800639 }
640
641 ctx.VisitDirectDeps(func(module android.Module) {
642 otherName := ctx.OtherModuleName(module)
643 tag := ctx.OtherModuleDependencyTag(module)
644
Colin Cross2d24c1b2018-05-23 10:59:18 -0700645 switch tag {
646 case bootClasspathTag:
647 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800648 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700649 } else {
650 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
651 }
652 case libTag:
653 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800654 case SdkLibraryDependency:
655 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700656 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900657 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900658 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700659 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800660 checkProducesJars(ctx, dep)
661 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800662 default:
663 ctx.ModuleErrorf("depends on non-java module %q", otherName)
664 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700665 case srcsLibTag:
666 switch dep := module.(type) {
667 case Dependency:
668 srcs := dep.(SrcDependency).CompiledSrcs()
669 whitelistPathPrefixes := make(map[string]bool)
670 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
671 for _, src := range srcs {
672 if _, ok := src.(android.WritablePath); ok { // generated sources
673 deps.srcs = append(deps.srcs, src)
674 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700675 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700676 if strings.HasPrefix(src.Rel(), k) {
677 deps.srcs = append(deps.srcs, src)
678 break
679 }
680 }
681 }
682 }
683 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
684 default:
685 ctx.ModuleErrorf("depends on non-java module %q", otherName)
686 }
Nan Zhang357466b2018-04-17 17:38:36 -0700687 case systemModulesTag:
688 if deps.systemModules != nil {
689 panic("Found two system module dependencies")
690 }
691 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000692 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700693 panic("Missing directory for system module dependency")
694 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000695 deps.systemModules = sm.outputDir
696 deps.systemModulesDeps = sm.outputDeps
Nan Zhang581fd212018-01-10 16:06:12 -0800697 }
698 })
699 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
700 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800701 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700702 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900703 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800704
705 // srcs may depend on some genrule output.
706 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800707 j.srcJars = append(j.srcJars, deps.srcJars...)
708
Nan Zhang581fd212018-01-10 16:06:12 -0800709 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800710 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800711
712 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800713 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800714
Nan Zhang9c69a122018-08-22 10:22:08 -0700715 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800716 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
717 }
718 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800719
Colin Cross8a497952019-03-05 22:25:09 -0800720 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000721 argFilesMap := map[string]string{}
722 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700723
Paul Duffin99e4a502019-02-11 15:38:42 +0000724 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800725 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000726 if _, exists := argFilesMap[label]; !exists {
727 argFilesMap[label] = strings.Join(paths.Strings(), " ")
728 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700729 } else {
730 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000731 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700732 }
733 }
734
735 var err error
Colin Cross15638152019-07-11 11:11:35 -0700736 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700737 if strings.HasPrefix(name, "location ") {
738 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000739 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700740 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700741 } else {
Colin Cross15638152019-07-11 11:11:35 -0700742 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000743 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700744 }
745 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700746 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700747 }
Colin Cross15638152019-07-11 11:11:35 -0700748 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700749 })
750
751 if err != nil {
752 ctx.PropertyErrorf("args", "%s", err.Error())
753 }
754
Nan Zhang581fd212018-01-10 16:06:12 -0800755 return deps
756}
757
758func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
759 j.addDeps(ctx)
760}
761
762func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
763 deps := j.collectDeps(ctx)
764
765 var implicits android.Paths
766 implicits = append(implicits, deps.bootClasspath...)
767 implicits = append(implicits, deps.classpath...)
768
Nan Zhang1598a9e2018-09-04 17:14:32 -0700769 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700770
Colin Cross83bb3162018-06-25 15:48:06 -0700771 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700772 if len(deps.bootClasspath) > 0 {
773 var systemModules classpath
774 if deps.systemModules != nil {
775 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800776 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000777 implicits = append(implicits, deps.systemModulesDeps...)
Colin Cross997262f2018-06-19 22:49:39 -0700778 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
779 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800780 }
781 if len(deps.classpath.Strings()) > 0 {
782 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
783 }
784
785 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700786 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800787
Nan Zhangaf322cc2018-06-19 15:15:38 -0700788 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800789
Nan Zhang1598a9e2018-09-04 17:14:32 -0700790 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
791
Nan Zhang581fd212018-01-10 16:06:12 -0800792 ctx.Build(pctx, android.BuildParams{
793 Rule: javadoc,
794 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800795 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800796 ImplicitOutput: j.docZip,
797 Inputs: j.srcFiles,
798 Implicits: implicits,
799 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700800 "outDir": android.PathForModuleOut(ctx, "out").String(),
801 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
802 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800803 "srcJars": strings.Join(j.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -0700804 "opts": proptools.NinjaEscape(opts),
Nan Zhang853f4202018-04-12 16:55:56 -0700805 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800806 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700807 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800808 "docZip": j.docZip.String(),
809 },
810 })
811}
812
Nan Zhanga40da042018-08-01 12:48:00 -0700813//
814// Droiddoc
815//
816type Droiddoc struct {
817 Javadoc
818
819 properties DroiddocProperties
820 apiFile android.WritablePath
821 dexApiFile android.WritablePath
822 privateApiFile android.WritablePath
823 privateDexApiFile android.WritablePath
824 removedApiFile android.WritablePath
825 removedDexApiFile android.WritablePath
826 exactApiFile android.WritablePath
827 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700828 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700829
830 checkCurrentApiTimestamp android.WritablePath
831 updateCurrentApiTimestamp android.WritablePath
832 checkLastReleasedApiTimestamp android.WritablePath
833
Nan Zhanga40da042018-08-01 12:48:00 -0700834 apiFilePath android.Path
835}
836
Colin Crossa3002fc2019-07-08 16:48:04 -0700837// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700838func DroiddocFactory() android.Module {
839 module := &Droiddoc{}
840
841 module.AddProperties(&module.properties,
842 &module.Javadoc.properties)
843
844 InitDroiddocModule(module, android.HostAndDeviceSupported)
845 return module
846}
847
Colin Crossa3002fc2019-07-08 16:48:04 -0700848// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700849func DroiddocHostFactory() android.Module {
850 module := &Droiddoc{}
851
852 module.AddProperties(&module.properties,
853 &module.Javadoc.properties)
854
855 InitDroiddocModule(module, android.HostSupported)
856 return module
857}
858
859func (d *Droiddoc) ApiFilePath() android.Path {
860 return d.apiFilePath
861}
862
Nan Zhang581fd212018-01-10 16:06:12 -0800863func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
864 d.Javadoc.addDeps(ctx)
865
Inseob Kim38449af2019-02-28 14:24:05 +0900866 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
867 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
868 }
869
Nan Zhang79614d12018-04-19 18:03:39 -0700870 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800871 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
872 }
Nan Zhang581fd212018-01-10 16:06:12 -0800873}
874
Nan Zhang66dc2362018-08-14 20:41:04 -0700875func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
876 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700877 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800878
Nan Zhanga40da042018-08-01 12:48:00 -0700879 *implicits = append(*implicits, deps.bootClasspath...)
880 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800881
Nan Zhangc94f9d82018-06-26 10:02:26 -0700882 if len(deps.bootClasspath.Strings()) > 0 {
883 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700884 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700885 }
Nan Zhanga40da042018-08-01 12:48:00 -0700886 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700887 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700888 dokkaClasspath := classpath{}
889 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
890 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
891 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700892
Nan Zhang9c69a122018-08-22 10:22:08 -0700893 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
894 // based stubs generation.
895 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
896 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
897 // the correct package name base path.
898 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
899 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
900 } else {
901 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
902 }
Nan Zhang581fd212018-01-10 16:06:12 -0800903
Nan Zhanga40da042018-08-01 12:48:00 -0700904 return flags, nil
905}
Nan Zhang581fd212018-01-10 16:06:12 -0800906
Nan Zhanga40da042018-08-01 12:48:00 -0700907func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700908 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800909
Nan Zhanga40da042018-08-01 12:48:00 -0700910 *implicits = append(*implicits, jsilver)
911 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700912
Nan Zhang46130972018-06-04 11:28:01 -0700913 var date string
914 if runtime.GOOS == "darwin" {
915 date = `date -r`
916 } else {
917 date = `date -d`
918 }
919
Nan Zhang443fa522018-08-20 20:58:28 -0700920 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
921 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
922 // 1.9 language features.
923 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700924 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross15638152019-07-11 11:11:35 -0700925 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
926 `-hdf page.now "$(` + date + ` @$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700927
Nan Zhanga40da042018-08-01 12:48:00 -0700928 if String(d.properties.Custom_template) == "" {
929 // TODO: This is almost always droiddoc-templates-sdk
930 ctx.PropertyErrorf("custom_template", "must specify a template")
931 }
932
933 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700934 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700935 *implicits = append(*implicits, t.deps...)
936 args = args + " -templatedir " + t.dir.String()
937 } else {
938 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
939 }
940 })
941
942 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800943 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800944 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800945 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700946 }
947
948 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800949 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800950 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800951 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700952 }
953
954 if len(d.properties.Html_dirs) > 2 {
955 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
956 }
957
Colin Cross8a497952019-03-05 22:25:09 -0800958 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700959 *implicits = append(*implicits, knownTags...)
960
961 for _, kt := range knownTags {
962 args = args + " -knowntags " + kt.String()
963 }
964
965 for _, hdf := range d.properties.Hdf {
966 args = args + " -hdf " + hdf
967 }
968
969 if String(d.properties.Proofread_file) != "" {
970 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
971 args = args + " -proofread " + proofreadFile.String()
972 }
973
974 if String(d.properties.Todo_file) != "" {
975 // tricky part:
976 // we should not compute full path for todo_file through PathForModuleOut().
977 // the non-standard doclet will get the full path relative to "-o".
978 args = args + " -todo " + String(d.properties.Todo_file)
979 }
980
981 if String(d.properties.Resourcesdir) != "" {
982 // TODO: should we add files under resourcesDir to the implicits? It seems that
983 // resourcesDir is one sub dir of htmlDir
984 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
985 args = args + " -resourcesdir " + resourcesDir.String()
986 }
987
988 if String(d.properties.Resourcesoutdir) != "" {
989 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
990 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
991 }
992 return args
993}
994
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
996 implicitOutputs *android.WritablePaths) string {
997 var doclavaFlags string
998 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
999 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1000 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001001 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1002 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001003 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1004 d.apiFilePath = d.apiFile
1005 }
1006
Nan Zhang1598a9e2018-09-04 17:14:32 -07001007 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1008 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1009 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001010 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1011 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001012 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1013 }
1014
1015 if String(d.properties.Private_api_filename) != "" {
1016 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1017 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001018 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1019 }
1020
1021 if String(d.properties.Dex_api_filename) != "" {
1022 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1023 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1024 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1025 }
1026
1027 if String(d.properties.Private_dex_api_filename) != "" {
1028 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1029 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001030 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1031 }
1032
1033 if String(d.properties.Removed_dex_api_filename) != "" {
1034 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1035 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001036 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1037 }
1038
1039 if String(d.properties.Exact_api_filename) != "" {
1040 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1041 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001042 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1043 }
1044
1045 if String(d.properties.Dex_mapping_filename) != "" {
1046 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1047 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001048 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1049 }
1050
Nan Zhang66dc2362018-08-14 20:41:04 -07001051 if String(d.properties.Proguard_filename) != "" {
1052 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1053 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001054 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1055 }
1056
Nan Zhanga40da042018-08-01 12:48:00 -07001057 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001058 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001059 }
1060
1061 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001062 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001063 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001064
1065 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001066}
1067
1068func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1069 var cmds string
1070 if String(d.properties.Static_doc_index_redirect) != "" {
1071 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1072 "static_doc_index_redirect")
1073 *implicits = append(*implicits, static_doc_index_redirect)
1074 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001075 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001076 }
1077
1078 if String(d.properties.Static_doc_properties) != "" {
1079 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1080 "static_doc_properties")
1081 *implicits = append(*implicits, static_doc_properties)
1082 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001083 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001084 }
1085 return cmds
1086}
1087
Nan Zhang1598a9e2018-09-04 17:14:32 -07001088func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1089 implicitOutputs android.WritablePaths,
1090 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1091 ctx.Build(pctx, android.BuildParams{
1092 Rule: javadoc,
1093 Description: "Doclava",
1094 Output: d.Javadoc.stubsSrcJar,
1095 Inputs: d.Javadoc.srcFiles,
1096 Implicits: implicits,
1097 ImplicitOutputs: implicitOutputs,
1098 Args: map[string]string{
1099 "outDir": android.PathForModuleOut(ctx, "out").String(),
1100 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1101 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1102 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001103 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001104 "bootclasspathArgs": bootclasspathArgs,
1105 "classpathArgs": classpathArgs,
1106 "sourcepathArgs": sourcepathArgs,
1107 "docZip": d.Javadoc.docZip.String(),
1108 "postDoclavaCmds": postDoclavaCmds,
1109 },
1110 })
1111}
1112
1113func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1114 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1115 ctx.Build(pctx, android.BuildParams{
1116 Rule: apiCheck,
1117 Description: "Doclava Check API",
1118 Output: output,
1119 Inputs: nil,
1120 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1121 checkApiClasspath...),
1122 Args: map[string]string{
1123 "msg": msg,
1124 "classpath": checkApiClasspath.FormJavaClassPath(""),
Colin Cross15638152019-07-11 11:11:35 -07001125 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001126 "apiFile": apiFile.String(),
1127 "apiFileToCheck": d.apiFile.String(),
1128 "removedApiFile": removedApiFile.String(),
1129 "removedApiFileToCheck": d.removedApiFile.String(),
1130 },
1131 })
1132}
1133
1134func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1135 classpathArgs, opts string) {
1136 ctx.Build(pctx, android.BuildParams{
1137 Rule: dokka,
1138 Description: "Dokka",
1139 Output: d.Javadoc.stubsSrcJar,
1140 Inputs: d.Javadoc.srcFiles,
1141 Implicits: implicits,
1142 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001143 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1144 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1145 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001146 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1147 "classpathArgs": classpathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001148 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001149 "docZip": d.Javadoc.docZip.String(),
1150 },
1151 })
1152}
1153
1154func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1155 deps := d.Javadoc.collectDeps(ctx)
1156
1157 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1158 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1159 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1160 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1161
1162 var implicits android.Paths
1163 implicits = append(implicits, d.Javadoc.srcJars...)
1164 implicits = append(implicits, d.Javadoc.argFiles...)
1165
1166 var implicitOutputs android.WritablePaths
1167 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1168 for _, o := range d.Javadoc.properties.Out {
1169 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1170 }
1171
1172 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1173 if err != nil {
1174 return
1175 }
1176
1177 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1178 if Bool(d.properties.Dokka_enabled) {
1179 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1180 } else {
1181 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1182 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1183 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1184 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1185 flags.postDoclavaCmds)
1186 }
1187
1188 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1189 !ctx.Config().IsPdkBuild() {
1190 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1191 "check_api.current.api_file")
1192 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1193 "check_api.current_removed_api_file")
1194
1195 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1196 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1197 fmt.Sprintf(`\n******************************\n`+
1198 `You have tried to change the API from what has been previously approved.\n\n`+
1199 `To make these errors go away, you have two choices:\n`+
1200 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1201 ` errors above.\n\n`+
1202 ` 2. You can update current.txt by executing the following command:\n`+
1203 ` make %s-update-current-api\n\n`+
1204 ` To submit the revised current.txt to the main Android repository,\n`+
1205 ` you will need approval.\n`+
1206 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1207 d.checkCurrentApiTimestamp)
1208
1209 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1210 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1211 d.updateCurrentApiTimestamp)
1212 }
1213
1214 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1215 !ctx.Config().IsPdkBuild() {
1216 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1217 "check_api.last_released.api_file")
1218 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1219 "check_api.last_released.removed_api_file")
1220
1221 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1222 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1223 `\n******************************\n`+
1224 `You have tried to change the API from what has been previously released in\n`+
1225 `an SDK. Please fix the errors listed above.\n`+
1226 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1227 d.checkLastReleasedApiTimestamp)
1228 }
1229}
1230
1231//
1232// Droidstubs
1233//
1234type Droidstubs struct {
1235 Javadoc
1236
Pete Gillin581d6082018-10-22 15:55:04 +01001237 properties DroidstubsProperties
1238 apiFile android.WritablePath
1239 apiXmlFile android.WritablePath
1240 lastReleasedApiXmlFile android.WritablePath
1241 dexApiFile android.WritablePath
1242 privateApiFile android.WritablePath
1243 privateDexApiFile android.WritablePath
1244 removedApiFile android.WritablePath
1245 removedDexApiFile android.WritablePath
1246 apiMappingFile android.WritablePath
1247 exactApiFile android.WritablePath
1248 proguardFile android.WritablePath
1249 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250
1251 checkCurrentApiTimestamp android.WritablePath
1252 updateCurrentApiTimestamp android.WritablePath
1253 checkLastReleasedApiTimestamp android.WritablePath
1254
Pete Gillin581d6082018-10-22 15:55:04 +01001255 checkNullabilityWarningsTimestamp android.WritablePath
1256
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001258 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259
1260 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001261
1262 jdiffDocZip android.WritablePath
1263 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264}
1265
Colin Crossa3002fc2019-07-08 16:48:04 -07001266// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1267// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1268// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001269func DroidstubsFactory() android.Module {
1270 module := &Droidstubs{}
1271
1272 module.AddProperties(&module.properties,
1273 &module.Javadoc.properties)
1274
1275 InitDroiddocModule(module, android.HostAndDeviceSupported)
1276 return module
1277}
1278
Colin Crossa3002fc2019-07-08 16:48:04 -07001279// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1280// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1281// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1282// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001283func DroidstubsHostFactory() android.Module {
1284 module := &Droidstubs{}
1285
1286 module.AddProperties(&module.properties,
1287 &module.Javadoc.properties)
1288
1289 InitDroiddocModule(module, android.HostSupported)
1290 return module
1291}
1292
1293func (d *Droidstubs) ApiFilePath() android.Path {
1294 return d.apiFilePath
1295}
1296
1297func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1298 d.Javadoc.addDeps(ctx)
1299
Inseob Kim38449af2019-02-28 14:24:05 +09001300 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1301 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1302 }
1303
Nan Zhang1598a9e2018-09-04 17:14:32 -07001304 if len(d.properties.Merge_annotations_dirs) != 0 {
1305 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1306 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1307 }
1308 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001309
Pete Gillin77167902018-09-19 18:16:26 +01001310 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1311 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1312 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1313 }
1314 }
1315
Nan Zhang9c69a122018-08-22 10:22:08 -07001316 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1317 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1318 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1319 }
1320 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001321}
1322
1323func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1324 deps deps) (droiddocBuilderFlags, error) {
1325 var flags droiddocBuilderFlags
1326
1327 *implicits = append(*implicits, deps.bootClasspath...)
1328 *implicits = append(*implicits, deps.classpath...)
1329
1330 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1331 // since it doesn't support system modules yet.
1332 if len(deps.bootClasspath.Strings()) > 0 {
1333 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1334 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1335 }
1336 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1337
Sundong Ahn56dce442018-10-05 18:41:09 +09001338 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001339 return flags, nil
1340}
1341
1342func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1343 implicitOutputs *android.WritablePaths) string {
1344 var metalavaFlags string
1345 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1346 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1347 String(d.properties.Api_filename) != "" {
1348 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1349 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1350 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1351 d.apiFilePath = d.apiFile
1352 }
1353
1354 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1355 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1356 String(d.properties.Removed_api_filename) != "" {
1357 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1358 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1359 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1360 }
1361
1362 if String(d.properties.Private_api_filename) != "" {
1363 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1364 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1365 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1366 }
1367
1368 if String(d.properties.Dex_api_filename) != "" {
1369 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1370 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1371 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1372 }
1373
1374 if String(d.properties.Private_dex_api_filename) != "" {
1375 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1376 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1377 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1378 }
1379
1380 if String(d.properties.Removed_dex_api_filename) != "" {
1381 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1382 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1383 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1384 }
1385
1386 if String(d.properties.Exact_api_filename) != "" {
1387 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1388 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1389 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1390 }
1391
Nan Zhang9c69a122018-08-22 10:22:08 -07001392 if String(d.properties.Dex_mapping_filename) != "" {
1393 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1394 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1395 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1396 }
1397
Nan Zhang199645c2018-09-19 12:40:06 -07001398 if String(d.properties.Proguard_filename) != "" {
1399 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1400 metalavaFlags += " --proguard " + d.proguardFile.String()
1401 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1402 }
1403
Nan Zhang9c69a122018-08-22 10:22:08 -07001404 if Bool(d.properties.Write_sdk_values) {
1405 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1406 }
1407
Nan Zhang1598a9e2018-09-04 17:14:32 -07001408 if Bool(d.properties.Create_doc_stubs) {
1409 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1410 } else {
1411 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1412 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001413 return metalavaFlags
1414}
1415
1416func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001417 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1418 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001419 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001420 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001421 validatingNullability :=
1422 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1423 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001424 migratingNullability := String(d.properties.Previous_api) != ""
1425 if !(migratingNullability || validatingNullability) {
1426 ctx.PropertyErrorf("previous_api",
1427 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001428 }
Pete Gillina262c052018-09-14 14:25:48 +01001429 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001430 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001431 *implicits = append(*implicits, previousApi)
1432 flags += " --migrate-nullness " + previousApi.String()
1433 }
Pete Gillinc382a562018-11-14 18:45:46 +00001434 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001435 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001436 }
Pete Gillina262c052018-09-14 14:25:48 +01001437 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001438 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1439 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1440 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001441 }
Nan Zhanga40da042018-08-01 12:48:00 -07001442
1443 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1444 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1445
Nan Zhangf4936b02018-08-01 15:00:28 -07001446 flags += " --extract-annotations " + d.annotationsZip.String()
1447
Nan Zhang1598a9e2018-09-04 17:14:32 -07001448 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001449 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001450 "has to be non-empty if annotations was enabled!")
1451 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001452 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1453 if t, ok := m.(*ExportedDroiddocDir); ok {
1454 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001455 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001456 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001457 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001458 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1459 }
1460 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001461 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001462 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001463 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001464 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001465
Nan Zhangdee152b2018-12-26 16:06:37 -08001466 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001467}
1468
1469func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1470 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1471 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001472 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1473 if t, ok := m.(*ExportedDroiddocDir); ok {
1474 *implicits = append(*implicits, t.deps...)
1475 flags += " --merge-inclusion-annotations " + t.dir.String()
1476 } else {
1477 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1478 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1479 }
1480 })
Nan Zhanga40da042018-08-01 12:48:00 -07001481
1482 return flags
1483}
1484
Nan Zhang9c69a122018-08-22 10:22:08 -07001485func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1486 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1487 var flags string
1488 if Bool(d.properties.Api_levels_annotations_enabled) {
1489 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1490 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1491
1492 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1493 ctx.PropertyErrorf("api_levels_annotations_dirs",
1494 "has to be non-empty if api levels annotations was enabled!")
1495 }
1496
1497 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1498 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1499 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1500
1501 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1502 if t, ok := m.(*ExportedDroiddocDir); ok {
1503 var androidJars android.Paths
1504 for _, dep := range t.deps {
1505 if strings.HasSuffix(dep.String(), "android.jar") {
1506 androidJars = append(androidJars, dep)
1507 }
1508 }
1509 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001510 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001511 } else {
1512 ctx.PropertyErrorf("api_levels_annotations_dirs",
1513 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1514 }
1515 })
1516
1517 }
1518
1519 return flags
1520}
1521
Nan Zhang71bbe632018-09-17 14:32:21 -07001522func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1523 implicitOutputs *android.WritablePaths) string {
1524 var flags string
1525 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1526 if d.apiFile.String() == "" {
1527 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1528 }
1529
1530 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1531 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1532
1533 flags = " --api-xml " + d.apiXmlFile.String()
1534
1535 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1536 ctx.PropertyErrorf("check_api.last_released.api_file",
1537 "has to be non-empty if jdiff was enabled!")
1538 }
1539 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1540 "check_api.last_released.api_file")
1541 *implicits = append(*implicits, lastReleasedApi)
1542
1543 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1544 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1545
1546 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1547 d.lastReleasedApiXmlFile.String()
1548 }
1549
1550 return flags
1551}
1552
Nan Zhang1598a9e2018-09-04 17:14:32 -07001553func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1554 implicitOutputs android.WritablePaths, javaVersion,
1555 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001556
Nan Zhang86d2d552018-08-09 15:33:27 -07001557 ctx.Build(pctx, android.BuildParams{
1558 Rule: metalava,
1559 Description: "Metalava",
1560 Output: d.Javadoc.stubsSrcJar,
1561 Inputs: d.Javadoc.srcFiles,
1562 Implicits: implicits,
1563 ImplicitOutputs: implicitOutputs,
1564 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001565 "outDir": android.PathForModuleOut(ctx, "out").String(),
1566 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1567 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1568 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001569 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001570 "bootclasspathArgs": bootclasspathArgs,
1571 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001572 "sourcepathArgs": sourcepathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001573 "opts": proptools.NinjaEscape(opts),
Nan Zhang86d2d552018-08-09 15:33:27 -07001574 },
1575 })
1576}
1577
Nan Zhang1598a9e2018-09-04 17:14:32 -07001578func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
1579 apiFile, removedApiFile android.Path, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001580 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001581 output android.WritablePath) {
1582 ctx.Build(pctx, android.BuildParams{
1583 Rule: metalavaApiCheck,
1584 Description: "Metalava Check API",
1585 Output: output,
1586 Inputs: d.Javadoc.srcFiles,
1587 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1588 implicits...),
1589 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001590 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001591 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1592 "javaVersion": javaVersion,
1593 "bootclasspathArgs": bootclasspathArgs,
1594 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001595 "sourcepathArgs": sourcepathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001596 "opts": proptools.NinjaEscape(opts),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001597 "msg": msg,
1598 },
1599 })
1600}
1601
Nan Zhang71bbe632018-09-17 14:32:21 -07001602func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1603 implicitOutputs android.WritablePaths,
1604 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1605 ctx.Build(pctx, android.BuildParams{
1606 Rule: javadoc,
1607 Description: "Jdiff",
1608 Output: d.jdiffStubsSrcJar,
1609 Inputs: d.Javadoc.srcFiles,
1610 Implicits: implicits,
1611 ImplicitOutputs: implicitOutputs,
1612 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001613 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1614 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1615 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001616 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001617 "opts": proptools.NinjaEscape(opts),
Nan Zhang71bbe632018-09-17 14:32:21 -07001618 "bootclasspathArgs": bootclasspathArgs,
1619 "classpathArgs": classpathArgs,
1620 "sourcepathArgs": sourcepathArgs,
1621 "docZip": d.jdiffDocZip.String(),
1622 },
1623 })
1624}
1625
Nan Zhang1598a9e2018-09-04 17:14:32 -07001626func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001627 deps := d.Javadoc.collectDeps(ctx)
1628
1629 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001630
Nan Zhanga40da042018-08-01 12:48:00 -07001631 var implicits android.Paths
1632 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001633 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001634
1635 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001636 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001637 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1638 }
1639
1640 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001641 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001642 jdiffImplicits := implicits
1643
Nan Zhanga40da042018-08-01 12:48:00 -07001644 if err != nil {
1645 return
1646 }
1647
Nan Zhang1598a9e2018-09-04 17:14:32 -07001648 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001649 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1650 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001651 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001652 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001653 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1654
Nan Zhang1598a9e2018-09-04 17:14:32 -07001655 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1656 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1657 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1658 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1659 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001660 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001661 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1662 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001663 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001664 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001665
Nan Zhang1598a9e2018-09-04 17:14:32 -07001666 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1667 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001668 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1669 "check_api.current.api_file")
1670 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1671 "check_api.current_removed_api_file")
1672
Nan Zhang2760dfc2018-08-24 17:32:54 +00001673 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001674 opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1675 " --check-compatibility:removed:current " + removedApiFile.String() +
Nan Zhangdee152b2018-12-26 16:06:37 -08001676 flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001677
Nan Zhang1598a9e2018-09-04 17:14:32 -07001678 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001679 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001680 fmt.Sprintf(`\n******************************\n`+
1681 `You have tried to change the API from what has been previously approved.\n\n`+
1682 `To make these errors go away, you have two choices:\n`+
1683 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1684 ` errors above.\n\n`+
1685 ` 2. You can update current.txt by executing the following command:\n`+
1686 ` make %s-update-current-api\n\n`+
1687 ` To submit the revised current.txt to the main Android repository,\n`+
1688 ` you will need approval.\n`+
1689 `******************************\n`, ctx.ModuleName()),
1690 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001691
1692 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001693 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1694 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001695 }
Nan Zhanga40da042018-08-01 12:48:00 -07001696
Nan Zhang1598a9e2018-09-04 17:14:32 -07001697 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1698 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001699 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1700 "check_api.last_released.api_file")
1701 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1702 "check_api.last_released.removed_api_file")
1703
Nan Zhang2760dfc2018-08-24 17:32:54 +00001704 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001705 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1706 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001707 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001708
Nan Zhang1598a9e2018-09-04 17:14:32 -07001709 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001710 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001711 `\n******************************\n`+
1712 `You have tried to change the API from what has been previously released in\n`+
1713 `an SDK. Please fix the errors listed above.\n`+
1714 `******************************\n`,
1715 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001716 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001717
Pete Gillin581d6082018-10-22 15:55:04 +01001718 if String(d.properties.Check_nullability_warnings) != "" {
1719 if d.nullabilityWarningsFile == nil {
1720 ctx.PropertyErrorf("check_nullability_warnings",
1721 "Cannot specify check_nullability_warnings unless validating nullability")
1722 }
1723 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1724 "check_nullability_warnings")
1725 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1726 msg := fmt.Sprintf(`\n******************************\n`+
1727 `The warnings encountered during nullability annotation validation did\n`+
1728 `not match the checked in file of expected warnings. The diffs are shown\n`+
1729 `above. You have two options:\n`+
1730 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1731 ` 2. Update the file of expected warnings by running:\n`+
1732 ` cp %s %s\n`+
1733 ` and submitting the updated file as part of your change.`,
1734 d.nullabilityWarningsFile, checkNullabilityWarnings)
1735 ctx.Build(pctx, android.BuildParams{
1736 Rule: nullabilityWarningsCheck,
1737 Description: "Nullability Warnings Check",
1738 Output: d.checkNullabilityWarningsTimestamp,
1739 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1740 Args: map[string]string{
1741 "expected": checkNullabilityWarnings.String(),
1742 "actual": d.nullabilityWarningsFile.String(),
1743 "msg": msg,
1744 },
1745 })
1746 }
1747
Nan Zhang71bbe632018-09-17 14:32:21 -07001748 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1749
Nan Zhang86b06202018-09-21 17:09:21 -07001750 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1751 // since there's cron job downstream that fetch this .zip file periodically.
1752 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001753 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1754 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1755
1756 var jdiffImplicitOutputs android.WritablePaths
1757 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1758
1759 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1760 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1761
Pete Gillin2b1ea2e2019-06-10 14:20:11 +01001762 opts := " -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
Nan Zhang71bbe632018-09-17 14:32:21 -07001763 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1764 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1765 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1766 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1767 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1768
1769 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1770 flags.sourcepathArgs, opts)
1771 }
Nan Zhang581fd212018-01-10 16:06:12 -08001772}
Dan Willemsencc090972018-02-26 14:33:31 -08001773
Nan Zhanga40da042018-08-01 12:48:00 -07001774//
Nan Zhangf4936b02018-08-01 15:00:28 -07001775// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001776//
Dan Willemsencc090972018-02-26 14:33:31 -08001777var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001778var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001779var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001780var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001781
Nan Zhangf4936b02018-08-01 15:00:28 -07001782type ExportedDroiddocDirProperties struct {
1783 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001784 Path *string
1785}
1786
Nan Zhangf4936b02018-08-01 15:00:28 -07001787type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001788 android.ModuleBase
1789
Nan Zhangf4936b02018-08-01 15:00:28 -07001790 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001791
1792 deps android.Paths
1793 dir android.Path
1794}
1795
Colin Crossa3002fc2019-07-08 16:48:04 -07001796// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001797func ExportedDroiddocDirFactory() android.Module {
1798 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001799 module.AddProperties(&module.properties)
1800 android.InitAndroidModule(module)
1801 return module
1802}
1803
Nan Zhangf4936b02018-08-01 15:00:28 -07001804func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001805
Nan Zhangf4936b02018-08-01 15:00:28 -07001806func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001807 path := String(d.properties.Path)
1808 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001809 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001810}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001811
1812//
1813// Defaults
1814//
1815type DocDefaults struct {
1816 android.ModuleBase
1817 android.DefaultsModuleBase
1818}
1819
Nan Zhangb2b33de2018-02-23 11:18:47 -08001820func DocDefaultsFactory() android.Module {
1821 module := &DocDefaults{}
1822
1823 module.AddProperties(
1824 &JavadocProperties{},
1825 &DroiddocProperties{},
1826 )
1827
1828 android.InitDefaultsModule(module)
1829
1830 return module
1831}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001832
1833func StubsDefaultsFactory() android.Module {
1834 module := &DocDefaults{}
1835
1836 module.AddProperties(
1837 &JavadocProperties{},
1838 &DroidstubsProperties{},
1839 )
1840
1841 android.InitDefaultsModule(module)
1842
1843 return module
1844}