blob: 714412c771587c5e2e623601ecc7a0740ab8083b [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang581fd212018-01-10 16:06:12 -080020 "strings"
21
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080029 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070030 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080031
Nan Zhang581fd212018-01-10 16:06:12 -080032 android.RegisterModuleType("droiddoc", DroiddocFactory)
33 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070034 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080035 android.RegisterModuleType("javadoc", JavadocFactory)
36 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070037
38 android.RegisterModuleType("droidstubs", DroidstubsFactory)
39 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080040}
41
Colin Crossa1ce2a02018-06-20 15:19:39 -070042var (
43 srcsLibTag = dependencyTag{name: "sources from javalib"}
44)
45
Nan Zhang581fd212018-01-10 16:06:12 -080046type JavadocProperties struct {
47 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
48 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080049 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080050
51 // list of directories rooted at the Android.bp file that will
52 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080053 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080054
55 // list of source files that should not be used to build the Java module.
56 // This is most useful in the arch/multilib variants to remove non-common files
57 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080058 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080059
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090060 // list of package names that should actually be used. If this property is left unspecified,
61 // all the sources from the srcs property is used.
62 Filter_packages []string
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080065 Libs []string `android:"arch_variant"`
66
67 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080068 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080069
Paul Duffine25c6442019-10-11 13:50:28 +010070 // if not blank, set to the version of the sdk to compile against.
71 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080072 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090073
Paul Duffine25c6442019-10-11 13:50:28 +010074 // When targeting 1.9 and above, override the modules to use with --system,
75 // otherwise provides defaults libraries to add to the bootclasspath.
76 // Defaults to "none"
77 System_modules *string
78
Jiyong Park1e440682018-05-23 18:42:04 +090079 Aidl struct {
80 // Top level directories to pass to aidl tool
81 Include_dirs []string
82
83 // Directories rooted at the Android.bp file to pass to aidl tool
84 Local_include_dirs []string
85 }
Nan Zhang357466b2018-04-17 17:38:36 -070086
87 // If not blank, set the java version passed to javadoc as -source
88 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080091 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070092
93 // user customized droiddoc args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070097 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070098 Args *string
99
100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // if set to true, collect the values used by the Dev tools and
146 // write them in files packaged with the SDK. Defaults to false.
147 Write_sdk_values *bool
148
149 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
152 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700154
Nan Zhang581fd212018-01-10 16:06:12 -0800155 // a list of files under current module source dir which contains known tags in Java sources.
156 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800157 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700158
159 // the tag name used to distinguish if the API files belong to public/system/test.
160 Api_tag_name *string
161
162 // the generated public API filename by Doclava.
163 Api_filename *string
164
David Brazdilfbe4cc32018-05-31 13:56:46 +0100165 // the generated public Dex API filename by Doclava.
166 Dex_api_filename *string
167
Nan Zhang28c68b92018-03-13 16:17:01 -0700168 // the generated private API filename by Doclava.
169 Private_api_filename *string
170
171 // the generated private Dex API filename by Doclava.
172 Private_dex_api_filename *string
173
174 // the generated removed API filename by Doclava.
175 Removed_api_filename *string
176
David Brazdilaac0c3c2018-04-24 16:23:29 +0100177 // the generated removed Dex API filename by Doclava.
178 Removed_dex_api_filename *string
179
Mathew Inwood76c3de12018-06-22 15:28:11 +0100180 // mapping of dex signatures to source file and line number. This is a temporary property and
181 // will be deleted; you probably shouldn't be using it.
182 Dex_mapping_filename *string
183
Nan Zhang28c68b92018-03-13 16:17:01 -0700184 // the generated exact API filename by Doclava.
185 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700186
Nan Zhang66dc2362018-08-14 20:41:04 -0700187 // the generated proguard filename by Doclava.
188 Proguard_filename *string
189
Nan Zhang853f4202018-04-12 16:55:56 -0700190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900197
198 // do not perform API check against Last_released, in the case that both two specified API
199 // files by Last_released are modules which don't exist.
200 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700201 }
Nan Zhang79614d12018-04-19 18:03:39 -0700202
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 // if set to true, generate docs through Dokka instead of Doclava.
204 Dokka_enabled *bool
205}
206
207type DroidstubsProperties struct {
208 // the tag name used to distinguish if the API files belong to public/system/test.
209 Api_tag_name *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Private_dex_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 Removed_dex_api_filename *string
228
Nan Zhang9c69a122018-08-22 10:22:08 -0700229 // mapping of dex signatures to source file and line number. This is a temporary property and
230 // will be deleted; you probably shouldn't be using it.
231 Dex_mapping_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700234 Exact_api_filename *string
235
Nan Zhang199645c2018-09-19 12:40:06 -0700236 // the generated proguard filename by Metalava.
237 Proguard_filename *string
238
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Check_api struct {
240 Last_released ApiToCheck
241
242 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900243
244 // do not perform API check against Last_released, in the case that both two specified API
245 // files by Last_released are modules which don't exist.
246 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200247
248 Api_lint struct {
249 Enabled *bool
250
251 // If set, performs api_lint on any new APIs not found in the given signature file
252 New_since *string `android:"path"`
253
254 // If not blank, path to the baseline txt file for approved API lint violations.
255 Baseline_file *string `android:"path"`
256 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700257 }
Nan Zhang79614d12018-04-19 18:03:39 -0700258
259 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800260 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700261
262 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700264
Pete Gillin77167902018-09-19 18:16:26 +0100265 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700266 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700267
Pete Gillin77167902018-09-19 18:16:26 +0100268 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
269 Merge_inclusion_annotations_dirs []string
270
Pete Gillinc382a562018-11-14 18:45:46 +0000271 // a file containing a list of classes to do nullability validation for.
272 Validate_nullability_from_list *string
273
Pete Gillin581d6082018-10-22 15:55:04 +0100274 // a file containing expected warnings produced by validation of nullability annotations.
275 Check_nullability_warnings *string
276
Nan Zhang1598a9e2018-09-04 17:14:32 -0700277 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
278 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700279
280 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
281 Api_levels_annotations_enabled *bool
282
283 // the dirs which Metalava extracts API levels annotations from.
284 Api_levels_annotations_dirs []string
285
286 // if set to true, collect the values used by the Dev tools and
287 // write them in files packaged with the SDK. Defaults to false.
288 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700289
290 // If set to true, .xml based public API file will be also generated, and
291 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
292 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800293}
294
Nan Zhanga40da042018-08-01 12:48:00 -0700295//
296// Common flags passed down to build rule
297//
298type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700299 bootClasspathArgs string
300 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700301 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700302 dokkaClasspathArgs string
303 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700304 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700305
Nan Zhanga40da042018-08-01 12:48:00 -0700306 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700307 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700308 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700309}
310
311func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
312 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
313 android.InitDefaultableModule(module)
314}
315
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200316func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
317 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
318 return false
319 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700320 return true
321 } else if String(apiToCheck.Api_file) != "" {
322 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
323 } else if String(apiToCheck.Removed_api_file) != "" {
324 panic("for " + apiVersionTag + " api_file has to be non-empty!")
325 }
326
327 return false
328}
329
Inseob Kim38449af2019-02-28 14:24:05 +0900330func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
331 api_file := String(apiToCheck.Api_file)
332 removed_api_file := String(apiToCheck.Removed_api_file)
333
334 api_module := android.SrcIsModule(api_file)
335 removed_api_module := android.SrcIsModule(removed_api_file)
336
337 if api_module == "" || removed_api_module == "" {
338 return
339 }
340
341 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
342 return
343 }
344
345 apiToCheck.Api_file = nil
346 apiToCheck.Removed_api_file = nil
347}
348
Nan Zhang1598a9e2018-09-04 17:14:32 -0700349type ApiFilePath interface {
350 ApiFilePath() android.Path
351}
352
Nan Zhanga40da042018-08-01 12:48:00 -0700353//
354// Javadoc
355//
Nan Zhang581fd212018-01-10 16:06:12 -0800356type Javadoc struct {
357 android.ModuleBase
358 android.DefaultableModuleBase
359
360 properties JavadocProperties
361
362 srcJars android.Paths
363 srcFiles android.Paths
364 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700365 argFiles android.Paths
366
367 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800368
Nan Zhangccff0f72018-03-08 17:26:16 -0800369 docZip android.WritablePath
370 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800371}
372
Colin Cross41955e82019-05-29 14:40:35 -0700373func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
374 switch tag {
375 case "":
376 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700377 case ".docs.zip":
378 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700379 default:
380 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
381 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800382}
383
Colin Crossa3002fc2019-07-08 16:48:04 -0700384// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800385func JavadocFactory() android.Module {
386 module := &Javadoc{}
387
388 module.AddProperties(&module.properties)
389
390 InitDroiddocModule(module, android.HostAndDeviceSupported)
391 return module
392}
393
Colin Crossa3002fc2019-07-08 16:48:04 -0700394// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800395func JavadocHostFactory() android.Module {
396 module := &Javadoc{}
397
398 module.AddProperties(&module.properties)
399
400 InitDroiddocModule(module, android.HostSupported)
401 return module
402}
403
Colin Cross41955e82019-05-29 14:40:35 -0700404var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800405
Colin Cross83bb3162018-06-25 15:48:06 -0700406func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900407 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700408}
409
Paul Duffine25c6442019-10-11 13:50:28 +0100410func (j *Javadoc) systemModules() string {
411 return proptools.String(j.properties.System_modules)
412}
413
Colin Cross83bb3162018-06-25 15:48:06 -0700414func (j *Javadoc) minSdkVersion() string {
415 return j.sdkVersion()
416}
417
Dan Willemsen419290a2018-10-31 15:28:47 -0700418func (j *Javadoc) targetSdkVersion() string {
419 return j.sdkVersion()
420}
421
Nan Zhang581fd212018-01-10 16:06:12 -0800422func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
423 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100424 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Colin Cross6d8d8c62019-10-28 15:10:03 -0700425 if sdkDep.useDefaultLibs {
426 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
427 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
428 if sdkDep.hasFrameworkLibs() {
429 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700430 }
Colin Cross6d8d8c62019-10-28 15:10:03 -0700431 } else if sdkDep.useModule {
432 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Paul Duffine25c6442019-10-11 13:50:28 +0100433 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800434 }
435 }
436
Colin Cross42d48b72018-08-29 14:10:52 -0700437 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800438}
439
Nan Zhanga40da042018-08-01 12:48:00 -0700440func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
441 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900442
Colin Cross3047fa22019-04-18 10:56:44 -0700443 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900444
445 return flags
446}
447
448func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700449 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900450
451 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
452 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
453
454 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700455 var deps android.Paths
456
Jiyong Park1e440682018-05-23 18:42:04 +0900457 if aidlPreprocess.Valid() {
458 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700459 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900460 } else {
461 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
462 }
463
464 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
465 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
466 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
467 flags = append(flags, "-I"+src.String())
468 }
469
Colin Cross3047fa22019-04-18 10:56:44 -0700470 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900471}
472
Jiyong Parkd90d7412019-08-20 22:49:19 +0900473// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900474func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700475 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900476
477 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700478 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900479
Jiyong Park1112c4c2019-08-16 21:12:10 +0900480 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
481
Jiyong Park1e440682018-05-23 18:42:04 +0900482 for _, srcFile := range srcFiles {
483 switch srcFile.Ext() {
484 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700485 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900486 case ".logtags":
487 javaFile := genLogtags(ctx, srcFile)
488 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900489 default:
490 outSrcFiles = append(outSrcFiles, srcFile)
491 }
492 }
493
Colin Crossc0806172019-06-14 18:51:47 -0700494 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
495 if len(aidlSrcs) > 0 {
496 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
497 outSrcFiles = append(outSrcFiles, srcJarFiles...)
498 }
499
Jiyong Park1e440682018-05-23 18:42:04 +0900500 return outSrcFiles
501}
502
Nan Zhang581fd212018-01-10 16:06:12 -0800503func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
504 var deps deps
505
Colin Cross83bb3162018-06-25 15:48:06 -0700506 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800507 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700508 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800509 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700510 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800511 }
512
513 ctx.VisitDirectDeps(func(module android.Module) {
514 otherName := ctx.OtherModuleName(module)
515 tag := ctx.OtherModuleDependencyTag(module)
516
Colin Cross2d24c1b2018-05-23 10:59:18 -0700517 switch tag {
518 case bootClasspathTag:
519 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800520 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffine25c6442019-10-11 13:50:28 +0100521 } else if sm, ok := module.(*SystemModules); ok {
522 // A system modules dependency has been added to the bootclasspath
523 // so add its libs to the bootclasspath.
524 deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700525 } else {
526 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
527 }
528 case libTag:
529 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800530 case SdkLibraryDependency:
531 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700532 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900533 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900534 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700535 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800536 checkProducesJars(ctx, dep)
537 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800538 default:
539 ctx.ModuleErrorf("depends on non-java module %q", otherName)
540 }
Nan Zhang357466b2018-04-17 17:38:36 -0700541 case systemModulesTag:
542 if deps.systemModules != nil {
543 panic("Found two system module dependencies")
544 }
545 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000546 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700547 panic("Missing directory for system module dependency")
548 }
Colin Crossb77043e2019-07-16 13:57:13 -0700549 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800550 }
551 })
552 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
553 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800554 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900555
556 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
557 if filterPackages == nil {
558 return srcs
559 }
560 filtered := []android.Path{}
561 for _, src := range srcs {
562 if src.Ext() != ".java" {
563 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
564 // but otherwise metalava emits stub sources having references to the generated AIDL classes
565 // in filtered-out pacages (e.g. com.android.internal.*).
566 // TODO(b/141149570) We need to fix this by introducing default private constructors or
567 // fixing metalava to not emit constructors having references to unknown classes.
568 filtered = append(filtered, src)
569 continue
570 }
571 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
572 for _, pkg := range filterPackages {
573 if strings.HasPrefix(packageName, pkg) {
574 filtered = append(filtered, src)
575 break
576 }
577 }
578 }
579 return filtered
580 }
581 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
582
Nan Zhanga40da042018-08-01 12:48:00 -0700583 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900584 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800585
586 // srcs may depend on some genrule output.
587 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800588 j.srcJars = append(j.srcJars, deps.srcJars...)
589
Nan Zhang581fd212018-01-10 16:06:12 -0800590 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800591 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800592
Nan Zhang9c69a122018-08-22 10:22:08 -0700593 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800594 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
595 }
596 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800597
Colin Cross8a497952019-03-05 22:25:09 -0800598 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000599 argFilesMap := map[string]string{}
600 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700601
Paul Duffin99e4a502019-02-11 15:38:42 +0000602 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800603 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000604 if _, exists := argFilesMap[label]; !exists {
605 argFilesMap[label] = strings.Join(paths.Strings(), " ")
606 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700607 } else {
608 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000609 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700610 }
611 }
612
613 var err error
Colin Cross15638152019-07-11 11:11:35 -0700614 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700615 if strings.HasPrefix(name, "location ") {
616 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000617 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700618 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700619 } else {
Colin Cross15638152019-07-11 11:11:35 -0700620 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000621 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700622 }
623 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700624 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700625 }
Colin Cross15638152019-07-11 11:11:35 -0700626 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700627 })
628
629 if err != nil {
630 ctx.PropertyErrorf("args", "%s", err.Error())
631 }
632
Nan Zhang581fd212018-01-10 16:06:12 -0800633 return deps
634}
635
636func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
637 j.addDeps(ctx)
638}
639
640func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
641 deps := j.collectDeps(ctx)
642
Colin Crossdaa4c672019-07-15 22:53:46 -0700643 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800644
Colin Crossdaa4c672019-07-15 22:53:46 -0700645 outDir := android.PathForModuleOut(ctx, "out")
646 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
647
648 j.stubsSrcJar = nil
649
650 rule := android.NewRuleBuilder()
651
652 rule.Command().Text("rm -rf").Text(outDir.String())
653 rule.Command().Text("mkdir -p").Text(outDir.String())
654
655 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700656
Colin Cross83bb3162018-06-25 15:48:06 -0700657 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800658
Colin Crossdaa4c672019-07-15 22:53:46 -0700659 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
660 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800661
Colin Cross1e743852019-10-28 11:37:20 -0700662 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700663 Flag("-J-Xmx1024m").
664 Flag("-XDignore.symbol.file").
665 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800666
Colin Crossdaa4c672019-07-15 22:53:46 -0700667 rule.Command().
668 BuiltTool(ctx, "soong_zip").
669 Flag("-write_if_changed").
670 Flag("-d").
671 FlagWithOutput("-o ", j.docZip).
672 FlagWithArg("-C ", outDir.String()).
673 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700674
Colin Crossdaa4c672019-07-15 22:53:46 -0700675 rule.Restat()
676
677 zipSyncCleanupCmd(rule, srcJarDir)
678
679 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800680}
681
Nan Zhanga40da042018-08-01 12:48:00 -0700682//
683// Droiddoc
684//
685type Droiddoc struct {
686 Javadoc
687
688 properties DroiddocProperties
689 apiFile android.WritablePath
690 dexApiFile android.WritablePath
691 privateApiFile android.WritablePath
692 privateDexApiFile android.WritablePath
693 removedApiFile android.WritablePath
694 removedDexApiFile android.WritablePath
695 exactApiFile android.WritablePath
696 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700697 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700698
699 checkCurrentApiTimestamp android.WritablePath
700 updateCurrentApiTimestamp android.WritablePath
701 checkLastReleasedApiTimestamp android.WritablePath
702
Nan Zhanga40da042018-08-01 12:48:00 -0700703 apiFilePath android.Path
704}
705
Colin Crossa3002fc2019-07-08 16:48:04 -0700706// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700707func DroiddocFactory() android.Module {
708 module := &Droiddoc{}
709
710 module.AddProperties(&module.properties,
711 &module.Javadoc.properties)
712
713 InitDroiddocModule(module, android.HostAndDeviceSupported)
714 return module
715}
716
Colin Crossa3002fc2019-07-08 16:48:04 -0700717// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700718func DroiddocHostFactory() android.Module {
719 module := &Droiddoc{}
720
721 module.AddProperties(&module.properties,
722 &module.Javadoc.properties)
723
724 InitDroiddocModule(module, android.HostSupported)
725 return module
726}
727
728func (d *Droiddoc) ApiFilePath() android.Path {
729 return d.apiFilePath
730}
731
Nan Zhang581fd212018-01-10 16:06:12 -0800732func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
733 d.Javadoc.addDeps(ctx)
734
Inseob Kim38449af2019-02-28 14:24:05 +0900735 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
736 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
737 }
738
Nan Zhang79614d12018-04-19 18:03:39 -0700739 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800740 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
741 }
Nan Zhang581fd212018-01-10 16:06:12 -0800742}
743
Colin Crossab054432019-07-15 16:13:59 -0700744func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700745 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
746 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
747 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700748 cmd.FlagWithArg("-source ", "1.8").
749 Flag("-J-Xmx1600m").
750 Flag("-J-XX:-OmitStackTraceInFastThrow").
751 Flag("-XDignore.symbol.file").
752 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
753 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
754 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700755 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 -0700756
Nan Zhanga40da042018-08-01 12:48:00 -0700757 if String(d.properties.Custom_template) == "" {
758 // TODO: This is almost always droiddoc-templates-sdk
759 ctx.PropertyErrorf("custom_template", "must specify a template")
760 }
761
762 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700763 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700764 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700765 } else {
766 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
767 }
768 })
769
770 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700771 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
772 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
773 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700774 }
775
776 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700777 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
778 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
779 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700780 }
781
782 if len(d.properties.Html_dirs) > 2 {
783 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
784 }
785
Colin Cross8a497952019-03-05 22:25:09 -0800786 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700787 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700788
Colin Crossab054432019-07-15 16:13:59 -0700789 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700790
791 if String(d.properties.Proofread_file) != "" {
792 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700793 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700794 }
795
796 if String(d.properties.Todo_file) != "" {
797 // tricky part:
798 // we should not compute full path for todo_file through PathForModuleOut().
799 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700800 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
801 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700802 }
803
804 if String(d.properties.Resourcesdir) != "" {
805 // TODO: should we add files under resourcesDir to the implicits? It seems that
806 // resourcesDir is one sub dir of htmlDir
807 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700808 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700809 }
810
811 if String(d.properties.Resourcesoutdir) != "" {
812 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700813 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700814 }
Nan Zhanga40da042018-08-01 12:48:00 -0700815}
816
Colin Crossab054432019-07-15 16:13:59 -0700817func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200818 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
819 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700820 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700821
Nan Zhanga40da042018-08-01 12:48:00 -0700822 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 d.apiFilePath = d.apiFile
825 }
826
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200827 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
828 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700829 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700830 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700831 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700832 }
833
834 if String(d.properties.Private_api_filename) != "" {
835 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700836 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700837 }
838
839 if String(d.properties.Dex_api_filename) != "" {
840 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700841 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700842 }
843
844 if String(d.properties.Private_dex_api_filename) != "" {
845 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700846 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700847 }
848
849 if String(d.properties.Removed_dex_api_filename) != "" {
850 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700851 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700852 }
853
854 if String(d.properties.Exact_api_filename) != "" {
855 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700856 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700857 }
858
859 if String(d.properties.Dex_mapping_filename) != "" {
860 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700861 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700862 }
863
Nan Zhang66dc2362018-08-14 20:41:04 -0700864 if String(d.properties.Proguard_filename) != "" {
865 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700866 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700867 }
868
Nan Zhanga40da042018-08-01 12:48:00 -0700869 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700870 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700871 }
872
873 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700874 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700875 }
Nan Zhanga40da042018-08-01 12:48:00 -0700876}
877
Colin Crossab054432019-07-15 16:13:59 -0700878func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700879 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700880 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
881 rule.Command().Text("cp").
882 Input(staticDocIndexRedirect).
883 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700884 }
885
886 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700887 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
888 rule.Command().Text("cp").
889 Input(staticDocProperties).
890 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700891 }
Nan Zhanga40da042018-08-01 12:48:00 -0700892}
893
Colin Crossab054432019-07-15 16:13:59 -0700894func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700895 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700896
897 cmd := rule.Command().
898 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
899 Flag(config.JavacVmFlags).
900 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700901 FlagWithRspFileInputList("@", srcs).
902 FlagWithInput("@", srcJarList)
903
Colin Crossab054432019-07-15 16:13:59 -0700904 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
905 // based stubs generation.
906 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
907 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
908 // the correct package name base path.
909 if len(sourcepaths) > 0 {
910 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
911 } else {
912 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
913 }
914
915 cmd.FlagWithArg("-d ", outDir.String()).
916 Flag("-quiet")
917
918 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700919}
920
Colin Crossdaa4c672019-07-15 22:53:46 -0700921func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
922 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
923 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
924
925 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
926
927 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
928 cmd.Flag(flag).Implicits(deps)
929
930 cmd.FlagWithArg("--patch-module ", "java.base=.")
931
932 if len(classpath) > 0 {
933 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
934 }
935
936 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700937}
938
Colin Crossdaa4c672019-07-15 22:53:46 -0700939func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
940 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
941 sourcepaths android.Paths) *android.RuleBuilderCommand {
942
943 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
944
945 if len(bootclasspath) == 0 && ctx.Device() {
946 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
947 // ensure java does not fall back to the default bootclasspath.
948 cmd.FlagWithArg("-bootclasspath ", `""`)
949 } else if len(bootclasspath) > 0 {
950 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
951 }
952
953 if len(classpath) > 0 {
954 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
955 }
956
957 return cmd
958}
959
Colin Crossab054432019-07-15 16:13:59 -0700960func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
961 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700962
Colin Crossab054432019-07-15 16:13:59 -0700963 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
964 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
965
966 return rule.Command().
967 BuiltTool(ctx, "dokka").
968 Flag(config.JavacVmFlags).
969 Flag(srcJarDir.String()).
970 FlagWithInputList("-classpath ", dokkaClasspath, ":").
971 FlagWithArg("-format ", "dac").
972 FlagWithArg("-dacRoot ", "/reference/kotlin").
973 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700974}
975
976func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
977 deps := d.Javadoc.collectDeps(ctx)
978
Colin Crossdaa4c672019-07-15 22:53:46 -0700979 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
980 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
981
Nan Zhang1598a9e2018-09-04 17:14:32 -0700982 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
983 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
984 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
985 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
986
Colin Crossab054432019-07-15 16:13:59 -0700987 outDir := android.PathForModuleOut(ctx, "out")
988 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
989 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700990
Colin Crossab054432019-07-15 16:13:59 -0700991 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700992
Colin Crossab054432019-07-15 16:13:59 -0700993 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
994 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995
Colin Crossab054432019-07-15 16:13:59 -0700996 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
997
998 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700999 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001000 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001001 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001002 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001003 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001004 }
1005
Colin Crossab054432019-07-15 16:13:59 -07001006 d.stubsFlags(ctx, cmd, stubsDir)
1007
1008 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1009
1010 var desc string
1011 if Bool(d.properties.Dokka_enabled) {
1012 desc = "dokka"
1013 } else {
1014 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1015
1016 for _, o := range d.Javadoc.properties.Out {
1017 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1018 }
1019
1020 d.postDoclavaCmds(ctx, rule)
1021 desc = "doclava"
1022 }
1023
1024 rule.Command().
1025 BuiltTool(ctx, "soong_zip").
1026 Flag("-write_if_changed").
1027 Flag("-d").
1028 FlagWithOutput("-o ", d.docZip).
1029 FlagWithArg("-C ", outDir.String()).
1030 FlagWithArg("-D ", outDir.String())
1031
1032 rule.Command().
1033 BuiltTool(ctx, "soong_zip").
1034 Flag("-write_if_changed").
1035 Flag("-jar").
1036 FlagWithOutput("-o ", d.stubsSrcJar).
1037 FlagWithArg("-C ", stubsDir.String()).
1038 FlagWithArg("-D ", stubsDir.String())
1039
1040 rule.Restat()
1041
1042 zipSyncCleanupCmd(rule, srcJarDir)
1043
1044 rule.Build(pctx, ctx, "javadoc", desc)
1045
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001046 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001047 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001048
1049 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1050 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001051
1052 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001053
1054 rule := android.NewRuleBuilder()
1055
1056 rule.Command().Text("( true")
1057
1058 rule.Command().
1059 BuiltTool(ctx, "apicheck").
1060 Flag("-JXmx1024m").
1061 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1062 OptionalFlag(d.properties.Check_api.Current.Args).
1063 Input(apiFile).
1064 Input(d.apiFile).
1065 Input(removedApiFile).
1066 Input(d.removedApiFile)
1067
1068 msg := fmt.Sprintf(`\n******************************\n`+
1069 `You have tried to change the API from what has been previously approved.\n\n`+
1070 `To make these errors go away, you have two choices:\n`+
1071 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1072 ` errors above.\n\n`+
1073 ` 2. You can update current.txt by executing the following command:\n`+
1074 ` make %s-update-current-api\n\n`+
1075 ` To submit the revised current.txt to the main Android repository,\n`+
1076 ` you will need approval.\n`+
1077 `******************************\n`, ctx.ModuleName())
1078
1079 rule.Command().
1080 Text("touch").Output(d.checkCurrentApiTimestamp).
1081 Text(") || (").
1082 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1083 Text("; exit 38").
1084 Text(")")
1085
1086 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001087
1088 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001089
1090 // update API rule
1091 rule = android.NewRuleBuilder()
1092
1093 rule.Command().Text("( true")
1094
1095 rule.Command().
1096 Text("cp").Flag("-f").
1097 Input(d.apiFile).Flag(apiFile.String())
1098
1099 rule.Command().
1100 Text("cp").Flag("-f").
1101 Input(d.removedApiFile).Flag(removedApiFile.String())
1102
1103 msg = "failed to update public API"
1104
1105 rule.Command().
1106 Text("touch").Output(d.updateCurrentApiTimestamp).
1107 Text(") || (").
1108 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1109 Text("; exit 38").
1110 Text(")")
1111
1112 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001113 }
1114
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001115 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001116 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001117
1118 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1119 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001120
1121 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001122
1123 rule := android.NewRuleBuilder()
1124
1125 rule.Command().
1126 Text("(").
1127 BuiltTool(ctx, "apicheck").
1128 Flag("-JXmx1024m").
1129 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1130 OptionalFlag(d.properties.Check_api.Last_released.Args).
1131 Input(apiFile).
1132 Input(d.apiFile).
1133 Input(removedApiFile).
1134 Input(d.removedApiFile)
1135
1136 msg := `\n******************************\n` +
1137 `You have tried to change the API from what has been previously released in\n` +
1138 `an SDK. Please fix the errors listed above.\n` +
1139 `******************************\n`
1140
1141 rule.Command().
1142 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1143 Text(") || (").
1144 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1145 Text("; exit 38").
1146 Text(")")
1147
1148 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001149 }
1150}
1151
1152//
1153// Droidstubs
1154//
1155type Droidstubs struct {
1156 Javadoc
1157
Pete Gillin581d6082018-10-22 15:55:04 +01001158 properties DroidstubsProperties
1159 apiFile android.WritablePath
1160 apiXmlFile android.WritablePath
1161 lastReleasedApiXmlFile android.WritablePath
1162 dexApiFile android.WritablePath
1163 privateApiFile android.WritablePath
1164 privateDexApiFile android.WritablePath
1165 removedApiFile android.WritablePath
1166 removedDexApiFile android.WritablePath
1167 apiMappingFile android.WritablePath
1168 exactApiFile android.WritablePath
1169 proguardFile android.WritablePath
1170 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001171
1172 checkCurrentApiTimestamp android.WritablePath
1173 updateCurrentApiTimestamp android.WritablePath
1174 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001175 apiLintTimestamp android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001176
Pete Gillin581d6082018-10-22 15:55:04 +01001177 checkNullabilityWarningsTimestamp android.WritablePath
1178
Nan Zhang1598a9e2018-09-04 17:14:32 -07001179 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001180 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001181
1182 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001183
1184 jdiffDocZip android.WritablePath
1185 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001186
1187 metadataZip android.WritablePath
1188 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001189}
1190
Colin Crossa3002fc2019-07-08 16:48:04 -07001191// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1192// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1193// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001194func DroidstubsFactory() android.Module {
1195 module := &Droidstubs{}
1196
1197 module.AddProperties(&module.properties,
1198 &module.Javadoc.properties)
1199
1200 InitDroiddocModule(module, android.HostAndDeviceSupported)
1201 return module
1202}
1203
Colin Crossa3002fc2019-07-08 16:48:04 -07001204// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1205// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1206// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1207// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001208func DroidstubsHostFactory() android.Module {
1209 module := &Droidstubs{}
1210
1211 module.AddProperties(&module.properties,
1212 &module.Javadoc.properties)
1213
1214 InitDroiddocModule(module, android.HostSupported)
1215 return module
1216}
1217
1218func (d *Droidstubs) ApiFilePath() android.Path {
1219 return d.apiFilePath
1220}
1221
1222func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1223 d.Javadoc.addDeps(ctx)
1224
Inseob Kim38449af2019-02-28 14:24:05 +09001225 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1226 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1227 }
1228
Nan Zhang1598a9e2018-09-04 17:14:32 -07001229 if len(d.properties.Merge_annotations_dirs) != 0 {
1230 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1231 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1232 }
1233 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001234
Pete Gillin77167902018-09-19 18:16:26 +01001235 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1236 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1237 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1238 }
1239 }
1240
Nan Zhang9c69a122018-08-22 10:22:08 -07001241 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1242 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1243 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1244 }
1245 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001246}
1247
Colin Cross33961b52019-07-11 11:01:22 -07001248func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001249 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1250 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 String(d.properties.Api_filename) != "" {
1252 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001253 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254 d.apiFilePath = d.apiFile
1255 }
1256
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001257 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1258 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 String(d.properties.Removed_api_filename) != "" {
1260 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001261 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001262 }
1263
1264 if String(d.properties.Private_api_filename) != "" {
1265 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001266 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001267 }
1268
1269 if String(d.properties.Dex_api_filename) != "" {
1270 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001271 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001272 }
1273
1274 if String(d.properties.Private_dex_api_filename) != "" {
1275 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001277 }
1278
1279 if String(d.properties.Removed_dex_api_filename) != "" {
1280 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001281 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001282 }
1283
1284 if String(d.properties.Exact_api_filename) != "" {
1285 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001286 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287 }
1288
Nan Zhang9c69a122018-08-22 10:22:08 -07001289 if String(d.properties.Dex_mapping_filename) != "" {
1290 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001291 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001292 }
1293
Nan Zhang199645c2018-09-19 12:40:06 -07001294 if String(d.properties.Proguard_filename) != "" {
1295 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001296 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001297 }
1298
Nan Zhang9c69a122018-08-22 10:22:08 -07001299 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001300 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1301 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001302 }
1303
Nan Zhang1598a9e2018-09-04 17:14:32 -07001304 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001305 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001306 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001307 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001308 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001309}
1310
Colin Cross33961b52019-07-11 11:01:22 -07001311func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001312 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001313 cmd.Flag("--include-annotations")
1314
Pete Gillinc382a562018-11-14 18:45:46 +00001315 validatingNullability :=
1316 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1317 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001318 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001319
Pete Gillina262c052018-09-14 14:25:48 +01001320 if !(migratingNullability || validatingNullability) {
1321 ctx.PropertyErrorf("previous_api",
1322 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001323 }
Colin Cross33961b52019-07-11 11:01:22 -07001324
Pete Gillina262c052018-09-14 14:25:48 +01001325 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001326 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001328 }
Colin Cross33961b52019-07-11 11:01:22 -07001329
Pete Gillinc382a562018-11-14 18:45:46 +00001330 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001331 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001332 }
Colin Cross33961b52019-07-11 11:01:22 -07001333
Pete Gillina262c052018-09-14 14:25:48 +01001334 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001335 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001336 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001337 }
Nan Zhanga40da042018-08-01 12:48:00 -07001338
1339 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001340 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001341
Nan Zhang1598a9e2018-09-04 17:14:32 -07001342 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001343 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001344 "has to be non-empty if annotations was enabled!")
1345 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001346
Colin Cross33961b52019-07-11 11:01:22 -07001347 d.mergeAnnoDirFlags(ctx, cmd)
1348
1349 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1350 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1351 FlagWithArg("--hide ", "SuperfluousPrefix").
1352 FlagWithArg("--hide ", "AnnotationExtraction")
1353 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001354}
1355
Colin Cross33961b52019-07-11 11:01:22 -07001356func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1357 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1358 if t, ok := m.(*ExportedDroiddocDir); ok {
1359 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1360 } else {
1361 ctx.PropertyErrorf("merge_annotations_dirs",
1362 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1363 }
1364 })
1365}
1366
1367func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001368 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1369 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001370 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001371 } else {
1372 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1373 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1374 }
1375 })
Nan Zhanga40da042018-08-01 12:48:00 -07001376}
1377
Colin Cross33961b52019-07-11 11:01:22 -07001378func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001379 if Bool(d.properties.Api_levels_annotations_enabled) {
1380 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001381
1382 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1383 ctx.PropertyErrorf("api_levels_annotations_dirs",
1384 "has to be non-empty if api levels annotations was enabled!")
1385 }
1386
Colin Cross33961b52019-07-11 11:01:22 -07001387 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1388 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1389 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1390 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001391
1392 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1393 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001394 for _, dep := range t.deps {
1395 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001396 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001397 }
1398 }
Colin Cross33961b52019-07-11 11:01:22 -07001399 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001400 } else {
1401 ctx.PropertyErrorf("api_levels_annotations_dirs",
1402 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1403 }
1404 })
1405
1406 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001407}
1408
Colin Cross33961b52019-07-11 11:01:22 -07001409func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001410 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1411 if d.apiFile.String() == "" {
1412 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1413 }
1414
1415 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001416 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001417
1418 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1419 ctx.PropertyErrorf("check_api.last_released.api_file",
1420 "has to be non-empty if jdiff was enabled!")
1421 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001422
Colin Cross33961b52019-07-11 11:01:22 -07001423 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001424 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001425 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1426 }
1427}
Nan Zhang71bbe632018-09-17 14:32:21 -07001428
Colin Cross1e743852019-10-28 11:37:20 -07001429func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Colin Cross33961b52019-07-11 11:01:22 -07001430 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1431 cmd := rule.Command().BuiltTool(ctx, "metalava").
1432 Flag(config.JavacVmFlags).
1433 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001434 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001435 FlagWithRspFileInputList("@", srcs).
1436 FlagWithInput("@", srcJarList)
1437
1438 if len(bootclasspath) > 0 {
1439 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001440 }
1441
Colin Cross33961b52019-07-11 11:01:22 -07001442 if len(classpath) > 0 {
1443 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1444 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001445
Colin Cross33961b52019-07-11 11:01:22 -07001446 if len(sourcepaths) > 0 {
1447 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1448 } else {
1449 cmd.FlagWithArg("-sourcepath ", `""`)
1450 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001451
Colin Cross33961b52019-07-11 11:01:22 -07001452 cmd.Flag("--no-banner").
1453 Flag("--color").
1454 Flag("--quiet").
1455 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001458}
1459
Nan Zhang1598a9e2018-09-04 17:14:32 -07001460func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001461 deps := d.Javadoc.collectDeps(ctx)
1462
1463 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001464
Colin Cross33961b52019-07-11 11:01:22 -07001465 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001466
Colin Crossdaa4c672019-07-15 22:53:46 -07001467 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001468
Colin Cross33961b52019-07-11 11:01:22 -07001469 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1470 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001471
Colin Cross33961b52019-07-11 11:01:22 -07001472 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001473
Colin Cross33961b52019-07-11 11:01:22 -07001474 rule.Command().Text("rm -rf").Text(stubsDir.String())
1475 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001476
Colin Cross33961b52019-07-11 11:01:22 -07001477 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1478
1479 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1480 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1481
1482 d.stubsFlags(ctx, cmd, stubsDir)
1483
1484 d.annotationsFlags(ctx, cmd)
1485 d.inclusionAnnotationsFlags(ctx, cmd)
1486 d.apiLevelsAnnotationsFlags(ctx, cmd)
1487 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001488
Nan Zhang1598a9e2018-09-04 17:14:32 -07001489 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1490 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1491 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1492 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1493 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001494 }
Colin Cross33961b52019-07-11 11:01:22 -07001495
1496 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1497 for _, o := range d.Javadoc.properties.Out {
1498 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1499 }
1500
1501 rule.Command().
1502 BuiltTool(ctx, "soong_zip").
1503 Flag("-write_if_changed").
1504 Flag("-jar").
1505 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1506 FlagWithArg("-C ", stubsDir.String()).
1507 FlagWithArg("-D ", stubsDir.String())
Jerome Gaillard0f599032019-10-10 19:29:11 +01001508
1509 if Bool(d.properties.Write_sdk_values) {
1510 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1511 rule.Command().
1512 BuiltTool(ctx, "soong_zip").
1513 Flag("-write_if_changed").
1514 Flag("-d").
1515 FlagWithOutput("-o ", d.metadataZip).
1516 FlagWithArg("-C ", d.metadataDir.String()).
1517 FlagWithArg("-D ", d.metadataDir.String())
1518 }
1519
Colin Cross33961b52019-07-11 11:01:22 -07001520 rule.Restat()
1521
1522 zipSyncCleanupCmd(rule, srcJarDir)
1523
1524 rule.Build(pctx, ctx, "metalava", "metalava")
1525
1526 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001527
Adrian Roos075eedc2019-10-10 12:07:03 +02001528 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1529 rule := android.NewRuleBuilder()
1530 rule.Command().Text("( true")
1531
1532 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1533 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1534
1535 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1536 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1537
Adrian Rooscab4a2c2019-10-14 16:32:41 +02001538 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1539
Adrian Roos075eedc2019-10-10 12:07:03 +02001540 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1541 if newSince.Valid() {
1542 cmd.FlagWithInput("--api-lint ", newSince.Path())
1543 } else {
1544 cmd.Flag("--api-lint")
1545 }
1546
1547 d.inclusionAnnotationsFlags(ctx, cmd)
1548 d.mergeAnnoDirFlags(ctx, cmd)
1549
1550 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1551 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1552 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1553
1554 if baselineFile.Valid() {
1555 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1556 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1557 }
1558
1559 zipSyncCleanupCmd(rule, srcJarDir)
1560
1561 msg := fmt.Sprintf(`\n******************************\n`+
1562 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1563 `To make these errors go away, you have two choices:\n`+
1564 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1565 ` 2. You can update the baseline by executing the following command:\n`+
1566 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1567 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1568 rule.Command().
1569 Text("touch").Output(d.apiLintTimestamp).
1570 Text(") || (").
1571 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1572 Text("; exit 38").
1573 Text(")")
1574
1575 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1576
1577 }
1578
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001579 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001580 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001581
1582 if len(d.Javadoc.properties.Out) > 0 {
1583 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1584 }
1585
1586 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1587 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001588 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1589 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001590
Nan Zhang2760dfc2018-08-24 17:32:54 +00001591 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001592
Colin Cross33961b52019-07-11 11:01:22 -07001593 rule := android.NewRuleBuilder()
1594
1595 rule.Command().Text("( true")
1596
1597 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1598 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1599
1600 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1601 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1602
1603 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1604 FlagWithInput("--check-compatibility:api:current ", apiFile).
1605 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1606
1607 d.inclusionAnnotationsFlags(ctx, cmd)
1608 d.mergeAnnoDirFlags(ctx, cmd)
1609
Adrian Roos14f75a92019-08-12 17:54:09 +02001610 if baselineFile.Valid() {
1611 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1612 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1613 }
1614
Colin Cross33961b52019-07-11 11:01:22 -07001615 zipSyncCleanupCmd(rule, srcJarDir)
1616
1617 msg := fmt.Sprintf(`\n******************************\n`+
1618 `You have tried to change the API from what has been previously approved.\n\n`+
1619 `To make these errors go away, you have two choices:\n`+
1620 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1621 ` errors above.\n\n`+
1622 ` 2. You can update current.txt by executing the following command:\n`+
1623 ` make %s-update-current-api\n\n`+
1624 ` To submit the revised current.txt to the main Android repository,\n`+
1625 ` you will need approval.\n`+
1626 `******************************\n`, ctx.ModuleName())
1627
1628 rule.Command().
1629 Text("touch").Output(d.checkCurrentApiTimestamp).
1630 Text(") || (").
1631 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1632 Text("; exit 38").
1633 Text(")")
1634
1635 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001636
1637 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001638
1639 // update API rule
1640 rule = android.NewRuleBuilder()
1641
1642 rule.Command().Text("( true")
1643
1644 rule.Command().
1645 Text("cp").Flag("-f").
1646 Input(d.apiFile).Flag(apiFile.String())
1647
1648 rule.Command().
1649 Text("cp").Flag("-f").
1650 Input(d.removedApiFile).Flag(removedApiFile.String())
1651
1652 msg = "failed to update public API"
1653
1654 rule.Command().
1655 Text("touch").Output(d.updateCurrentApiTimestamp).
1656 Text(") || (").
1657 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1658 Text("; exit 38").
1659 Text(")")
1660
1661 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001662 }
Nan Zhanga40da042018-08-01 12:48:00 -07001663
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001664 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001665 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001666
1667 if len(d.Javadoc.properties.Out) > 0 {
1668 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1669 }
1670
1671 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1672 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001673 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1674 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001675
Nan Zhang2760dfc2018-08-24 17:32:54 +00001676 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001677
Colin Cross33961b52019-07-11 11:01:22 -07001678 rule := android.NewRuleBuilder()
1679
1680 rule.Command().Text("( true")
1681
1682 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1683 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1684
1685 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1686 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1687
1688 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1689 FlagWithInput("--check-compatibility:api:released ", apiFile)
1690
1691 d.inclusionAnnotationsFlags(ctx, cmd)
1692
1693 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1694
1695 d.mergeAnnoDirFlags(ctx, cmd)
1696
Adrian Roos14f75a92019-08-12 17:54:09 +02001697 if baselineFile.Valid() {
1698 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1699 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1700 }
1701
Colin Cross33961b52019-07-11 11:01:22 -07001702 zipSyncCleanupCmd(rule, srcJarDir)
1703
1704 msg := `\n******************************\n` +
1705 `You have tried to change the API from what has been previously released in\n` +
1706 `an SDK. Please fix the errors listed above.\n` +
1707 `******************************\n`
1708 rule.Command().
1709 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1710 Text(") || (").
1711 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1712 Text("; exit 38").
1713 Text(")")
1714
1715 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001716 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001717
Pete Gillin581d6082018-10-22 15:55:04 +01001718 if String(d.properties.Check_nullability_warnings) != "" {
1719 if d.nullabilityWarningsFile == nil {
1720 ctx.PropertyErrorf("check_nullability_warnings",
1721 "Cannot specify check_nullability_warnings unless validating nullability")
1722 }
Colin Cross33961b52019-07-11 11:01:22 -07001723
1724 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1725
Pete Gillin581d6082018-10-22 15:55:04 +01001726 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001727
Pete Gillin581d6082018-10-22 15:55:04 +01001728 msg := fmt.Sprintf(`\n******************************\n`+
1729 `The warnings encountered during nullability annotation validation did\n`+
1730 `not match the checked in file of expected warnings. The diffs are shown\n`+
1731 `above. You have two options:\n`+
1732 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1733 ` 2. Update the file of expected warnings by running:\n`+
1734 ` cp %s %s\n`+
1735 ` and submitting the updated file as part of your change.`,
1736 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001737
1738 rule := android.NewRuleBuilder()
1739
1740 rule.Command().
1741 Text("(").
1742 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1743 Text("&&").
1744 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1745 Text(") || (").
1746 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1747 Text("; exit 38").
1748 Text(")")
1749
1750 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001751 }
1752
Nan Zhang71bbe632018-09-17 14:32:21 -07001753 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001754 if len(d.Javadoc.properties.Out) > 0 {
1755 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1756 }
1757
1758 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1759 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1760 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1761
1762 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001763
Nan Zhang86b06202018-09-21 17:09:21 -07001764 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1765 // since there's cron job downstream that fetch this .zip file periodically.
1766 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001767 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1768 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1769
Nan Zhang71bbe632018-09-17 14:32:21 -07001770 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001771
Colin Cross33961b52019-07-11 11:01:22 -07001772 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1773 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001774
Colin Cross33961b52019-07-11 11:01:22 -07001775 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1776
Colin Crossdaa4c672019-07-15 22:53:46 -07001777 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001778 deps.bootClasspath, deps.classpath, d.sourcepaths)
1779
1780 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001781 Flag("-XDignore.symbol.file").
1782 FlagWithArg("-doclet ", "jdiff.JDiff").
1783 FlagWithInput("-docletpath ", jdiff).
1784 Flag("-quiet").
1785 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1786 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1787 Implicit(d.apiXmlFile).
1788 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1789 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1790 Implicit(d.lastReleasedApiXmlFile)
1791
Colin Cross33961b52019-07-11 11:01:22 -07001792 rule.Command().
1793 BuiltTool(ctx, "soong_zip").
1794 Flag("-write_if_changed").
1795 Flag("-d").
1796 FlagWithOutput("-o ", d.jdiffDocZip).
1797 FlagWithArg("-C ", outDir.String()).
1798 FlagWithArg("-D ", outDir.String())
1799
1800 rule.Command().
1801 BuiltTool(ctx, "soong_zip").
1802 Flag("-write_if_changed").
1803 Flag("-jar").
1804 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1805 FlagWithArg("-C ", stubsDir.String()).
1806 FlagWithArg("-D ", stubsDir.String())
1807
1808 rule.Restat()
1809
1810 zipSyncCleanupCmd(rule, srcJarDir)
1811
1812 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001813 }
Nan Zhang581fd212018-01-10 16:06:12 -08001814}
Dan Willemsencc090972018-02-26 14:33:31 -08001815
Nan Zhanga40da042018-08-01 12:48:00 -07001816//
Nan Zhangf4936b02018-08-01 15:00:28 -07001817// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001818//
Dan Willemsencc090972018-02-26 14:33:31 -08001819var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001820var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001821var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001822var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001823
Nan Zhangf4936b02018-08-01 15:00:28 -07001824type ExportedDroiddocDirProperties struct {
1825 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001826 Path *string
1827}
1828
Nan Zhangf4936b02018-08-01 15:00:28 -07001829type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001830 android.ModuleBase
1831
Nan Zhangf4936b02018-08-01 15:00:28 -07001832 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001833
1834 deps android.Paths
1835 dir android.Path
1836}
1837
Colin Crossa3002fc2019-07-08 16:48:04 -07001838// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001839func ExportedDroiddocDirFactory() android.Module {
1840 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001841 module.AddProperties(&module.properties)
1842 android.InitAndroidModule(module)
1843 return module
1844}
1845
Nan Zhangf4936b02018-08-01 15:00:28 -07001846func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001847
Nan Zhangf4936b02018-08-01 15:00:28 -07001848func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001849 path := String(d.properties.Path)
1850 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001851 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001852}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001853
1854//
1855// Defaults
1856//
1857type DocDefaults struct {
1858 android.ModuleBase
1859 android.DefaultsModuleBase
1860}
1861
Nan Zhangb2b33de2018-02-23 11:18:47 -08001862func DocDefaultsFactory() android.Module {
1863 module := &DocDefaults{}
1864
1865 module.AddProperties(
1866 &JavadocProperties{},
1867 &DroiddocProperties{},
1868 )
1869
1870 android.InitDefaultsModule(module)
1871
1872 return module
1873}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001874
1875func StubsDefaultsFactory() android.Module {
1876 module := &DocDefaults{}
1877
1878 module.AddProperties(
1879 &JavadocProperties{},
1880 &DroidstubsProperties{},
1881 )
1882
1883 android.InitDefaultsModule(module)
1884
1885 return module
1886}
Colin Cross33961b52019-07-11 11:01:22 -07001887
1888func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1889 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1890
1891 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1892 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1893 srcJarList := srcJarDir.Join(ctx, "list")
1894
1895 rule.Temporary(srcJarList)
1896
1897 rule.Command().BuiltTool(ctx, "zipsync").
1898 FlagWithArg("-d ", srcJarDir.String()).
1899 FlagWithOutput("-l ", srcJarList).
1900 FlagWithArg("-f ", `"*.java"`).
1901 Inputs(srcJars)
1902
1903 return srcJarList
1904}
1905
1906func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1907 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1908}