blob: 32758f6ff50d0760bcc50d2ec9f7abe4fc202ca8 [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang581fd212018-01-10 16:06:12 -080020 "strings"
21
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080029 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070030 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080031
Nan Zhang581fd212018-01-10 16:06:12 -080032 android.RegisterModuleType("droiddoc", DroiddocFactory)
33 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070034 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080035 android.RegisterModuleType("javadoc", JavadocFactory)
36 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070037
38 android.RegisterModuleType("droidstubs", DroidstubsFactory)
39 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080040}
41
Colin Crossa1ce2a02018-06-20 15:19:39 -070042var (
43 srcsLibTag = dependencyTag{name: "sources from javalib"}
44)
45
Nan Zhang581fd212018-01-10 16:06:12 -080046type JavadocProperties struct {
47 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
48 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080049 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080050
51 // list of directories rooted at the Android.bp file that will
52 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080053 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080054
55 // list of source files that should not be used to build the Java module.
56 // This is most useful in the arch/multilib variants to remove non-common files
57 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080058 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080059
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090060 // list of package names that should actually be used. If this property is left unspecified,
61 // all the sources from the srcs property is used.
62 Filter_packages []string
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080065 Libs []string `android:"arch_variant"`
66
67 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080068 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080069
Paul Duffine25c6442019-10-11 13:50:28 +010070 // if not blank, set to the version of the sdk to compile against.
71 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080072 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090073
Paul Duffine25c6442019-10-11 13:50:28 +010074 // When targeting 1.9 and above, override the modules to use with --system,
75 // otherwise provides defaults libraries to add to the bootclasspath.
76 // Defaults to "none"
77 System_modules *string
78
Jiyong Park1e440682018-05-23 18:42:04 +090079 Aidl struct {
80 // Top level directories to pass to aidl tool
81 Include_dirs []string
82
83 // Directories rooted at the Android.bp file to pass to aidl tool
84 Local_include_dirs []string
85 }
Nan Zhang357466b2018-04-17 17:38:36 -070086
87 // If not blank, set the java version passed to javadoc as -source
88 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080091 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070092
93 // user customized droiddoc args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070097 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070098 Args *string
99
100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // if set to true, collect the values used by the Dev tools and
146 // write them in files packaged with the SDK. Defaults to false.
147 Write_sdk_values *bool
148
149 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
152 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700154
Nan Zhang581fd212018-01-10 16:06:12 -0800155 // a list of files under current module source dir which contains known tags in Java sources.
156 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800157 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700158
159 // the tag name used to distinguish if the API files belong to public/system/test.
160 Api_tag_name *string
161
162 // the generated public API filename by Doclava.
163 Api_filename *string
164
David Brazdilfbe4cc32018-05-31 13:56:46 +0100165 // the generated public Dex API filename by Doclava.
166 Dex_api_filename *string
167
Nan Zhang28c68b92018-03-13 16:17:01 -0700168 // the generated private API filename by Doclava.
169 Private_api_filename *string
170
171 // the generated private Dex API filename by Doclava.
172 Private_dex_api_filename *string
173
174 // the generated removed API filename by Doclava.
175 Removed_api_filename *string
176
David Brazdilaac0c3c2018-04-24 16:23:29 +0100177 // the generated removed Dex API filename by Doclava.
178 Removed_dex_api_filename *string
179
Mathew Inwood76c3de12018-06-22 15:28:11 +0100180 // mapping of dex signatures to source file and line number. This is a temporary property and
181 // will be deleted; you probably shouldn't be using it.
182 Dex_mapping_filename *string
183
Nan Zhang28c68b92018-03-13 16:17:01 -0700184 // the generated exact API filename by Doclava.
185 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700186
Nan Zhang66dc2362018-08-14 20:41:04 -0700187 // the generated proguard filename by Doclava.
188 Proguard_filename *string
189
Nan Zhang853f4202018-04-12 16:55:56 -0700190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900197
198 // do not perform API check against Last_released, in the case that both two specified API
199 // files by Last_released are modules which don't exist.
200 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700201 }
Nan Zhang79614d12018-04-19 18:03:39 -0700202
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 // if set to true, generate docs through Dokka instead of Doclava.
204 Dokka_enabled *bool
205}
206
207type DroidstubsProperties struct {
208 // the tag name used to distinguish if the API files belong to public/system/test.
209 Api_tag_name *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Private_dex_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 Removed_dex_api_filename *string
228
Nan Zhang9c69a122018-08-22 10:22:08 -0700229 // mapping of dex signatures to source file and line number. This is a temporary property and
230 // will be deleted; you probably shouldn't be using it.
231 Dex_mapping_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700234 Exact_api_filename *string
235
Nan Zhang199645c2018-09-19 12:40:06 -0700236 // the generated proguard filename by Metalava.
237 Proguard_filename *string
238
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Check_api struct {
240 Last_released ApiToCheck
241
242 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900243
244 // do not perform API check against Last_released, in the case that both two specified API
245 // files by Last_released are modules which don't exist.
246 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200247
248 Api_lint struct {
249 Enabled *bool
250
251 // If set, performs api_lint on any new APIs not found in the given signature file
252 New_since *string `android:"path"`
253
254 // If not blank, path to the baseline txt file for approved API lint violations.
255 Baseline_file *string `android:"path"`
256 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700257 }
Nan Zhang79614d12018-04-19 18:03:39 -0700258
259 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800260 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700261
262 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700264
Pete Gillin77167902018-09-19 18:16:26 +0100265 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700266 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700267
Pete Gillin77167902018-09-19 18:16:26 +0100268 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
269 Merge_inclusion_annotations_dirs []string
270
Pete Gillinc382a562018-11-14 18:45:46 +0000271 // a file containing a list of classes to do nullability validation for.
272 Validate_nullability_from_list *string
273
Pete Gillin581d6082018-10-22 15:55:04 +0100274 // a file containing expected warnings produced by validation of nullability annotations.
275 Check_nullability_warnings *string
276
Nan Zhang1598a9e2018-09-04 17:14:32 -0700277 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
278 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700279
280 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
281 Api_levels_annotations_enabled *bool
282
283 // the dirs which Metalava extracts API levels annotations from.
284 Api_levels_annotations_dirs []string
285
286 // if set to true, collect the values used by the Dev tools and
287 // write them in files packaged with the SDK. Defaults to false.
288 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700289
290 // If set to true, .xml based public API file will be also generated, and
291 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
292 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800293}
294
Nan Zhanga40da042018-08-01 12:48:00 -0700295//
296// Common flags passed down to build rule
297//
298type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700299 bootClasspathArgs string
300 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700301 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700302 dokkaClasspathArgs string
303 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700304 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700305
Nan Zhanga40da042018-08-01 12:48:00 -0700306 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700307 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700308 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700309}
310
311func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
312 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
313 android.InitDefaultableModule(module)
314}
315
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200316func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
317 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
318 return false
319 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700320 return true
321 } else if String(apiToCheck.Api_file) != "" {
322 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
323 } else if String(apiToCheck.Removed_api_file) != "" {
324 panic("for " + apiVersionTag + " api_file has to be non-empty!")
325 }
326
327 return false
328}
329
Inseob Kim38449af2019-02-28 14:24:05 +0900330func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
331 api_file := String(apiToCheck.Api_file)
332 removed_api_file := String(apiToCheck.Removed_api_file)
333
334 api_module := android.SrcIsModule(api_file)
335 removed_api_module := android.SrcIsModule(removed_api_file)
336
337 if api_module == "" || removed_api_module == "" {
338 return
339 }
340
341 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
342 return
343 }
344
345 apiToCheck.Api_file = nil
346 apiToCheck.Removed_api_file = nil
347}
348
Nan Zhang1598a9e2018-09-04 17:14:32 -0700349type ApiFilePath interface {
350 ApiFilePath() android.Path
351}
352
Nan Zhanga40da042018-08-01 12:48:00 -0700353//
354// Javadoc
355//
Nan Zhang581fd212018-01-10 16:06:12 -0800356type Javadoc struct {
357 android.ModuleBase
358 android.DefaultableModuleBase
359
360 properties JavadocProperties
361
362 srcJars android.Paths
363 srcFiles android.Paths
364 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700365 argFiles android.Paths
366
367 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800368
Nan Zhangccff0f72018-03-08 17:26:16 -0800369 docZip android.WritablePath
370 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800371}
372
Colin Cross41955e82019-05-29 14:40:35 -0700373func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
374 switch tag {
375 case "":
376 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700377 case ".docs.zip":
378 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700379 default:
380 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
381 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800382}
383
Colin Crossa3002fc2019-07-08 16:48:04 -0700384// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800385func JavadocFactory() android.Module {
386 module := &Javadoc{}
387
388 module.AddProperties(&module.properties)
389
390 InitDroiddocModule(module, android.HostAndDeviceSupported)
391 return module
392}
393
Colin Crossa3002fc2019-07-08 16:48:04 -0700394// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800395func JavadocHostFactory() android.Module {
396 module := &Javadoc{}
397
398 module.AddProperties(&module.properties)
399
400 InitDroiddocModule(module, android.HostSupported)
401 return module
402}
403
Colin Cross41955e82019-05-29 14:40:35 -0700404var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800405
Colin Cross83bb3162018-06-25 15:48:06 -0700406func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900407 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700408}
409
Paul Duffine25c6442019-10-11 13:50:28 +0100410func (j *Javadoc) systemModules() string {
411 return proptools.String(j.properties.System_modules)
412}
413
Colin Cross83bb3162018-06-25 15:48:06 -0700414func (j *Javadoc) minSdkVersion() string {
415 return j.sdkVersion()
416}
417
Dan Willemsen419290a2018-10-31 15:28:47 -0700418func (j *Javadoc) targetSdkVersion() string {
419 return j.sdkVersion()
420}
421
Nan Zhang581fd212018-01-10 16:06:12 -0800422func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
423 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100424 sdkDep := decodeSdkDep(ctx, sdkContext(j))
425 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700426 if sdkDep.useDefaultLibs {
427 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
Pete Gillina1c9e9d2019-10-17 14:52:07 +0100428 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
Paul Duffin250e6192019-06-07 10:44:37 +0100429 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700430 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
431 }
432 } else if sdkDep.useModule {
Pete Gillina1c9e9d2019-10-17 14:52:07 +0100433 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Nan Zhang5994b622018-09-21 16:39:51 -0700434 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700435 }
Paul Duffine25c6442019-10-11 13:50:28 +0100436 } else if sdkDep.systemModules != "" {
437 // Add the system modules to both the system modules and bootclasspath.
438 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
439 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800440 }
441 }
442
Colin Cross42d48b72018-08-29 14:10:52 -0700443 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800444}
445
Nan Zhanga40da042018-08-01 12:48:00 -0700446func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
447 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900448
Colin Cross3047fa22019-04-18 10:56:44 -0700449 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900450
451 return flags
452}
453
454func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700455 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900456
457 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
458 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
459
460 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700461 var deps android.Paths
462
Jiyong Park1e440682018-05-23 18:42:04 +0900463 if aidlPreprocess.Valid() {
464 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700465 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900466 } else {
467 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
468 }
469
470 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
471 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
472 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
473 flags = append(flags, "-I"+src.String())
474 }
475
Colin Cross3047fa22019-04-18 10:56:44 -0700476 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900477}
478
Jiyong Parkd90d7412019-08-20 22:49:19 +0900479// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900480func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700481 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900482
483 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700484 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900485
Jiyong Park1112c4c2019-08-16 21:12:10 +0900486 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
487
Jiyong Park1e440682018-05-23 18:42:04 +0900488 for _, srcFile := range srcFiles {
489 switch srcFile.Ext() {
490 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700491 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900492 case ".logtags":
493 javaFile := genLogtags(ctx, srcFile)
494 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900495 default:
496 outSrcFiles = append(outSrcFiles, srcFile)
497 }
498 }
499
Colin Crossc0806172019-06-14 18:51:47 -0700500 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
501 if len(aidlSrcs) > 0 {
502 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
503 outSrcFiles = append(outSrcFiles, srcJarFiles...)
504 }
505
Jiyong Park1e440682018-05-23 18:42:04 +0900506 return outSrcFiles
507}
508
Nan Zhang581fd212018-01-10 16:06:12 -0800509func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
510 var deps deps
511
Colin Cross83bb3162018-06-25 15:48:06 -0700512 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800513 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700514 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800515 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700516 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800517 }
518
519 ctx.VisitDirectDeps(func(module android.Module) {
520 otherName := ctx.OtherModuleName(module)
521 tag := ctx.OtherModuleDependencyTag(module)
522
Colin Cross2d24c1b2018-05-23 10:59:18 -0700523 switch tag {
524 case bootClasspathTag:
525 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800526 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffine25c6442019-10-11 13:50:28 +0100527 } else if sm, ok := module.(*SystemModules); ok {
528 // A system modules dependency has been added to the bootclasspath
529 // so add its libs to the bootclasspath.
530 deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700531 } else {
532 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
533 }
534 case libTag:
535 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800536 case SdkLibraryDependency:
537 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700538 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900539 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900540 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700541 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800542 checkProducesJars(ctx, dep)
543 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800544 default:
545 ctx.ModuleErrorf("depends on non-java module %q", otherName)
546 }
Nan Zhang357466b2018-04-17 17:38:36 -0700547 case systemModulesTag:
548 if deps.systemModules != nil {
549 panic("Found two system module dependencies")
550 }
551 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000552 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700553 panic("Missing directory for system module dependency")
554 }
Colin Crossb77043e2019-07-16 13:57:13 -0700555 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800556 }
557 })
558 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
559 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800560 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900561
562 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
563 if filterPackages == nil {
564 return srcs
565 }
566 filtered := []android.Path{}
567 for _, src := range srcs {
568 if src.Ext() != ".java" {
569 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
570 // but otherwise metalava emits stub sources having references to the generated AIDL classes
571 // in filtered-out pacages (e.g. com.android.internal.*).
572 // TODO(b/141149570) We need to fix this by introducing default private constructors or
573 // fixing metalava to not emit constructors having references to unknown classes.
574 filtered = append(filtered, src)
575 continue
576 }
577 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
578 for _, pkg := range filterPackages {
579 if strings.HasPrefix(packageName, pkg) {
580 filtered = append(filtered, src)
581 break
582 }
583 }
584 }
585 return filtered
586 }
587 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
588
Nan Zhanga40da042018-08-01 12:48:00 -0700589 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900590 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800591
592 // srcs may depend on some genrule output.
593 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800594 j.srcJars = append(j.srcJars, deps.srcJars...)
595
Nan Zhang581fd212018-01-10 16:06:12 -0800596 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800597 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800598
Nan Zhang9c69a122018-08-22 10:22:08 -0700599 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800600 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
601 }
602 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800603
Colin Cross8a497952019-03-05 22:25:09 -0800604 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000605 argFilesMap := map[string]string{}
606 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700607
Paul Duffin99e4a502019-02-11 15:38:42 +0000608 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800609 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000610 if _, exists := argFilesMap[label]; !exists {
611 argFilesMap[label] = strings.Join(paths.Strings(), " ")
612 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700613 } else {
614 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000615 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700616 }
617 }
618
619 var err error
Colin Cross15638152019-07-11 11:11:35 -0700620 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700621 if strings.HasPrefix(name, "location ") {
622 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000623 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700624 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700625 } else {
Colin Cross15638152019-07-11 11:11:35 -0700626 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000627 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700628 }
629 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700630 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700631 }
Colin Cross15638152019-07-11 11:11:35 -0700632 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700633 })
634
635 if err != nil {
636 ctx.PropertyErrorf("args", "%s", err.Error())
637 }
638
Nan Zhang581fd212018-01-10 16:06:12 -0800639 return deps
640}
641
642func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
643 j.addDeps(ctx)
644}
645
646func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
647 deps := j.collectDeps(ctx)
648
Colin Crossdaa4c672019-07-15 22:53:46 -0700649 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800650
Colin Crossdaa4c672019-07-15 22:53:46 -0700651 outDir := android.PathForModuleOut(ctx, "out")
652 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
653
654 j.stubsSrcJar = nil
655
656 rule := android.NewRuleBuilder()
657
658 rule.Command().Text("rm -rf").Text(outDir.String())
659 rule.Command().Text("mkdir -p").Text(outDir.String())
660
661 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700662
Colin Cross83bb3162018-06-25 15:48:06 -0700663 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800664
Colin Crossdaa4c672019-07-15 22:53:46 -0700665 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
666 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800667
Colin Cross1e743852019-10-28 11:37:20 -0700668 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700669 Flag("-J-Xmx1024m").
670 Flag("-XDignore.symbol.file").
671 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800672
Colin Crossdaa4c672019-07-15 22:53:46 -0700673 rule.Command().
674 BuiltTool(ctx, "soong_zip").
675 Flag("-write_if_changed").
676 Flag("-d").
677 FlagWithOutput("-o ", j.docZip).
678 FlagWithArg("-C ", outDir.String()).
679 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700680
Colin Crossdaa4c672019-07-15 22:53:46 -0700681 rule.Restat()
682
683 zipSyncCleanupCmd(rule, srcJarDir)
684
685 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800686}
687
Nan Zhanga40da042018-08-01 12:48:00 -0700688//
689// Droiddoc
690//
691type Droiddoc struct {
692 Javadoc
693
694 properties DroiddocProperties
695 apiFile android.WritablePath
696 dexApiFile android.WritablePath
697 privateApiFile android.WritablePath
698 privateDexApiFile android.WritablePath
699 removedApiFile android.WritablePath
700 removedDexApiFile android.WritablePath
701 exactApiFile android.WritablePath
702 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700703 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700704
705 checkCurrentApiTimestamp android.WritablePath
706 updateCurrentApiTimestamp android.WritablePath
707 checkLastReleasedApiTimestamp android.WritablePath
708
Nan Zhanga40da042018-08-01 12:48:00 -0700709 apiFilePath android.Path
710}
711
Colin Crossa3002fc2019-07-08 16:48:04 -0700712// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700713func DroiddocFactory() android.Module {
714 module := &Droiddoc{}
715
716 module.AddProperties(&module.properties,
717 &module.Javadoc.properties)
718
719 InitDroiddocModule(module, android.HostAndDeviceSupported)
720 return module
721}
722
Colin Crossa3002fc2019-07-08 16:48:04 -0700723// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700724func DroiddocHostFactory() android.Module {
725 module := &Droiddoc{}
726
727 module.AddProperties(&module.properties,
728 &module.Javadoc.properties)
729
730 InitDroiddocModule(module, android.HostSupported)
731 return module
732}
733
734func (d *Droiddoc) ApiFilePath() android.Path {
735 return d.apiFilePath
736}
737
Nan Zhang581fd212018-01-10 16:06:12 -0800738func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
739 d.Javadoc.addDeps(ctx)
740
Inseob Kim38449af2019-02-28 14:24:05 +0900741 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
742 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
743 }
744
Nan Zhang79614d12018-04-19 18:03:39 -0700745 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800746 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
747 }
Nan Zhang581fd212018-01-10 16:06:12 -0800748}
749
Colin Crossab054432019-07-15 16:13:59 -0700750func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700751 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
752 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
753 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700754 cmd.FlagWithArg("-source ", "1.8").
755 Flag("-J-Xmx1600m").
756 Flag("-J-XX:-OmitStackTraceInFastThrow").
757 Flag("-XDignore.symbol.file").
758 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
759 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
760 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700761 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 -0700762
Nan Zhanga40da042018-08-01 12:48:00 -0700763 if String(d.properties.Custom_template) == "" {
764 // TODO: This is almost always droiddoc-templates-sdk
765 ctx.PropertyErrorf("custom_template", "must specify a template")
766 }
767
768 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700769 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700770 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700771 } else {
772 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
773 }
774 })
775
776 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700777 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
778 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
779 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700780 }
781
782 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700783 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
784 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
785 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700786 }
787
788 if len(d.properties.Html_dirs) > 2 {
789 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
790 }
791
Colin Cross8a497952019-03-05 22:25:09 -0800792 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700793 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700794
Colin Crossab054432019-07-15 16:13:59 -0700795 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700796
797 if String(d.properties.Proofread_file) != "" {
798 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700799 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700800 }
801
802 if String(d.properties.Todo_file) != "" {
803 // tricky part:
804 // we should not compute full path for todo_file through PathForModuleOut().
805 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700806 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
807 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700808 }
809
810 if String(d.properties.Resourcesdir) != "" {
811 // TODO: should we add files under resourcesDir to the implicits? It seems that
812 // resourcesDir is one sub dir of htmlDir
813 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700814 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700815 }
816
817 if String(d.properties.Resourcesoutdir) != "" {
818 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700819 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700820 }
Nan Zhanga40da042018-08-01 12:48:00 -0700821}
822
Colin Crossab054432019-07-15 16:13:59 -0700823func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200824 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
825 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700826 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700827
Nan Zhanga40da042018-08-01 12:48:00 -0700828 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700829 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700830 d.apiFilePath = d.apiFile
831 }
832
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200833 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
834 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700835 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700836 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700837 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700838 }
839
840 if String(d.properties.Private_api_filename) != "" {
841 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700842 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700843 }
844
845 if String(d.properties.Dex_api_filename) != "" {
846 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700847 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700848 }
849
850 if String(d.properties.Private_dex_api_filename) != "" {
851 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700852 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700853 }
854
855 if String(d.properties.Removed_dex_api_filename) != "" {
856 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700857 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700858 }
859
860 if String(d.properties.Exact_api_filename) != "" {
861 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700862 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700863 }
864
865 if String(d.properties.Dex_mapping_filename) != "" {
866 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700867 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700868 }
869
Nan Zhang66dc2362018-08-14 20:41:04 -0700870 if String(d.properties.Proguard_filename) != "" {
871 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700872 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700873 }
874
Nan Zhanga40da042018-08-01 12:48:00 -0700875 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700876 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700877 }
878
879 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700880 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700881 }
Nan Zhanga40da042018-08-01 12:48:00 -0700882}
883
Colin Crossab054432019-07-15 16:13:59 -0700884func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700885 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700886 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
887 rule.Command().Text("cp").
888 Input(staticDocIndexRedirect).
889 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700890 }
891
892 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700893 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
894 rule.Command().Text("cp").
895 Input(staticDocProperties).
896 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700897 }
Nan Zhanga40da042018-08-01 12:48:00 -0700898}
899
Colin Crossab054432019-07-15 16:13:59 -0700900func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700901 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700902
903 cmd := rule.Command().
904 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
905 Flag(config.JavacVmFlags).
906 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700907 FlagWithRspFileInputList("@", srcs).
908 FlagWithInput("@", srcJarList)
909
Colin Crossab054432019-07-15 16:13:59 -0700910 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
911 // based stubs generation.
912 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
913 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
914 // the correct package name base path.
915 if len(sourcepaths) > 0 {
916 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
917 } else {
918 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
919 }
920
921 cmd.FlagWithArg("-d ", outDir.String()).
922 Flag("-quiet")
923
924 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700925}
926
Colin Crossdaa4c672019-07-15 22:53:46 -0700927func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
928 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
929 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
930
931 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
932
933 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
934 cmd.Flag(flag).Implicits(deps)
935
936 cmd.FlagWithArg("--patch-module ", "java.base=.")
937
938 if len(classpath) > 0 {
939 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
940 }
941
942 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700943}
944
Colin Crossdaa4c672019-07-15 22:53:46 -0700945func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
946 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
947 sourcepaths android.Paths) *android.RuleBuilderCommand {
948
949 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
950
951 if len(bootclasspath) == 0 && ctx.Device() {
952 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
953 // ensure java does not fall back to the default bootclasspath.
954 cmd.FlagWithArg("-bootclasspath ", `""`)
955 } else if len(bootclasspath) > 0 {
956 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
957 }
958
959 if len(classpath) > 0 {
960 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
961 }
962
963 return cmd
964}
965
Colin Crossab054432019-07-15 16:13:59 -0700966func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
967 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700968
Colin Crossab054432019-07-15 16:13:59 -0700969 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
970 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
971
972 return rule.Command().
973 BuiltTool(ctx, "dokka").
974 Flag(config.JavacVmFlags).
975 Flag(srcJarDir.String()).
976 FlagWithInputList("-classpath ", dokkaClasspath, ":").
977 FlagWithArg("-format ", "dac").
978 FlagWithArg("-dacRoot ", "/reference/kotlin").
979 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700980}
981
982func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
983 deps := d.Javadoc.collectDeps(ctx)
984
Colin Crossdaa4c672019-07-15 22:53:46 -0700985 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
986 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
987
Nan Zhang1598a9e2018-09-04 17:14:32 -0700988 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
989 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
990 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
991 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
992
Colin Crossab054432019-07-15 16:13:59 -0700993 outDir := android.PathForModuleOut(ctx, "out")
994 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
995 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700996
Colin Crossab054432019-07-15 16:13:59 -0700997 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700998
Colin Crossab054432019-07-15 16:13:59 -0700999 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1000 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001001
Colin Crossab054432019-07-15 16:13:59 -07001002 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1003
1004 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001005 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001006 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001007 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001008 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001009 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001010 }
1011
Colin Crossab054432019-07-15 16:13:59 -07001012 d.stubsFlags(ctx, cmd, stubsDir)
1013
1014 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1015
1016 var desc string
1017 if Bool(d.properties.Dokka_enabled) {
1018 desc = "dokka"
1019 } else {
1020 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1021
1022 for _, o := range d.Javadoc.properties.Out {
1023 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1024 }
1025
1026 d.postDoclavaCmds(ctx, rule)
1027 desc = "doclava"
1028 }
1029
1030 rule.Command().
1031 BuiltTool(ctx, "soong_zip").
1032 Flag("-write_if_changed").
1033 Flag("-d").
1034 FlagWithOutput("-o ", d.docZip).
1035 FlagWithArg("-C ", outDir.String()).
1036 FlagWithArg("-D ", outDir.String())
1037
1038 rule.Command().
1039 BuiltTool(ctx, "soong_zip").
1040 Flag("-write_if_changed").
1041 Flag("-jar").
1042 FlagWithOutput("-o ", d.stubsSrcJar).
1043 FlagWithArg("-C ", stubsDir.String()).
1044 FlagWithArg("-D ", stubsDir.String())
1045
1046 rule.Restat()
1047
1048 zipSyncCleanupCmd(rule, srcJarDir)
1049
1050 rule.Build(pctx, ctx, "javadoc", desc)
1051
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001052 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001053 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001054
1055 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1056 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001057
1058 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001059
1060 rule := android.NewRuleBuilder()
1061
1062 rule.Command().Text("( true")
1063
1064 rule.Command().
1065 BuiltTool(ctx, "apicheck").
1066 Flag("-JXmx1024m").
1067 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1068 OptionalFlag(d.properties.Check_api.Current.Args).
1069 Input(apiFile).
1070 Input(d.apiFile).
1071 Input(removedApiFile).
1072 Input(d.removedApiFile)
1073
1074 msg := fmt.Sprintf(`\n******************************\n`+
1075 `You have tried to change the API from what has been previously approved.\n\n`+
1076 `To make these errors go away, you have two choices:\n`+
1077 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1078 ` errors above.\n\n`+
1079 ` 2. You can update current.txt by executing the following command:\n`+
1080 ` make %s-update-current-api\n\n`+
1081 ` To submit the revised current.txt to the main Android repository,\n`+
1082 ` you will need approval.\n`+
1083 `******************************\n`, ctx.ModuleName())
1084
1085 rule.Command().
1086 Text("touch").Output(d.checkCurrentApiTimestamp).
1087 Text(") || (").
1088 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1089 Text("; exit 38").
1090 Text(")")
1091
1092 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001093
1094 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001095
1096 // update API rule
1097 rule = android.NewRuleBuilder()
1098
1099 rule.Command().Text("( true")
1100
1101 rule.Command().
1102 Text("cp").Flag("-f").
1103 Input(d.apiFile).Flag(apiFile.String())
1104
1105 rule.Command().
1106 Text("cp").Flag("-f").
1107 Input(d.removedApiFile).Flag(removedApiFile.String())
1108
1109 msg = "failed to update public API"
1110
1111 rule.Command().
1112 Text("touch").Output(d.updateCurrentApiTimestamp).
1113 Text(") || (").
1114 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1115 Text("; exit 38").
1116 Text(")")
1117
1118 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001119 }
1120
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001121 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001122 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001123
1124 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1125 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001126
1127 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001128
1129 rule := android.NewRuleBuilder()
1130
1131 rule.Command().
1132 Text("(").
1133 BuiltTool(ctx, "apicheck").
1134 Flag("-JXmx1024m").
1135 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1136 OptionalFlag(d.properties.Check_api.Last_released.Args).
1137 Input(apiFile).
1138 Input(d.apiFile).
1139 Input(removedApiFile).
1140 Input(d.removedApiFile)
1141
1142 msg := `\n******************************\n` +
1143 `You have tried to change the API from what has been previously released in\n` +
1144 `an SDK. Please fix the errors listed above.\n` +
1145 `******************************\n`
1146
1147 rule.Command().
1148 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1149 Text(") || (").
1150 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1151 Text("; exit 38").
1152 Text(")")
1153
1154 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001155 }
1156}
1157
1158//
1159// Droidstubs
1160//
1161type Droidstubs struct {
1162 Javadoc
1163
Pete Gillin581d6082018-10-22 15:55:04 +01001164 properties DroidstubsProperties
1165 apiFile android.WritablePath
1166 apiXmlFile android.WritablePath
1167 lastReleasedApiXmlFile android.WritablePath
1168 dexApiFile android.WritablePath
1169 privateApiFile android.WritablePath
1170 privateDexApiFile android.WritablePath
1171 removedApiFile android.WritablePath
1172 removedDexApiFile android.WritablePath
1173 apiMappingFile android.WritablePath
1174 exactApiFile android.WritablePath
1175 proguardFile android.WritablePath
1176 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001177
1178 checkCurrentApiTimestamp android.WritablePath
1179 updateCurrentApiTimestamp android.WritablePath
1180 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001181 apiLintTimestamp android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001182
Pete Gillin581d6082018-10-22 15:55:04 +01001183 checkNullabilityWarningsTimestamp android.WritablePath
1184
Nan Zhang1598a9e2018-09-04 17:14:32 -07001185 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001186 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001187
1188 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001189
1190 jdiffDocZip android.WritablePath
1191 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001192
1193 metadataZip android.WritablePath
1194 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001195}
1196
Colin Crossa3002fc2019-07-08 16:48:04 -07001197// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1198// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1199// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001200func DroidstubsFactory() android.Module {
1201 module := &Droidstubs{}
1202
1203 module.AddProperties(&module.properties,
1204 &module.Javadoc.properties)
1205
1206 InitDroiddocModule(module, android.HostAndDeviceSupported)
1207 return module
1208}
1209
Colin Crossa3002fc2019-07-08 16:48:04 -07001210// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1211// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1212// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1213// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001214func DroidstubsHostFactory() android.Module {
1215 module := &Droidstubs{}
1216
1217 module.AddProperties(&module.properties,
1218 &module.Javadoc.properties)
1219
1220 InitDroiddocModule(module, android.HostSupported)
1221 return module
1222}
1223
1224func (d *Droidstubs) ApiFilePath() android.Path {
1225 return d.apiFilePath
1226}
1227
1228func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1229 d.Javadoc.addDeps(ctx)
1230
Inseob Kim38449af2019-02-28 14:24:05 +09001231 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1232 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1233 }
1234
Nan Zhang1598a9e2018-09-04 17:14:32 -07001235 if len(d.properties.Merge_annotations_dirs) != 0 {
1236 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1237 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1238 }
1239 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001240
Pete Gillin77167902018-09-19 18:16:26 +01001241 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1242 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1243 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1244 }
1245 }
1246
Nan Zhang9c69a122018-08-22 10:22:08 -07001247 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1248 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1249 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1250 }
1251 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001252}
1253
Colin Cross33961b52019-07-11 11:01:22 -07001254func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001255 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1256 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257 String(d.properties.Api_filename) != "" {
1258 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001259 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260 d.apiFilePath = d.apiFile
1261 }
1262
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001263 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1264 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265 String(d.properties.Removed_api_filename) != "" {
1266 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001267 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001268 }
1269
1270 if String(d.properties.Private_api_filename) != "" {
1271 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001272 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001273 }
1274
1275 if String(d.properties.Dex_api_filename) != "" {
1276 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001277 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001278 }
1279
1280 if String(d.properties.Private_dex_api_filename) != "" {
1281 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001282 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001283 }
1284
1285 if String(d.properties.Removed_dex_api_filename) != "" {
1286 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001287 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001288 }
1289
1290 if String(d.properties.Exact_api_filename) != "" {
1291 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001292 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001293 }
1294
Nan Zhang9c69a122018-08-22 10:22:08 -07001295 if String(d.properties.Dex_mapping_filename) != "" {
1296 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001297 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001298 }
1299
Nan Zhang199645c2018-09-19 12:40:06 -07001300 if String(d.properties.Proguard_filename) != "" {
1301 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001302 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001303 }
1304
Nan Zhang9c69a122018-08-22 10:22:08 -07001305 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001306 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1307 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001308 }
1309
Nan Zhang1598a9e2018-09-04 17:14:32 -07001310 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001311 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001312 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001313 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001314 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001315}
1316
Colin Cross33961b52019-07-11 11:01:22 -07001317func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001318 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.Flag("--include-annotations")
1320
Pete Gillinc382a562018-11-14 18:45:46 +00001321 validatingNullability :=
1322 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1323 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001324 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001325
Pete Gillina262c052018-09-14 14:25:48 +01001326 if !(migratingNullability || validatingNullability) {
1327 ctx.PropertyErrorf("previous_api",
1328 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001329 }
Colin Cross33961b52019-07-11 11:01:22 -07001330
Pete Gillina262c052018-09-14 14:25:48 +01001331 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001332 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001333 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001334 }
Colin Cross33961b52019-07-11 11:01:22 -07001335
Pete Gillinc382a562018-11-14 18:45:46 +00001336 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001337 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001338 }
Colin Cross33961b52019-07-11 11:01:22 -07001339
Pete Gillina262c052018-09-14 14:25:48 +01001340 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001341 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001342 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001343 }
Nan Zhanga40da042018-08-01 12:48:00 -07001344
1345 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001346 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001347
Nan Zhang1598a9e2018-09-04 17:14:32 -07001348 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001349 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001350 "has to be non-empty if annotations was enabled!")
1351 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001352
Colin Cross33961b52019-07-11 11:01:22 -07001353 d.mergeAnnoDirFlags(ctx, cmd)
1354
1355 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1356 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1357 FlagWithArg("--hide ", "SuperfluousPrefix").
1358 FlagWithArg("--hide ", "AnnotationExtraction")
1359 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001360}
1361
Colin Cross33961b52019-07-11 11:01:22 -07001362func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1363 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1364 if t, ok := m.(*ExportedDroiddocDir); ok {
1365 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1366 } else {
1367 ctx.PropertyErrorf("merge_annotations_dirs",
1368 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1369 }
1370 })
1371}
1372
1373func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001374 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1375 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001376 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001377 } else {
1378 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1379 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1380 }
1381 })
Nan Zhanga40da042018-08-01 12:48:00 -07001382}
1383
Colin Cross33961b52019-07-11 11:01:22 -07001384func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001385 if Bool(d.properties.Api_levels_annotations_enabled) {
1386 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001387
1388 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1389 ctx.PropertyErrorf("api_levels_annotations_dirs",
1390 "has to be non-empty if api levels annotations was enabled!")
1391 }
1392
Colin Cross33961b52019-07-11 11:01:22 -07001393 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1394 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1395 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1396 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001397
1398 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1399 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001400 for _, dep := range t.deps {
1401 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001402 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001403 }
1404 }
Colin Cross33961b52019-07-11 11:01:22 -07001405 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001406 } else {
1407 ctx.PropertyErrorf("api_levels_annotations_dirs",
1408 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1409 }
1410 })
1411
1412 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001413}
1414
Colin Cross33961b52019-07-11 11:01:22 -07001415func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001416 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1417 if d.apiFile.String() == "" {
1418 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1419 }
1420
1421 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001422 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001423
1424 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1425 ctx.PropertyErrorf("check_api.last_released.api_file",
1426 "has to be non-empty if jdiff was enabled!")
1427 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001428
Colin Cross33961b52019-07-11 11:01:22 -07001429 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001430 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001431 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1432 }
1433}
Nan Zhang71bbe632018-09-17 14:32:21 -07001434
Colin Cross1e743852019-10-28 11:37:20 -07001435func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Colin Cross33961b52019-07-11 11:01:22 -07001436 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1437 cmd := rule.Command().BuiltTool(ctx, "metalava").
1438 Flag(config.JavacVmFlags).
1439 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001440 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001441 FlagWithRspFileInputList("@", srcs).
1442 FlagWithInput("@", srcJarList)
1443
1444 if len(bootclasspath) > 0 {
1445 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001446 }
1447
Colin Cross33961b52019-07-11 11:01:22 -07001448 if len(classpath) > 0 {
1449 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1450 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001451
Colin Cross33961b52019-07-11 11:01:22 -07001452 if len(sourcepaths) > 0 {
1453 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1454 } else {
1455 cmd.FlagWithArg("-sourcepath ", `""`)
1456 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001457
Colin Cross33961b52019-07-11 11:01:22 -07001458 cmd.Flag("--no-banner").
1459 Flag("--color").
1460 Flag("--quiet").
1461 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001462
Colin Cross33961b52019-07-11 11:01:22 -07001463 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001464}
1465
Nan Zhang1598a9e2018-09-04 17:14:32 -07001466func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001467 deps := d.Javadoc.collectDeps(ctx)
1468
1469 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001470
Colin Cross33961b52019-07-11 11:01:22 -07001471 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001472
Colin Crossdaa4c672019-07-15 22:53:46 -07001473 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001474
Colin Cross33961b52019-07-11 11:01:22 -07001475 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1476 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001477
Colin Cross33961b52019-07-11 11:01:22 -07001478 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001479
Colin Cross33961b52019-07-11 11:01:22 -07001480 rule.Command().Text("rm -rf").Text(stubsDir.String())
1481 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001482
Colin Cross33961b52019-07-11 11:01:22 -07001483 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1484
1485 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1486 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1487
1488 d.stubsFlags(ctx, cmd, stubsDir)
1489
1490 d.annotationsFlags(ctx, cmd)
1491 d.inclusionAnnotationsFlags(ctx, cmd)
1492 d.apiLevelsAnnotationsFlags(ctx, cmd)
1493 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001494
Nan Zhang1598a9e2018-09-04 17:14:32 -07001495 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1496 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1497 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1498 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1499 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001500 }
Colin Cross33961b52019-07-11 11:01:22 -07001501
1502 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1503 for _, o := range d.Javadoc.properties.Out {
1504 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1505 }
1506
1507 rule.Command().
1508 BuiltTool(ctx, "soong_zip").
1509 Flag("-write_if_changed").
1510 Flag("-jar").
1511 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1512 FlagWithArg("-C ", stubsDir.String()).
1513 FlagWithArg("-D ", stubsDir.String())
Jerome Gaillard0f599032019-10-10 19:29:11 +01001514
1515 if Bool(d.properties.Write_sdk_values) {
1516 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1517 rule.Command().
1518 BuiltTool(ctx, "soong_zip").
1519 Flag("-write_if_changed").
1520 Flag("-d").
1521 FlagWithOutput("-o ", d.metadataZip).
1522 FlagWithArg("-C ", d.metadataDir.String()).
1523 FlagWithArg("-D ", d.metadataDir.String())
1524 }
1525
Colin Cross33961b52019-07-11 11:01:22 -07001526 rule.Restat()
1527
1528 zipSyncCleanupCmd(rule, srcJarDir)
1529
1530 rule.Build(pctx, ctx, "metalava", "metalava")
1531
1532 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001533
Adrian Roos075eedc2019-10-10 12:07:03 +02001534 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1535 rule := android.NewRuleBuilder()
1536 rule.Command().Text("( true")
1537
1538 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1539 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1540
1541 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1542 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1543
Adrian Rooscab4a2c2019-10-14 16:32:41 +02001544 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1545
Adrian Roos075eedc2019-10-10 12:07:03 +02001546 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1547 if newSince.Valid() {
1548 cmd.FlagWithInput("--api-lint ", newSince.Path())
1549 } else {
1550 cmd.Flag("--api-lint")
1551 }
1552
1553 d.inclusionAnnotationsFlags(ctx, cmd)
1554 d.mergeAnnoDirFlags(ctx, cmd)
1555
1556 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1557 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1558 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1559
1560 if baselineFile.Valid() {
1561 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1562 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1563 }
1564
1565 zipSyncCleanupCmd(rule, srcJarDir)
1566
1567 msg := fmt.Sprintf(`\n******************************\n`+
1568 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1569 `To make these errors go away, you have two choices:\n`+
1570 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1571 ` 2. You can update the baseline by executing the following command:\n`+
1572 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1573 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1574 rule.Command().
1575 Text("touch").Output(d.apiLintTimestamp).
1576 Text(") || (").
1577 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1578 Text("; exit 38").
1579 Text(")")
1580
1581 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1582
1583 }
1584
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001585 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001586 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001587
1588 if len(d.Javadoc.properties.Out) > 0 {
1589 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1590 }
1591
1592 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1593 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001594 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1595 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001596
Nan Zhang2760dfc2018-08-24 17:32:54 +00001597 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001598
Colin Cross33961b52019-07-11 11:01:22 -07001599 rule := android.NewRuleBuilder()
1600
1601 rule.Command().Text("( true")
1602
1603 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1604 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1605
1606 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1607 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1608
1609 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1610 FlagWithInput("--check-compatibility:api:current ", apiFile).
1611 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1612
1613 d.inclusionAnnotationsFlags(ctx, cmd)
1614 d.mergeAnnoDirFlags(ctx, cmd)
1615
Adrian Roos14f75a92019-08-12 17:54:09 +02001616 if baselineFile.Valid() {
1617 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1618 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1619 }
1620
Colin Cross33961b52019-07-11 11:01:22 -07001621 zipSyncCleanupCmd(rule, srcJarDir)
1622
1623 msg := fmt.Sprintf(`\n******************************\n`+
1624 `You have tried to change the API from what has been previously approved.\n\n`+
1625 `To make these errors go away, you have two choices:\n`+
1626 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1627 ` errors above.\n\n`+
1628 ` 2. You can update current.txt by executing the following command:\n`+
1629 ` make %s-update-current-api\n\n`+
1630 ` To submit the revised current.txt to the main Android repository,\n`+
1631 ` you will need approval.\n`+
1632 `******************************\n`, ctx.ModuleName())
1633
1634 rule.Command().
1635 Text("touch").Output(d.checkCurrentApiTimestamp).
1636 Text(") || (").
1637 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1638 Text("; exit 38").
1639 Text(")")
1640
1641 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001642
1643 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001644
1645 // update API rule
1646 rule = android.NewRuleBuilder()
1647
1648 rule.Command().Text("( true")
1649
1650 rule.Command().
1651 Text("cp").Flag("-f").
1652 Input(d.apiFile).Flag(apiFile.String())
1653
1654 rule.Command().
1655 Text("cp").Flag("-f").
1656 Input(d.removedApiFile).Flag(removedApiFile.String())
1657
1658 msg = "failed to update public API"
1659
1660 rule.Command().
1661 Text("touch").Output(d.updateCurrentApiTimestamp).
1662 Text(") || (").
1663 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1664 Text("; exit 38").
1665 Text(")")
1666
1667 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001668 }
Nan Zhanga40da042018-08-01 12:48:00 -07001669
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001670 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001671 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001672
1673 if len(d.Javadoc.properties.Out) > 0 {
1674 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1675 }
1676
1677 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1678 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001679 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1680 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001681
Nan Zhang2760dfc2018-08-24 17:32:54 +00001682 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001683
Colin Cross33961b52019-07-11 11:01:22 -07001684 rule := android.NewRuleBuilder()
1685
1686 rule.Command().Text("( true")
1687
1688 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1689 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1690
1691 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1692 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1693
1694 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1695 FlagWithInput("--check-compatibility:api:released ", apiFile)
1696
1697 d.inclusionAnnotationsFlags(ctx, cmd)
1698
1699 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1700
1701 d.mergeAnnoDirFlags(ctx, cmd)
1702
Adrian Roos14f75a92019-08-12 17:54:09 +02001703 if baselineFile.Valid() {
1704 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1705 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1706 }
1707
Colin Cross33961b52019-07-11 11:01:22 -07001708 zipSyncCleanupCmd(rule, srcJarDir)
1709
1710 msg := `\n******************************\n` +
1711 `You have tried to change the API from what has been previously released in\n` +
1712 `an SDK. Please fix the errors listed above.\n` +
1713 `******************************\n`
1714 rule.Command().
1715 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1716 Text(") || (").
1717 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1718 Text("; exit 38").
1719 Text(")")
1720
1721 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001722 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001723
Pete Gillin581d6082018-10-22 15:55:04 +01001724 if String(d.properties.Check_nullability_warnings) != "" {
1725 if d.nullabilityWarningsFile == nil {
1726 ctx.PropertyErrorf("check_nullability_warnings",
1727 "Cannot specify check_nullability_warnings unless validating nullability")
1728 }
Colin Cross33961b52019-07-11 11:01:22 -07001729
1730 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1731
Pete Gillin581d6082018-10-22 15:55:04 +01001732 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001733
Pete Gillin581d6082018-10-22 15:55:04 +01001734 msg := fmt.Sprintf(`\n******************************\n`+
1735 `The warnings encountered during nullability annotation validation did\n`+
1736 `not match the checked in file of expected warnings. The diffs are shown\n`+
1737 `above. You have two options:\n`+
1738 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1739 ` 2. Update the file of expected warnings by running:\n`+
1740 ` cp %s %s\n`+
1741 ` and submitting the updated file as part of your change.`,
1742 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001743
1744 rule := android.NewRuleBuilder()
1745
1746 rule.Command().
1747 Text("(").
1748 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1749 Text("&&").
1750 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1751 Text(") || (").
1752 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1753 Text("; exit 38").
1754 Text(")")
1755
1756 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001757 }
1758
Nan Zhang71bbe632018-09-17 14:32:21 -07001759 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001760 if len(d.Javadoc.properties.Out) > 0 {
1761 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1762 }
1763
1764 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1765 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1766 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1767
1768 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001769
Nan Zhang86b06202018-09-21 17:09:21 -07001770 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1771 // since there's cron job downstream that fetch this .zip file periodically.
1772 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001773 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1774 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1775
Nan Zhang71bbe632018-09-17 14:32:21 -07001776 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001777
Colin Cross33961b52019-07-11 11:01:22 -07001778 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1779 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001780
Colin Cross33961b52019-07-11 11:01:22 -07001781 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1782
Colin Crossdaa4c672019-07-15 22:53:46 -07001783 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001784 deps.bootClasspath, deps.classpath, d.sourcepaths)
1785
1786 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001787 Flag("-XDignore.symbol.file").
1788 FlagWithArg("-doclet ", "jdiff.JDiff").
1789 FlagWithInput("-docletpath ", jdiff).
1790 Flag("-quiet").
1791 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1792 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1793 Implicit(d.apiXmlFile).
1794 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1795 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1796 Implicit(d.lastReleasedApiXmlFile)
1797
Colin Cross33961b52019-07-11 11:01:22 -07001798 rule.Command().
1799 BuiltTool(ctx, "soong_zip").
1800 Flag("-write_if_changed").
1801 Flag("-d").
1802 FlagWithOutput("-o ", d.jdiffDocZip).
1803 FlagWithArg("-C ", outDir.String()).
1804 FlagWithArg("-D ", outDir.String())
1805
1806 rule.Command().
1807 BuiltTool(ctx, "soong_zip").
1808 Flag("-write_if_changed").
1809 Flag("-jar").
1810 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1811 FlagWithArg("-C ", stubsDir.String()).
1812 FlagWithArg("-D ", stubsDir.String())
1813
1814 rule.Restat()
1815
1816 zipSyncCleanupCmd(rule, srcJarDir)
1817
1818 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001819 }
Nan Zhang581fd212018-01-10 16:06:12 -08001820}
Dan Willemsencc090972018-02-26 14:33:31 -08001821
Nan Zhanga40da042018-08-01 12:48:00 -07001822//
Nan Zhangf4936b02018-08-01 15:00:28 -07001823// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001824//
Dan Willemsencc090972018-02-26 14:33:31 -08001825var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001826var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001827var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001828var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001829
Nan Zhangf4936b02018-08-01 15:00:28 -07001830type ExportedDroiddocDirProperties struct {
1831 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001832 Path *string
1833}
1834
Nan Zhangf4936b02018-08-01 15:00:28 -07001835type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001836 android.ModuleBase
1837
Nan Zhangf4936b02018-08-01 15:00:28 -07001838 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001839
1840 deps android.Paths
1841 dir android.Path
1842}
1843
Colin Crossa3002fc2019-07-08 16:48:04 -07001844// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001845func ExportedDroiddocDirFactory() android.Module {
1846 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001847 module.AddProperties(&module.properties)
1848 android.InitAndroidModule(module)
1849 return module
1850}
1851
Nan Zhangf4936b02018-08-01 15:00:28 -07001852func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001853
Nan Zhangf4936b02018-08-01 15:00:28 -07001854func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001855 path := String(d.properties.Path)
1856 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001857 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001858}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001859
1860//
1861// Defaults
1862//
1863type DocDefaults struct {
1864 android.ModuleBase
1865 android.DefaultsModuleBase
1866}
1867
Nan Zhangb2b33de2018-02-23 11:18:47 -08001868func DocDefaultsFactory() android.Module {
1869 module := &DocDefaults{}
1870
1871 module.AddProperties(
1872 &JavadocProperties{},
1873 &DroiddocProperties{},
1874 )
1875
1876 android.InitDefaultsModule(module)
1877
1878 return module
1879}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001880
1881func StubsDefaultsFactory() android.Module {
1882 module := &DocDefaults{}
1883
1884 module.AddProperties(
1885 &JavadocProperties{},
1886 &DroidstubsProperties{},
1887 )
1888
1889 android.InitDefaultsModule(module)
1890
1891 return module
1892}
Colin Cross33961b52019-07-11 11:01:22 -07001893
1894func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1895 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1896
1897 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1898 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1899 srcJarList := srcJarDir.Join(ctx, "list")
1900
1901 rule.Temporary(srcJarList)
1902
1903 rule.Command().BuiltTool(ctx, "zipsync").
1904 FlagWithArg("-d ", srcJarDir.String()).
1905 FlagWithOutput("-l ", srcJarList).
1906 FlagWithArg("-f ", `"*.java"`).
1907 Inputs(srcJars)
1908
1909 return srcJarList
1910}
1911
1912func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1913 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1914}