blob: c898498a8fddfacc63fef40076677533bf54edba [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))
Colin Cross6d8d8c62019-10-28 15:10:03 -0700425 if sdkDep.useDefaultLibs {
426 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
427 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
428 if sdkDep.hasFrameworkLibs() {
429 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700430 }
Colin Cross6d8d8c62019-10-28 15:10:03 -0700431 } else if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700432 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100433 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700434 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800435 }
436 }
437
Colin Cross42d48b72018-08-29 14:10:52 -0700438 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800439}
440
Nan Zhanga40da042018-08-01 12:48:00 -0700441func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
442 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900443
Colin Cross3047fa22019-04-18 10:56:44 -0700444 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900445
446 return flags
447}
448
449func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700450 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900451
452 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
453 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
454
455 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700456 var deps android.Paths
457
Jiyong Park1e440682018-05-23 18:42:04 +0900458 if aidlPreprocess.Valid() {
459 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700460 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900461 } else {
462 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
463 }
464
465 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
466 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
467 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
468 flags = append(flags, "-I"+src.String())
469 }
470
Colin Cross3047fa22019-04-18 10:56:44 -0700471 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900472}
473
Jiyong Parkd90d7412019-08-20 22:49:19 +0900474// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900475func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700476 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900477
478 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700479 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900480
Jiyong Park1112c4c2019-08-16 21:12:10 +0900481 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
482
Jiyong Park1e440682018-05-23 18:42:04 +0900483 for _, srcFile := range srcFiles {
484 switch srcFile.Ext() {
485 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700486 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900487 case ".logtags":
488 javaFile := genLogtags(ctx, srcFile)
489 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900490 default:
491 outSrcFiles = append(outSrcFiles, srcFile)
492 }
493 }
494
Colin Crossc0806172019-06-14 18:51:47 -0700495 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
496 if len(aidlSrcs) > 0 {
497 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
498 outSrcFiles = append(outSrcFiles, srcJarFiles...)
499 }
500
Jiyong Park1e440682018-05-23 18:42:04 +0900501 return outSrcFiles
502}
503
Nan Zhang581fd212018-01-10 16:06:12 -0800504func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
505 var deps deps
506
Colin Cross83bb3162018-06-25 15:48:06 -0700507 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800508 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700509 ctx.AddMissingDependencies(sdkDep.bootclasspath)
510 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800511 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700512 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800513 }
514
515 ctx.VisitDirectDeps(func(module android.Module) {
516 otherName := ctx.OtherModuleName(module)
517 tag := ctx.OtherModuleDependencyTag(module)
518
Colin Cross2d24c1b2018-05-23 10:59:18 -0700519 switch tag {
520 case bootClasspathTag:
521 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800522 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffine25c6442019-10-11 13:50:28 +0100523 } else if sm, ok := module.(*SystemModules); ok {
524 // A system modules dependency has been added to the bootclasspath
525 // so add its libs to the bootclasspath.
526 deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700527 } else {
528 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
529 }
530 case libTag:
531 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800532 case SdkLibraryDependency:
533 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700534 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900535 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900536 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700537 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800538 checkProducesJars(ctx, dep)
539 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800540 default:
541 ctx.ModuleErrorf("depends on non-java module %q", otherName)
542 }
Colin Cross6cef4812019-10-17 14:23:50 -0700543 case java9LibTag:
544 switch dep := module.(type) {
545 case Dependency:
546 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
547 default:
548 ctx.ModuleErrorf("depends on non-java module %q", otherName)
549 }
Nan Zhang357466b2018-04-17 17:38:36 -0700550 case systemModulesTag:
551 if deps.systemModules != nil {
552 panic("Found two system module dependencies")
553 }
554 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000555 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700556 panic("Missing directory for system module dependency")
557 }
Colin Crossb77043e2019-07-16 13:57:13 -0700558 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800559 }
560 })
561 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
562 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800563 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900564
565 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
566 if filterPackages == nil {
567 return srcs
568 }
569 filtered := []android.Path{}
570 for _, src := range srcs {
571 if src.Ext() != ".java" {
572 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
573 // but otherwise metalava emits stub sources having references to the generated AIDL classes
574 // in filtered-out pacages (e.g. com.android.internal.*).
575 // TODO(b/141149570) We need to fix this by introducing default private constructors or
576 // fixing metalava to not emit constructors having references to unknown classes.
577 filtered = append(filtered, src)
578 continue
579 }
580 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
581 for _, pkg := range filterPackages {
582 if strings.HasPrefix(packageName, pkg) {
583 filtered = append(filtered, src)
584 break
585 }
586 }
587 }
588 return filtered
589 }
590 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
591
Nan Zhanga40da042018-08-01 12:48:00 -0700592 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900593 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800594
595 // srcs may depend on some genrule output.
596 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800597 j.srcJars = append(j.srcJars, deps.srcJars...)
598
Nan Zhang581fd212018-01-10 16:06:12 -0800599 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800600 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800601
Nan Zhang9c69a122018-08-22 10:22:08 -0700602 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800603 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
604 }
605 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800606
Colin Cross8a497952019-03-05 22:25:09 -0800607 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000608 argFilesMap := map[string]string{}
609 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700610
Paul Duffin99e4a502019-02-11 15:38:42 +0000611 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800612 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000613 if _, exists := argFilesMap[label]; !exists {
614 argFilesMap[label] = strings.Join(paths.Strings(), " ")
615 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700616 } else {
617 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000618 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700619 }
620 }
621
622 var err error
Colin Cross15638152019-07-11 11:11:35 -0700623 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700624 if strings.HasPrefix(name, "location ") {
625 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000626 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700627 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700628 } else {
Colin Cross15638152019-07-11 11:11:35 -0700629 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000630 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700631 }
632 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700633 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700634 }
Colin Cross15638152019-07-11 11:11:35 -0700635 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700636 })
637
638 if err != nil {
639 ctx.PropertyErrorf("args", "%s", err.Error())
640 }
641
Nan Zhang581fd212018-01-10 16:06:12 -0800642 return deps
643}
644
645func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
646 j.addDeps(ctx)
647}
648
649func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
650 deps := j.collectDeps(ctx)
651
Colin Crossdaa4c672019-07-15 22:53:46 -0700652 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800653
Colin Crossdaa4c672019-07-15 22:53:46 -0700654 outDir := android.PathForModuleOut(ctx, "out")
655 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
656
657 j.stubsSrcJar = nil
658
659 rule := android.NewRuleBuilder()
660
661 rule.Command().Text("rm -rf").Text(outDir.String())
662 rule.Command().Text("mkdir -p").Text(outDir.String())
663
664 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700665
Colin Cross83bb3162018-06-25 15:48:06 -0700666 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800667
Colin Crossdaa4c672019-07-15 22:53:46 -0700668 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
669 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800670
Colin Cross1e743852019-10-28 11:37:20 -0700671 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700672 Flag("-J-Xmx1024m").
673 Flag("-XDignore.symbol.file").
674 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800675
Colin Crossdaa4c672019-07-15 22:53:46 -0700676 rule.Command().
677 BuiltTool(ctx, "soong_zip").
678 Flag("-write_if_changed").
679 Flag("-d").
680 FlagWithOutput("-o ", j.docZip).
681 FlagWithArg("-C ", outDir.String()).
682 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700683
Colin Crossdaa4c672019-07-15 22:53:46 -0700684 rule.Restat()
685
686 zipSyncCleanupCmd(rule, srcJarDir)
687
688 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800689}
690
Nan Zhanga40da042018-08-01 12:48:00 -0700691//
692// Droiddoc
693//
694type Droiddoc struct {
695 Javadoc
696
697 properties DroiddocProperties
698 apiFile android.WritablePath
699 dexApiFile android.WritablePath
700 privateApiFile android.WritablePath
701 privateDexApiFile android.WritablePath
702 removedApiFile android.WritablePath
703 removedDexApiFile android.WritablePath
704 exactApiFile android.WritablePath
705 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700706 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700707
708 checkCurrentApiTimestamp android.WritablePath
709 updateCurrentApiTimestamp android.WritablePath
710 checkLastReleasedApiTimestamp android.WritablePath
711
Nan Zhanga40da042018-08-01 12:48:00 -0700712 apiFilePath android.Path
713}
714
Colin Crossa3002fc2019-07-08 16:48:04 -0700715// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700716func DroiddocFactory() android.Module {
717 module := &Droiddoc{}
718
719 module.AddProperties(&module.properties,
720 &module.Javadoc.properties)
721
722 InitDroiddocModule(module, android.HostAndDeviceSupported)
723 return module
724}
725
Colin Crossa3002fc2019-07-08 16:48:04 -0700726// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700727func DroiddocHostFactory() android.Module {
728 module := &Droiddoc{}
729
730 module.AddProperties(&module.properties,
731 &module.Javadoc.properties)
732
733 InitDroiddocModule(module, android.HostSupported)
734 return module
735}
736
737func (d *Droiddoc) ApiFilePath() android.Path {
738 return d.apiFilePath
739}
740
Nan Zhang581fd212018-01-10 16:06:12 -0800741func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
742 d.Javadoc.addDeps(ctx)
743
Inseob Kim38449af2019-02-28 14:24:05 +0900744 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
745 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
746 }
747
Nan Zhang79614d12018-04-19 18:03:39 -0700748 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800749 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
750 }
Nan Zhang581fd212018-01-10 16:06:12 -0800751}
752
Colin Crossab054432019-07-15 16:13:59 -0700753func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700754 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
755 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
756 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700757 cmd.FlagWithArg("-source ", "1.8").
758 Flag("-J-Xmx1600m").
759 Flag("-J-XX:-OmitStackTraceInFastThrow").
760 Flag("-XDignore.symbol.file").
761 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
762 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
763 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700764 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 -0700765
Nan Zhanga40da042018-08-01 12:48:00 -0700766 if String(d.properties.Custom_template) == "" {
767 // TODO: This is almost always droiddoc-templates-sdk
768 ctx.PropertyErrorf("custom_template", "must specify a template")
769 }
770
771 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700772 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700773 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700774 } else {
775 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
776 }
777 })
778
779 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700780 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
781 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
782 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700783 }
784
785 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700786 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
787 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
788 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700789 }
790
791 if len(d.properties.Html_dirs) > 2 {
792 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
793 }
794
Colin Cross8a497952019-03-05 22:25:09 -0800795 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700796 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700797
Colin Crossab054432019-07-15 16:13:59 -0700798 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700799
800 if String(d.properties.Proofread_file) != "" {
801 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700802 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700803 }
804
805 if String(d.properties.Todo_file) != "" {
806 // tricky part:
807 // we should not compute full path for todo_file through PathForModuleOut().
808 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700809 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
810 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700811 }
812
813 if String(d.properties.Resourcesdir) != "" {
814 // TODO: should we add files under resourcesDir to the implicits? It seems that
815 // resourcesDir is one sub dir of htmlDir
816 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700817 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700818 }
819
820 if String(d.properties.Resourcesoutdir) != "" {
821 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700822 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700823 }
Nan Zhanga40da042018-08-01 12:48:00 -0700824}
825
Colin Crossab054432019-07-15 16:13:59 -0700826func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200827 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
828 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700829 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700830
Nan Zhanga40da042018-08-01 12:48:00 -0700831 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700833 d.apiFilePath = d.apiFile
834 }
835
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200836 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
837 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700838 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700839 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700840 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700841 }
842
843 if String(d.properties.Private_api_filename) != "" {
844 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700845 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700846 }
847
848 if String(d.properties.Dex_api_filename) != "" {
849 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700850 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700851 }
852
853 if String(d.properties.Private_dex_api_filename) != "" {
854 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700855 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700856 }
857
858 if String(d.properties.Removed_dex_api_filename) != "" {
859 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700860 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700861 }
862
863 if String(d.properties.Exact_api_filename) != "" {
864 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700865 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700866 }
867
868 if String(d.properties.Dex_mapping_filename) != "" {
869 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700870 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700871 }
872
Nan Zhang66dc2362018-08-14 20:41:04 -0700873 if String(d.properties.Proguard_filename) != "" {
874 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700875 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700876 }
877
Nan Zhanga40da042018-08-01 12:48:00 -0700878 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700879 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700880 }
881
882 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700883 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700884 }
Nan Zhanga40da042018-08-01 12:48:00 -0700885}
886
Colin Crossab054432019-07-15 16:13:59 -0700887func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700888 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700889 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
890 rule.Command().Text("cp").
891 Input(staticDocIndexRedirect).
892 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700893 }
894
895 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700896 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
897 rule.Command().Text("cp").
898 Input(staticDocProperties).
899 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700900 }
Nan Zhanga40da042018-08-01 12:48:00 -0700901}
902
Colin Crossab054432019-07-15 16:13:59 -0700903func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700904 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700905
906 cmd := rule.Command().
907 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
908 Flag(config.JavacVmFlags).
909 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700910 FlagWithRspFileInputList("@", srcs).
911 FlagWithInput("@", srcJarList)
912
Colin Crossab054432019-07-15 16:13:59 -0700913 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
914 // based stubs generation.
915 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
916 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
917 // the correct package name base path.
918 if len(sourcepaths) > 0 {
919 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
920 } else {
921 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
922 }
923
924 cmd.FlagWithArg("-d ", outDir.String()).
925 Flag("-quiet")
926
927 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700928}
929
Colin Crossdaa4c672019-07-15 22:53:46 -0700930func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
931 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
932 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
933
934 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
935
936 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
937 cmd.Flag(flag).Implicits(deps)
938
939 cmd.FlagWithArg("--patch-module ", "java.base=.")
940
941 if len(classpath) > 0 {
942 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
943 }
944
945 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700946}
947
Colin Crossdaa4c672019-07-15 22:53:46 -0700948func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
949 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
950 sourcepaths android.Paths) *android.RuleBuilderCommand {
951
952 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
953
954 if len(bootclasspath) == 0 && ctx.Device() {
955 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
956 // ensure java does not fall back to the default bootclasspath.
957 cmd.FlagWithArg("-bootclasspath ", `""`)
958 } else if len(bootclasspath) > 0 {
959 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
960 }
961
962 if len(classpath) > 0 {
963 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
964 }
965
966 return cmd
967}
968
Colin Crossab054432019-07-15 16:13:59 -0700969func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
970 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700971
Colin Crossab054432019-07-15 16:13:59 -0700972 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
973 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
974
975 return rule.Command().
976 BuiltTool(ctx, "dokka").
977 Flag(config.JavacVmFlags).
978 Flag(srcJarDir.String()).
979 FlagWithInputList("-classpath ", dokkaClasspath, ":").
980 FlagWithArg("-format ", "dac").
981 FlagWithArg("-dacRoot ", "/reference/kotlin").
982 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700983}
984
985func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
986 deps := d.Javadoc.collectDeps(ctx)
987
Colin Crossdaa4c672019-07-15 22:53:46 -0700988 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
989 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
990
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
992 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
993 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
994 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
995
Colin Crossab054432019-07-15 16:13:59 -0700996 outDir := android.PathForModuleOut(ctx, "out")
997 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
998 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700999
Colin Crossab054432019-07-15 16:13:59 -07001000 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -07001001
Colin Crossab054432019-07-15 16:13:59 -07001002 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1003 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001004
Colin Crossab054432019-07-15 16:13:59 -07001005 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1006
1007 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001008 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001009 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001010 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001011 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001012 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001013 }
1014
Colin Crossab054432019-07-15 16:13:59 -07001015 d.stubsFlags(ctx, cmd, stubsDir)
1016
1017 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1018
1019 var desc string
1020 if Bool(d.properties.Dokka_enabled) {
1021 desc = "dokka"
1022 } else {
1023 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1024
1025 for _, o := range d.Javadoc.properties.Out {
1026 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1027 }
1028
1029 d.postDoclavaCmds(ctx, rule)
1030 desc = "doclava"
1031 }
1032
1033 rule.Command().
1034 BuiltTool(ctx, "soong_zip").
1035 Flag("-write_if_changed").
1036 Flag("-d").
1037 FlagWithOutput("-o ", d.docZip).
1038 FlagWithArg("-C ", outDir.String()).
1039 FlagWithArg("-D ", outDir.String())
1040
1041 rule.Command().
1042 BuiltTool(ctx, "soong_zip").
1043 Flag("-write_if_changed").
1044 Flag("-jar").
1045 FlagWithOutput("-o ", d.stubsSrcJar).
1046 FlagWithArg("-C ", stubsDir.String()).
1047 FlagWithArg("-D ", stubsDir.String())
1048
1049 rule.Restat()
1050
1051 zipSyncCleanupCmd(rule, srcJarDir)
1052
1053 rule.Build(pctx, ctx, "javadoc", desc)
1054
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001055 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001056 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001057
1058 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1059 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001060
1061 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001062
1063 rule := android.NewRuleBuilder()
1064
1065 rule.Command().Text("( true")
1066
1067 rule.Command().
1068 BuiltTool(ctx, "apicheck").
1069 Flag("-JXmx1024m").
1070 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1071 OptionalFlag(d.properties.Check_api.Current.Args).
1072 Input(apiFile).
1073 Input(d.apiFile).
1074 Input(removedApiFile).
1075 Input(d.removedApiFile)
1076
1077 msg := fmt.Sprintf(`\n******************************\n`+
1078 `You have tried to change the API from what has been previously approved.\n\n`+
1079 `To make these errors go away, you have two choices:\n`+
1080 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1081 ` errors above.\n\n`+
1082 ` 2. You can update current.txt by executing the following command:\n`+
1083 ` make %s-update-current-api\n\n`+
1084 ` To submit the revised current.txt to the main Android repository,\n`+
1085 ` you will need approval.\n`+
1086 `******************************\n`, ctx.ModuleName())
1087
1088 rule.Command().
1089 Text("touch").Output(d.checkCurrentApiTimestamp).
1090 Text(") || (").
1091 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1092 Text("; exit 38").
1093 Text(")")
1094
1095 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001096
1097 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001098
1099 // update API rule
1100 rule = android.NewRuleBuilder()
1101
1102 rule.Command().Text("( true")
1103
1104 rule.Command().
1105 Text("cp").Flag("-f").
1106 Input(d.apiFile).Flag(apiFile.String())
1107
1108 rule.Command().
1109 Text("cp").Flag("-f").
1110 Input(d.removedApiFile).Flag(removedApiFile.String())
1111
1112 msg = "failed to update public API"
1113
1114 rule.Command().
1115 Text("touch").Output(d.updateCurrentApiTimestamp).
1116 Text(") || (").
1117 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1118 Text("; exit 38").
1119 Text(")")
1120
1121 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001122 }
1123
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001124 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001125 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001126
1127 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1128 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001129
1130 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001131
1132 rule := android.NewRuleBuilder()
1133
1134 rule.Command().
1135 Text("(").
1136 BuiltTool(ctx, "apicheck").
1137 Flag("-JXmx1024m").
1138 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1139 OptionalFlag(d.properties.Check_api.Last_released.Args).
1140 Input(apiFile).
1141 Input(d.apiFile).
1142 Input(removedApiFile).
1143 Input(d.removedApiFile)
1144
1145 msg := `\n******************************\n` +
1146 `You have tried to change the API from what has been previously released in\n` +
1147 `an SDK. Please fix the errors listed above.\n` +
1148 `******************************\n`
1149
1150 rule.Command().
1151 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1152 Text(") || (").
1153 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1154 Text("; exit 38").
1155 Text(")")
1156
1157 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001158 }
1159}
1160
1161//
1162// Droidstubs
1163//
1164type Droidstubs struct {
1165 Javadoc
1166
Pete Gillin581d6082018-10-22 15:55:04 +01001167 properties DroidstubsProperties
1168 apiFile android.WritablePath
1169 apiXmlFile android.WritablePath
1170 lastReleasedApiXmlFile android.WritablePath
1171 dexApiFile android.WritablePath
1172 privateApiFile android.WritablePath
1173 privateDexApiFile android.WritablePath
1174 removedApiFile android.WritablePath
1175 removedDexApiFile android.WritablePath
1176 apiMappingFile android.WritablePath
1177 exactApiFile android.WritablePath
1178 proguardFile android.WritablePath
1179 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001180
1181 checkCurrentApiTimestamp android.WritablePath
1182 updateCurrentApiTimestamp android.WritablePath
1183 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001184 apiLintTimestamp android.WritablePath
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001185 apiLintReport android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001186
Pete Gillin581d6082018-10-22 15:55:04 +01001187 checkNullabilityWarningsTimestamp android.WritablePath
1188
Nan Zhang1598a9e2018-09-04 17:14:32 -07001189 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001190 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001191
1192 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001193
1194 jdiffDocZip android.WritablePath
1195 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001196
1197 metadataZip android.WritablePath
1198 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001199}
1200
Colin Crossa3002fc2019-07-08 16:48:04 -07001201// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1202// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1203// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001204func DroidstubsFactory() android.Module {
1205 module := &Droidstubs{}
1206
1207 module.AddProperties(&module.properties,
1208 &module.Javadoc.properties)
1209
1210 InitDroiddocModule(module, android.HostAndDeviceSupported)
1211 return module
1212}
1213
Colin Crossa3002fc2019-07-08 16:48:04 -07001214// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1215// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1216// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1217// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001218func DroidstubsHostFactory() android.Module {
1219 module := &Droidstubs{}
1220
1221 module.AddProperties(&module.properties,
1222 &module.Javadoc.properties)
1223
1224 InitDroiddocModule(module, android.HostSupported)
1225 return module
1226}
1227
1228func (d *Droidstubs) ApiFilePath() android.Path {
1229 return d.apiFilePath
1230}
1231
1232func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1233 d.Javadoc.addDeps(ctx)
1234
Inseob Kim38449af2019-02-28 14:24:05 +09001235 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1236 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1237 }
1238
Nan Zhang1598a9e2018-09-04 17:14:32 -07001239 if len(d.properties.Merge_annotations_dirs) != 0 {
1240 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1241 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1242 }
1243 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001244
Pete Gillin77167902018-09-19 18:16:26 +01001245 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1246 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1247 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1248 }
1249 }
1250
Nan Zhang9c69a122018-08-22 10:22:08 -07001251 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1252 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1253 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1254 }
1255 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256}
1257
Colin Cross33961b52019-07-11 11:01:22 -07001258func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001259 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1260 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261 String(d.properties.Api_filename) != "" {
1262 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001263 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264 d.apiFilePath = d.apiFile
1265 }
1266
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001267 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1268 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001269 String(d.properties.Removed_api_filename) != "" {
1270 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001271 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001272 }
1273
1274 if String(d.properties.Private_api_filename) != "" {
1275 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001277 }
1278
1279 if String(d.properties.Dex_api_filename) != "" {
1280 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001281 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001282 }
1283
1284 if String(d.properties.Private_dex_api_filename) != "" {
1285 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001286 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287 }
1288
1289 if String(d.properties.Removed_dex_api_filename) != "" {
1290 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001291 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 }
1293
1294 if String(d.properties.Exact_api_filename) != "" {
1295 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001296 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001297 }
1298
Nan Zhang9c69a122018-08-22 10:22:08 -07001299 if String(d.properties.Dex_mapping_filename) != "" {
1300 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001301 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001302 }
1303
Nan Zhang199645c2018-09-19 12:40:06 -07001304 if String(d.properties.Proguard_filename) != "" {
1305 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001306 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001307 }
1308
Nan Zhang9c69a122018-08-22 10:22:08 -07001309 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001310 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1311 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001312 }
1313
Nan Zhang1598a9e2018-09-04 17:14:32 -07001314 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001316 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001317 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001318 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001319}
1320
Colin Cross33961b52019-07-11 11:01:22 -07001321func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001322 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001323 cmd.Flag("--include-annotations")
1324
Pete Gillinc382a562018-11-14 18:45:46 +00001325 validatingNullability :=
1326 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1327 String(d.properties.Validate_nullability_from_list) != ""
Paul Duffin13a9dd62019-11-04 10:26:47 +00001328
Pete Gillina262c052018-09-14 14:25:48 +01001329 migratingNullability := String(d.properties.Previous_api) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001330 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001331 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001332 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001333 }
Colin Cross33961b52019-07-11 11:01:22 -07001334
Pete Gillinc382a562018-11-14 18:45:46 +00001335 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001336 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001337 }
Colin Cross33961b52019-07-11 11:01:22 -07001338
Pete Gillina262c052018-09-14 14:25:48 +01001339 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001340 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001341 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001342 }
Nan Zhanga40da042018-08-01 12:48:00 -07001343
1344 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001345 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001346
Nan Zhang1598a9e2018-09-04 17:14:32 -07001347 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001348 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001349 "has to be non-empty if annotations was enabled!")
1350 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001351
Colin Cross33961b52019-07-11 11:01:22 -07001352 d.mergeAnnoDirFlags(ctx, cmd)
1353
1354 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1355 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1356 FlagWithArg("--hide ", "SuperfluousPrefix").
1357 FlagWithArg("--hide ", "AnnotationExtraction")
1358 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001359}
1360
Colin Cross33961b52019-07-11 11:01:22 -07001361func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1362 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1363 if t, ok := m.(*ExportedDroiddocDir); ok {
1364 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1365 } else {
1366 ctx.PropertyErrorf("merge_annotations_dirs",
1367 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1368 }
1369 })
1370}
1371
1372func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001373 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1374 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001375 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001376 } else {
1377 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1378 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1379 }
1380 })
Nan Zhanga40da042018-08-01 12:48:00 -07001381}
1382
Colin Cross33961b52019-07-11 11:01:22 -07001383func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001384 if Bool(d.properties.Api_levels_annotations_enabled) {
1385 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001386
1387 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1388 ctx.PropertyErrorf("api_levels_annotations_dirs",
1389 "has to be non-empty if api levels annotations was enabled!")
1390 }
1391
Colin Cross33961b52019-07-11 11:01:22 -07001392 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1393 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1394 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1395 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001396
1397 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1398 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001399 for _, dep := range t.deps {
1400 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001401 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001402 }
1403 }
Colin Cross33961b52019-07-11 11:01:22 -07001404 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001405 } else {
1406 ctx.PropertyErrorf("api_levels_annotations_dirs",
1407 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1408 }
1409 })
1410
1411 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001412}
1413
Colin Cross33961b52019-07-11 11:01:22 -07001414func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001415 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1416 if d.apiFile.String() == "" {
1417 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1418 }
1419
1420 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001421 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001422
1423 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1424 ctx.PropertyErrorf("check_api.last_released.api_file",
1425 "has to be non-empty if jdiff was enabled!")
1426 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001427
Colin Cross33961b52019-07-11 11:01:22 -07001428 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001429 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001430 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1431 }
1432}
Nan Zhang71bbe632018-09-17 14:32:21 -07001433
Colin Cross1e743852019-10-28 11:37:20 -07001434func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Colin Cross33961b52019-07-11 11:01:22 -07001435 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1436 cmd := rule.Command().BuiltTool(ctx, "metalava").
1437 Flag(config.JavacVmFlags).
1438 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001439 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001440 FlagWithRspFileInputList("@", srcs).
1441 FlagWithInput("@", srcJarList)
1442
1443 if len(bootclasspath) > 0 {
1444 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001445 }
1446
Colin Cross33961b52019-07-11 11:01:22 -07001447 if len(classpath) > 0 {
1448 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1449 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001450
Colin Cross33961b52019-07-11 11:01:22 -07001451 if len(sourcepaths) > 0 {
1452 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1453 } else {
1454 cmd.FlagWithArg("-sourcepath ", `""`)
1455 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 cmd.Flag("--no-banner").
1458 Flag("--color").
1459 Flag("--quiet").
1460 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001461
Colin Cross33961b52019-07-11 11:01:22 -07001462 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001463}
1464
Nan Zhang1598a9e2018-09-04 17:14:32 -07001465func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001466 deps := d.Javadoc.collectDeps(ctx)
1467
1468 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001469
Colin Cross33961b52019-07-11 11:01:22 -07001470 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001471
Colin Crossdaa4c672019-07-15 22:53:46 -07001472 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001473
Colin Cross33961b52019-07-11 11:01:22 -07001474 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1475 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001476
Colin Cross33961b52019-07-11 11:01:22 -07001477 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001478
Colin Cross33961b52019-07-11 11:01:22 -07001479 rule.Command().Text("rm -rf").Text(stubsDir.String())
1480 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001481
Colin Cross33961b52019-07-11 11:01:22 -07001482 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1483
1484 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1485 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1486
1487 d.stubsFlags(ctx, cmd, stubsDir)
1488
1489 d.annotationsFlags(ctx, cmd)
1490 d.inclusionAnnotationsFlags(ctx, cmd)
1491 d.apiLevelsAnnotationsFlags(ctx, cmd)
1492 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001493
Nan Zhang1598a9e2018-09-04 17:14:32 -07001494 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1495 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1496 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1497 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1498 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001499 }
Colin Cross33961b52019-07-11 11:01:22 -07001500
1501 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1502 for _, o := range d.Javadoc.properties.Out {
1503 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1504 }
1505
1506 rule.Command().
1507 BuiltTool(ctx, "soong_zip").
1508 Flag("-write_if_changed").
1509 Flag("-jar").
1510 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1511 FlagWithArg("-C ", stubsDir.String()).
1512 FlagWithArg("-D ", stubsDir.String())
Jerome Gaillard0f599032019-10-10 19:29:11 +01001513
1514 if Bool(d.properties.Write_sdk_values) {
1515 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1516 rule.Command().
1517 BuiltTool(ctx, "soong_zip").
1518 Flag("-write_if_changed").
1519 Flag("-d").
1520 FlagWithOutput("-o ", d.metadataZip).
1521 FlagWithArg("-C ", d.metadataDir.String()).
1522 FlagWithArg("-D ", d.metadataDir.String())
1523 }
1524
Colin Cross33961b52019-07-11 11:01:22 -07001525 rule.Restat()
1526
1527 zipSyncCleanupCmd(rule, srcJarDir)
1528
1529 rule.Build(pctx, ctx, "metalava", "metalava")
1530
1531 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001532
Adrian Roos075eedc2019-10-10 12:07:03 +02001533 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1534 rule := android.NewRuleBuilder()
1535 rule.Command().Text("( true")
1536
1537 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1538 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1539
1540 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1541 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1542
Adrian Rooscab4a2c2019-10-14 16:32:41 +02001543 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1544
Adrian Roos075eedc2019-10-10 12:07:03 +02001545 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1546 if newSince.Valid() {
1547 cmd.FlagWithInput("--api-lint ", newSince.Path())
1548 } else {
1549 cmd.Flag("--api-lint")
1550 }
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001551 d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
1552 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)
Adrian Roos075eedc2019-10-10 12:07:03 +02001553
1554 d.inclusionAnnotationsFlags(ctx, cmd)
1555 d.mergeAnnoDirFlags(ctx, cmd)
1556
1557 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1558 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1559 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1560
1561 if baselineFile.Valid() {
1562 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1563 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1564 }
1565
1566 zipSyncCleanupCmd(rule, srcJarDir)
1567
1568 msg := fmt.Sprintf(`\n******************************\n`+
1569 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1570 `To make these errors go away, you have two choices:\n`+
1571 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1572 ` 2. You can update the baseline by executing the following command:\n`+
1573 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1574 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1575 rule.Command().
1576 Text("touch").Output(d.apiLintTimestamp).
1577 Text(") || (").
1578 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1579 Text("; exit 38").
1580 Text(")")
1581
1582 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1583
1584 }
1585
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001586 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001587 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001588
1589 if len(d.Javadoc.properties.Out) > 0 {
1590 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1591 }
1592
1593 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1594 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001595 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1596 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001597
Nan Zhang2760dfc2018-08-24 17:32:54 +00001598 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001599
Colin Cross33961b52019-07-11 11:01:22 -07001600 rule := android.NewRuleBuilder()
1601
1602 rule.Command().Text("( true")
1603
1604 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1605 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1606
1607 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1608 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1609
1610 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1611 FlagWithInput("--check-compatibility:api:current ", apiFile).
1612 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1613
1614 d.inclusionAnnotationsFlags(ctx, cmd)
1615 d.mergeAnnoDirFlags(ctx, cmd)
1616
Adrian Roos14f75a92019-08-12 17:54:09 +02001617 if baselineFile.Valid() {
1618 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1619 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1620 }
1621
Colin Cross33961b52019-07-11 11:01:22 -07001622 zipSyncCleanupCmd(rule, srcJarDir)
1623
1624 msg := fmt.Sprintf(`\n******************************\n`+
1625 `You have tried to change the API from what has been previously approved.\n\n`+
1626 `To make these errors go away, you have two choices:\n`+
1627 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1628 ` errors above.\n\n`+
1629 ` 2. You can update current.txt by executing the following command:\n`+
1630 ` make %s-update-current-api\n\n`+
1631 ` To submit the revised current.txt to the main Android repository,\n`+
1632 ` you will need approval.\n`+
1633 `******************************\n`, ctx.ModuleName())
1634
1635 rule.Command().
1636 Text("touch").Output(d.checkCurrentApiTimestamp).
1637 Text(") || (").
1638 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1639 Text("; exit 38").
1640 Text(")")
1641
1642 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001643
1644 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001645
1646 // update API rule
1647 rule = android.NewRuleBuilder()
1648
1649 rule.Command().Text("( true")
1650
1651 rule.Command().
1652 Text("cp").Flag("-f").
1653 Input(d.apiFile).Flag(apiFile.String())
1654
1655 rule.Command().
1656 Text("cp").Flag("-f").
1657 Input(d.removedApiFile).Flag(removedApiFile.String())
1658
1659 msg = "failed to update public API"
1660
1661 rule.Command().
1662 Text("touch").Output(d.updateCurrentApiTimestamp).
1663 Text(") || (").
1664 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1665 Text("; exit 38").
1666 Text(")")
1667
1668 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001669 }
Nan Zhanga40da042018-08-01 12:48:00 -07001670
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001671 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001672 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001673
1674 if len(d.Javadoc.properties.Out) > 0 {
1675 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1676 }
1677
1678 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1679 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001680 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1681 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001682
Nan Zhang2760dfc2018-08-24 17:32:54 +00001683 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001684
Colin Cross33961b52019-07-11 11:01:22 -07001685 rule := android.NewRuleBuilder()
1686
1687 rule.Command().Text("( true")
1688
1689 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1690 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1691
1692 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1693 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1694
1695 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1696 FlagWithInput("--check-compatibility:api:released ", apiFile)
1697
1698 d.inclusionAnnotationsFlags(ctx, cmd)
1699
1700 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1701
1702 d.mergeAnnoDirFlags(ctx, cmd)
1703
Adrian Roos14f75a92019-08-12 17:54:09 +02001704 if baselineFile.Valid() {
1705 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1706 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1707 }
1708
Colin Cross33961b52019-07-11 11:01:22 -07001709 zipSyncCleanupCmd(rule, srcJarDir)
1710
1711 msg := `\n******************************\n` +
1712 `You have tried to change the API from what has been previously released in\n` +
1713 `an SDK. Please fix the errors listed above.\n` +
1714 `******************************\n`
1715 rule.Command().
1716 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1717 Text(") || (").
1718 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1719 Text("; exit 38").
1720 Text(")")
1721
1722 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001723 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001724
Pete Gillin581d6082018-10-22 15:55:04 +01001725 if String(d.properties.Check_nullability_warnings) != "" {
1726 if d.nullabilityWarningsFile == nil {
1727 ctx.PropertyErrorf("check_nullability_warnings",
1728 "Cannot specify check_nullability_warnings unless validating nullability")
1729 }
Colin Cross33961b52019-07-11 11:01:22 -07001730
1731 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1732
Pete Gillin581d6082018-10-22 15:55:04 +01001733 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001734
Pete Gillin581d6082018-10-22 15:55:04 +01001735 msg := fmt.Sprintf(`\n******************************\n`+
1736 `The warnings encountered during nullability annotation validation did\n`+
1737 `not match the checked in file of expected warnings. The diffs are shown\n`+
1738 `above. You have two options:\n`+
1739 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1740 ` 2. Update the file of expected warnings by running:\n`+
1741 ` cp %s %s\n`+
1742 ` and submitting the updated file as part of your change.`,
1743 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001744
1745 rule := android.NewRuleBuilder()
1746
1747 rule.Command().
1748 Text("(").
1749 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1750 Text("&&").
1751 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1752 Text(") || (").
1753 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1754 Text("; exit 38").
1755 Text(")")
1756
1757 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001758 }
1759
Nan Zhang71bbe632018-09-17 14:32:21 -07001760 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001761 if len(d.Javadoc.properties.Out) > 0 {
1762 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1763 }
1764
1765 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1766 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1767 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1768
1769 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001770
Nan Zhang86b06202018-09-21 17:09:21 -07001771 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1772 // since there's cron job downstream that fetch this .zip file periodically.
1773 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001774 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1775 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1776
Nan Zhang71bbe632018-09-17 14:32:21 -07001777 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001778
Colin Cross33961b52019-07-11 11:01:22 -07001779 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1780 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001781
Colin Cross33961b52019-07-11 11:01:22 -07001782 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1783
Colin Crossdaa4c672019-07-15 22:53:46 -07001784 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001785 deps.bootClasspath, deps.classpath, d.sourcepaths)
1786
1787 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001788 Flag("-XDignore.symbol.file").
1789 FlagWithArg("-doclet ", "jdiff.JDiff").
1790 FlagWithInput("-docletpath ", jdiff).
1791 Flag("-quiet").
1792 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1793 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1794 Implicit(d.apiXmlFile).
1795 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1796 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1797 Implicit(d.lastReleasedApiXmlFile)
1798
Colin Cross33961b52019-07-11 11:01:22 -07001799 rule.Command().
1800 BuiltTool(ctx, "soong_zip").
1801 Flag("-write_if_changed").
1802 Flag("-d").
1803 FlagWithOutput("-o ", d.jdiffDocZip).
1804 FlagWithArg("-C ", outDir.String()).
1805 FlagWithArg("-D ", outDir.String())
1806
1807 rule.Command().
1808 BuiltTool(ctx, "soong_zip").
1809 Flag("-write_if_changed").
1810 Flag("-jar").
1811 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1812 FlagWithArg("-C ", stubsDir.String()).
1813 FlagWithArg("-D ", stubsDir.String())
1814
1815 rule.Restat()
1816
1817 zipSyncCleanupCmd(rule, srcJarDir)
1818
1819 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001820 }
Nan Zhang581fd212018-01-10 16:06:12 -08001821}
Dan Willemsencc090972018-02-26 14:33:31 -08001822
Nan Zhanga40da042018-08-01 12:48:00 -07001823//
Nan Zhangf4936b02018-08-01 15:00:28 -07001824// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001825//
Dan Willemsencc090972018-02-26 14:33:31 -08001826var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001827var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001828var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001829var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001830
Nan Zhangf4936b02018-08-01 15:00:28 -07001831type ExportedDroiddocDirProperties struct {
1832 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001833 Path *string
1834}
1835
Nan Zhangf4936b02018-08-01 15:00:28 -07001836type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001837 android.ModuleBase
1838
Nan Zhangf4936b02018-08-01 15:00:28 -07001839 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001840
1841 deps android.Paths
1842 dir android.Path
1843}
1844
Colin Crossa3002fc2019-07-08 16:48:04 -07001845// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001846func ExportedDroiddocDirFactory() android.Module {
1847 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001848 module.AddProperties(&module.properties)
1849 android.InitAndroidModule(module)
1850 return module
1851}
1852
Nan Zhangf4936b02018-08-01 15:00:28 -07001853func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001854
Nan Zhangf4936b02018-08-01 15:00:28 -07001855func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001856 path := String(d.properties.Path)
1857 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001858 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001859}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001860
1861//
1862// Defaults
1863//
1864type DocDefaults struct {
1865 android.ModuleBase
1866 android.DefaultsModuleBase
1867}
1868
Nan Zhangb2b33de2018-02-23 11:18:47 -08001869func DocDefaultsFactory() android.Module {
1870 module := &DocDefaults{}
1871
1872 module.AddProperties(
1873 &JavadocProperties{},
1874 &DroiddocProperties{},
1875 )
1876
1877 android.InitDefaultsModule(module)
1878
1879 return module
1880}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001881
1882func StubsDefaultsFactory() android.Module {
1883 module := &DocDefaults{}
1884
1885 module.AddProperties(
1886 &JavadocProperties{},
1887 &DroidstubsProperties{},
1888 )
1889
1890 android.InitDefaultsModule(module)
1891
1892 return module
1893}
Colin Cross33961b52019-07-11 11:01:22 -07001894
1895func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1896 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1897
1898 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1899 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1900 srcJarList := srcJarDir.Join(ctx, "list")
1901
1902 rule.Temporary(srcJarList)
1903
1904 rule.Command().BuiltTool(ctx, "zipsync").
1905 FlagWithArg("-d ", srcJarDir.String()).
1906 FlagWithOutput("-l ", srcJarList).
1907 FlagWithArg("-f ", `"*.java"`).
1908 Inputs(srcJars)
1909
1910 return srcJarList
1911}
1912
1913func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1914 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1915}