blob: 59aef12d1ea54166026d039c37c0f9e8b021dc37 [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 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000639 deps.systemModules = sm.outputDir
640 deps.systemModulesDeps = sm.outputDeps
Nan Zhang581fd212018-01-10 16:06:12 -0800641 }
642 })
643 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
644 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800645 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700646 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900647 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800648
649 // srcs may depend on some genrule output.
650 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800651 j.srcJars = append(j.srcJars, deps.srcJars...)
652
Nan Zhang581fd212018-01-10 16:06:12 -0800653 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800654 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800655
656 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800657 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800658
Nan Zhang9c69a122018-08-22 10:22:08 -0700659 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800660 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
661 }
662 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800663
Colin Cross8a497952019-03-05 22:25:09 -0800664 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000665 argFilesMap := map[string]string{}
666 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700667
Paul Duffin99e4a502019-02-11 15:38:42 +0000668 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800669 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000670 if _, exists := argFilesMap[label]; !exists {
671 argFilesMap[label] = strings.Join(paths.Strings(), " ")
672 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700673 } else {
674 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000675 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700676 }
677 }
678
679 var err error
Colin Cross15638152019-07-11 11:11:35 -0700680 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700681 if strings.HasPrefix(name, "location ") {
682 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000683 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700684 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700685 } else {
Colin Cross15638152019-07-11 11:11:35 -0700686 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000687 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700688 }
689 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700690 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700691 }
Colin Cross15638152019-07-11 11:11:35 -0700692 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700693 })
694
695 if err != nil {
696 ctx.PropertyErrorf("args", "%s", err.Error())
697 }
698
Nan Zhang581fd212018-01-10 16:06:12 -0800699 return deps
700}
701
702func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
703 j.addDeps(ctx)
704}
705
706func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
707 deps := j.collectDeps(ctx)
708
709 var implicits android.Paths
710 implicits = append(implicits, deps.bootClasspath...)
711 implicits = append(implicits, deps.classpath...)
712
Nan Zhang1598a9e2018-09-04 17:14:32 -0700713 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700714
Colin Cross83bb3162018-06-25 15:48:06 -0700715 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700716 if len(deps.bootClasspath) > 0 {
717 var systemModules classpath
718 if deps.systemModules != nil {
719 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800720 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000721 implicits = append(implicits, deps.systemModulesDeps...)
Colin Cross997262f2018-06-19 22:49:39 -0700722 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
723 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800724 }
725 if len(deps.classpath.Strings()) > 0 {
726 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
727 }
728
729 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700730 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800731
Nan Zhangaf322cc2018-06-19 15:15:38 -0700732 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800733
Nan Zhang1598a9e2018-09-04 17:14:32 -0700734 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
735
Nan Zhang581fd212018-01-10 16:06:12 -0800736 ctx.Build(pctx, android.BuildParams{
737 Rule: javadoc,
738 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800739 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800740 ImplicitOutput: j.docZip,
741 Inputs: j.srcFiles,
742 Implicits: implicits,
743 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700744 "outDir": android.PathForModuleOut(ctx, "out").String(),
745 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
746 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800747 "srcJars": strings.Join(j.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -0700748 "opts": proptools.NinjaEscape(opts),
Nan Zhang853f4202018-04-12 16:55:56 -0700749 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800750 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700751 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800752 "docZip": j.docZip.String(),
753 },
754 })
755}
756
Nan Zhanga40da042018-08-01 12:48:00 -0700757//
758// Droiddoc
759//
760type Droiddoc struct {
761 Javadoc
762
763 properties DroiddocProperties
764 apiFile android.WritablePath
765 dexApiFile android.WritablePath
766 privateApiFile android.WritablePath
767 privateDexApiFile android.WritablePath
768 removedApiFile android.WritablePath
769 removedDexApiFile android.WritablePath
770 exactApiFile android.WritablePath
771 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700772 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700773
774 checkCurrentApiTimestamp android.WritablePath
775 updateCurrentApiTimestamp android.WritablePath
776 checkLastReleasedApiTimestamp android.WritablePath
777
Nan Zhanga40da042018-08-01 12:48:00 -0700778 apiFilePath android.Path
779}
780
Colin Crossa3002fc2019-07-08 16:48:04 -0700781// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700782func DroiddocFactory() android.Module {
783 module := &Droiddoc{}
784
785 module.AddProperties(&module.properties,
786 &module.Javadoc.properties)
787
788 InitDroiddocModule(module, android.HostAndDeviceSupported)
789 return module
790}
791
Colin Crossa3002fc2019-07-08 16:48:04 -0700792// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700793func DroiddocHostFactory() android.Module {
794 module := &Droiddoc{}
795
796 module.AddProperties(&module.properties,
797 &module.Javadoc.properties)
798
799 InitDroiddocModule(module, android.HostSupported)
800 return module
801}
802
803func (d *Droiddoc) ApiFilePath() android.Path {
804 return d.apiFilePath
805}
806
Nan Zhang581fd212018-01-10 16:06:12 -0800807func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
808 d.Javadoc.addDeps(ctx)
809
Inseob Kim38449af2019-02-28 14:24:05 +0900810 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
811 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
812 }
813
Nan Zhang79614d12018-04-19 18:03:39 -0700814 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800815 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
816 }
Nan Zhang581fd212018-01-10 16:06:12 -0800817}
818
Nan Zhang66dc2362018-08-14 20:41:04 -0700819func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
820 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700821 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800822
Nan Zhanga40da042018-08-01 12:48:00 -0700823 *implicits = append(*implicits, deps.bootClasspath...)
824 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800825
Nan Zhangc94f9d82018-06-26 10:02:26 -0700826 if len(deps.bootClasspath.Strings()) > 0 {
827 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700828 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700829 }
Nan Zhanga40da042018-08-01 12:48:00 -0700830 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700831 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700832 dokkaClasspath := classpath{}
833 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
834 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
835 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700836
Nan Zhang9c69a122018-08-22 10:22:08 -0700837 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
838 // based stubs generation.
839 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
840 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
841 // the correct package name base path.
842 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
843 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
844 } else {
845 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
846 }
Nan Zhang581fd212018-01-10 16:06:12 -0800847
Nan Zhanga40da042018-08-01 12:48:00 -0700848 return flags, nil
849}
Nan Zhang581fd212018-01-10 16:06:12 -0800850
Nan Zhanga40da042018-08-01 12:48:00 -0700851func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700852 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800853
Nan Zhanga40da042018-08-01 12:48:00 -0700854 *implicits = append(*implicits, jsilver)
855 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700856
Nan Zhang46130972018-06-04 11:28:01 -0700857 var date string
858 if runtime.GOOS == "darwin" {
859 date = `date -r`
860 } else {
861 date = `date -d`
862 }
863
Nan Zhang443fa522018-08-20 20:58:28 -0700864 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
865 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
866 // 1.9 language features.
867 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700868 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross15638152019-07-11 11:11:35 -0700869 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
870 `-hdf page.now "$(` + date + ` @$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700871
Nan Zhanga40da042018-08-01 12:48:00 -0700872 if String(d.properties.Custom_template) == "" {
873 // TODO: This is almost always droiddoc-templates-sdk
874 ctx.PropertyErrorf("custom_template", "must specify a template")
875 }
876
877 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700878 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700879 *implicits = append(*implicits, t.deps...)
880 args = args + " -templatedir " + t.dir.String()
881 } else {
882 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
883 }
884 })
885
886 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800887 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800888 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800889 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700890 }
891
892 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800893 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800894 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800895 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700896 }
897
898 if len(d.properties.Html_dirs) > 2 {
899 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
900 }
901
Colin Cross8a497952019-03-05 22:25:09 -0800902 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700903 *implicits = append(*implicits, knownTags...)
904
905 for _, kt := range knownTags {
906 args = args + " -knowntags " + kt.String()
907 }
908
909 for _, hdf := range d.properties.Hdf {
910 args = args + " -hdf " + hdf
911 }
912
913 if String(d.properties.Proofread_file) != "" {
914 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
915 args = args + " -proofread " + proofreadFile.String()
916 }
917
918 if String(d.properties.Todo_file) != "" {
919 // tricky part:
920 // we should not compute full path for todo_file through PathForModuleOut().
921 // the non-standard doclet will get the full path relative to "-o".
922 args = args + " -todo " + String(d.properties.Todo_file)
923 }
924
925 if String(d.properties.Resourcesdir) != "" {
926 // TODO: should we add files under resourcesDir to the implicits? It seems that
927 // resourcesDir is one sub dir of htmlDir
928 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
929 args = args + " -resourcesdir " + resourcesDir.String()
930 }
931
932 if String(d.properties.Resourcesoutdir) != "" {
933 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
934 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
935 }
936 return args
937}
938
Nan Zhang1598a9e2018-09-04 17:14:32 -0700939func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
940 implicitOutputs *android.WritablePaths) string {
941 var doclavaFlags string
942 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
943 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
944 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700945 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
946 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700947 *implicitOutputs = append(*implicitOutputs, d.apiFile)
948 d.apiFilePath = d.apiFile
949 }
950
Nan Zhang1598a9e2018-09-04 17:14:32 -0700951 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
952 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
953 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700954 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
955 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700956 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
957 }
958
959 if String(d.properties.Private_api_filename) != "" {
960 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
961 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700962 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
963 }
964
965 if String(d.properties.Dex_api_filename) != "" {
966 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
967 doclavaFlags += " -dexApi " + d.dexApiFile.String()
968 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
969 }
970
971 if String(d.properties.Private_dex_api_filename) != "" {
972 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
973 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700974 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
975 }
976
977 if String(d.properties.Removed_dex_api_filename) != "" {
978 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
979 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700980 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
981 }
982
983 if String(d.properties.Exact_api_filename) != "" {
984 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
985 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700986 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
987 }
988
989 if String(d.properties.Dex_mapping_filename) != "" {
990 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
991 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700992 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
993 }
994
Nan Zhang66dc2362018-08-14 20:41:04 -0700995 if String(d.properties.Proguard_filename) != "" {
996 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
997 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -0700998 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
999 }
1000
Nan Zhanga40da042018-08-01 12:48:00 -07001001 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001002 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001003 }
1004
1005 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001006 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001007 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001008
1009 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001010}
1011
1012func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1013 var cmds string
1014 if String(d.properties.Static_doc_index_redirect) != "" {
1015 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1016 "static_doc_index_redirect")
1017 *implicits = append(*implicits, static_doc_index_redirect)
1018 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001019 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001020 }
1021
1022 if String(d.properties.Static_doc_properties) != "" {
1023 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1024 "static_doc_properties")
1025 *implicits = append(*implicits, static_doc_properties)
1026 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001027 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001028 }
1029 return cmds
1030}
1031
Nan Zhang1598a9e2018-09-04 17:14:32 -07001032func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1033 implicitOutputs android.WritablePaths,
1034 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1035 ctx.Build(pctx, android.BuildParams{
1036 Rule: javadoc,
1037 Description: "Doclava",
1038 Output: d.Javadoc.stubsSrcJar,
1039 Inputs: d.Javadoc.srcFiles,
1040 Implicits: implicits,
1041 ImplicitOutputs: implicitOutputs,
1042 Args: map[string]string{
1043 "outDir": android.PathForModuleOut(ctx, "out").String(),
1044 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1045 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1046 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001047 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001048 "bootclasspathArgs": bootclasspathArgs,
1049 "classpathArgs": classpathArgs,
1050 "sourcepathArgs": sourcepathArgs,
1051 "docZip": d.Javadoc.docZip.String(),
1052 "postDoclavaCmds": postDoclavaCmds,
1053 },
1054 })
1055}
1056
1057func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1058 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1059 ctx.Build(pctx, android.BuildParams{
1060 Rule: apiCheck,
1061 Description: "Doclava Check API",
1062 Output: output,
1063 Inputs: nil,
1064 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1065 checkApiClasspath...),
1066 Args: map[string]string{
1067 "msg": msg,
1068 "classpath": checkApiClasspath.FormJavaClassPath(""),
Colin Cross15638152019-07-11 11:11:35 -07001069 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001070 "apiFile": apiFile.String(),
1071 "apiFileToCheck": d.apiFile.String(),
1072 "removedApiFile": removedApiFile.String(),
1073 "removedApiFileToCheck": d.removedApiFile.String(),
1074 },
1075 })
1076}
1077
1078func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1079 classpathArgs, opts string) {
1080 ctx.Build(pctx, android.BuildParams{
1081 Rule: dokka,
1082 Description: "Dokka",
1083 Output: d.Javadoc.stubsSrcJar,
1084 Inputs: d.Javadoc.srcFiles,
1085 Implicits: implicits,
1086 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001087 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1088 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1089 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001090 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1091 "classpathArgs": classpathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001092 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001093 "docZip": d.Javadoc.docZip.String(),
1094 },
1095 })
1096}
1097
1098func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1099 deps := d.Javadoc.collectDeps(ctx)
1100
1101 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1102 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1103 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1104 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1105
1106 var implicits android.Paths
1107 implicits = append(implicits, d.Javadoc.srcJars...)
1108 implicits = append(implicits, d.Javadoc.argFiles...)
1109
1110 var implicitOutputs android.WritablePaths
1111 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1112 for _, o := range d.Javadoc.properties.Out {
1113 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1114 }
1115
1116 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1117 if err != nil {
1118 return
1119 }
1120
1121 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1122 if Bool(d.properties.Dokka_enabled) {
1123 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1124 } else {
1125 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1126 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1127 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1128 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1129 flags.postDoclavaCmds)
1130 }
1131
1132 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1133 !ctx.Config().IsPdkBuild() {
1134 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1135 "check_api.current.api_file")
1136 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1137 "check_api.current_removed_api_file")
1138
1139 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1140 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1141 fmt.Sprintf(`\n******************************\n`+
1142 `You have tried to change the API from what has been previously approved.\n\n`+
1143 `To make these errors go away, you have two choices:\n`+
1144 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1145 ` errors above.\n\n`+
1146 ` 2. You can update current.txt by executing the following command:\n`+
1147 ` make %s-update-current-api\n\n`+
1148 ` To submit the revised current.txt to the main Android repository,\n`+
1149 ` you will need approval.\n`+
1150 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1151 d.checkCurrentApiTimestamp)
1152
1153 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1154 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1155 d.updateCurrentApiTimestamp)
1156 }
1157
1158 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1159 !ctx.Config().IsPdkBuild() {
1160 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1161 "check_api.last_released.api_file")
1162 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1163 "check_api.last_released.removed_api_file")
1164
1165 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1166 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1167 `\n******************************\n`+
1168 `You have tried to change the API from what has been previously released in\n`+
1169 `an SDK. Please fix the errors listed above.\n`+
1170 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1171 d.checkLastReleasedApiTimestamp)
1172 }
1173}
1174
1175//
1176// Droidstubs
1177//
1178type Droidstubs struct {
1179 Javadoc
1180
Pete Gillin581d6082018-10-22 15:55:04 +01001181 properties DroidstubsProperties
1182 apiFile android.WritablePath
1183 apiXmlFile android.WritablePath
1184 lastReleasedApiXmlFile android.WritablePath
1185 dexApiFile android.WritablePath
1186 privateApiFile android.WritablePath
1187 privateDexApiFile android.WritablePath
1188 removedApiFile android.WritablePath
1189 removedDexApiFile android.WritablePath
1190 apiMappingFile android.WritablePath
1191 exactApiFile android.WritablePath
1192 proguardFile android.WritablePath
1193 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001194
1195 checkCurrentApiTimestamp android.WritablePath
1196 updateCurrentApiTimestamp android.WritablePath
1197 checkLastReleasedApiTimestamp android.WritablePath
1198
Pete Gillin581d6082018-10-22 15:55:04 +01001199 checkNullabilityWarningsTimestamp android.WritablePath
1200
Nan Zhang1598a9e2018-09-04 17:14:32 -07001201 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001202 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001203
1204 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001205
1206 jdiffDocZip android.WritablePath
1207 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001208}
1209
Colin Crossa3002fc2019-07-08 16:48:04 -07001210// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1211// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1212// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001213func DroidstubsFactory() android.Module {
1214 module := &Droidstubs{}
1215
1216 module.AddProperties(&module.properties,
1217 &module.Javadoc.properties)
1218
1219 InitDroiddocModule(module, android.HostAndDeviceSupported)
1220 return module
1221}
1222
Colin Crossa3002fc2019-07-08 16:48:04 -07001223// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1224// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1225// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1226// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001227func DroidstubsHostFactory() android.Module {
1228 module := &Droidstubs{}
1229
1230 module.AddProperties(&module.properties,
1231 &module.Javadoc.properties)
1232
1233 InitDroiddocModule(module, android.HostSupported)
1234 return module
1235}
1236
1237func (d *Droidstubs) ApiFilePath() android.Path {
1238 return d.apiFilePath
1239}
1240
1241func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1242 d.Javadoc.addDeps(ctx)
1243
Inseob Kim38449af2019-02-28 14:24:05 +09001244 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1245 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1246 }
1247
Nan Zhang1598a9e2018-09-04 17:14:32 -07001248 if len(d.properties.Merge_annotations_dirs) != 0 {
1249 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1250 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1251 }
1252 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001253
Pete Gillin77167902018-09-19 18:16:26 +01001254 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1255 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1256 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1257 }
1258 }
1259
Nan Zhang9c69a122018-08-22 10:22:08 -07001260 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1261 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1262 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1263 }
1264 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265}
1266
Colin Cross33961b52019-07-11 11:01:22 -07001267func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001268 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1269 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1270 String(d.properties.Api_filename) != "" {
1271 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001272 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001273 d.apiFilePath = d.apiFile
1274 }
1275
1276 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1277 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1278 String(d.properties.Removed_api_filename) != "" {
1279 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001280 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001281 }
1282
1283 if String(d.properties.Private_api_filename) != "" {
1284 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001286 }
1287
1288 if String(d.properties.Dex_api_filename) != "" {
1289 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001290 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001291 }
1292
1293 if String(d.properties.Private_dex_api_filename) != "" {
1294 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001295 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296 }
1297
1298 if String(d.properties.Removed_dex_api_filename) != "" {
1299 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001300 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001301 }
1302
1303 if String(d.properties.Exact_api_filename) != "" {
1304 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001305 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001306 }
1307
Nan Zhang9c69a122018-08-22 10:22:08 -07001308 if String(d.properties.Dex_mapping_filename) != "" {
1309 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001310 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001311 }
1312
Nan Zhang199645c2018-09-19 12:40:06 -07001313 if String(d.properties.Proguard_filename) != "" {
1314 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001316 }
1317
Nan Zhang9c69a122018-08-22 10:22:08 -07001318 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001320 }
1321
Nan Zhang1598a9e2018-09-04 17:14:32 -07001322 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001323 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001324 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001325 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001326 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001327}
1328
Colin Cross33961b52019-07-11 11:01:22 -07001329func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001330 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001331 cmd.Flag("--include-annotations")
1332
Pete Gillinc382a562018-11-14 18:45:46 +00001333 validatingNullability :=
1334 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1335 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001336 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001337
Pete Gillina262c052018-09-14 14:25:48 +01001338 if !(migratingNullability || validatingNullability) {
1339 ctx.PropertyErrorf("previous_api",
1340 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001341 }
Colin Cross33961b52019-07-11 11:01:22 -07001342
Pete Gillina262c052018-09-14 14:25:48 +01001343 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001344 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001345 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001346 }
Colin Cross33961b52019-07-11 11:01:22 -07001347
Pete Gillinc382a562018-11-14 18:45:46 +00001348 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001349 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001350 }
Colin Cross33961b52019-07-11 11:01:22 -07001351
Pete Gillina262c052018-09-14 14:25:48 +01001352 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001353 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001354 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001355 }
Nan Zhanga40da042018-08-01 12:48:00 -07001356
1357 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001358 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001359
Nan Zhang1598a9e2018-09-04 17:14:32 -07001360 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001361 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001362 "has to be non-empty if annotations was enabled!")
1363 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001364
Colin Cross33961b52019-07-11 11:01:22 -07001365 d.mergeAnnoDirFlags(ctx, cmd)
1366
1367 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1368 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1369 FlagWithArg("--hide ", "SuperfluousPrefix").
1370 FlagWithArg("--hide ", "AnnotationExtraction")
1371 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001372}
1373
Colin Cross33961b52019-07-11 11:01:22 -07001374func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1375 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1376 if t, ok := m.(*ExportedDroiddocDir); ok {
1377 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1378 } else {
1379 ctx.PropertyErrorf("merge_annotations_dirs",
1380 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1381 }
1382 })
1383}
1384
1385func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001386 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1387 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001388 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001389 } else {
1390 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1391 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1392 }
1393 })
Nan Zhanga40da042018-08-01 12:48:00 -07001394}
1395
Colin Cross33961b52019-07-11 11:01:22 -07001396func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001397 if Bool(d.properties.Api_levels_annotations_enabled) {
1398 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001399
1400 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1401 ctx.PropertyErrorf("api_levels_annotations_dirs",
1402 "has to be non-empty if api levels annotations was enabled!")
1403 }
1404
Colin Cross33961b52019-07-11 11:01:22 -07001405 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1406 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1407 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1408 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001409
1410 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1411 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001412 for _, dep := range t.deps {
1413 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001414 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001415 }
1416 }
Colin Cross33961b52019-07-11 11:01:22 -07001417 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001418 } else {
1419 ctx.PropertyErrorf("api_levels_annotations_dirs",
1420 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1421 }
1422 })
1423
1424 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001425}
1426
Colin Cross33961b52019-07-11 11:01:22 -07001427func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001428 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1429 if d.apiFile.String() == "" {
1430 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1431 }
1432
1433 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001434 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001435
1436 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1437 ctx.PropertyErrorf("check_api.last_released.api_file",
1438 "has to be non-empty if jdiff was enabled!")
1439 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001440
Colin Cross33961b52019-07-11 11:01:22 -07001441 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001442 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001443 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1444 }
1445}
Nan Zhang71bbe632018-09-17 14:32:21 -07001446
Colin Cross33961b52019-07-11 11:01:22 -07001447func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1448 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1449 cmd := rule.Command().BuiltTool(ctx, "metalava").
1450 Flag(config.JavacVmFlags).
1451 FlagWithArg("-encoding ", "UTF-8").
1452 FlagWithArg("-source ", javaVersion).
1453 FlagWithRspFileInputList("@", srcs).
1454 FlagWithInput("@", srcJarList)
1455
1456 if len(bootclasspath) > 0 {
1457 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001458 }
1459
Colin Cross33961b52019-07-11 11:01:22 -07001460 if len(classpath) > 0 {
1461 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1462 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001463
Colin Cross33961b52019-07-11 11:01:22 -07001464 if len(sourcepaths) > 0 {
1465 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1466 } else {
1467 cmd.FlagWithArg("-sourcepath ", `""`)
1468 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001469
Colin Cross33961b52019-07-11 11:01:22 -07001470 cmd.Flag("--no-banner").
1471 Flag("--color").
1472 Flag("--quiet").
1473 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001474
Colin Cross33961b52019-07-11 11:01:22 -07001475 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001476}
1477
Nan Zhang1598a9e2018-09-04 17:14:32 -07001478func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001479 deps := d.Javadoc.collectDeps(ctx)
1480
1481 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001482
Colin Cross33961b52019-07-11 11:01:22 -07001483 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001484
Colin Cross33961b52019-07-11 11:01:22 -07001485 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1486 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhanga40da042018-08-01 12:48:00 -07001487
Colin Cross33961b52019-07-11 11:01:22 -07001488 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001489
Colin Cross33961b52019-07-11 11:01:22 -07001490 rule.Command().Text("rm -rf").Text(stubsDir.String())
1491 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001492
Colin Cross33961b52019-07-11 11:01:22 -07001493 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1494
1495 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1496 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1497
1498 d.stubsFlags(ctx, cmd, stubsDir)
1499
1500 d.annotationsFlags(ctx, cmd)
1501 d.inclusionAnnotationsFlags(ctx, cmd)
1502 d.apiLevelsAnnotationsFlags(ctx, cmd)
1503 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001504
Nan Zhang1598a9e2018-09-04 17:14:32 -07001505 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1506 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1507 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1508 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1509 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001510 }
Colin Cross33961b52019-07-11 11:01:22 -07001511
1512 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1513 for _, o := range d.Javadoc.properties.Out {
1514 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1515 }
1516
1517 rule.Command().
1518 BuiltTool(ctx, "soong_zip").
1519 Flag("-write_if_changed").
1520 Flag("-jar").
1521 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1522 FlagWithArg("-C ", stubsDir.String()).
1523 FlagWithArg("-D ", stubsDir.String())
1524 rule.Restat()
1525
1526 zipSyncCleanupCmd(rule, srcJarDir)
1527
1528 rule.Build(pctx, ctx, "metalava", "metalava")
1529
1530 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001531
Nan Zhang1598a9e2018-09-04 17:14:32 -07001532 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1533 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001534
1535 if len(d.Javadoc.properties.Out) > 0 {
1536 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1537 }
1538
1539 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1540 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001541
Nan Zhang2760dfc2018-08-24 17:32:54 +00001542 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001543
Colin Cross33961b52019-07-11 11:01:22 -07001544 rule := android.NewRuleBuilder()
1545
1546 rule.Command().Text("( true")
1547
1548 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1549 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1550
1551 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1552 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1553
1554 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1555 FlagWithInput("--check-compatibility:api:current ", apiFile).
1556 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1557
1558 d.inclusionAnnotationsFlags(ctx, cmd)
1559 d.mergeAnnoDirFlags(ctx, cmd)
1560
1561 zipSyncCleanupCmd(rule, srcJarDir)
1562
1563 msg := fmt.Sprintf(`\n******************************\n`+
1564 `You have tried to change the API from what has been previously approved.\n\n`+
1565 `To make these errors go away, you have two choices:\n`+
1566 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1567 ` errors above.\n\n`+
1568 ` 2. You can update current.txt by executing the following command:\n`+
1569 ` make %s-update-current-api\n\n`+
1570 ` To submit the revised current.txt to the main Android repository,\n`+
1571 ` you will need approval.\n`+
1572 `******************************\n`, ctx.ModuleName())
1573
1574 rule.Command().
1575 Text("touch").Output(d.checkCurrentApiTimestamp).
1576 Text(") || (").
1577 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1578 Text("; exit 38").
1579 Text(")")
1580
1581 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001582
1583 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001584
1585 // update API rule
1586 rule = android.NewRuleBuilder()
1587
1588 rule.Command().Text("( true")
1589
1590 rule.Command().
1591 Text("cp").Flag("-f").
1592 Input(d.apiFile).Flag(apiFile.String())
1593
1594 rule.Command().
1595 Text("cp").Flag("-f").
1596 Input(d.removedApiFile).Flag(removedApiFile.String())
1597
1598 msg = "failed to update public API"
1599
1600 rule.Command().
1601 Text("touch").Output(d.updateCurrentApiTimestamp).
1602 Text(") || (").
1603 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1604 Text("; exit 38").
1605 Text(")")
1606
1607 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001608 }
Nan Zhanga40da042018-08-01 12:48:00 -07001609
Nan Zhang1598a9e2018-09-04 17:14:32 -07001610 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1611 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001612
1613 if len(d.Javadoc.properties.Out) > 0 {
1614 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1615 }
1616
1617 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1618 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001619
Nan Zhang2760dfc2018-08-24 17:32:54 +00001620 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001621
Colin Cross33961b52019-07-11 11:01:22 -07001622 rule := android.NewRuleBuilder()
1623
1624 rule.Command().Text("( true")
1625
1626 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1627 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1628
1629 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1630 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1631
1632 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1633 FlagWithInput("--check-compatibility:api:released ", apiFile)
1634
1635 d.inclusionAnnotationsFlags(ctx, cmd)
1636
1637 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1638
1639 d.mergeAnnoDirFlags(ctx, cmd)
1640
1641 zipSyncCleanupCmd(rule, srcJarDir)
1642
1643 msg := `\n******************************\n` +
1644 `You have tried to change the API from what has been previously released in\n` +
1645 `an SDK. Please fix the errors listed above.\n` +
1646 `******************************\n`
1647 rule.Command().
1648 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1649 Text(") || (").
1650 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1651 Text("; exit 38").
1652 Text(")")
1653
1654 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001655 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001656
Pete Gillin581d6082018-10-22 15:55:04 +01001657 if String(d.properties.Check_nullability_warnings) != "" {
1658 if d.nullabilityWarningsFile == nil {
1659 ctx.PropertyErrorf("check_nullability_warnings",
1660 "Cannot specify check_nullability_warnings unless validating nullability")
1661 }
Colin Cross33961b52019-07-11 11:01:22 -07001662
1663 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1664
Pete Gillin581d6082018-10-22 15:55:04 +01001665 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001666
Pete Gillin581d6082018-10-22 15:55:04 +01001667 msg := fmt.Sprintf(`\n******************************\n`+
1668 `The warnings encountered during nullability annotation validation did\n`+
1669 `not match the checked in file of expected warnings. The diffs are shown\n`+
1670 `above. You have two options:\n`+
1671 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1672 ` 2. Update the file of expected warnings by running:\n`+
1673 ` cp %s %s\n`+
1674 ` and submitting the updated file as part of your change.`,
1675 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001676
1677 rule := android.NewRuleBuilder()
1678
1679 rule.Command().
1680 Text("(").
1681 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1682 Text("&&").
1683 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1684 Text(") || (").
1685 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1686 Text("; exit 38").
1687 Text(")")
1688
1689 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001690 }
1691
Nan Zhang71bbe632018-09-17 14:32:21 -07001692 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001693 if len(d.Javadoc.properties.Out) > 0 {
1694 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1695 }
1696
1697 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1698 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1699 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1700
1701 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001702
Nan Zhang86b06202018-09-21 17:09:21 -07001703 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1704 // since there's cron job downstream that fetch this .zip file periodically.
1705 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001706 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1707 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1708
Nan Zhang71bbe632018-09-17 14:32:21 -07001709 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001710
Colin Cross33961b52019-07-11 11:01:22 -07001711 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1712 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001713
Colin Cross33961b52019-07-11 11:01:22 -07001714 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1715
1716 cmd := rule.Command().
1717 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
1718 FlagWithArg("-encoding ", "UTF-8").
1719 FlagWithRspFileInputList("@", d.Javadoc.srcFiles).
1720 FlagWithInput("@", srcJarList).
1721 FlagWithArg("-source ", "1.8").
1722 Flag("-J-Xmx1600m").
1723 Flag("-XDignore.symbol.file").
1724 FlagWithArg("-doclet ", "jdiff.JDiff").
1725 FlagWithInput("-docletpath ", jdiff).
1726 Flag("-quiet").
1727 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1728 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1729 Implicit(d.apiXmlFile).
1730 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1731 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1732 Implicit(d.lastReleasedApiXmlFile)
1733
1734 if len(deps.bootClasspath) > 0 {
1735 cmd.FlagWithInputList("-bootclasspath ", deps.bootClasspath.Paths(), ":")
1736 }
1737
1738 if len(deps.classpath) > 0 {
1739 cmd.FlagWithInputList("-classpath ", deps.classpath.Paths(), ":")
1740 }
1741
1742 cmd.FlagWithArg("-d ", outDir.String()).
1743 Flag("-quiet")
1744
1745 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
1746 // based stubs generation.
1747 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
1748 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
1749 // the correct package name base path.
1750 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
1751 cmd.FlagWithList("-sourcepath ", d.Javadoc.sourcepaths.Strings(), ":")
1752 } else {
1753 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
1754 }
1755
1756 rule.Command().
1757 BuiltTool(ctx, "soong_zip").
1758 Flag("-write_if_changed").
1759 Flag("-d").
1760 FlagWithOutput("-o ", d.jdiffDocZip).
1761 FlagWithArg("-C ", outDir.String()).
1762 FlagWithArg("-D ", outDir.String())
1763
1764 rule.Command().
1765 BuiltTool(ctx, "soong_zip").
1766 Flag("-write_if_changed").
1767 Flag("-jar").
1768 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1769 FlagWithArg("-C ", stubsDir.String()).
1770 FlagWithArg("-D ", stubsDir.String())
1771
1772 rule.Restat()
1773
1774 zipSyncCleanupCmd(rule, srcJarDir)
1775
1776 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001777 }
Nan Zhang581fd212018-01-10 16:06:12 -08001778}
Dan Willemsencc090972018-02-26 14:33:31 -08001779
Nan Zhanga40da042018-08-01 12:48:00 -07001780//
Nan Zhangf4936b02018-08-01 15:00:28 -07001781// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001782//
Dan Willemsencc090972018-02-26 14:33:31 -08001783var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001784var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001785var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001786var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001787
Nan Zhangf4936b02018-08-01 15:00:28 -07001788type ExportedDroiddocDirProperties struct {
1789 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001790 Path *string
1791}
1792
Nan Zhangf4936b02018-08-01 15:00:28 -07001793type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001794 android.ModuleBase
1795
Nan Zhangf4936b02018-08-01 15:00:28 -07001796 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001797
1798 deps android.Paths
1799 dir android.Path
1800}
1801
Colin Crossa3002fc2019-07-08 16:48:04 -07001802// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001803func ExportedDroiddocDirFactory() android.Module {
1804 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001805 module.AddProperties(&module.properties)
1806 android.InitAndroidModule(module)
1807 return module
1808}
1809
Nan Zhangf4936b02018-08-01 15:00:28 -07001810func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001811
Nan Zhangf4936b02018-08-01 15:00:28 -07001812func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001813 path := String(d.properties.Path)
1814 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001815 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001816}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001817
1818//
1819// Defaults
1820//
1821type DocDefaults struct {
1822 android.ModuleBase
1823 android.DefaultsModuleBase
1824}
1825
Nan Zhangb2b33de2018-02-23 11:18:47 -08001826func DocDefaultsFactory() android.Module {
1827 module := &DocDefaults{}
1828
1829 module.AddProperties(
1830 &JavadocProperties{},
1831 &DroiddocProperties{},
1832 )
1833
1834 android.InitDefaultsModule(module)
1835
1836 return module
1837}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001838
1839func StubsDefaultsFactory() android.Module {
1840 module := &DocDefaults{}
1841
1842 module.AddProperties(
1843 &JavadocProperties{},
1844 &DroidstubsProperties{},
1845 )
1846
1847 android.InitDefaultsModule(module)
1848
1849 return module
1850}
Colin Cross33961b52019-07-11 11:01:22 -07001851
1852func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1853 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1854
1855 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1856 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1857 srcJarList := srcJarDir.Join(ctx, "list")
1858
1859 rule.Temporary(srcJarList)
1860
1861 rule.Command().BuiltTool(ctx, "zipsync").
1862 FlagWithArg("-d ", srcJarDir.String()).
1863 FlagWithOutput("-l ", srcJarList).
1864 FlagWithArg("-f ", `"*.java"`).
1865 Inputs(srcJars)
1866
1867 return srcJarList
1868}
1869
1870func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1871 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1872}