blob: 56f451ee73f03676363f5afedd237a5e1087f22b [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 (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang581fd212018-01-10 16:06:12 -080020 "strings"
21
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080029 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070030 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080031
Nan Zhang581fd212018-01-10 16:06:12 -080032 android.RegisterModuleType("droiddoc", DroiddocFactory)
33 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070034 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080035 android.RegisterModuleType("javadoc", JavadocFactory)
36 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070037
38 android.RegisterModuleType("droidstubs", DroidstubsFactory)
39 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080040}
41
Colin Crossa1ce2a02018-06-20 15:19:39 -070042var (
43 srcsLibTag = dependencyTag{name: "sources from javalib"}
44)
45
Nan Zhang581fd212018-01-10 16:06:12 -080046type JavadocProperties struct {
47 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
48 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080049 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080050
51 // list of directories rooted at the Android.bp file that will
52 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080053 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080054
55 // list of source files that should not be used to build the Java module.
56 // This is most useful in the arch/multilib variants to remove non-common files
57 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080058 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080059
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090060 // list of package names that should actually be used. If this property is left unspecified,
61 // all the sources from the srcs property is used.
62 Filter_packages []string
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080065 Libs []string `android:"arch_variant"`
66
67 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080068 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080069
Paul Duffine25c6442019-10-11 13:50:28 +010070 // if not blank, set to the version of the sdk to compile against.
71 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080072 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090073
Paul Duffine25c6442019-10-11 13:50:28 +010074 // When targeting 1.9 and above, override the modules to use with --system,
75 // otherwise provides defaults libraries to add to the bootclasspath.
76 // Defaults to "none"
77 System_modules *string
78
Jiyong Park1e440682018-05-23 18:42:04 +090079 Aidl struct {
80 // Top level directories to pass to aidl tool
81 Include_dirs []string
82
83 // Directories rooted at the Android.bp file to pass to aidl tool
84 Local_include_dirs []string
85 }
Nan Zhang357466b2018-04-17 17:38:36 -070086
87 // If not blank, set the java version passed to javadoc as -source
88 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080091 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070092
93 // user customized droiddoc args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070097 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070098 Args *string
99
100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // if set to true, collect the values used by the Dev tools and
146 // write them in files packaged with the SDK. Defaults to false.
147 Write_sdk_values *bool
148
149 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
152 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700154
Nan Zhang581fd212018-01-10 16:06:12 -0800155 // a list of files under current module source dir which contains known tags in Java sources.
156 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800157 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700158
159 // the tag name used to distinguish if the API files belong to public/system/test.
160 Api_tag_name *string
161
162 // the generated public API filename by Doclava.
163 Api_filename *string
164
David Brazdilfbe4cc32018-05-31 13:56:46 +0100165 // the generated public Dex API filename by Doclava.
166 Dex_api_filename *string
167
Nan Zhang28c68b92018-03-13 16:17:01 -0700168 // the generated private API filename by Doclava.
169 Private_api_filename *string
170
171 // the generated private Dex API filename by Doclava.
172 Private_dex_api_filename *string
173
174 // the generated removed API filename by Doclava.
175 Removed_api_filename *string
176
David Brazdilaac0c3c2018-04-24 16:23:29 +0100177 // the generated removed Dex API filename by Doclava.
178 Removed_dex_api_filename *string
179
Mathew Inwood76c3de12018-06-22 15:28:11 +0100180 // mapping of dex signatures to source file and line number. This is a temporary property and
181 // will be deleted; you probably shouldn't be using it.
182 Dex_mapping_filename *string
183
Nan Zhang28c68b92018-03-13 16:17:01 -0700184 // the generated exact API filename by Doclava.
185 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700186
Nan Zhang66dc2362018-08-14 20:41:04 -0700187 // the generated proguard filename by Doclava.
188 Proguard_filename *string
189
Nan Zhang853f4202018-04-12 16:55:56 -0700190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900197
198 // do not perform API check against Last_released, in the case that both two specified API
199 // files by Last_released are modules which don't exist.
200 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700201 }
Nan Zhang79614d12018-04-19 18:03:39 -0700202
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 // if set to true, generate docs through Dokka instead of Doclava.
204 Dokka_enabled *bool
205}
206
207type DroidstubsProperties struct {
208 // the tag name used to distinguish if the API files belong to public/system/test.
209 Api_tag_name *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Private_dex_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 Removed_dex_api_filename *string
228
Nan Zhang9c69a122018-08-22 10:22:08 -0700229 // mapping of dex signatures to source file and line number. This is a temporary property and
230 // will be deleted; you probably shouldn't be using it.
231 Dex_mapping_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700234 Exact_api_filename *string
235
Nan Zhang199645c2018-09-19 12:40:06 -0700236 // the generated proguard filename by Metalava.
237 Proguard_filename *string
238
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Check_api struct {
240 Last_released ApiToCheck
241
242 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900243
244 // do not perform API check against Last_released, in the case that both two specified API
245 // files by Last_released are modules which don't exist.
246 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200247
248 Api_lint struct {
249 Enabled *bool
250
251 // If set, performs api_lint on any new APIs not found in the given signature file
252 New_since *string `android:"path"`
253
254 // If not blank, path to the baseline txt file for approved API lint violations.
255 Baseline_file *string `android:"path"`
256 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700257 }
Nan Zhang79614d12018-04-19 18:03:39 -0700258
259 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800260 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700261
262 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700264
Pete Gillin77167902018-09-19 18:16:26 +0100265 // 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 -0700266 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700267
Pete Gillin77167902018-09-19 18:16:26 +0100268 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
269 Merge_inclusion_annotations_dirs []string
270
Pete Gillinc382a562018-11-14 18:45:46 +0000271 // a file containing a list of classes to do nullability validation for.
272 Validate_nullability_from_list *string
273
Pete Gillin581d6082018-10-22 15:55:04 +0100274 // a file containing expected warnings produced by validation of nullability annotations.
275 Check_nullability_warnings *string
276
Nan Zhang1598a9e2018-09-04 17:14:32 -0700277 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
278 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700279
280 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
281 Api_levels_annotations_enabled *bool
282
283 // the dirs which Metalava extracts API levels annotations from.
284 Api_levels_annotations_dirs []string
285
286 // if set to true, collect the values used by the Dev tools and
287 // write them in files packaged with the SDK. Defaults to false.
288 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700289
290 // If set to true, .xml based public API file will be also generated, and
291 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
292 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800293}
294
Nan Zhanga40da042018-08-01 12:48:00 -0700295//
296// Common flags passed down to build rule
297//
298type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700299 bootClasspathArgs string
300 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700301 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700302 dokkaClasspathArgs string
303 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700304 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700305
Nan Zhanga40da042018-08-01 12:48:00 -0700306 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700307 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700308 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700309}
310
311func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
312 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
313 android.InitDefaultableModule(module)
314}
315
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200316func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
317 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
318 return false
319 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700320 return true
321 } else if String(apiToCheck.Api_file) != "" {
322 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
323 } else if String(apiToCheck.Removed_api_file) != "" {
324 panic("for " + apiVersionTag + " api_file has to be non-empty!")
325 }
326
327 return false
328}
329
Inseob Kim38449af2019-02-28 14:24:05 +0900330func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
331 api_file := String(apiToCheck.Api_file)
332 removed_api_file := String(apiToCheck.Removed_api_file)
333
334 api_module := android.SrcIsModule(api_file)
335 removed_api_module := android.SrcIsModule(removed_api_file)
336
337 if api_module == "" || removed_api_module == "" {
338 return
339 }
340
341 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
342 return
343 }
344
345 apiToCheck.Api_file = nil
346 apiToCheck.Removed_api_file = nil
347}
348
Nan Zhang1598a9e2018-09-04 17:14:32 -0700349type ApiFilePath interface {
350 ApiFilePath() android.Path
351}
352
Nan Zhanga40da042018-08-01 12:48:00 -0700353//
354// Javadoc
355//
Nan Zhang581fd212018-01-10 16:06:12 -0800356type Javadoc struct {
357 android.ModuleBase
358 android.DefaultableModuleBase
359
360 properties JavadocProperties
361
362 srcJars android.Paths
363 srcFiles android.Paths
364 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700365 argFiles android.Paths
366
367 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800368
Nan Zhangccff0f72018-03-08 17:26:16 -0800369 docZip android.WritablePath
370 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800371}
372
Colin Cross41955e82019-05-29 14:40:35 -0700373func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
374 switch tag {
375 case "":
376 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700377 case ".docs.zip":
378 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700379 default:
380 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
381 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800382}
383
Colin Crossa3002fc2019-07-08 16:48:04 -0700384// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800385func JavadocFactory() android.Module {
386 module := &Javadoc{}
387
388 module.AddProperties(&module.properties)
389
390 InitDroiddocModule(module, android.HostAndDeviceSupported)
391 return module
392}
393
Colin Crossa3002fc2019-07-08 16:48:04 -0700394// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800395func JavadocHostFactory() android.Module {
396 module := &Javadoc{}
397
398 module.AddProperties(&module.properties)
399
400 InitDroiddocModule(module, android.HostSupported)
401 return module
402}
403
Colin Cross41955e82019-05-29 14:40:35 -0700404var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800405
Colin Cross83bb3162018-06-25 15:48:06 -0700406func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900407 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700408}
409
Paul Duffine25c6442019-10-11 13:50:28 +0100410func (j *Javadoc) systemModules() string {
411 return proptools.String(j.properties.System_modules)
412}
413
Colin Cross83bb3162018-06-25 15:48:06 -0700414func (j *Javadoc) minSdkVersion() string {
415 return j.sdkVersion()
416}
417
Dan Willemsen419290a2018-10-31 15:28:47 -0700418func (j *Javadoc) targetSdkVersion() string {
419 return j.sdkVersion()
420}
421
Nan Zhang581fd212018-01-10 16:06:12 -0800422func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
423 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100424 sdkDep := decodeSdkDep(ctx, sdkContext(j))
425 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700426 if sdkDep.useDefaultLibs {
427 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
428 if ctx.Config().TargetOpenJDK9() {
429 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
430 }
Paul Duffin250e6192019-06-07 10:44:37 +0100431 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700432 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
433 }
434 } else if sdkDep.useModule {
435 if ctx.Config().TargetOpenJDK9() {
436 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
437 }
438 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700439 }
Paul Duffine25c6442019-10-11 13:50:28 +0100440 } else if sdkDep.systemModules != "" {
441 // Add the system modules to both the system modules and bootclasspath.
442 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
443 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800444 }
445 }
446
Colin Cross42d48b72018-08-29 14:10:52 -0700447 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800448}
449
Nan Zhanga40da042018-08-01 12:48:00 -0700450func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
451 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900452
Colin Cross3047fa22019-04-18 10:56:44 -0700453 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900454
455 return flags
456}
457
458func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700459 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900460
461 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
462 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
463
464 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700465 var deps android.Paths
466
Jiyong Park1e440682018-05-23 18:42:04 +0900467 if aidlPreprocess.Valid() {
468 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700469 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900470 } else {
471 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
472 }
473
474 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
475 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
476 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
477 flags = append(flags, "-I"+src.String())
478 }
479
Colin Cross3047fa22019-04-18 10:56:44 -0700480 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900481}
482
Jiyong Parkd90d7412019-08-20 22:49:19 +0900483// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900484func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700485 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900486
487 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700488 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900489
Jiyong Park1112c4c2019-08-16 21:12:10 +0900490 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
491
Jiyong Park1e440682018-05-23 18:42:04 +0900492 for _, srcFile := range srcFiles {
493 switch srcFile.Ext() {
494 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700495 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900496 case ".logtags":
497 javaFile := genLogtags(ctx, srcFile)
498 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900499 default:
500 outSrcFiles = append(outSrcFiles, srcFile)
501 }
502 }
503
Colin Crossc0806172019-06-14 18:51:47 -0700504 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
505 if len(aidlSrcs) > 0 {
506 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
507 outSrcFiles = append(outSrcFiles, srcJarFiles...)
508 }
509
Jiyong Park1e440682018-05-23 18:42:04 +0900510 return outSrcFiles
511}
512
Nan Zhang581fd212018-01-10 16:06:12 -0800513func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
514 var deps deps
515
Colin Cross83bb3162018-06-25 15:48:06 -0700516 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800517 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700518 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800519 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700520 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800521 }
522
523 ctx.VisitDirectDeps(func(module android.Module) {
524 otherName := ctx.OtherModuleName(module)
525 tag := ctx.OtherModuleDependencyTag(module)
526
Colin Cross2d24c1b2018-05-23 10:59:18 -0700527 switch tag {
528 case bootClasspathTag:
529 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800530 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffine25c6442019-10-11 13:50:28 +0100531 } else if sm, ok := module.(*SystemModules); ok {
532 // A system modules dependency has been added to the bootclasspath
533 // so add its libs to the bootclasspath.
534 deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700535 } else {
536 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
537 }
538 case libTag:
539 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800540 case SdkLibraryDependency:
541 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700542 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900543 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900544 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700545 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800546 checkProducesJars(ctx, dep)
547 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800548 default:
549 ctx.ModuleErrorf("depends on non-java module %q", otherName)
550 }
Nan Zhang357466b2018-04-17 17:38:36 -0700551 case systemModulesTag:
552 if deps.systemModules != nil {
553 panic("Found two system module dependencies")
554 }
555 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000556 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700557 panic("Missing directory for system module dependency")
558 }
Colin Crossb77043e2019-07-16 13:57:13 -0700559 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800560 }
561 })
562 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
563 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800564 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900565
566 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
567 if filterPackages == nil {
568 return srcs
569 }
570 filtered := []android.Path{}
571 for _, src := range srcs {
572 if src.Ext() != ".java" {
573 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
574 // but otherwise metalava emits stub sources having references to the generated AIDL classes
575 // in filtered-out pacages (e.g. com.android.internal.*).
576 // TODO(b/141149570) We need to fix this by introducing default private constructors or
577 // fixing metalava to not emit constructors having references to unknown classes.
578 filtered = append(filtered, src)
579 continue
580 }
581 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
582 for _, pkg := range filterPackages {
583 if strings.HasPrefix(packageName, pkg) {
584 filtered = append(filtered, src)
585 break
586 }
587 }
588 }
589 return filtered
590 }
591 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
592
Nan Zhanga40da042018-08-01 12:48:00 -0700593 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900594 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800595
596 // srcs may depend on some genrule output.
597 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800598 j.srcJars = append(j.srcJars, deps.srcJars...)
599
Nan Zhang581fd212018-01-10 16:06:12 -0800600 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800601 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800602
Nan Zhang9c69a122018-08-22 10:22:08 -0700603 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800604 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
605 }
606 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800607
Colin Cross8a497952019-03-05 22:25:09 -0800608 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000609 argFilesMap := map[string]string{}
610 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700611
Paul Duffin99e4a502019-02-11 15:38:42 +0000612 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800613 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000614 if _, exists := argFilesMap[label]; !exists {
615 argFilesMap[label] = strings.Join(paths.Strings(), " ")
616 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700617 } else {
618 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000619 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700620 }
621 }
622
623 var err error
Colin Cross15638152019-07-11 11:11:35 -0700624 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700625 if strings.HasPrefix(name, "location ") {
626 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000627 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700628 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700629 } else {
Colin Cross15638152019-07-11 11:11:35 -0700630 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000631 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700632 }
633 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700634 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700635 }
Colin Cross15638152019-07-11 11:11:35 -0700636 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700637 })
638
639 if err != nil {
640 ctx.PropertyErrorf("args", "%s", err.Error())
641 }
642
Nan Zhang581fd212018-01-10 16:06:12 -0800643 return deps
644}
645
646func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
647 j.addDeps(ctx)
648}
649
650func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
651 deps := j.collectDeps(ctx)
652
Colin Crossdaa4c672019-07-15 22:53:46 -0700653 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800654
Colin Crossdaa4c672019-07-15 22:53:46 -0700655 outDir := android.PathForModuleOut(ctx, "out")
656 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
657
658 j.stubsSrcJar = nil
659
660 rule := android.NewRuleBuilder()
661
662 rule.Command().Text("rm -rf").Text(outDir.String())
663 rule.Command().Text("mkdir -p").Text(outDir.String())
664
665 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700666
Colin Cross83bb3162018-06-25 15:48:06 -0700667 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800668
Colin Crossdaa4c672019-07-15 22:53:46 -0700669 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
670 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800671
Colin Crossdaa4c672019-07-15 22:53:46 -0700672 cmd.FlagWithArg("-source ", javaVersion).
673 Flag("-J-Xmx1024m").
674 Flag("-XDignore.symbol.file").
675 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800676
Colin Crossdaa4c672019-07-15 22:53:46 -0700677 rule.Command().
678 BuiltTool(ctx, "soong_zip").
679 Flag("-write_if_changed").
680 Flag("-d").
681 FlagWithOutput("-o ", j.docZip).
682 FlagWithArg("-C ", outDir.String()).
683 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700684
Colin Crossdaa4c672019-07-15 22:53:46 -0700685 rule.Restat()
686
687 zipSyncCleanupCmd(rule, srcJarDir)
688
689 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800690}
691
Nan Zhanga40da042018-08-01 12:48:00 -0700692//
693// Droiddoc
694//
695type Droiddoc struct {
696 Javadoc
697
698 properties DroiddocProperties
699 apiFile android.WritablePath
700 dexApiFile android.WritablePath
701 privateApiFile android.WritablePath
702 privateDexApiFile android.WritablePath
703 removedApiFile android.WritablePath
704 removedDexApiFile android.WritablePath
705 exactApiFile android.WritablePath
706 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700707 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700708
709 checkCurrentApiTimestamp android.WritablePath
710 updateCurrentApiTimestamp android.WritablePath
711 checkLastReleasedApiTimestamp android.WritablePath
712
Nan Zhanga40da042018-08-01 12:48:00 -0700713 apiFilePath android.Path
714}
715
Colin Crossa3002fc2019-07-08 16:48:04 -0700716// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700717func DroiddocFactory() android.Module {
718 module := &Droiddoc{}
719
720 module.AddProperties(&module.properties,
721 &module.Javadoc.properties)
722
723 InitDroiddocModule(module, android.HostAndDeviceSupported)
724 return module
725}
726
Colin Crossa3002fc2019-07-08 16:48:04 -0700727// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700728func DroiddocHostFactory() android.Module {
729 module := &Droiddoc{}
730
731 module.AddProperties(&module.properties,
732 &module.Javadoc.properties)
733
734 InitDroiddocModule(module, android.HostSupported)
735 return module
736}
737
738func (d *Droiddoc) ApiFilePath() android.Path {
739 return d.apiFilePath
740}
741
Nan Zhang581fd212018-01-10 16:06:12 -0800742func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
743 d.Javadoc.addDeps(ctx)
744
Inseob Kim38449af2019-02-28 14:24:05 +0900745 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
746 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
747 }
748
Nan Zhang79614d12018-04-19 18:03:39 -0700749 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800750 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
751 }
Nan Zhang581fd212018-01-10 16:06:12 -0800752}
753
Colin Crossab054432019-07-15 16:13:59 -0700754func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700755 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
756 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
757 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700758 cmd.FlagWithArg("-source ", "1.8").
759 Flag("-J-Xmx1600m").
760 Flag("-J-XX:-OmitStackTraceInFastThrow").
761 Flag("-XDignore.symbol.file").
762 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
763 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
764 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700765 FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700766
Nan Zhanga40da042018-08-01 12:48:00 -0700767 if String(d.properties.Custom_template) == "" {
768 // TODO: This is almost always droiddoc-templates-sdk
769 ctx.PropertyErrorf("custom_template", "must specify a template")
770 }
771
772 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700773 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700774 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700775 } else {
776 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
777 }
778 })
779
780 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700781 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
782 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
783 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700784 }
785
786 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700787 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
788 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
789 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700790 }
791
792 if len(d.properties.Html_dirs) > 2 {
793 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
794 }
795
Colin Cross8a497952019-03-05 22:25:09 -0800796 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700797 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700798
Colin Crossab054432019-07-15 16:13:59 -0700799 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700800
801 if String(d.properties.Proofread_file) != "" {
802 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700803 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700804 }
805
806 if String(d.properties.Todo_file) != "" {
807 // tricky part:
808 // we should not compute full path for todo_file through PathForModuleOut().
809 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700810 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
811 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700812 }
813
814 if String(d.properties.Resourcesdir) != "" {
815 // TODO: should we add files under resourcesDir to the implicits? It seems that
816 // resourcesDir is one sub dir of htmlDir
817 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700818 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700819 }
820
821 if String(d.properties.Resourcesoutdir) != "" {
822 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700824 }
Nan Zhanga40da042018-08-01 12:48:00 -0700825}
826
Colin Crossab054432019-07-15 16:13:59 -0700827func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200828 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
829 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700830 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700831
Nan Zhanga40da042018-08-01 12:48:00 -0700832 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700834 d.apiFilePath = d.apiFile
835 }
836
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200837 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
838 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700839 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700840 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700841 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700842 }
843
844 if String(d.properties.Private_api_filename) != "" {
845 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700846 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700847 }
848
849 if String(d.properties.Dex_api_filename) != "" {
850 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700851 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700852 }
853
854 if String(d.properties.Private_dex_api_filename) != "" {
855 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700856 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700857 }
858
859 if String(d.properties.Removed_dex_api_filename) != "" {
860 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700861 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700862 }
863
864 if String(d.properties.Exact_api_filename) != "" {
865 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700866 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700867 }
868
869 if String(d.properties.Dex_mapping_filename) != "" {
870 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700871 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700872 }
873
Nan Zhang66dc2362018-08-14 20:41:04 -0700874 if String(d.properties.Proguard_filename) != "" {
875 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700876 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700877 }
878
Nan Zhanga40da042018-08-01 12:48:00 -0700879 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700880 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700881 }
882
883 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700884 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700885 }
Nan Zhanga40da042018-08-01 12:48:00 -0700886}
887
Colin Crossab054432019-07-15 16:13:59 -0700888func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700889 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700890 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
891 rule.Command().Text("cp").
892 Input(staticDocIndexRedirect).
893 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700894 }
895
896 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700897 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
898 rule.Command().Text("cp").
899 Input(staticDocProperties).
900 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700901 }
Nan Zhanga40da042018-08-01 12:48:00 -0700902}
903
Colin Crossab054432019-07-15 16:13:59 -0700904func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700905 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700906
907 cmd := rule.Command().
908 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
909 Flag(config.JavacVmFlags).
910 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700911 FlagWithRspFileInputList("@", srcs).
912 FlagWithInput("@", srcJarList)
913
Colin Crossab054432019-07-15 16:13:59 -0700914 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
915 // based stubs generation.
916 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
917 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
918 // the correct package name base path.
919 if len(sourcepaths) > 0 {
920 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
921 } else {
922 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
923 }
924
925 cmd.FlagWithArg("-d ", outDir.String()).
926 Flag("-quiet")
927
928 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700929}
930
Colin Crossdaa4c672019-07-15 22:53:46 -0700931func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
932 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
933 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
934
935 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
936
937 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
938 cmd.Flag(flag).Implicits(deps)
939
940 cmd.FlagWithArg("--patch-module ", "java.base=.")
941
942 if len(classpath) > 0 {
943 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
944 }
945
946 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700947}
948
Colin Crossdaa4c672019-07-15 22:53:46 -0700949func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
950 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
951 sourcepaths android.Paths) *android.RuleBuilderCommand {
952
953 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
954
955 if len(bootclasspath) == 0 && ctx.Device() {
956 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
957 // ensure java does not fall back to the default bootclasspath.
958 cmd.FlagWithArg("-bootclasspath ", `""`)
959 } else if len(bootclasspath) > 0 {
960 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
961 }
962
963 if len(classpath) > 0 {
964 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
965 }
966
967 return cmd
968}
969
Colin Crossab054432019-07-15 16:13:59 -0700970func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
971 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700972
Colin Crossab054432019-07-15 16:13:59 -0700973 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
974 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
975
976 return rule.Command().
977 BuiltTool(ctx, "dokka").
978 Flag(config.JavacVmFlags).
979 Flag(srcJarDir.String()).
980 FlagWithInputList("-classpath ", dokkaClasspath, ":").
981 FlagWithArg("-format ", "dac").
982 FlagWithArg("-dacRoot ", "/reference/kotlin").
983 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700984}
985
986func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
987 deps := d.Javadoc.collectDeps(ctx)
988
Colin Crossdaa4c672019-07-15 22:53:46 -0700989 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
990 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
991
Nan Zhang1598a9e2018-09-04 17:14:32 -0700992 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
993 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
994 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
995 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
996
Colin Crossab054432019-07-15 16:13:59 -0700997 outDir := android.PathForModuleOut(ctx, "out")
998 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
999 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001000
Colin Crossab054432019-07-15 16:13:59 -07001001 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -07001002
Colin Crossab054432019-07-15 16:13:59 -07001003 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1004 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001005
Colin Crossab054432019-07-15 16:13:59 -07001006 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1007
1008 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001009 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001010 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001011 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001012 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001013 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001014 }
1015
Colin Crossab054432019-07-15 16:13:59 -07001016 d.stubsFlags(ctx, cmd, stubsDir)
1017
1018 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1019
1020 var desc string
1021 if Bool(d.properties.Dokka_enabled) {
1022 desc = "dokka"
1023 } else {
1024 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1025
1026 for _, o := range d.Javadoc.properties.Out {
1027 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1028 }
1029
1030 d.postDoclavaCmds(ctx, rule)
1031 desc = "doclava"
1032 }
1033
1034 rule.Command().
1035 BuiltTool(ctx, "soong_zip").
1036 Flag("-write_if_changed").
1037 Flag("-d").
1038 FlagWithOutput("-o ", d.docZip).
1039 FlagWithArg("-C ", outDir.String()).
1040 FlagWithArg("-D ", outDir.String())
1041
1042 rule.Command().
1043 BuiltTool(ctx, "soong_zip").
1044 Flag("-write_if_changed").
1045 Flag("-jar").
1046 FlagWithOutput("-o ", d.stubsSrcJar).
1047 FlagWithArg("-C ", stubsDir.String()).
1048 FlagWithArg("-D ", stubsDir.String())
1049
1050 rule.Restat()
1051
1052 zipSyncCleanupCmd(rule, srcJarDir)
1053
1054 rule.Build(pctx, ctx, "javadoc", desc)
1055
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001056 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001057 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001058
1059 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1060 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001061
1062 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001063
1064 rule := android.NewRuleBuilder()
1065
1066 rule.Command().Text("( true")
1067
1068 rule.Command().
1069 BuiltTool(ctx, "apicheck").
1070 Flag("-JXmx1024m").
1071 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1072 OptionalFlag(d.properties.Check_api.Current.Args).
1073 Input(apiFile).
1074 Input(d.apiFile).
1075 Input(removedApiFile).
1076 Input(d.removedApiFile)
1077
1078 msg := fmt.Sprintf(`\n******************************\n`+
1079 `You have tried to change the API from what has been previously approved.\n\n`+
1080 `To make these errors go away, you have two choices:\n`+
1081 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1082 ` errors above.\n\n`+
1083 ` 2. You can update current.txt by executing the following command:\n`+
1084 ` make %s-update-current-api\n\n`+
1085 ` To submit the revised current.txt to the main Android repository,\n`+
1086 ` you will need approval.\n`+
1087 `******************************\n`, ctx.ModuleName())
1088
1089 rule.Command().
1090 Text("touch").Output(d.checkCurrentApiTimestamp).
1091 Text(") || (").
1092 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1093 Text("; exit 38").
1094 Text(")")
1095
1096 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001097
1098 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001099
1100 // update API rule
1101 rule = android.NewRuleBuilder()
1102
1103 rule.Command().Text("( true")
1104
1105 rule.Command().
1106 Text("cp").Flag("-f").
1107 Input(d.apiFile).Flag(apiFile.String())
1108
1109 rule.Command().
1110 Text("cp").Flag("-f").
1111 Input(d.removedApiFile).Flag(removedApiFile.String())
1112
1113 msg = "failed to update public API"
1114
1115 rule.Command().
1116 Text("touch").Output(d.updateCurrentApiTimestamp).
1117 Text(") || (").
1118 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1119 Text("; exit 38").
1120 Text(")")
1121
1122 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001123 }
1124
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001125 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001126 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001127
1128 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1129 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001130
1131 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001132
1133 rule := android.NewRuleBuilder()
1134
1135 rule.Command().
1136 Text("(").
1137 BuiltTool(ctx, "apicheck").
1138 Flag("-JXmx1024m").
1139 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1140 OptionalFlag(d.properties.Check_api.Last_released.Args).
1141 Input(apiFile).
1142 Input(d.apiFile).
1143 Input(removedApiFile).
1144 Input(d.removedApiFile)
1145
1146 msg := `\n******************************\n` +
1147 `You have tried to change the API from what has been previously released in\n` +
1148 `an SDK. Please fix the errors listed above.\n` +
1149 `******************************\n`
1150
1151 rule.Command().
1152 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1153 Text(") || (").
1154 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1155 Text("; exit 38").
1156 Text(")")
1157
1158 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001159 }
1160}
1161
1162//
1163// Droidstubs
1164//
1165type Droidstubs struct {
1166 Javadoc
1167
Pete Gillin581d6082018-10-22 15:55:04 +01001168 properties DroidstubsProperties
1169 apiFile android.WritablePath
1170 apiXmlFile android.WritablePath
1171 lastReleasedApiXmlFile android.WritablePath
1172 dexApiFile android.WritablePath
1173 privateApiFile android.WritablePath
1174 privateDexApiFile android.WritablePath
1175 removedApiFile android.WritablePath
1176 removedDexApiFile android.WritablePath
1177 apiMappingFile android.WritablePath
1178 exactApiFile android.WritablePath
1179 proguardFile android.WritablePath
1180 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001181
1182 checkCurrentApiTimestamp android.WritablePath
1183 updateCurrentApiTimestamp android.WritablePath
1184 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001185 apiLintTimestamp android.WritablePath
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001186 apiLintReport android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001187
Pete Gillin581d6082018-10-22 15:55:04 +01001188 checkNullabilityWarningsTimestamp android.WritablePath
1189
Nan Zhang1598a9e2018-09-04 17:14:32 -07001190 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001191 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001192
1193 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001194
1195 jdiffDocZip android.WritablePath
1196 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001197}
1198
Colin Crossa3002fc2019-07-08 16:48:04 -07001199// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1200// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1201// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001202func DroidstubsFactory() android.Module {
1203 module := &Droidstubs{}
1204
1205 module.AddProperties(&module.properties,
1206 &module.Javadoc.properties)
1207
1208 InitDroiddocModule(module, android.HostAndDeviceSupported)
1209 return module
1210}
1211
Colin Crossa3002fc2019-07-08 16:48:04 -07001212// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1213// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1214// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1215// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001216func DroidstubsHostFactory() android.Module {
1217 module := &Droidstubs{}
1218
1219 module.AddProperties(&module.properties,
1220 &module.Javadoc.properties)
1221
1222 InitDroiddocModule(module, android.HostSupported)
1223 return module
1224}
1225
1226func (d *Droidstubs) ApiFilePath() android.Path {
1227 return d.apiFilePath
1228}
1229
1230func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1231 d.Javadoc.addDeps(ctx)
1232
Inseob Kim38449af2019-02-28 14:24:05 +09001233 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1234 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1235 }
1236
Nan Zhang1598a9e2018-09-04 17:14:32 -07001237 if len(d.properties.Merge_annotations_dirs) != 0 {
1238 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1239 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1240 }
1241 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001242
Pete Gillin77167902018-09-19 18:16:26 +01001243 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1244 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1245 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1246 }
1247 }
1248
Nan Zhang9c69a122018-08-22 10:22:08 -07001249 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1250 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1251 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1252 }
1253 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254}
1255
Colin Cross33961b52019-07-11 11:01:22 -07001256func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001257 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1258 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 String(d.properties.Api_filename) != "" {
1260 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001261 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001262 d.apiFilePath = d.apiFile
1263 }
1264
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001265 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1266 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001267 String(d.properties.Removed_api_filename) != "" {
1268 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001269 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001270 }
1271
1272 if String(d.properties.Private_api_filename) != "" {
1273 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001274 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001275 }
1276
1277 if String(d.properties.Dex_api_filename) != "" {
1278 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001279 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001280 }
1281
1282 if String(d.properties.Private_dex_api_filename) != "" {
1283 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001285 }
1286
1287 if String(d.properties.Removed_dex_api_filename) != "" {
1288 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001289 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001290 }
1291
1292 if String(d.properties.Exact_api_filename) != "" {
1293 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001294 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 }
1296
Nan Zhang9c69a122018-08-22 10:22:08 -07001297 if String(d.properties.Dex_mapping_filename) != "" {
1298 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001299 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001300 }
1301
Nan Zhang199645c2018-09-19 12:40:06 -07001302 if String(d.properties.Proguard_filename) != "" {
1303 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001304 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001305 }
1306
Nan Zhang9c69a122018-08-22 10:22:08 -07001307 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001308 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001309 }
1310
Nan Zhang1598a9e2018-09-04 17:14:32 -07001311 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001312 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001313 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001314 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001315 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001316}
1317
Colin Cross33961b52019-07-11 11:01:22 -07001318func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001319 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001320 cmd.Flag("--include-annotations")
1321
Pete Gillinc382a562018-11-14 18:45:46 +00001322 validatingNullability :=
1323 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1324 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001325 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001326
Pete Gillina262c052018-09-14 14:25:48 +01001327 if !(migratingNullability || validatingNullability) {
1328 ctx.PropertyErrorf("previous_api",
1329 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001330 }
Colin Cross33961b52019-07-11 11:01:22 -07001331
Pete Gillina262c052018-09-14 14:25:48 +01001332 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001333 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001334 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001335 }
Colin Cross33961b52019-07-11 11:01:22 -07001336
Pete Gillinc382a562018-11-14 18:45:46 +00001337 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001338 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001339 }
Colin Cross33961b52019-07-11 11:01:22 -07001340
Pete Gillina262c052018-09-14 14:25:48 +01001341 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001342 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001343 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001344 }
Nan Zhanga40da042018-08-01 12:48:00 -07001345
1346 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001347 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001348
Nan Zhang1598a9e2018-09-04 17:14:32 -07001349 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001350 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001351 "has to be non-empty if annotations was enabled!")
1352 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001353
Colin Cross33961b52019-07-11 11:01:22 -07001354 d.mergeAnnoDirFlags(ctx, cmd)
1355
1356 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1357 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1358 FlagWithArg("--hide ", "SuperfluousPrefix").
1359 FlagWithArg("--hide ", "AnnotationExtraction")
1360 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001361}
1362
Colin Cross33961b52019-07-11 11:01:22 -07001363func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1364 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1365 if t, ok := m.(*ExportedDroiddocDir); ok {
1366 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1367 } else {
1368 ctx.PropertyErrorf("merge_annotations_dirs",
1369 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1370 }
1371 })
1372}
1373
1374func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001375 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1376 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001377 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001378 } else {
1379 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1380 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1381 }
1382 })
Nan Zhanga40da042018-08-01 12:48:00 -07001383}
1384
Colin Cross33961b52019-07-11 11:01:22 -07001385func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001386 if Bool(d.properties.Api_levels_annotations_enabled) {
1387 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001388
1389 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1390 ctx.PropertyErrorf("api_levels_annotations_dirs",
1391 "has to be non-empty if api levels annotations was enabled!")
1392 }
1393
Colin Cross33961b52019-07-11 11:01:22 -07001394 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1395 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1396 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1397 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001398
1399 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1400 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001401 for _, dep := range t.deps {
1402 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001403 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001404 }
1405 }
Colin Cross33961b52019-07-11 11:01:22 -07001406 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001407 } else {
1408 ctx.PropertyErrorf("api_levels_annotations_dirs",
1409 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1410 }
1411 })
1412
1413 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001414}
1415
Colin Cross33961b52019-07-11 11:01:22 -07001416func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001417 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1418 if d.apiFile.String() == "" {
1419 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1420 }
1421
1422 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001423 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001424
1425 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1426 ctx.PropertyErrorf("check_api.last_released.api_file",
1427 "has to be non-empty if jdiff was enabled!")
1428 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001429
Colin Cross33961b52019-07-11 11:01:22 -07001430 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001431 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001432 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1433 }
1434}
Nan Zhang71bbe632018-09-17 14:32:21 -07001435
Colin Cross33961b52019-07-11 11:01:22 -07001436func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1437 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1438 cmd := rule.Command().BuiltTool(ctx, "metalava").
1439 Flag(config.JavacVmFlags).
1440 FlagWithArg("-encoding ", "UTF-8").
1441 FlagWithArg("-source ", javaVersion).
1442 FlagWithRspFileInputList("@", srcs).
1443 FlagWithInput("@", srcJarList)
1444
1445 if len(bootclasspath) > 0 {
1446 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001447 }
1448
Colin Cross33961b52019-07-11 11:01:22 -07001449 if len(classpath) > 0 {
1450 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1451 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001452
Colin Cross33961b52019-07-11 11:01:22 -07001453 if len(sourcepaths) > 0 {
1454 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1455 } else {
1456 cmd.FlagWithArg("-sourcepath ", `""`)
1457 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001458
Colin Cross33961b52019-07-11 11:01:22 -07001459 cmd.Flag("--no-banner").
1460 Flag("--color").
1461 Flag("--quiet").
1462 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001463
Colin Cross33961b52019-07-11 11:01:22 -07001464 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001465}
1466
Nan Zhang1598a9e2018-09-04 17:14:32 -07001467func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001468 deps := d.Javadoc.collectDeps(ctx)
1469
1470 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001471
Colin Cross33961b52019-07-11 11:01:22 -07001472 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001473
Colin Crossdaa4c672019-07-15 22:53:46 -07001474 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001475
Colin Cross33961b52019-07-11 11:01:22 -07001476 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1477 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001478
Colin Cross33961b52019-07-11 11:01:22 -07001479 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001480
Colin Cross33961b52019-07-11 11:01:22 -07001481 rule.Command().Text("rm -rf").Text(stubsDir.String())
1482 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001483
Colin Cross33961b52019-07-11 11:01:22 -07001484 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1485
1486 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1487 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1488
1489 d.stubsFlags(ctx, cmd, stubsDir)
1490
1491 d.annotationsFlags(ctx, cmd)
1492 d.inclusionAnnotationsFlags(ctx, cmd)
1493 d.apiLevelsAnnotationsFlags(ctx, cmd)
1494 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001495
Nan Zhang1598a9e2018-09-04 17:14:32 -07001496 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1497 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1498 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1499 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1500 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001501 }
Colin Cross33961b52019-07-11 11:01:22 -07001502
1503 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1504 for _, o := range d.Javadoc.properties.Out {
1505 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1506 }
1507
1508 rule.Command().
1509 BuiltTool(ctx, "soong_zip").
1510 Flag("-write_if_changed").
1511 Flag("-jar").
1512 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1513 FlagWithArg("-C ", stubsDir.String()).
1514 FlagWithArg("-D ", stubsDir.String())
1515 rule.Restat()
1516
1517 zipSyncCleanupCmd(rule, srcJarDir)
1518
1519 rule.Build(pctx, ctx, "metalava", "metalava")
1520
1521 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001522
Adrian Roos075eedc2019-10-10 12:07:03 +02001523 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1524 rule := android.NewRuleBuilder()
1525 rule.Command().Text("( true")
1526
1527 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1528 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1529
1530 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1531 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1532
1533 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1534 if newSince.Valid() {
1535 cmd.FlagWithInput("--api-lint ", newSince.Path())
1536 } else {
1537 cmd.Flag("--api-lint")
1538 }
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001539 d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
1540 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)
Adrian Roos075eedc2019-10-10 12:07:03 +02001541
1542 d.inclusionAnnotationsFlags(ctx, cmd)
1543 d.mergeAnnoDirFlags(ctx, cmd)
1544
1545 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1546 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1547 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1548
1549 if baselineFile.Valid() {
1550 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1551 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1552 }
1553
1554 zipSyncCleanupCmd(rule, srcJarDir)
1555
1556 msg := fmt.Sprintf(`\n******************************\n`+
1557 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1558 `To make these errors go away, you have two choices:\n`+
1559 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1560 ` 2. You can update the baseline by executing the following command:\n`+
1561 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1562 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1563 rule.Command().
1564 Text("touch").Output(d.apiLintTimestamp).
1565 Text(") || (").
1566 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1567 Text("; exit 38").
1568 Text(")")
1569
1570 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1571
1572 }
1573
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001574 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001575 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001576
1577 if len(d.Javadoc.properties.Out) > 0 {
1578 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1579 }
1580
1581 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1582 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001583 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1584 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001585
Nan Zhang2760dfc2018-08-24 17:32:54 +00001586 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001587
Colin Cross33961b52019-07-11 11:01:22 -07001588 rule := android.NewRuleBuilder()
1589
1590 rule.Command().Text("( true")
1591
1592 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1593 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1594
1595 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1596 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1597
1598 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1599 FlagWithInput("--check-compatibility:api:current ", apiFile).
1600 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1601
1602 d.inclusionAnnotationsFlags(ctx, cmd)
1603 d.mergeAnnoDirFlags(ctx, cmd)
1604
Adrian Roos14f75a92019-08-12 17:54:09 +02001605 if baselineFile.Valid() {
1606 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1607 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1608 }
1609
Colin Cross33961b52019-07-11 11:01:22 -07001610 zipSyncCleanupCmd(rule, srcJarDir)
1611
1612 msg := fmt.Sprintf(`\n******************************\n`+
1613 `You have tried to change the API from what has been previously approved.\n\n`+
1614 `To make these errors go away, you have two choices:\n`+
1615 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1616 ` errors above.\n\n`+
1617 ` 2. You can update current.txt by executing the following command:\n`+
1618 ` make %s-update-current-api\n\n`+
1619 ` To submit the revised current.txt to the main Android repository,\n`+
1620 ` you will need approval.\n`+
1621 `******************************\n`, ctx.ModuleName())
1622
1623 rule.Command().
1624 Text("touch").Output(d.checkCurrentApiTimestamp).
1625 Text(") || (").
1626 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1627 Text("; exit 38").
1628 Text(")")
1629
1630 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001631
1632 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001633
1634 // update API rule
1635 rule = android.NewRuleBuilder()
1636
1637 rule.Command().Text("( true")
1638
1639 rule.Command().
1640 Text("cp").Flag("-f").
1641 Input(d.apiFile).Flag(apiFile.String())
1642
1643 rule.Command().
1644 Text("cp").Flag("-f").
1645 Input(d.removedApiFile).Flag(removedApiFile.String())
1646
1647 msg = "failed to update public API"
1648
1649 rule.Command().
1650 Text("touch").Output(d.updateCurrentApiTimestamp).
1651 Text(") || (").
1652 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1653 Text("; exit 38").
1654 Text(")")
1655
1656 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001657 }
Nan Zhanga40da042018-08-01 12:48:00 -07001658
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001659 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001660 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001661
1662 if len(d.Javadoc.properties.Out) > 0 {
1663 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1664 }
1665
1666 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1667 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001668 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1669 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001670
Nan Zhang2760dfc2018-08-24 17:32:54 +00001671 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001672
Colin Cross33961b52019-07-11 11:01:22 -07001673 rule := android.NewRuleBuilder()
1674
1675 rule.Command().Text("( true")
1676
1677 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1678 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1679
1680 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1681 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1682
1683 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1684 FlagWithInput("--check-compatibility:api:released ", apiFile)
1685
1686 d.inclusionAnnotationsFlags(ctx, cmd)
1687
1688 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1689
1690 d.mergeAnnoDirFlags(ctx, cmd)
1691
Adrian Roos14f75a92019-08-12 17:54:09 +02001692 if baselineFile.Valid() {
1693 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1694 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1695 }
1696
Colin Cross33961b52019-07-11 11:01:22 -07001697 zipSyncCleanupCmd(rule, srcJarDir)
1698
1699 msg := `\n******************************\n` +
1700 `You have tried to change the API from what has been previously released in\n` +
1701 `an SDK. Please fix the errors listed above.\n` +
1702 `******************************\n`
1703 rule.Command().
1704 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1705 Text(") || (").
1706 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1707 Text("; exit 38").
1708 Text(")")
1709
1710 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001711 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001712
Pete Gillin581d6082018-10-22 15:55:04 +01001713 if String(d.properties.Check_nullability_warnings) != "" {
1714 if d.nullabilityWarningsFile == nil {
1715 ctx.PropertyErrorf("check_nullability_warnings",
1716 "Cannot specify check_nullability_warnings unless validating nullability")
1717 }
Colin Cross33961b52019-07-11 11:01:22 -07001718
1719 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1720
Pete Gillin581d6082018-10-22 15:55:04 +01001721 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001722
Pete Gillin581d6082018-10-22 15:55:04 +01001723 msg := fmt.Sprintf(`\n******************************\n`+
1724 `The warnings encountered during nullability annotation validation did\n`+
1725 `not match the checked in file of expected warnings. The diffs are shown\n`+
1726 `above. You have two options:\n`+
1727 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1728 ` 2. Update the file of expected warnings by running:\n`+
1729 ` cp %s %s\n`+
1730 ` and submitting the updated file as part of your change.`,
1731 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001732
1733 rule := android.NewRuleBuilder()
1734
1735 rule.Command().
1736 Text("(").
1737 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1738 Text("&&").
1739 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1740 Text(") || (").
1741 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1742 Text("; exit 38").
1743 Text(")")
1744
1745 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001746 }
1747
Nan Zhang71bbe632018-09-17 14:32:21 -07001748 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001749 if len(d.Javadoc.properties.Out) > 0 {
1750 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1751 }
1752
1753 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1754 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1755 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1756
1757 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001758
Nan Zhang86b06202018-09-21 17:09:21 -07001759 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1760 // since there's cron job downstream that fetch this .zip file periodically.
1761 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001762 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1763 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1764
Nan Zhang71bbe632018-09-17 14:32:21 -07001765 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001766
Colin Cross33961b52019-07-11 11:01:22 -07001767 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1768 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001769
Colin Cross33961b52019-07-11 11:01:22 -07001770 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1771
Colin Crossdaa4c672019-07-15 22:53:46 -07001772 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001773 deps.bootClasspath, deps.classpath, d.sourcepaths)
1774
1775 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001776 Flag("-XDignore.symbol.file").
1777 FlagWithArg("-doclet ", "jdiff.JDiff").
1778 FlagWithInput("-docletpath ", jdiff).
1779 Flag("-quiet").
1780 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1781 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1782 Implicit(d.apiXmlFile).
1783 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1784 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1785 Implicit(d.lastReleasedApiXmlFile)
1786
Colin Cross33961b52019-07-11 11:01:22 -07001787 rule.Command().
1788 BuiltTool(ctx, "soong_zip").
1789 Flag("-write_if_changed").
1790 Flag("-d").
1791 FlagWithOutput("-o ", d.jdiffDocZip).
1792 FlagWithArg("-C ", outDir.String()).
1793 FlagWithArg("-D ", outDir.String())
1794
1795 rule.Command().
1796 BuiltTool(ctx, "soong_zip").
1797 Flag("-write_if_changed").
1798 Flag("-jar").
1799 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1800 FlagWithArg("-C ", stubsDir.String()).
1801 FlagWithArg("-D ", stubsDir.String())
1802
1803 rule.Restat()
1804
1805 zipSyncCleanupCmd(rule, srcJarDir)
1806
1807 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001808 }
Nan Zhang581fd212018-01-10 16:06:12 -08001809}
Dan Willemsencc090972018-02-26 14:33:31 -08001810
Nan Zhanga40da042018-08-01 12:48:00 -07001811//
Nan Zhangf4936b02018-08-01 15:00:28 -07001812// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001813//
Dan Willemsencc090972018-02-26 14:33:31 -08001814var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001815var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001816var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001817var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001818
Nan Zhangf4936b02018-08-01 15:00:28 -07001819type ExportedDroiddocDirProperties struct {
1820 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001821 Path *string
1822}
1823
Nan Zhangf4936b02018-08-01 15:00:28 -07001824type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001825 android.ModuleBase
1826
Nan Zhangf4936b02018-08-01 15:00:28 -07001827 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001828
1829 deps android.Paths
1830 dir android.Path
1831}
1832
Colin Crossa3002fc2019-07-08 16:48:04 -07001833// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001834func ExportedDroiddocDirFactory() android.Module {
1835 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001836 module.AddProperties(&module.properties)
1837 android.InitAndroidModule(module)
1838 return module
1839}
1840
Nan Zhangf4936b02018-08-01 15:00:28 -07001841func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001842
Nan Zhangf4936b02018-08-01 15:00:28 -07001843func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001844 path := String(d.properties.Path)
1845 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001846 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001847}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001848
1849//
1850// Defaults
1851//
1852type DocDefaults struct {
1853 android.ModuleBase
1854 android.DefaultsModuleBase
1855}
1856
Nan Zhangb2b33de2018-02-23 11:18:47 -08001857func DocDefaultsFactory() android.Module {
1858 module := &DocDefaults{}
1859
1860 module.AddProperties(
1861 &JavadocProperties{},
1862 &DroiddocProperties{},
1863 )
1864
1865 android.InitDefaultsModule(module)
1866
1867 return module
1868}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001869
1870func StubsDefaultsFactory() android.Module {
1871 module := &DocDefaults{}
1872
1873 module.AddProperties(
1874 &JavadocProperties{},
1875 &DroidstubsProperties{},
1876 )
1877
1878 android.InitDefaultsModule(module)
1879
1880 return module
1881}
Colin Cross33961b52019-07-11 11:01:22 -07001882
1883func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1884 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1885
1886 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1887 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1888 srcJarList := srcJarDir.Join(ctx, "list")
1889
1890 rule.Temporary(srcJarList)
1891
1892 rule.Command().BuiltTool(ctx, "zipsync").
1893 FlagWithArg("-d ", srcJarDir.String()).
1894 FlagWithOutput("-l ", srcJarList).
1895 FlagWithArg("-f ", `"*.java"`).
1896 Inputs(srcJars)
1897
1898 return srcJarList
1899}
1900
1901func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1902 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1903}