blob: e57ced7381d54f66196b0a62c5f3be605840709d [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
Nan Zhang1598a9e2018-09-04 17:14:32 -070072 dokka = pctx.AndroidStaticRule("dokka",
73 blueprint.RuleParams{
74 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
75 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
76 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070077 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.DokkaJar} $srcJarDir ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070078 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
79 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
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 Zhang1598a9e2018-09-04 17:14:32 -070082 CommandDeps: []string{
83 "${config.ZipSyncCmd}",
84 "${config.DokkaJar}",
85 "${config.MetalavaJar}",
86 "${config.SoongZipCmd}",
87 },
88 Restat: true,
89 },
90 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -080091)
92
93func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080094 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070095 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080096
Nan Zhang581fd212018-01-10 16:06:12 -080097 android.RegisterModuleType("droiddoc", DroiddocFactory)
98 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070099 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800100 android.RegisterModuleType("javadoc", JavadocFactory)
101 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700102
103 android.RegisterModuleType("droidstubs", DroidstubsFactory)
104 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800105}
106
Colin Crossa1ce2a02018-06-20 15:19:39 -0700107var (
108 srcsLibTag = dependencyTag{name: "sources from javalib"}
109)
110
Nan Zhang581fd212018-01-10 16:06:12 -0800111type JavadocProperties struct {
112 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
113 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -0800114 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800115
116 // list of directories rooted at the Android.bp file that will
117 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800118 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800119
120 // list of source files that should not be used to build the Java module.
121 // This is most useful in the arch/multilib variants to remove non-common files
122 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800123 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhangb2b33de2018-02-23 11:18:47 -0800125 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800126 Libs []string `android:"arch_variant"`
127
Nan Zhangb2b33de2018-02-23 11:18:47 -0800128 // the java library (in classpath) for documentation that provides java srcs and srcjars.
129 Srcs_lib *string
130
131 // the base dirs under srcs_lib will be scanned for java srcs.
132 Srcs_lib_whitelist_dirs []string
133
134 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
135 Srcs_lib_whitelist_pkgs []string
136
Nan Zhang581fd212018-01-10 16:06:12 -0800137 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800139
140 // if not blank, set to the version of the sdk to compile against
141 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900142
143 Aidl struct {
144 // Top level directories to pass to aidl tool
145 Include_dirs []string
146
147 // Directories rooted at the Android.bp file to pass to aidl tool
148 Local_include_dirs []string
149 }
Nan Zhang357466b2018-04-17 17:38:36 -0700150
151 // If not blank, set the java version passed to javadoc as -source
152 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700153
154 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800155 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700156
157 // user customized droiddoc args.
158 // Available variables for substitution:
159 //
160 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700161 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700162 Args *string
163
164 // names of the output files used in args that will be generated
165 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800166}
167
Nan Zhang61819ce2018-05-04 18:49:16 -0700168type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900169 // path to the API txt file that the new API extracted from source code is checked
170 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800171 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700172
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900173 // path to the API txt file that the new @removed API extractd from source code is
174 // checked against. The path can be local to the module or from other module (via
175 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800176 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700177
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900178 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700179 Args *string
180}
181
Nan Zhang581fd212018-01-10 16:06:12 -0800182type DroiddocProperties struct {
183 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800184 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800185
Nan Zhanga40da042018-08-01 12:48:00 -0700186 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800187 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800188
189 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800190 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800191
192 // proofread file contains all of the text content of the javadocs concatenated into one file,
193 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800194 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800195
196 // a todo file lists the program elements that are missing documentation.
197 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800198 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800199
200 // directory under current module source that provide additional resources (images).
201 Resourcesdir *string
202
203 // resources output directory under out/soong/.intermediates.
204 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800205
Nan Zhange2ba5d42018-07-11 15:16:55 -0700206 // if set to true, collect the values used by the Dev tools and
207 // write them in files packaged with the SDK. Defaults to false.
208 Write_sdk_values *bool
209
210 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800211 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700212
213 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800214 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700215
Nan Zhang581fd212018-01-10 16:06:12 -0800216 // a list of files under current module source dir which contains known tags in Java sources.
217 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800218 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700219
220 // the tag name used to distinguish if the API files belong to public/system/test.
221 Api_tag_name *string
222
223 // the generated public API filename by Doclava.
224 Api_filename *string
225
David Brazdilfbe4cc32018-05-31 13:56:46 +0100226 // the generated public Dex API filename by Doclava.
227 Dex_api_filename *string
228
Nan Zhang28c68b92018-03-13 16:17:01 -0700229 // the generated private API filename by Doclava.
230 Private_api_filename *string
231
232 // the generated private Dex API filename by Doclava.
233 Private_dex_api_filename *string
234
235 // the generated removed API filename by Doclava.
236 Removed_api_filename *string
237
David Brazdilaac0c3c2018-04-24 16:23:29 +0100238 // the generated removed Dex API filename by Doclava.
239 Removed_dex_api_filename *string
240
Mathew Inwood76c3de12018-06-22 15:28:11 +0100241 // mapping of dex signatures to source file and line number. This is a temporary property and
242 // will be deleted; you probably shouldn't be using it.
243 Dex_mapping_filename *string
244
Nan Zhang28c68b92018-03-13 16:17:01 -0700245 // the generated exact API filename by Doclava.
246 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700247
Nan Zhang66dc2362018-08-14 20:41:04 -0700248 // the generated proguard filename by Doclava.
249 Proguard_filename *string
250
Nan Zhang853f4202018-04-12 16:55:56 -0700251 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
252 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700253
254 Check_api struct {
255 Last_released ApiToCheck
256
257 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900258
259 // do not perform API check against Last_released, in the case that both two specified API
260 // files by Last_released are modules which don't exist.
261 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700262 }
Nan Zhang79614d12018-04-19 18:03:39 -0700263
Nan Zhang1598a9e2018-09-04 17:14:32 -0700264 // if set to true, generate docs through Dokka instead of Doclava.
265 Dokka_enabled *bool
266}
267
268type DroidstubsProperties struct {
269 // the tag name used to distinguish if the API files belong to public/system/test.
270 Api_tag_name *string
271
Nan Zhang199645c2018-09-19 12:40:06 -0700272 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700273 Api_filename *string
274
Nan Zhang199645c2018-09-19 12:40:06 -0700275 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700276 Dex_api_filename *string
277
Nan Zhang199645c2018-09-19 12:40:06 -0700278 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700279 Private_api_filename *string
280
Nan Zhang199645c2018-09-19 12:40:06 -0700281 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700282 Private_dex_api_filename *string
283
Nan Zhang199645c2018-09-19 12:40:06 -0700284 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700285 Removed_api_filename *string
286
Nan Zhang199645c2018-09-19 12:40:06 -0700287 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700288 Removed_dex_api_filename *string
289
Nan Zhang9c69a122018-08-22 10:22:08 -0700290 // mapping of dex signatures to source file and line number. This is a temporary property and
291 // will be deleted; you probably shouldn't be using it.
292 Dex_mapping_filename *string
293
Nan Zhang199645c2018-09-19 12:40:06 -0700294 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700295 Exact_api_filename *string
296
Nan Zhang199645c2018-09-19 12:40:06 -0700297 // the generated proguard filename by Metalava.
298 Proguard_filename *string
299
Nan Zhang1598a9e2018-09-04 17:14:32 -0700300 Check_api struct {
301 Last_released ApiToCheck
302
303 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900304
305 // do not perform API check against Last_released, in the case that both two specified API
306 // files by Last_released are modules which don't exist.
307 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700308 }
Nan Zhang79614d12018-04-19 18:03:39 -0700309
310 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800311 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700312
313 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700314 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700315
Pete Gillin77167902018-09-19 18:16:26 +0100316 // 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 -0700317 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700318
Pete Gillin77167902018-09-19 18:16:26 +0100319 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
320 Merge_inclusion_annotations_dirs []string
321
Pete Gillinc382a562018-11-14 18:45:46 +0000322 // a file containing a list of classes to do nullability validation for.
323 Validate_nullability_from_list *string
324
Pete Gillin581d6082018-10-22 15:55:04 +0100325 // a file containing expected warnings produced by validation of nullability annotations.
326 Check_nullability_warnings *string
327
Nan Zhang1598a9e2018-09-04 17:14:32 -0700328 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
329 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700330
331 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
332 Api_levels_annotations_enabled *bool
333
334 // the dirs which Metalava extracts API levels annotations from.
335 Api_levels_annotations_dirs []string
336
337 // if set to true, collect the values used by the Dev tools and
338 // write them in files packaged with the SDK. Defaults to false.
339 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700340
341 // If set to true, .xml based public API file will be also generated, and
342 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
343 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800344}
345
Nan Zhanga40da042018-08-01 12:48:00 -0700346//
347// Common flags passed down to build rule
348//
349type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700350 bootClasspathArgs string
351 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700352 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700353 dokkaClasspathArgs string
354 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700355 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700356
Nan Zhanga40da042018-08-01 12:48:00 -0700357 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700358 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700359 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700360}
361
362func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
363 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
364 android.InitDefaultableModule(module)
365}
366
Nan Zhang1598a9e2018-09-04 17:14:32 -0700367func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
368 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
369 return true
370 } else if String(apiToCheck.Api_file) != "" {
371 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
372 } else if String(apiToCheck.Removed_api_file) != "" {
373 panic("for " + apiVersionTag + " api_file has to be non-empty!")
374 }
375
376 return false
377}
378
Inseob Kim38449af2019-02-28 14:24:05 +0900379func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
380 api_file := String(apiToCheck.Api_file)
381 removed_api_file := String(apiToCheck.Removed_api_file)
382
383 api_module := android.SrcIsModule(api_file)
384 removed_api_module := android.SrcIsModule(removed_api_file)
385
386 if api_module == "" || removed_api_module == "" {
387 return
388 }
389
390 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
391 return
392 }
393
394 apiToCheck.Api_file = nil
395 apiToCheck.Removed_api_file = nil
396}
397
Nan Zhang1598a9e2018-09-04 17:14:32 -0700398type ApiFilePath interface {
399 ApiFilePath() android.Path
400}
401
402func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
403 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
404 ctx.Build(pctx, android.BuildParams{
405 Rule: updateApi,
406 Description: "Update API",
407 Output: output,
408 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
409 destApiFile, destRemovedApiFile),
410 Args: map[string]string{
411 "destApiFile": destApiFile.String(),
412 "srcApiFile": srcApiFile.String(),
413 "destRemovedApiFile": destRemovedApiFile.String(),
414 "srcRemovedApiFile": srcRemovedApiFile.String(),
415 },
416 })
417}
418
Nan Zhanga40da042018-08-01 12:48:00 -0700419//
420// Javadoc
421//
Nan Zhang581fd212018-01-10 16:06:12 -0800422type Javadoc struct {
423 android.ModuleBase
424 android.DefaultableModuleBase
425
426 properties JavadocProperties
427
428 srcJars android.Paths
429 srcFiles android.Paths
430 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700431 argFiles android.Paths
432
433 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800434
Nan Zhangccff0f72018-03-08 17:26:16 -0800435 docZip android.WritablePath
436 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800437}
438
Colin Cross41955e82019-05-29 14:40:35 -0700439func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
440 switch tag {
441 case "":
442 return android.Paths{j.stubsSrcJar}, nil
443 default:
444 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
445 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800446}
447
Colin Crossa3002fc2019-07-08 16:48:04 -0700448// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800449func JavadocFactory() android.Module {
450 module := &Javadoc{}
451
452 module.AddProperties(&module.properties)
453
454 InitDroiddocModule(module, android.HostAndDeviceSupported)
455 return module
456}
457
Colin Crossa3002fc2019-07-08 16:48:04 -0700458// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800459func JavadocHostFactory() android.Module {
460 module := &Javadoc{}
461
462 module.AddProperties(&module.properties)
463
464 InitDroiddocModule(module, android.HostSupported)
465 return module
466}
467
Colin Cross41955e82019-05-29 14:40:35 -0700468var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800469
Colin Cross83bb3162018-06-25 15:48:06 -0700470func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900471 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700472}
473
474func (j *Javadoc) minSdkVersion() string {
475 return j.sdkVersion()
476}
477
Dan Willemsen419290a2018-10-31 15:28:47 -0700478func (j *Javadoc) targetSdkVersion() string {
479 return j.sdkVersion()
480}
481
Nan Zhang581fd212018-01-10 16:06:12 -0800482func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
483 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100484 sdkDep := decodeSdkDep(ctx, sdkContext(j))
485 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700486 if sdkDep.useDefaultLibs {
487 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
488 if ctx.Config().TargetOpenJDK9() {
489 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
490 }
Paul Duffin250e6192019-06-07 10:44:37 +0100491 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700492 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
493 }
494 } else if sdkDep.useModule {
495 if ctx.Config().TargetOpenJDK9() {
496 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
497 }
498 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700499 }
Nan Zhang581fd212018-01-10 16:06:12 -0800500 }
501 }
502
Colin Cross42d48b72018-08-29 14:10:52 -0700503 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700504 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700505 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700506 }
Nan Zhang581fd212018-01-10 16:06:12 -0800507}
508
Nan Zhangb2b33de2018-02-23 11:18:47 -0800509func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
510 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
511 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900512 // convert foo.bar.baz to foo/bar/baz
513 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
514 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800515 if _, found := whitelistPathPrefixes[prefix]; !found {
516 whitelistPathPrefixes[prefix] = true
517 }
518 }
519 }
520}
521
Nan Zhanga40da042018-08-01 12:48:00 -0700522func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
523 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900524
Colin Cross3047fa22019-04-18 10:56:44 -0700525 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900526
527 return flags
528}
529
530func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700531 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900532
533 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
534 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
535
536 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700537 var deps android.Paths
538
Jiyong Park1e440682018-05-23 18:42:04 +0900539 if aidlPreprocess.Valid() {
540 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700541 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900542 } else {
543 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
544 }
545
546 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
547 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
548 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
549 flags = append(flags, "-I"+src.String())
550 }
551
Colin Cross3047fa22019-04-18 10:56:44 -0700552 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900553}
554
555func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700556 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900557
558 outSrcFiles := make(android.Paths, 0, len(srcFiles))
559
560 for _, srcFile := range srcFiles {
561 switch srcFile.Ext() {
562 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700563 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900564 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900565 case ".sysprop":
566 javaFile := genSysprop(ctx, srcFile)
567 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900568 default:
569 outSrcFiles = append(outSrcFiles, srcFile)
570 }
571 }
572
573 return outSrcFiles
574}
575
Nan Zhang581fd212018-01-10 16:06:12 -0800576func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
577 var deps deps
578
Colin Cross83bb3162018-06-25 15:48:06 -0700579 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800580 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700581 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800582 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700583 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800584 }
585
586 ctx.VisitDirectDeps(func(module android.Module) {
587 otherName := ctx.OtherModuleName(module)
588 tag := ctx.OtherModuleDependencyTag(module)
589
Colin Cross2d24c1b2018-05-23 10:59:18 -0700590 switch tag {
591 case bootClasspathTag:
592 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800593 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700594 } else {
595 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
596 }
597 case libTag:
598 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800599 case SdkLibraryDependency:
600 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700601 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900602 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700603 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800604 checkProducesJars(ctx, dep)
605 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800606 default:
607 ctx.ModuleErrorf("depends on non-java module %q", otherName)
608 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700609 case srcsLibTag:
610 switch dep := module.(type) {
611 case Dependency:
612 srcs := dep.(SrcDependency).CompiledSrcs()
613 whitelistPathPrefixes := make(map[string]bool)
614 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
615 for _, src := range srcs {
616 if _, ok := src.(android.WritablePath); ok { // generated sources
617 deps.srcs = append(deps.srcs, src)
618 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700619 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700620 if strings.HasPrefix(src.Rel(), k) {
621 deps.srcs = append(deps.srcs, src)
622 break
623 }
624 }
625 }
626 }
627 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
628 default:
629 ctx.ModuleErrorf("depends on non-java module %q", otherName)
630 }
Nan Zhang357466b2018-04-17 17:38:36 -0700631 case systemModulesTag:
632 if deps.systemModules != nil {
633 panic("Found two system module dependencies")
634 }
635 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000636 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700637 panic("Missing directory for system module dependency")
638 }
Colin Crossb77043e2019-07-16 13:57:13 -0700639 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800640 }
641 })
642 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
643 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800644 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700645 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900646 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800647
648 // srcs may depend on some genrule output.
649 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800650 j.srcJars = append(j.srcJars, deps.srcJars...)
651
Nan Zhang581fd212018-01-10 16:06:12 -0800652 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800653 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800654
655 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800656 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800657
Nan Zhang9c69a122018-08-22 10:22:08 -0700658 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800659 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
660 }
661 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800662
Colin Cross8a497952019-03-05 22:25:09 -0800663 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000664 argFilesMap := map[string]string{}
665 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700666
Paul Duffin99e4a502019-02-11 15:38:42 +0000667 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800668 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000669 if _, exists := argFilesMap[label]; !exists {
670 argFilesMap[label] = strings.Join(paths.Strings(), " ")
671 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700672 } else {
673 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000674 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700675 }
676 }
677
678 var err error
Colin Cross15638152019-07-11 11:11:35 -0700679 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700680 if strings.HasPrefix(name, "location ") {
681 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000682 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700683 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700684 } else {
Colin Cross15638152019-07-11 11:11:35 -0700685 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000686 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700687 }
688 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700689 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700690 }
Colin Cross15638152019-07-11 11:11:35 -0700691 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700692 })
693
694 if err != nil {
695 ctx.PropertyErrorf("args", "%s", err.Error())
696 }
697
Nan Zhang581fd212018-01-10 16:06:12 -0800698 return deps
699}
700
701func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
702 j.addDeps(ctx)
703}
704
705func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
706 deps := j.collectDeps(ctx)
707
708 var implicits android.Paths
709 implicits = append(implicits, deps.bootClasspath...)
710 implicits = append(implicits, deps.classpath...)
711
Nan Zhang1598a9e2018-09-04 17:14:32 -0700712 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700713
Colin Cross83bb3162018-06-25 15:48:06 -0700714 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700715 if len(deps.bootClasspath) > 0 {
Colin Crossb77043e2019-07-16 13:57:13 -0700716 var systemModulesDeps android.Paths
717 bootClasspathArgs, systemModulesDeps = deps.systemModules.FormJavaSystemModulesPath(ctx.Device())
Colin Cross997262f2018-06-19 22:49:39 -0700718 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Colin Crossb77043e2019-07-16 13:57:13 -0700719 implicits = append(implicits, systemModulesDeps...)
Nan Zhang581fd212018-01-10 16:06:12 -0800720 }
721 if len(deps.classpath.Strings()) > 0 {
722 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
723 }
724
725 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700726 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800727
Nan Zhangaf322cc2018-06-19 15:15:38 -0700728 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800729
Nan Zhang1598a9e2018-09-04 17:14:32 -0700730 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
731
Nan Zhang581fd212018-01-10 16:06:12 -0800732 ctx.Build(pctx, android.BuildParams{
733 Rule: javadoc,
734 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800735 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800736 ImplicitOutput: j.docZip,
737 Inputs: j.srcFiles,
738 Implicits: implicits,
739 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700740 "outDir": android.PathForModuleOut(ctx, "out").String(),
741 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
742 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800743 "srcJars": strings.Join(j.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -0700744 "opts": proptools.NinjaEscape(opts),
Nan Zhang853f4202018-04-12 16:55:56 -0700745 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800746 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700747 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800748 "docZip": j.docZip.String(),
749 },
750 })
751}
752
Nan Zhanga40da042018-08-01 12:48:00 -0700753//
754// Droiddoc
755//
756type Droiddoc struct {
757 Javadoc
758
759 properties DroiddocProperties
760 apiFile android.WritablePath
761 dexApiFile android.WritablePath
762 privateApiFile android.WritablePath
763 privateDexApiFile android.WritablePath
764 removedApiFile android.WritablePath
765 removedDexApiFile android.WritablePath
766 exactApiFile android.WritablePath
767 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700768 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700769
770 checkCurrentApiTimestamp android.WritablePath
771 updateCurrentApiTimestamp android.WritablePath
772 checkLastReleasedApiTimestamp android.WritablePath
773
Nan Zhanga40da042018-08-01 12:48:00 -0700774 apiFilePath android.Path
775}
776
Colin Crossa3002fc2019-07-08 16:48:04 -0700777// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700778func DroiddocFactory() android.Module {
779 module := &Droiddoc{}
780
781 module.AddProperties(&module.properties,
782 &module.Javadoc.properties)
783
784 InitDroiddocModule(module, android.HostAndDeviceSupported)
785 return module
786}
787
Colin Crossa3002fc2019-07-08 16:48:04 -0700788// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700789func DroiddocHostFactory() android.Module {
790 module := &Droiddoc{}
791
792 module.AddProperties(&module.properties,
793 &module.Javadoc.properties)
794
795 InitDroiddocModule(module, android.HostSupported)
796 return module
797}
798
799func (d *Droiddoc) ApiFilePath() android.Path {
800 return d.apiFilePath
801}
802
Nan Zhang581fd212018-01-10 16:06:12 -0800803func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
804 d.Javadoc.addDeps(ctx)
805
Inseob Kim38449af2019-02-28 14:24:05 +0900806 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
807 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
808 }
809
Nan Zhang79614d12018-04-19 18:03:39 -0700810 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800811 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
812 }
Nan Zhang581fd212018-01-10 16:06:12 -0800813}
814
Nan Zhang66dc2362018-08-14 20:41:04 -0700815func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
816 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700817 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800818
Nan Zhanga40da042018-08-01 12:48:00 -0700819 *implicits = append(*implicits, deps.bootClasspath...)
820 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800821
Nan Zhangc94f9d82018-06-26 10:02:26 -0700822 if len(deps.bootClasspath.Strings()) > 0 {
823 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700824 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700825 }
Nan Zhanga40da042018-08-01 12:48:00 -0700826 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700827 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700828 dokkaClasspath := classpath{}
829 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
830 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
831 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700832
Nan Zhang9c69a122018-08-22 10:22:08 -0700833 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
834 // based stubs generation.
835 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
836 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
837 // the correct package name base path.
838 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
839 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
840 } else {
841 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
842 }
Nan Zhang581fd212018-01-10 16:06:12 -0800843
Nan Zhanga40da042018-08-01 12:48:00 -0700844 return flags, nil
845}
Nan Zhang581fd212018-01-10 16:06:12 -0800846
Nan Zhanga40da042018-08-01 12:48:00 -0700847func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700848 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800849
Nan Zhanga40da042018-08-01 12:48:00 -0700850 *implicits = append(*implicits, jsilver)
851 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700852
Nan Zhang46130972018-06-04 11:28:01 -0700853 var date string
854 if runtime.GOOS == "darwin" {
855 date = `date -r`
856 } else {
857 date = `date -d`
858 }
859
Nan Zhang443fa522018-08-20 20:58:28 -0700860 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
861 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
862 // 1.9 language features.
863 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700864 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross15638152019-07-11 11:11:35 -0700865 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
866 `-hdf page.now "$(` + date + ` @$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700867
Nan Zhanga40da042018-08-01 12:48:00 -0700868 if String(d.properties.Custom_template) == "" {
869 // TODO: This is almost always droiddoc-templates-sdk
870 ctx.PropertyErrorf("custom_template", "must specify a template")
871 }
872
873 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700874 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700875 *implicits = append(*implicits, t.deps...)
876 args = args + " -templatedir " + t.dir.String()
877 } else {
878 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
879 }
880 })
881
882 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800883 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800884 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800885 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700886 }
887
888 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800889 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800890 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800891 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700892 }
893
894 if len(d.properties.Html_dirs) > 2 {
895 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
896 }
897
Colin Cross8a497952019-03-05 22:25:09 -0800898 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700899 *implicits = append(*implicits, knownTags...)
900
901 for _, kt := range knownTags {
902 args = args + " -knowntags " + kt.String()
903 }
904
905 for _, hdf := range d.properties.Hdf {
906 args = args + " -hdf " + hdf
907 }
908
909 if String(d.properties.Proofread_file) != "" {
910 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
911 args = args + " -proofread " + proofreadFile.String()
912 }
913
914 if String(d.properties.Todo_file) != "" {
915 // tricky part:
916 // we should not compute full path for todo_file through PathForModuleOut().
917 // the non-standard doclet will get the full path relative to "-o".
918 args = args + " -todo " + String(d.properties.Todo_file)
919 }
920
921 if String(d.properties.Resourcesdir) != "" {
922 // TODO: should we add files under resourcesDir to the implicits? It seems that
923 // resourcesDir is one sub dir of htmlDir
924 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
925 args = args + " -resourcesdir " + resourcesDir.String()
926 }
927
928 if String(d.properties.Resourcesoutdir) != "" {
929 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
930 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
931 }
932 return args
933}
934
Nan Zhang1598a9e2018-09-04 17:14:32 -0700935func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
936 implicitOutputs *android.WritablePaths) string {
937 var doclavaFlags string
938 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
939 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
940 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700941 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
942 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700943 *implicitOutputs = append(*implicitOutputs, d.apiFile)
944 d.apiFilePath = d.apiFile
945 }
946
Nan Zhang1598a9e2018-09-04 17:14:32 -0700947 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
948 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
949 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700950 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
951 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700952 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
953 }
954
955 if String(d.properties.Private_api_filename) != "" {
956 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
957 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700958 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
959 }
960
961 if String(d.properties.Dex_api_filename) != "" {
962 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
963 doclavaFlags += " -dexApi " + d.dexApiFile.String()
964 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
965 }
966
967 if String(d.properties.Private_dex_api_filename) != "" {
968 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
969 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700970 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
971 }
972
973 if String(d.properties.Removed_dex_api_filename) != "" {
974 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
975 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700976 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
977 }
978
979 if String(d.properties.Exact_api_filename) != "" {
980 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
981 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700982 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
983 }
984
985 if String(d.properties.Dex_mapping_filename) != "" {
986 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
987 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700988 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
989 }
990
Nan Zhang66dc2362018-08-14 20:41:04 -0700991 if String(d.properties.Proguard_filename) != "" {
992 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
993 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -0700994 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
995 }
996
Nan Zhanga40da042018-08-01 12:48:00 -0700997 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -0700998 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -0700999 }
1000
1001 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001002 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001003 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001004
1005 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001006}
1007
1008func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1009 var cmds string
1010 if String(d.properties.Static_doc_index_redirect) != "" {
1011 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1012 "static_doc_index_redirect")
1013 *implicits = append(*implicits, static_doc_index_redirect)
1014 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001015 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001016 }
1017
1018 if String(d.properties.Static_doc_properties) != "" {
1019 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1020 "static_doc_properties")
1021 *implicits = append(*implicits, static_doc_properties)
1022 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001023 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001024 }
1025 return cmds
1026}
1027
Nan Zhang1598a9e2018-09-04 17:14:32 -07001028func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1029 implicitOutputs android.WritablePaths,
1030 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1031 ctx.Build(pctx, android.BuildParams{
1032 Rule: javadoc,
1033 Description: "Doclava",
1034 Output: d.Javadoc.stubsSrcJar,
1035 Inputs: d.Javadoc.srcFiles,
1036 Implicits: implicits,
1037 ImplicitOutputs: implicitOutputs,
1038 Args: map[string]string{
1039 "outDir": android.PathForModuleOut(ctx, "out").String(),
1040 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1041 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1042 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001043 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001044 "bootclasspathArgs": bootclasspathArgs,
1045 "classpathArgs": classpathArgs,
1046 "sourcepathArgs": sourcepathArgs,
1047 "docZip": d.Javadoc.docZip.String(),
1048 "postDoclavaCmds": postDoclavaCmds,
1049 },
1050 })
1051}
1052
1053func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1054 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1055 ctx.Build(pctx, android.BuildParams{
1056 Rule: apiCheck,
1057 Description: "Doclava Check API",
1058 Output: output,
1059 Inputs: nil,
1060 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1061 checkApiClasspath...),
1062 Args: map[string]string{
1063 "msg": msg,
1064 "classpath": checkApiClasspath.FormJavaClassPath(""),
Colin Cross15638152019-07-11 11:11:35 -07001065 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001066 "apiFile": apiFile.String(),
1067 "apiFileToCheck": d.apiFile.String(),
1068 "removedApiFile": removedApiFile.String(),
1069 "removedApiFileToCheck": d.removedApiFile.String(),
1070 },
1071 })
1072}
1073
1074func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1075 classpathArgs, opts string) {
1076 ctx.Build(pctx, android.BuildParams{
1077 Rule: dokka,
1078 Description: "Dokka",
1079 Output: d.Javadoc.stubsSrcJar,
1080 Inputs: d.Javadoc.srcFiles,
1081 Implicits: implicits,
1082 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001083 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1084 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1085 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001086 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1087 "classpathArgs": classpathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001088 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001089 "docZip": d.Javadoc.docZip.String(),
1090 },
1091 })
1092}
1093
1094func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1095 deps := d.Javadoc.collectDeps(ctx)
1096
1097 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1098 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1099 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1100 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1101
1102 var implicits android.Paths
1103 implicits = append(implicits, d.Javadoc.srcJars...)
1104 implicits = append(implicits, d.Javadoc.argFiles...)
1105
1106 var implicitOutputs android.WritablePaths
1107 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1108 for _, o := range d.Javadoc.properties.Out {
1109 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1110 }
1111
1112 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1113 if err != nil {
1114 return
1115 }
1116
1117 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1118 if Bool(d.properties.Dokka_enabled) {
1119 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1120 } else {
1121 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1122 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1123 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1124 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1125 flags.postDoclavaCmds)
1126 }
1127
1128 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1129 !ctx.Config().IsPdkBuild() {
1130 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1131 "check_api.current.api_file")
1132 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1133 "check_api.current_removed_api_file")
1134
1135 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1136 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1137 fmt.Sprintf(`\n******************************\n`+
1138 `You have tried to change the API from what has been previously approved.\n\n`+
1139 `To make these errors go away, you have two choices:\n`+
1140 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1141 ` errors above.\n\n`+
1142 ` 2. You can update current.txt by executing the following command:\n`+
1143 ` make %s-update-current-api\n\n`+
1144 ` To submit the revised current.txt to the main Android repository,\n`+
1145 ` you will need approval.\n`+
1146 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1147 d.checkCurrentApiTimestamp)
1148
1149 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1150 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1151 d.updateCurrentApiTimestamp)
1152 }
1153
1154 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1155 !ctx.Config().IsPdkBuild() {
1156 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1157 "check_api.last_released.api_file")
1158 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1159 "check_api.last_released.removed_api_file")
1160
1161 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1162 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1163 `\n******************************\n`+
1164 `You have tried to change the API from what has been previously released in\n`+
1165 `an SDK. Please fix the errors listed above.\n`+
1166 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1167 d.checkLastReleasedApiTimestamp)
1168 }
1169}
1170
1171//
1172// Droidstubs
1173//
1174type Droidstubs struct {
1175 Javadoc
1176
Pete Gillin581d6082018-10-22 15:55:04 +01001177 properties DroidstubsProperties
1178 apiFile android.WritablePath
1179 apiXmlFile android.WritablePath
1180 lastReleasedApiXmlFile android.WritablePath
1181 dexApiFile android.WritablePath
1182 privateApiFile android.WritablePath
1183 privateDexApiFile android.WritablePath
1184 removedApiFile android.WritablePath
1185 removedDexApiFile android.WritablePath
1186 apiMappingFile android.WritablePath
1187 exactApiFile android.WritablePath
1188 proguardFile android.WritablePath
1189 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001190
1191 checkCurrentApiTimestamp android.WritablePath
1192 updateCurrentApiTimestamp android.WritablePath
1193 checkLastReleasedApiTimestamp android.WritablePath
1194
Pete Gillin581d6082018-10-22 15:55:04 +01001195 checkNullabilityWarningsTimestamp android.WritablePath
1196
Nan Zhang1598a9e2018-09-04 17:14:32 -07001197 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001198 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001199
1200 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001201
1202 jdiffDocZip android.WritablePath
1203 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001204}
1205
Colin Crossa3002fc2019-07-08 16:48:04 -07001206// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1207// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1208// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001209func DroidstubsFactory() android.Module {
1210 module := &Droidstubs{}
1211
1212 module.AddProperties(&module.properties,
1213 &module.Javadoc.properties)
1214
1215 InitDroiddocModule(module, android.HostAndDeviceSupported)
1216 return module
1217}
1218
Colin Crossa3002fc2019-07-08 16:48:04 -07001219// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1220// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1221// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1222// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001223func DroidstubsHostFactory() android.Module {
1224 module := &Droidstubs{}
1225
1226 module.AddProperties(&module.properties,
1227 &module.Javadoc.properties)
1228
1229 InitDroiddocModule(module, android.HostSupported)
1230 return module
1231}
1232
1233func (d *Droidstubs) ApiFilePath() android.Path {
1234 return d.apiFilePath
1235}
1236
1237func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1238 d.Javadoc.addDeps(ctx)
1239
Inseob Kim38449af2019-02-28 14:24:05 +09001240 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1241 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1242 }
1243
Nan Zhang1598a9e2018-09-04 17:14:32 -07001244 if len(d.properties.Merge_annotations_dirs) != 0 {
1245 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1246 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1247 }
1248 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001249
Pete Gillin77167902018-09-19 18:16:26 +01001250 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1251 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1252 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1253 }
1254 }
1255
Nan Zhang9c69a122018-08-22 10:22:08 -07001256 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1257 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1258 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1259 }
1260 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261}
1262
Colin Cross33961b52019-07-11 11:01:22 -07001263func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1265 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1266 String(d.properties.Api_filename) != "" {
1267 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001268 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001269 d.apiFilePath = d.apiFile
1270 }
1271
1272 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1273 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1274 String(d.properties.Removed_api_filename) != "" {
1275 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001277 }
1278
1279 if String(d.properties.Private_api_filename) != "" {
1280 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001281 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001282 }
1283
1284 if String(d.properties.Dex_api_filename) != "" {
1285 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001286 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287 }
1288
1289 if String(d.properties.Private_dex_api_filename) != "" {
1290 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001291 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 }
1293
1294 if String(d.properties.Removed_dex_api_filename) != "" {
1295 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001296 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001297 }
1298
1299 if String(d.properties.Exact_api_filename) != "" {
1300 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001301 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001302 }
1303
Nan Zhang9c69a122018-08-22 10:22:08 -07001304 if String(d.properties.Dex_mapping_filename) != "" {
1305 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001306 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001307 }
1308
Nan Zhang199645c2018-09-19 12:40:06 -07001309 if String(d.properties.Proguard_filename) != "" {
1310 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001311 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001312 }
1313
Nan Zhang9c69a122018-08-22 10:22:08 -07001314 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001316 }
1317
Nan Zhang1598a9e2018-09-04 17:14:32 -07001318 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001320 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001321 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001322 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001323}
1324
Colin Cross33961b52019-07-11 11:01:22 -07001325func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001326 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.Flag("--include-annotations")
1328
Pete Gillinc382a562018-11-14 18:45:46 +00001329 validatingNullability :=
1330 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1331 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001332 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001333
Pete Gillina262c052018-09-14 14:25:48 +01001334 if !(migratingNullability || validatingNullability) {
1335 ctx.PropertyErrorf("previous_api",
1336 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001337 }
Colin Cross33961b52019-07-11 11:01:22 -07001338
Pete Gillina262c052018-09-14 14:25:48 +01001339 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001340 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001341 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001342 }
Colin Cross33961b52019-07-11 11:01:22 -07001343
Pete Gillinc382a562018-11-14 18:45:46 +00001344 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001345 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001346 }
Colin Cross33961b52019-07-11 11:01:22 -07001347
Pete Gillina262c052018-09-14 14:25:48 +01001348 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001349 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001350 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001351 }
Nan Zhanga40da042018-08-01 12:48:00 -07001352
1353 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001354 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001355
Nan Zhang1598a9e2018-09-04 17:14:32 -07001356 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001357 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001358 "has to be non-empty if annotations was enabled!")
1359 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001360
Colin Cross33961b52019-07-11 11:01:22 -07001361 d.mergeAnnoDirFlags(ctx, cmd)
1362
1363 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1364 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1365 FlagWithArg("--hide ", "SuperfluousPrefix").
1366 FlagWithArg("--hide ", "AnnotationExtraction")
1367 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001368}
1369
Colin Cross33961b52019-07-11 11:01:22 -07001370func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1371 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1372 if t, ok := m.(*ExportedDroiddocDir); ok {
1373 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1374 } else {
1375 ctx.PropertyErrorf("merge_annotations_dirs",
1376 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1377 }
1378 })
1379}
1380
1381func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001382 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1383 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001384 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001385 } else {
1386 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1387 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1388 }
1389 })
Nan Zhanga40da042018-08-01 12:48:00 -07001390}
1391
Colin Cross33961b52019-07-11 11:01:22 -07001392func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001393 if Bool(d.properties.Api_levels_annotations_enabled) {
1394 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001395
1396 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1397 ctx.PropertyErrorf("api_levels_annotations_dirs",
1398 "has to be non-empty if api levels annotations was enabled!")
1399 }
1400
Colin Cross33961b52019-07-11 11:01:22 -07001401 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1402 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1403 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1404 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001405
1406 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1407 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001408 for _, dep := range t.deps {
1409 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001410 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001411 }
1412 }
Colin Cross33961b52019-07-11 11:01:22 -07001413 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001414 } else {
1415 ctx.PropertyErrorf("api_levels_annotations_dirs",
1416 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1417 }
1418 })
1419
1420 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001421}
1422
Colin Cross33961b52019-07-11 11:01:22 -07001423func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001424 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1425 if d.apiFile.String() == "" {
1426 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1427 }
1428
1429 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001430 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001431
1432 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1433 ctx.PropertyErrorf("check_api.last_released.api_file",
1434 "has to be non-empty if jdiff was enabled!")
1435 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001436
Colin Cross33961b52019-07-11 11:01:22 -07001437 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001438 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001439 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1440 }
1441}
Nan Zhang71bbe632018-09-17 14:32:21 -07001442
Colin Cross33961b52019-07-11 11:01:22 -07001443func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1444 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1445 cmd := rule.Command().BuiltTool(ctx, "metalava").
1446 Flag(config.JavacVmFlags).
1447 FlagWithArg("-encoding ", "UTF-8").
1448 FlagWithArg("-source ", javaVersion).
1449 FlagWithRspFileInputList("@", srcs).
1450 FlagWithInput("@", srcJarList)
1451
1452 if len(bootclasspath) > 0 {
1453 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001454 }
1455
Colin Cross33961b52019-07-11 11:01:22 -07001456 if len(classpath) > 0 {
1457 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1458 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 if len(sourcepaths) > 0 {
1461 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1462 } else {
1463 cmd.FlagWithArg("-sourcepath ", `""`)
1464 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001465
Colin Cross33961b52019-07-11 11:01:22 -07001466 cmd.Flag("--no-banner").
1467 Flag("--color").
1468 Flag("--quiet").
1469 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001470
Colin Cross33961b52019-07-11 11:01:22 -07001471 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001472}
1473
Nan Zhang1598a9e2018-09-04 17:14:32 -07001474func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001475 deps := d.Javadoc.collectDeps(ctx)
1476
1477 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001478
Colin Cross33961b52019-07-11 11:01:22 -07001479 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001480
Colin Cross33961b52019-07-11 11:01:22 -07001481 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1482 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhanga40da042018-08-01 12:48:00 -07001483
Colin Cross33961b52019-07-11 11:01:22 -07001484 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001485
Colin Cross33961b52019-07-11 11:01:22 -07001486 rule.Command().Text("rm -rf").Text(stubsDir.String())
1487 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001488
Colin Cross33961b52019-07-11 11:01:22 -07001489 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1490
1491 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1492 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1493
1494 d.stubsFlags(ctx, cmd, stubsDir)
1495
1496 d.annotationsFlags(ctx, cmd)
1497 d.inclusionAnnotationsFlags(ctx, cmd)
1498 d.apiLevelsAnnotationsFlags(ctx, cmd)
1499 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001500
Nan Zhang1598a9e2018-09-04 17:14:32 -07001501 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1502 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1503 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1504 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1505 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001506 }
Colin Cross33961b52019-07-11 11:01:22 -07001507
1508 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1509 for _, o := range d.Javadoc.properties.Out {
1510 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1511 }
1512
1513 rule.Command().
1514 BuiltTool(ctx, "soong_zip").
1515 Flag("-write_if_changed").
1516 Flag("-jar").
1517 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1518 FlagWithArg("-C ", stubsDir.String()).
1519 FlagWithArg("-D ", stubsDir.String())
1520 rule.Restat()
1521
1522 zipSyncCleanupCmd(rule, srcJarDir)
1523
1524 rule.Build(pctx, ctx, "metalava", "metalava")
1525
1526 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001527
Nan Zhang1598a9e2018-09-04 17:14:32 -07001528 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1529 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001530
1531 if len(d.Javadoc.properties.Out) > 0 {
1532 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1533 }
1534
1535 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1536 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001537
Nan Zhang2760dfc2018-08-24 17:32:54 +00001538 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001539
Colin Cross33961b52019-07-11 11:01:22 -07001540 rule := android.NewRuleBuilder()
1541
1542 rule.Command().Text("( true")
1543
1544 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1545 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1546
1547 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1548 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1549
1550 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1551 FlagWithInput("--check-compatibility:api:current ", apiFile).
1552 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1553
1554 d.inclusionAnnotationsFlags(ctx, cmd)
1555 d.mergeAnnoDirFlags(ctx, cmd)
1556
1557 zipSyncCleanupCmd(rule, srcJarDir)
1558
1559 msg := fmt.Sprintf(`\n******************************\n`+
1560 `You have tried to change the API from what has been previously approved.\n\n`+
1561 `To make these errors go away, you have two choices:\n`+
1562 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1563 ` errors above.\n\n`+
1564 ` 2. You can update current.txt by executing the following command:\n`+
1565 ` make %s-update-current-api\n\n`+
1566 ` To submit the revised current.txt to the main Android repository,\n`+
1567 ` you will need approval.\n`+
1568 `******************************\n`, ctx.ModuleName())
1569
1570 rule.Command().
1571 Text("touch").Output(d.checkCurrentApiTimestamp).
1572 Text(") || (").
1573 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1574 Text("; exit 38").
1575 Text(")")
1576
1577 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001578
1579 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001580
1581 // update API rule
1582 rule = android.NewRuleBuilder()
1583
1584 rule.Command().Text("( true")
1585
1586 rule.Command().
1587 Text("cp").Flag("-f").
1588 Input(d.apiFile).Flag(apiFile.String())
1589
1590 rule.Command().
1591 Text("cp").Flag("-f").
1592 Input(d.removedApiFile).Flag(removedApiFile.String())
1593
1594 msg = "failed to update public API"
1595
1596 rule.Command().
1597 Text("touch").Output(d.updateCurrentApiTimestamp).
1598 Text(") || (").
1599 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1600 Text("; exit 38").
1601 Text(")")
1602
1603 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001604 }
Nan Zhanga40da042018-08-01 12:48:00 -07001605
Nan Zhang1598a9e2018-09-04 17:14:32 -07001606 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1607 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001608
1609 if len(d.Javadoc.properties.Out) > 0 {
1610 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1611 }
1612
1613 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1614 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001615
Nan Zhang2760dfc2018-08-24 17:32:54 +00001616 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001617
Colin Cross33961b52019-07-11 11:01:22 -07001618 rule := android.NewRuleBuilder()
1619
1620 rule.Command().Text("( true")
1621
1622 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1623 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1624
1625 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1626 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1627
1628 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1629 FlagWithInput("--check-compatibility:api:released ", apiFile)
1630
1631 d.inclusionAnnotationsFlags(ctx, cmd)
1632
1633 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1634
1635 d.mergeAnnoDirFlags(ctx, cmd)
1636
1637 zipSyncCleanupCmd(rule, srcJarDir)
1638
1639 msg := `\n******************************\n` +
1640 `You have tried to change the API from what has been previously released in\n` +
1641 `an SDK. Please fix the errors listed above.\n` +
1642 `******************************\n`
1643 rule.Command().
1644 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1645 Text(") || (").
1646 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1647 Text("; exit 38").
1648 Text(")")
1649
1650 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001651 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001652
Pete Gillin581d6082018-10-22 15:55:04 +01001653 if String(d.properties.Check_nullability_warnings) != "" {
1654 if d.nullabilityWarningsFile == nil {
1655 ctx.PropertyErrorf("check_nullability_warnings",
1656 "Cannot specify check_nullability_warnings unless validating nullability")
1657 }
Colin Cross33961b52019-07-11 11:01:22 -07001658
1659 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1660
Pete Gillin581d6082018-10-22 15:55:04 +01001661 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001662
Pete Gillin581d6082018-10-22 15:55:04 +01001663 msg := fmt.Sprintf(`\n******************************\n`+
1664 `The warnings encountered during nullability annotation validation did\n`+
1665 `not match the checked in file of expected warnings. The diffs are shown\n`+
1666 `above. You have two options:\n`+
1667 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1668 ` 2. Update the file of expected warnings by running:\n`+
1669 ` cp %s %s\n`+
1670 ` and submitting the updated file as part of your change.`,
1671 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001672
1673 rule := android.NewRuleBuilder()
1674
1675 rule.Command().
1676 Text("(").
1677 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1678 Text("&&").
1679 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1680 Text(") || (").
1681 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1682 Text("; exit 38").
1683 Text(")")
1684
1685 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001686 }
1687
Nan Zhang71bbe632018-09-17 14:32:21 -07001688 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001689 if len(d.Javadoc.properties.Out) > 0 {
1690 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1691 }
1692
1693 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1694 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1695 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1696
1697 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001698
Nan Zhang86b06202018-09-21 17:09:21 -07001699 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1700 // since there's cron job downstream that fetch this .zip file periodically.
1701 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001702 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1703 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1704
Nan Zhang71bbe632018-09-17 14:32:21 -07001705 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001706
Colin Cross33961b52019-07-11 11:01:22 -07001707 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1708 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001709
Colin Cross33961b52019-07-11 11:01:22 -07001710 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1711
1712 cmd := rule.Command().
1713 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
1714 FlagWithArg("-encoding ", "UTF-8").
1715 FlagWithRspFileInputList("@", d.Javadoc.srcFiles).
1716 FlagWithInput("@", srcJarList).
1717 FlagWithArg("-source ", "1.8").
1718 Flag("-J-Xmx1600m").
1719 Flag("-XDignore.symbol.file").
1720 FlagWithArg("-doclet ", "jdiff.JDiff").
1721 FlagWithInput("-docletpath ", jdiff).
1722 Flag("-quiet").
1723 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1724 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1725 Implicit(d.apiXmlFile).
1726 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1727 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1728 Implicit(d.lastReleasedApiXmlFile)
1729
1730 if len(deps.bootClasspath) > 0 {
1731 cmd.FlagWithInputList("-bootclasspath ", deps.bootClasspath.Paths(), ":")
1732 }
1733
1734 if len(deps.classpath) > 0 {
1735 cmd.FlagWithInputList("-classpath ", deps.classpath.Paths(), ":")
1736 }
1737
1738 cmd.FlagWithArg("-d ", outDir.String()).
1739 Flag("-quiet")
1740
1741 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
1742 // based stubs generation.
1743 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
1744 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
1745 // the correct package name base path.
1746 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
1747 cmd.FlagWithList("-sourcepath ", d.Javadoc.sourcepaths.Strings(), ":")
1748 } else {
1749 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
1750 }
1751
1752 rule.Command().
1753 BuiltTool(ctx, "soong_zip").
1754 Flag("-write_if_changed").
1755 Flag("-d").
1756 FlagWithOutput("-o ", d.jdiffDocZip).
1757 FlagWithArg("-C ", outDir.String()).
1758 FlagWithArg("-D ", outDir.String())
1759
1760 rule.Command().
1761 BuiltTool(ctx, "soong_zip").
1762 Flag("-write_if_changed").
1763 Flag("-jar").
1764 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1765 FlagWithArg("-C ", stubsDir.String()).
1766 FlagWithArg("-D ", stubsDir.String())
1767
1768 rule.Restat()
1769
1770 zipSyncCleanupCmd(rule, srcJarDir)
1771
1772 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001773 }
Nan Zhang581fd212018-01-10 16:06:12 -08001774}
Dan Willemsencc090972018-02-26 14:33:31 -08001775
Nan Zhanga40da042018-08-01 12:48:00 -07001776//
Nan Zhangf4936b02018-08-01 15:00:28 -07001777// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001778//
Dan Willemsencc090972018-02-26 14:33:31 -08001779var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001780var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001781var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001782var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001783
Nan Zhangf4936b02018-08-01 15:00:28 -07001784type ExportedDroiddocDirProperties struct {
1785 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001786 Path *string
1787}
1788
Nan Zhangf4936b02018-08-01 15:00:28 -07001789type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001790 android.ModuleBase
1791
Nan Zhangf4936b02018-08-01 15:00:28 -07001792 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001793
1794 deps android.Paths
1795 dir android.Path
1796}
1797
Colin Crossa3002fc2019-07-08 16:48:04 -07001798// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001799func ExportedDroiddocDirFactory() android.Module {
1800 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001801 module.AddProperties(&module.properties)
1802 android.InitAndroidModule(module)
1803 return module
1804}
1805
Nan Zhangf4936b02018-08-01 15:00:28 -07001806func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001807
Nan Zhangf4936b02018-08-01 15:00:28 -07001808func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001809 path := String(d.properties.Path)
1810 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001811 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001812}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001813
1814//
1815// Defaults
1816//
1817type DocDefaults struct {
1818 android.ModuleBase
1819 android.DefaultsModuleBase
1820}
1821
Nan Zhangb2b33de2018-02-23 11:18:47 -08001822func DocDefaultsFactory() android.Module {
1823 module := &DocDefaults{}
1824
1825 module.AddProperties(
1826 &JavadocProperties{},
1827 &DroiddocProperties{},
1828 )
1829
1830 android.InitDefaultsModule(module)
1831
1832 return module
1833}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001834
1835func StubsDefaultsFactory() android.Module {
1836 module := &DocDefaults{}
1837
1838 module.AddProperties(
1839 &JavadocProperties{},
1840 &DroidstubsProperties{},
1841 )
1842
1843 android.InitDefaultsModule(module)
1844
1845 return module
1846}
Colin Cross33961b52019-07-11 11:01:22 -07001847
1848func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1849 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1850
1851 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1852 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1853 srcJarList := srcJarDir.Join(ctx, "list")
1854
1855 rule.Temporary(srcJarList)
1856
1857 rule.Command().BuiltTool(ctx, "zipsync").
1858 FlagWithArg("-d ", srcJarDir.String()).
1859 FlagWithOutput("-l ", srcJarList).
1860 FlagWithArg("-f ", `"*.java"`).
1861 Inputs(srcJars)
1862
1863 return srcJarList
1864}
1865
1866func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1867 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1868}