blob: 2df2852a4341c67dbb0d50232a09b94a3a5165aa [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
70 // if not blank, set to the version of the sdk to compile against
71 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090072
73 Aidl struct {
74 // Top level directories to pass to aidl tool
75 Include_dirs []string
76
77 // Directories rooted at the Android.bp file to pass to aidl tool
78 Local_include_dirs []string
79 }
Nan Zhang357466b2018-04-17 17:38:36 -070080
81 // If not blank, set the java version passed to javadoc as -source
82 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070083
84 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080085 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070086
87 // user customized droiddoc args.
88 // Available variables for substitution:
89 //
90 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070091 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070092 Args *string
93
94 // names of the output files used in args that will be generated
95 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080096}
97
Nan Zhang61819ce2018-05-04 18:49:16 -070098type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +090099 // path to the API txt file that the new API extracted from source code is checked
100 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800101 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700102
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900103 // path to the API txt file that the new @removed API extractd from source code is
104 // checked against. The path can be local to the module or from other module (via
105 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800106 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700107
Adrian Roos14f75a92019-08-12 17:54:09 +0200108 // If not blank, path to the baseline txt file for approved API check violations.
109 Baseline_file *string `android:"path"`
110
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900111 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700112 Args *string
113}
114
Nan Zhang581fd212018-01-10 16:06:12 -0800115type DroiddocProperties struct {
116 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800117 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800118
Nan Zhanga40da042018-08-01 12:48:00 -0700119 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800121
122 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
125 // proofread file contains all of the text content of the javadocs concatenated into one file,
126 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700127 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800128
129 // a todo file lists the program elements that are missing documentation.
130 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800131 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800132
133 // directory under current module source that provide additional resources (images).
134 Resourcesdir *string
135
136 // resources output directory under out/soong/.intermediates.
137 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800138
Nan Zhange2ba5d42018-07-11 15:16:55 -0700139 // if set to true, collect the values used by the Dev tools and
140 // write them in files packaged with the SDK. Defaults to false.
141 Write_sdk_values *bool
142
143 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800144 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145
146 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800147 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700148
Nan Zhang581fd212018-01-10 16:06:12 -0800149 // a list of files under current module source dir which contains known tags in Java sources.
150 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800151 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700152
153 // the tag name used to distinguish if the API files belong to public/system/test.
154 Api_tag_name *string
155
156 // the generated public API filename by Doclava.
157 Api_filename *string
158
David Brazdilfbe4cc32018-05-31 13:56:46 +0100159 // the generated public Dex API filename by Doclava.
160 Dex_api_filename *string
161
Nan Zhang28c68b92018-03-13 16:17:01 -0700162 // the generated private API filename by Doclava.
163 Private_api_filename *string
164
165 // the generated private Dex API filename by Doclava.
166 Private_dex_api_filename *string
167
168 // the generated removed API filename by Doclava.
169 Removed_api_filename *string
170
David Brazdilaac0c3c2018-04-24 16:23:29 +0100171 // the generated removed Dex API filename by Doclava.
172 Removed_dex_api_filename *string
173
Mathew Inwood76c3de12018-06-22 15:28:11 +0100174 // mapping of dex signatures to source file and line number. This is a temporary property and
175 // will be deleted; you probably shouldn't be using it.
176 Dex_mapping_filename *string
177
Nan Zhang28c68b92018-03-13 16:17:01 -0700178 // the generated exact API filename by Doclava.
179 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700180
Nan Zhang66dc2362018-08-14 20:41:04 -0700181 // the generated proguard filename by Doclava.
182 Proguard_filename *string
183
Nan Zhang853f4202018-04-12 16:55:56 -0700184 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
185 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700186
187 Check_api struct {
188 Last_released ApiToCheck
189
190 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900191
192 // do not perform API check against Last_released, in the case that both two specified API
193 // files by Last_released are modules which don't exist.
194 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700195 }
Nan Zhang79614d12018-04-19 18:03:39 -0700196
Nan Zhang1598a9e2018-09-04 17:14:32 -0700197 // if set to true, generate docs through Dokka instead of Doclava.
198 Dokka_enabled *bool
199}
200
201type DroidstubsProperties struct {
202 // the tag name used to distinguish if the API files belong to public/system/test.
203 Api_tag_name *string
204
Nan Zhang199645c2018-09-19 12:40:06 -0700205 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206 Api_filename *string
207
Nan Zhang199645c2018-09-19 12:40:06 -0700208 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Dex_api_filename *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Private_api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Private_dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Removed_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Removed_dex_api_filename *string
222
Nan Zhang9c69a122018-08-22 10:22:08 -0700223 // mapping of dex signatures to source file and line number. This is a temporary property and
224 // will be deleted; you probably shouldn't be using it.
225 Dex_mapping_filename *string
226
Nan Zhang199645c2018-09-19 12:40:06 -0700227 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700228 Exact_api_filename *string
229
Nan Zhang199645c2018-09-19 12:40:06 -0700230 // the generated proguard filename by Metalava.
231 Proguard_filename *string
232
Nan Zhang1598a9e2018-09-04 17:14:32 -0700233 Check_api struct {
234 Last_released ApiToCheck
235
236 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900237
238 // do not perform API check against Last_released, in the case that both two specified API
239 // files by Last_released are modules which don't exist.
240 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200241
242 Api_lint struct {
243 Enabled *bool
244
245 // If set, performs api_lint on any new APIs not found in the given signature file
246 New_since *string `android:"path"`
247
248 // If not blank, path to the baseline txt file for approved API lint violations.
249 Baseline_file *string `android:"path"`
250 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700251 }
Nan Zhang79614d12018-04-19 18:03:39 -0700252
253 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800254 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700255
256 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700257 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700258
Pete Gillin77167902018-09-19 18:16:26 +0100259 // 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 -0700260 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700261
Pete Gillin77167902018-09-19 18:16:26 +0100262 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
263 Merge_inclusion_annotations_dirs []string
264
Pete Gillinc382a562018-11-14 18:45:46 +0000265 // a file containing a list of classes to do nullability validation for.
266 Validate_nullability_from_list *string
267
Pete Gillin581d6082018-10-22 15:55:04 +0100268 // a file containing expected warnings produced by validation of nullability annotations.
269 Check_nullability_warnings *string
270
Nan Zhang1598a9e2018-09-04 17:14:32 -0700271 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
272 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700273
274 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
275 Api_levels_annotations_enabled *bool
276
277 // the dirs which Metalava extracts API levels annotations from.
278 Api_levels_annotations_dirs []string
279
280 // if set to true, collect the values used by the Dev tools and
281 // write them in files packaged with the SDK. Defaults to false.
282 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700283
284 // If set to true, .xml based public API file will be also generated, and
285 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
286 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800287}
288
Nan Zhanga40da042018-08-01 12:48:00 -0700289//
290// Common flags passed down to build rule
291//
292type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700293 bootClasspathArgs string
294 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700295 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700296 dokkaClasspathArgs string
297 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700298 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700299
Nan Zhanga40da042018-08-01 12:48:00 -0700300 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700301 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700302 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700303}
304
305func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
306 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
307 android.InitDefaultableModule(module)
308}
309
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200310func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
311 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
312 return false
313 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700314 return true
315 } else if String(apiToCheck.Api_file) != "" {
316 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
317 } else if String(apiToCheck.Removed_api_file) != "" {
318 panic("for " + apiVersionTag + " api_file has to be non-empty!")
319 }
320
321 return false
322}
323
Inseob Kim38449af2019-02-28 14:24:05 +0900324func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
325 api_file := String(apiToCheck.Api_file)
326 removed_api_file := String(apiToCheck.Removed_api_file)
327
328 api_module := android.SrcIsModule(api_file)
329 removed_api_module := android.SrcIsModule(removed_api_file)
330
331 if api_module == "" || removed_api_module == "" {
332 return
333 }
334
335 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
336 return
337 }
338
339 apiToCheck.Api_file = nil
340 apiToCheck.Removed_api_file = nil
341}
342
Nan Zhang1598a9e2018-09-04 17:14:32 -0700343type ApiFilePath interface {
344 ApiFilePath() android.Path
345}
346
Nan Zhanga40da042018-08-01 12:48:00 -0700347//
348// Javadoc
349//
Nan Zhang581fd212018-01-10 16:06:12 -0800350type Javadoc struct {
351 android.ModuleBase
352 android.DefaultableModuleBase
353
354 properties JavadocProperties
355
356 srcJars android.Paths
357 srcFiles android.Paths
358 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700359 argFiles android.Paths
360
361 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800362
Nan Zhangccff0f72018-03-08 17:26:16 -0800363 docZip android.WritablePath
364 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800365}
366
Colin Cross41955e82019-05-29 14:40:35 -0700367func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
368 switch tag {
369 case "":
370 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700371 case ".docs.zip":
372 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700373 default:
374 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
375 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800376}
377
Colin Crossa3002fc2019-07-08 16:48:04 -0700378// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800379func JavadocFactory() android.Module {
380 module := &Javadoc{}
381
382 module.AddProperties(&module.properties)
383
384 InitDroiddocModule(module, android.HostAndDeviceSupported)
385 return module
386}
387
Colin Crossa3002fc2019-07-08 16:48:04 -0700388// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800389func JavadocHostFactory() android.Module {
390 module := &Javadoc{}
391
392 module.AddProperties(&module.properties)
393
394 InitDroiddocModule(module, android.HostSupported)
395 return module
396}
397
Colin Cross41955e82019-05-29 14:40:35 -0700398var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800399
Colin Cross83bb3162018-06-25 15:48:06 -0700400func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900401 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700402}
403
404func (j *Javadoc) minSdkVersion() string {
405 return j.sdkVersion()
406}
407
Dan Willemsen419290a2018-10-31 15:28:47 -0700408func (j *Javadoc) targetSdkVersion() string {
409 return j.sdkVersion()
410}
411
Nan Zhang581fd212018-01-10 16:06:12 -0800412func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
413 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100414 sdkDep := decodeSdkDep(ctx, sdkContext(j))
415 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700416 if sdkDep.useDefaultLibs {
417 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
418 if ctx.Config().TargetOpenJDK9() {
419 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
420 }
Paul Duffin250e6192019-06-07 10:44:37 +0100421 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700422 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
423 }
424 } else if sdkDep.useModule {
425 if ctx.Config().TargetOpenJDK9() {
426 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
427 }
428 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700429 }
Nan Zhang581fd212018-01-10 16:06:12 -0800430 }
431 }
432
Colin Cross42d48b72018-08-29 14:10:52 -0700433 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800434}
435
Nan Zhanga40da042018-08-01 12:48:00 -0700436func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
437 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900438
Colin Cross3047fa22019-04-18 10:56:44 -0700439 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900440
441 return flags
442}
443
444func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700445 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900446
447 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
448 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
449
450 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700451 var deps android.Paths
452
Jiyong Park1e440682018-05-23 18:42:04 +0900453 if aidlPreprocess.Valid() {
454 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700455 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900456 } else {
457 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
458 }
459
460 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
461 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
462 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
463 flags = append(flags, "-I"+src.String())
464 }
465
Colin Cross3047fa22019-04-18 10:56:44 -0700466 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900467}
468
Jiyong Parkd90d7412019-08-20 22:49:19 +0900469// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900470func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700471 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900472
473 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700474 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900475
Jiyong Park1112c4c2019-08-16 21:12:10 +0900476 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
477
Jiyong Park1e440682018-05-23 18:42:04 +0900478 for _, srcFile := range srcFiles {
479 switch srcFile.Ext() {
480 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700481 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900482 case ".logtags":
483 javaFile := genLogtags(ctx, srcFile)
484 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900485 default:
486 outSrcFiles = append(outSrcFiles, srcFile)
487 }
488 }
489
Colin Crossc0806172019-06-14 18:51:47 -0700490 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
491 if len(aidlSrcs) > 0 {
492 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
493 outSrcFiles = append(outSrcFiles, srcJarFiles...)
494 }
495
Jiyong Park1e440682018-05-23 18:42:04 +0900496 return outSrcFiles
497}
498
Nan Zhang581fd212018-01-10 16:06:12 -0800499func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
500 var deps deps
501
Colin Cross83bb3162018-06-25 15:48:06 -0700502 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800503 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700504 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800505 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700506 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800507 }
508
509 ctx.VisitDirectDeps(func(module android.Module) {
510 otherName := ctx.OtherModuleName(module)
511 tag := ctx.OtherModuleDependencyTag(module)
512
Colin Cross2d24c1b2018-05-23 10:59:18 -0700513 switch tag {
514 case bootClasspathTag:
515 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800516 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700517 } else {
518 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
519 }
520 case libTag:
521 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800522 case SdkLibraryDependency:
523 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700524 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900525 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900526 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700527 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800528 checkProducesJars(ctx, dep)
529 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800530 default:
531 ctx.ModuleErrorf("depends on non-java module %q", otherName)
532 }
Nan Zhang357466b2018-04-17 17:38:36 -0700533 case systemModulesTag:
534 if deps.systemModules != nil {
535 panic("Found two system module dependencies")
536 }
537 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000538 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700539 panic("Missing directory for system module dependency")
540 }
Colin Crossb77043e2019-07-16 13:57:13 -0700541 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800542 }
543 })
544 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
545 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800546 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900547
548 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
549 if filterPackages == nil {
550 return srcs
551 }
552 filtered := []android.Path{}
553 for _, src := range srcs {
554 if src.Ext() != ".java" {
555 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
556 // but otherwise metalava emits stub sources having references to the generated AIDL classes
557 // in filtered-out pacages (e.g. com.android.internal.*).
558 // TODO(b/141149570) We need to fix this by introducing default private constructors or
559 // fixing metalava to not emit constructors having references to unknown classes.
560 filtered = append(filtered, src)
561 continue
562 }
563 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
564 for _, pkg := range filterPackages {
565 if strings.HasPrefix(packageName, pkg) {
566 filtered = append(filtered, src)
567 break
568 }
569 }
570 }
571 return filtered
572 }
573 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
574
Nan Zhanga40da042018-08-01 12:48:00 -0700575 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900576 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800577
578 // srcs may depend on some genrule output.
579 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800580 j.srcJars = append(j.srcJars, deps.srcJars...)
581
Nan Zhang581fd212018-01-10 16:06:12 -0800582 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800583 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800584
Nan Zhang9c69a122018-08-22 10:22:08 -0700585 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800586 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
587 }
588 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800589
Colin Cross8a497952019-03-05 22:25:09 -0800590 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000591 argFilesMap := map[string]string{}
592 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700593
Paul Duffin99e4a502019-02-11 15:38:42 +0000594 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800595 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000596 if _, exists := argFilesMap[label]; !exists {
597 argFilesMap[label] = strings.Join(paths.Strings(), " ")
598 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700599 } else {
600 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000601 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700602 }
603 }
604
605 var err error
Colin Cross15638152019-07-11 11:11:35 -0700606 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700607 if strings.HasPrefix(name, "location ") {
608 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000609 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700610 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700611 } else {
Colin Cross15638152019-07-11 11:11:35 -0700612 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000613 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700614 }
615 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700616 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700617 }
Colin Cross15638152019-07-11 11:11:35 -0700618 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700619 })
620
621 if err != nil {
622 ctx.PropertyErrorf("args", "%s", err.Error())
623 }
624
Nan Zhang581fd212018-01-10 16:06:12 -0800625 return deps
626}
627
628func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
629 j.addDeps(ctx)
630}
631
632func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
633 deps := j.collectDeps(ctx)
634
Colin Crossdaa4c672019-07-15 22:53:46 -0700635 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800636
Colin Crossdaa4c672019-07-15 22:53:46 -0700637 outDir := android.PathForModuleOut(ctx, "out")
638 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
639
640 j.stubsSrcJar = nil
641
642 rule := android.NewRuleBuilder()
643
644 rule.Command().Text("rm -rf").Text(outDir.String())
645 rule.Command().Text("mkdir -p").Text(outDir.String())
646
647 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700648
Colin Cross83bb3162018-06-25 15:48:06 -0700649 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800650
Colin Crossdaa4c672019-07-15 22:53:46 -0700651 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
652 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800653
Colin Crossdaa4c672019-07-15 22:53:46 -0700654 cmd.FlagWithArg("-source ", javaVersion).
655 Flag("-J-Xmx1024m").
656 Flag("-XDignore.symbol.file").
657 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800658
Colin Crossdaa4c672019-07-15 22:53:46 -0700659 rule.Command().
660 BuiltTool(ctx, "soong_zip").
661 Flag("-write_if_changed").
662 Flag("-d").
663 FlagWithOutput("-o ", j.docZip).
664 FlagWithArg("-C ", outDir.String()).
665 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700666
Colin Crossdaa4c672019-07-15 22:53:46 -0700667 rule.Restat()
668
669 zipSyncCleanupCmd(rule, srcJarDir)
670
671 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800672}
673
Nan Zhanga40da042018-08-01 12:48:00 -0700674//
675// Droiddoc
676//
677type Droiddoc struct {
678 Javadoc
679
680 properties DroiddocProperties
681 apiFile android.WritablePath
682 dexApiFile android.WritablePath
683 privateApiFile android.WritablePath
684 privateDexApiFile android.WritablePath
685 removedApiFile android.WritablePath
686 removedDexApiFile android.WritablePath
687 exactApiFile android.WritablePath
688 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700689 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700690
691 checkCurrentApiTimestamp android.WritablePath
692 updateCurrentApiTimestamp android.WritablePath
693 checkLastReleasedApiTimestamp android.WritablePath
694
Nan Zhanga40da042018-08-01 12:48:00 -0700695 apiFilePath android.Path
696}
697
Colin Crossa3002fc2019-07-08 16:48:04 -0700698// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700699func DroiddocFactory() android.Module {
700 module := &Droiddoc{}
701
702 module.AddProperties(&module.properties,
703 &module.Javadoc.properties)
704
705 InitDroiddocModule(module, android.HostAndDeviceSupported)
706 return module
707}
708
Colin Crossa3002fc2019-07-08 16:48:04 -0700709// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700710func DroiddocHostFactory() android.Module {
711 module := &Droiddoc{}
712
713 module.AddProperties(&module.properties,
714 &module.Javadoc.properties)
715
716 InitDroiddocModule(module, android.HostSupported)
717 return module
718}
719
720func (d *Droiddoc) ApiFilePath() android.Path {
721 return d.apiFilePath
722}
723
Nan Zhang581fd212018-01-10 16:06:12 -0800724func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
725 d.Javadoc.addDeps(ctx)
726
Inseob Kim38449af2019-02-28 14:24:05 +0900727 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
728 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
729 }
730
Nan Zhang79614d12018-04-19 18:03:39 -0700731 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800732 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
733 }
Nan Zhang581fd212018-01-10 16:06:12 -0800734}
735
Colin Crossab054432019-07-15 16:13:59 -0700736func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700737 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
738 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
739 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700740 cmd.FlagWithArg("-source ", "1.8").
741 Flag("-J-Xmx1600m").
742 Flag("-J-XX:-OmitStackTraceInFastThrow").
743 Flag("-XDignore.symbol.file").
744 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
745 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
746 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700747 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 -0700748
Nan Zhanga40da042018-08-01 12:48:00 -0700749 if String(d.properties.Custom_template) == "" {
750 // TODO: This is almost always droiddoc-templates-sdk
751 ctx.PropertyErrorf("custom_template", "must specify a template")
752 }
753
754 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700755 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700756 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700757 } else {
758 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
759 }
760 })
761
762 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700763 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
764 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
765 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700766 }
767
768 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700769 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
770 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
771 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700772 }
773
774 if len(d.properties.Html_dirs) > 2 {
775 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
776 }
777
Colin Cross8a497952019-03-05 22:25:09 -0800778 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700779 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700780
Colin Crossab054432019-07-15 16:13:59 -0700781 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700782
783 if String(d.properties.Proofread_file) != "" {
784 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700785 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700786 }
787
788 if String(d.properties.Todo_file) != "" {
789 // tricky part:
790 // we should not compute full path for todo_file through PathForModuleOut().
791 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700792 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
793 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700794 }
795
796 if String(d.properties.Resourcesdir) != "" {
797 // TODO: should we add files under resourcesDir to the implicits? It seems that
798 // resourcesDir is one sub dir of htmlDir
799 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700800 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700801 }
802
803 if String(d.properties.Resourcesoutdir) != "" {
804 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700805 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700806 }
Nan Zhanga40da042018-08-01 12:48:00 -0700807}
808
Colin Crossab054432019-07-15 16:13:59 -0700809func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200810 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
811 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700812 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700813
Nan Zhanga40da042018-08-01 12:48:00 -0700814 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700815 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700816 d.apiFilePath = d.apiFile
817 }
818
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200819 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
820 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700821 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700822 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 }
825
826 if String(d.properties.Private_api_filename) != "" {
827 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700828 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700829 }
830
831 if String(d.properties.Dex_api_filename) != "" {
832 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700834 }
835
836 if String(d.properties.Private_dex_api_filename) != "" {
837 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700838 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
841 if String(d.properties.Removed_dex_api_filename) != "" {
842 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700843 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700844 }
845
846 if String(d.properties.Exact_api_filename) != "" {
847 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700848 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700849 }
850
851 if String(d.properties.Dex_mapping_filename) != "" {
852 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700853 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700854 }
855
Nan Zhang66dc2362018-08-14 20:41:04 -0700856 if String(d.properties.Proguard_filename) != "" {
857 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700858 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700859 }
860
Nan Zhanga40da042018-08-01 12:48:00 -0700861 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700862 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700863 }
864
865 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700866 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700867 }
Nan Zhanga40da042018-08-01 12:48:00 -0700868}
869
Colin Crossab054432019-07-15 16:13:59 -0700870func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700871 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700872 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
873 rule.Command().Text("cp").
874 Input(staticDocIndexRedirect).
875 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700876 }
877
878 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700879 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
880 rule.Command().Text("cp").
881 Input(staticDocProperties).
882 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700883 }
Nan Zhanga40da042018-08-01 12:48:00 -0700884}
885
Colin Crossab054432019-07-15 16:13:59 -0700886func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700887 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700888
889 cmd := rule.Command().
890 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
891 Flag(config.JavacVmFlags).
892 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700893 FlagWithRspFileInputList("@", srcs).
894 FlagWithInput("@", srcJarList)
895
Colin Crossab054432019-07-15 16:13:59 -0700896 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
897 // based stubs generation.
898 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
899 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
900 // the correct package name base path.
901 if len(sourcepaths) > 0 {
902 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
903 } else {
904 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
905 }
906
907 cmd.FlagWithArg("-d ", outDir.String()).
908 Flag("-quiet")
909
910 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700911}
912
Colin Crossdaa4c672019-07-15 22:53:46 -0700913func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
914 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
915 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
916
917 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
918
919 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
920 cmd.Flag(flag).Implicits(deps)
921
922 cmd.FlagWithArg("--patch-module ", "java.base=.")
923
924 if len(classpath) > 0 {
925 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
926 }
927
928 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700929}
930
Colin Crossdaa4c672019-07-15 22:53:46 -0700931func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
932 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
933 sourcepaths android.Paths) *android.RuleBuilderCommand {
934
935 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
936
937 if len(bootclasspath) == 0 && ctx.Device() {
938 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
939 // ensure java does not fall back to the default bootclasspath.
940 cmd.FlagWithArg("-bootclasspath ", `""`)
941 } else if len(bootclasspath) > 0 {
942 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
943 }
944
945 if len(classpath) > 0 {
946 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
947 }
948
949 return cmd
950}
951
Colin Crossab054432019-07-15 16:13:59 -0700952func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
953 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700954
Colin Crossab054432019-07-15 16:13:59 -0700955 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
956 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
957
958 return rule.Command().
959 BuiltTool(ctx, "dokka").
960 Flag(config.JavacVmFlags).
961 Flag(srcJarDir.String()).
962 FlagWithInputList("-classpath ", dokkaClasspath, ":").
963 FlagWithArg("-format ", "dac").
964 FlagWithArg("-dacRoot ", "/reference/kotlin").
965 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700966}
967
968func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
969 deps := d.Javadoc.collectDeps(ctx)
970
Colin Crossdaa4c672019-07-15 22:53:46 -0700971 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
972 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
973
Nan Zhang1598a9e2018-09-04 17:14:32 -0700974 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
975 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
976 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
977 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
978
Colin Crossab054432019-07-15 16:13:59 -0700979 outDir := android.PathForModuleOut(ctx, "out")
980 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
981 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700982
Colin Crossab054432019-07-15 16:13:59 -0700983 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700984
Colin Crossab054432019-07-15 16:13:59 -0700985 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
986 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700987
Colin Crossab054432019-07-15 16:13:59 -0700988 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
989
990 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700992 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700993 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700994 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700995 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700996 }
997
Colin Crossab054432019-07-15 16:13:59 -0700998 d.stubsFlags(ctx, cmd, stubsDir)
999
1000 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1001
1002 var desc string
1003 if Bool(d.properties.Dokka_enabled) {
1004 desc = "dokka"
1005 } else {
1006 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1007
1008 for _, o := range d.Javadoc.properties.Out {
1009 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1010 }
1011
1012 d.postDoclavaCmds(ctx, rule)
1013 desc = "doclava"
1014 }
1015
1016 rule.Command().
1017 BuiltTool(ctx, "soong_zip").
1018 Flag("-write_if_changed").
1019 Flag("-d").
1020 FlagWithOutput("-o ", d.docZip).
1021 FlagWithArg("-C ", outDir.String()).
1022 FlagWithArg("-D ", outDir.String())
1023
1024 rule.Command().
1025 BuiltTool(ctx, "soong_zip").
1026 Flag("-write_if_changed").
1027 Flag("-jar").
1028 FlagWithOutput("-o ", d.stubsSrcJar).
1029 FlagWithArg("-C ", stubsDir.String()).
1030 FlagWithArg("-D ", stubsDir.String())
1031
1032 rule.Restat()
1033
1034 zipSyncCleanupCmd(rule, srcJarDir)
1035
1036 rule.Build(pctx, ctx, "javadoc", desc)
1037
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001038 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001039 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001040
1041 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1042 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001043
1044 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001045
1046 rule := android.NewRuleBuilder()
1047
1048 rule.Command().Text("( true")
1049
1050 rule.Command().
1051 BuiltTool(ctx, "apicheck").
1052 Flag("-JXmx1024m").
1053 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1054 OptionalFlag(d.properties.Check_api.Current.Args).
1055 Input(apiFile).
1056 Input(d.apiFile).
1057 Input(removedApiFile).
1058 Input(d.removedApiFile)
1059
1060 msg := fmt.Sprintf(`\n******************************\n`+
1061 `You have tried to change the API from what has been previously approved.\n\n`+
1062 `To make these errors go away, you have two choices:\n`+
1063 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1064 ` errors above.\n\n`+
1065 ` 2. You can update current.txt by executing the following command:\n`+
1066 ` make %s-update-current-api\n\n`+
1067 ` To submit the revised current.txt to the main Android repository,\n`+
1068 ` you will need approval.\n`+
1069 `******************************\n`, ctx.ModuleName())
1070
1071 rule.Command().
1072 Text("touch").Output(d.checkCurrentApiTimestamp).
1073 Text(") || (").
1074 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1075 Text("; exit 38").
1076 Text(")")
1077
1078 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001079
1080 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001081
1082 // update API rule
1083 rule = android.NewRuleBuilder()
1084
1085 rule.Command().Text("( true")
1086
1087 rule.Command().
1088 Text("cp").Flag("-f").
1089 Input(d.apiFile).Flag(apiFile.String())
1090
1091 rule.Command().
1092 Text("cp").Flag("-f").
1093 Input(d.removedApiFile).Flag(removedApiFile.String())
1094
1095 msg = "failed to update public API"
1096
1097 rule.Command().
1098 Text("touch").Output(d.updateCurrentApiTimestamp).
1099 Text(") || (").
1100 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1101 Text("; exit 38").
1102 Text(")")
1103
1104 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001105 }
1106
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001107 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001108 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001109
1110 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1111 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001112
1113 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001114
1115 rule := android.NewRuleBuilder()
1116
1117 rule.Command().
1118 Text("(").
1119 BuiltTool(ctx, "apicheck").
1120 Flag("-JXmx1024m").
1121 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1122 OptionalFlag(d.properties.Check_api.Last_released.Args).
1123 Input(apiFile).
1124 Input(d.apiFile).
1125 Input(removedApiFile).
1126 Input(d.removedApiFile)
1127
1128 msg := `\n******************************\n` +
1129 `You have tried to change the API from what has been previously released in\n` +
1130 `an SDK. Please fix the errors listed above.\n` +
1131 `******************************\n`
1132
1133 rule.Command().
1134 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1135 Text(") || (").
1136 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1137 Text("; exit 38").
1138 Text(")")
1139
1140 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001141 }
1142}
1143
1144//
1145// Droidstubs
1146//
1147type Droidstubs struct {
1148 Javadoc
1149
Pete Gillin581d6082018-10-22 15:55:04 +01001150 properties DroidstubsProperties
1151 apiFile android.WritablePath
1152 apiXmlFile android.WritablePath
1153 lastReleasedApiXmlFile android.WritablePath
1154 dexApiFile android.WritablePath
1155 privateApiFile android.WritablePath
1156 privateDexApiFile android.WritablePath
1157 removedApiFile android.WritablePath
1158 removedDexApiFile android.WritablePath
1159 apiMappingFile android.WritablePath
1160 exactApiFile android.WritablePath
1161 proguardFile android.WritablePath
1162 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001163
1164 checkCurrentApiTimestamp android.WritablePath
1165 updateCurrentApiTimestamp android.WritablePath
1166 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001167 apiLintTimestamp android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001168
Pete Gillin581d6082018-10-22 15:55:04 +01001169 checkNullabilityWarningsTimestamp android.WritablePath
1170
Nan Zhang1598a9e2018-09-04 17:14:32 -07001171 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001172 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001173
1174 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001175
1176 jdiffDocZip android.WritablePath
1177 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001178}
1179
Colin Crossa3002fc2019-07-08 16:48:04 -07001180// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1181// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1182// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001183func DroidstubsFactory() android.Module {
1184 module := &Droidstubs{}
1185
1186 module.AddProperties(&module.properties,
1187 &module.Javadoc.properties)
1188
1189 InitDroiddocModule(module, android.HostAndDeviceSupported)
1190 return module
1191}
1192
Colin Crossa3002fc2019-07-08 16:48:04 -07001193// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1194// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1195// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1196// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001197func DroidstubsHostFactory() android.Module {
1198 module := &Droidstubs{}
1199
1200 module.AddProperties(&module.properties,
1201 &module.Javadoc.properties)
1202
1203 InitDroiddocModule(module, android.HostSupported)
1204 return module
1205}
1206
1207func (d *Droidstubs) ApiFilePath() android.Path {
1208 return d.apiFilePath
1209}
1210
1211func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1212 d.Javadoc.addDeps(ctx)
1213
Inseob Kim38449af2019-02-28 14:24:05 +09001214 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1215 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1216 }
1217
Nan Zhang1598a9e2018-09-04 17:14:32 -07001218 if len(d.properties.Merge_annotations_dirs) != 0 {
1219 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1220 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1221 }
1222 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001223
Pete Gillin77167902018-09-19 18:16:26 +01001224 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1225 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1226 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1227 }
1228 }
1229
Nan Zhang9c69a122018-08-22 10:22:08 -07001230 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1231 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1232 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1233 }
1234 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001235}
1236
Colin Cross33961b52019-07-11 11:01:22 -07001237func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001238 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1239 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001240 String(d.properties.Api_filename) != "" {
1241 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001242 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001243 d.apiFilePath = d.apiFile
1244 }
1245
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001246 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1247 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001248 String(d.properties.Removed_api_filename) != "" {
1249 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001250 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 }
1252
1253 if String(d.properties.Private_api_filename) != "" {
1254 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001255 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256 }
1257
1258 if String(d.properties.Dex_api_filename) != "" {
1259 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001260 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261 }
1262
1263 if String(d.properties.Private_dex_api_filename) != "" {
1264 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001265 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001266 }
1267
1268 if String(d.properties.Removed_dex_api_filename) != "" {
1269 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001270 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001271 }
1272
1273 if String(d.properties.Exact_api_filename) != "" {
1274 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001275 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001276 }
1277
Nan Zhang9c69a122018-08-22 10:22:08 -07001278 if String(d.properties.Dex_mapping_filename) != "" {
1279 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001280 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001281 }
1282
Nan Zhang199645c2018-09-19 12:40:06 -07001283 if String(d.properties.Proguard_filename) != "" {
1284 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001286 }
1287
Nan Zhang9c69a122018-08-22 10:22:08 -07001288 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001289 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001290 }
1291
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001293 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001294 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001295 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001297}
1298
Colin Cross33961b52019-07-11 11:01:22 -07001299func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001300 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001301 cmd.Flag("--include-annotations")
1302
Pete Gillinc382a562018-11-14 18:45:46 +00001303 validatingNullability :=
1304 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1305 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001306 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001307
Pete Gillina262c052018-09-14 14:25:48 +01001308 if !(migratingNullability || validatingNullability) {
1309 ctx.PropertyErrorf("previous_api",
1310 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001311 }
Colin Cross33961b52019-07-11 11:01:22 -07001312
Pete Gillina262c052018-09-14 14:25:48 +01001313 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001314 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001316 }
Colin Cross33961b52019-07-11 11:01:22 -07001317
Pete Gillinc382a562018-11-14 18:45:46 +00001318 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001320 }
Colin Cross33961b52019-07-11 11:01:22 -07001321
Pete Gillina262c052018-09-14 14:25:48 +01001322 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001323 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001324 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001325 }
Nan Zhanga40da042018-08-01 12:48:00 -07001326
1327 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001328 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001329
Nan Zhang1598a9e2018-09-04 17:14:32 -07001330 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001331 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001332 "has to be non-empty if annotations was enabled!")
1333 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001334
Colin Cross33961b52019-07-11 11:01:22 -07001335 d.mergeAnnoDirFlags(ctx, cmd)
1336
1337 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1338 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1339 FlagWithArg("--hide ", "SuperfluousPrefix").
1340 FlagWithArg("--hide ", "AnnotationExtraction")
1341 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001342}
1343
Colin Cross33961b52019-07-11 11:01:22 -07001344func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1345 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1346 if t, ok := m.(*ExportedDroiddocDir); ok {
1347 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1348 } else {
1349 ctx.PropertyErrorf("merge_annotations_dirs",
1350 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1351 }
1352 })
1353}
1354
1355func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001356 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1357 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001358 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001359 } else {
1360 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1361 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1362 }
1363 })
Nan Zhanga40da042018-08-01 12:48:00 -07001364}
1365
Colin Cross33961b52019-07-11 11:01:22 -07001366func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001367 if Bool(d.properties.Api_levels_annotations_enabled) {
1368 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001369
1370 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1371 ctx.PropertyErrorf("api_levels_annotations_dirs",
1372 "has to be non-empty if api levels annotations was enabled!")
1373 }
1374
Colin Cross33961b52019-07-11 11:01:22 -07001375 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1376 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1377 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1378 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001379
1380 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1381 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001382 for _, dep := range t.deps {
1383 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001384 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001385 }
1386 }
Colin Cross33961b52019-07-11 11:01:22 -07001387 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001388 } else {
1389 ctx.PropertyErrorf("api_levels_annotations_dirs",
1390 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1391 }
1392 })
1393
1394 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001395}
1396
Colin Cross33961b52019-07-11 11:01:22 -07001397func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001398 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1399 if d.apiFile.String() == "" {
1400 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1401 }
1402
1403 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001404 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001405
1406 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1407 ctx.PropertyErrorf("check_api.last_released.api_file",
1408 "has to be non-empty if jdiff was enabled!")
1409 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001410
Colin Cross33961b52019-07-11 11:01:22 -07001411 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001412 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001413 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1414 }
1415}
Nan Zhang71bbe632018-09-17 14:32:21 -07001416
Colin Cross33961b52019-07-11 11:01:22 -07001417func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1418 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1419 cmd := rule.Command().BuiltTool(ctx, "metalava").
1420 Flag(config.JavacVmFlags).
1421 FlagWithArg("-encoding ", "UTF-8").
1422 FlagWithArg("-source ", javaVersion).
1423 FlagWithRspFileInputList("@", srcs).
1424 FlagWithInput("@", srcJarList)
1425
1426 if len(bootclasspath) > 0 {
1427 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001428 }
1429
Colin Cross33961b52019-07-11 11:01:22 -07001430 if len(classpath) > 0 {
1431 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1432 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001433
Colin Cross33961b52019-07-11 11:01:22 -07001434 if len(sourcepaths) > 0 {
1435 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1436 } else {
1437 cmd.FlagWithArg("-sourcepath ", `""`)
1438 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001439
Colin Cross33961b52019-07-11 11:01:22 -07001440 cmd.Flag("--no-banner").
1441 Flag("--color").
1442 Flag("--quiet").
1443 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001444
Colin Cross33961b52019-07-11 11:01:22 -07001445 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001446}
1447
Nan Zhang1598a9e2018-09-04 17:14:32 -07001448func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001449 deps := d.Javadoc.collectDeps(ctx)
1450
1451 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001452
Colin Cross33961b52019-07-11 11:01:22 -07001453 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001454
Colin Crossdaa4c672019-07-15 22:53:46 -07001455 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1458 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001461
Colin Cross33961b52019-07-11 11:01:22 -07001462 rule.Command().Text("rm -rf").Text(stubsDir.String())
1463 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001464
Colin Cross33961b52019-07-11 11:01:22 -07001465 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1466
1467 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1468 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1469
1470 d.stubsFlags(ctx, cmd, stubsDir)
1471
1472 d.annotationsFlags(ctx, cmd)
1473 d.inclusionAnnotationsFlags(ctx, cmd)
1474 d.apiLevelsAnnotationsFlags(ctx, cmd)
1475 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001476
Nan Zhang1598a9e2018-09-04 17:14:32 -07001477 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1478 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1479 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1480 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1481 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001482 }
Colin Cross33961b52019-07-11 11:01:22 -07001483
1484 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1485 for _, o := range d.Javadoc.properties.Out {
1486 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1487 }
1488
1489 rule.Command().
1490 BuiltTool(ctx, "soong_zip").
1491 Flag("-write_if_changed").
1492 Flag("-jar").
1493 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1494 FlagWithArg("-C ", stubsDir.String()).
1495 FlagWithArg("-D ", stubsDir.String())
1496 rule.Restat()
1497
1498 zipSyncCleanupCmd(rule, srcJarDir)
1499
1500 rule.Build(pctx, ctx, "metalava", "metalava")
1501
1502 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001503
Adrian Roos075eedc2019-10-10 12:07:03 +02001504 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1505 rule := android.NewRuleBuilder()
1506 rule.Command().Text("( true")
1507
1508 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1509 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1510
1511 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1512 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1513
1514 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1515 if newSince.Valid() {
1516 cmd.FlagWithInput("--api-lint ", newSince.Path())
1517 } else {
1518 cmd.Flag("--api-lint")
1519 }
1520
1521 d.inclusionAnnotationsFlags(ctx, cmd)
1522 d.mergeAnnoDirFlags(ctx, cmd)
1523
1524 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1525 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1526 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1527
1528 if baselineFile.Valid() {
1529 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1530 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1531 }
1532
1533 zipSyncCleanupCmd(rule, srcJarDir)
1534
1535 msg := fmt.Sprintf(`\n******************************\n`+
1536 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1537 `To make these errors go away, you have two choices:\n`+
1538 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1539 ` 2. You can update the baseline by executing the following command:\n`+
1540 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1541 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1542 rule.Command().
1543 Text("touch").Output(d.apiLintTimestamp).
1544 Text(") || (").
1545 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1546 Text("; exit 38").
1547 Text(")")
1548
1549 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1550
1551 }
1552
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001553 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001554 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001555
1556 if len(d.Javadoc.properties.Out) > 0 {
1557 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1558 }
1559
1560 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1561 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001562 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1563 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001564
Nan Zhang2760dfc2018-08-24 17:32:54 +00001565 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001566
Colin Cross33961b52019-07-11 11:01:22 -07001567 rule := android.NewRuleBuilder()
1568
1569 rule.Command().Text("( true")
1570
1571 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1572 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1573
1574 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1575 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1576
1577 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1578 FlagWithInput("--check-compatibility:api:current ", apiFile).
1579 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1580
1581 d.inclusionAnnotationsFlags(ctx, cmd)
1582 d.mergeAnnoDirFlags(ctx, cmd)
1583
Adrian Roos14f75a92019-08-12 17:54:09 +02001584 if baselineFile.Valid() {
1585 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1586 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1587 }
1588
Colin Cross33961b52019-07-11 11:01:22 -07001589 zipSyncCleanupCmd(rule, srcJarDir)
1590
1591 msg := fmt.Sprintf(`\n******************************\n`+
1592 `You have tried to change the API from what has been previously approved.\n\n`+
1593 `To make these errors go away, you have two choices:\n`+
1594 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1595 ` errors above.\n\n`+
1596 ` 2. You can update current.txt by executing the following command:\n`+
1597 ` make %s-update-current-api\n\n`+
1598 ` To submit the revised current.txt to the main Android repository,\n`+
1599 ` you will need approval.\n`+
1600 `******************************\n`, ctx.ModuleName())
1601
1602 rule.Command().
1603 Text("touch").Output(d.checkCurrentApiTimestamp).
1604 Text(") || (").
1605 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1606 Text("; exit 38").
1607 Text(")")
1608
1609 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001610
1611 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001612
1613 // update API rule
1614 rule = android.NewRuleBuilder()
1615
1616 rule.Command().Text("( true")
1617
1618 rule.Command().
1619 Text("cp").Flag("-f").
1620 Input(d.apiFile).Flag(apiFile.String())
1621
1622 rule.Command().
1623 Text("cp").Flag("-f").
1624 Input(d.removedApiFile).Flag(removedApiFile.String())
1625
1626 msg = "failed to update public API"
1627
1628 rule.Command().
1629 Text("touch").Output(d.updateCurrentApiTimestamp).
1630 Text(") || (").
1631 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1632 Text("; exit 38").
1633 Text(")")
1634
1635 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001636 }
Nan Zhanga40da042018-08-01 12:48:00 -07001637
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001638 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001639 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001640
1641 if len(d.Javadoc.properties.Out) > 0 {
1642 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1643 }
1644
1645 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1646 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001647 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1648 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001649
Nan Zhang2760dfc2018-08-24 17:32:54 +00001650 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001651
Colin Cross33961b52019-07-11 11:01:22 -07001652 rule := android.NewRuleBuilder()
1653
1654 rule.Command().Text("( true")
1655
1656 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1657 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1658
1659 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1660 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1661
1662 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1663 FlagWithInput("--check-compatibility:api:released ", apiFile)
1664
1665 d.inclusionAnnotationsFlags(ctx, cmd)
1666
1667 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1668
1669 d.mergeAnnoDirFlags(ctx, cmd)
1670
Adrian Roos14f75a92019-08-12 17:54:09 +02001671 if baselineFile.Valid() {
1672 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1673 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1674 }
1675
Colin Cross33961b52019-07-11 11:01:22 -07001676 zipSyncCleanupCmd(rule, srcJarDir)
1677
1678 msg := `\n******************************\n` +
1679 `You have tried to change the API from what has been previously released in\n` +
1680 `an SDK. Please fix the errors listed above.\n` +
1681 `******************************\n`
1682 rule.Command().
1683 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1684 Text(") || (").
1685 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1686 Text("; exit 38").
1687 Text(")")
1688
1689 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001690 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001691
Pete Gillin581d6082018-10-22 15:55:04 +01001692 if String(d.properties.Check_nullability_warnings) != "" {
1693 if d.nullabilityWarningsFile == nil {
1694 ctx.PropertyErrorf("check_nullability_warnings",
1695 "Cannot specify check_nullability_warnings unless validating nullability")
1696 }
Colin Cross33961b52019-07-11 11:01:22 -07001697
1698 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1699
Pete Gillin581d6082018-10-22 15:55:04 +01001700 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001701
Pete Gillin581d6082018-10-22 15:55:04 +01001702 msg := fmt.Sprintf(`\n******************************\n`+
1703 `The warnings encountered during nullability annotation validation did\n`+
1704 `not match the checked in file of expected warnings. The diffs are shown\n`+
1705 `above. You have two options:\n`+
1706 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1707 ` 2. Update the file of expected warnings by running:\n`+
1708 ` cp %s %s\n`+
1709 ` and submitting the updated file as part of your change.`,
1710 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001711
1712 rule := android.NewRuleBuilder()
1713
1714 rule.Command().
1715 Text("(").
1716 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1717 Text("&&").
1718 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1719 Text(") || (").
1720 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1721 Text("; exit 38").
1722 Text(")")
1723
1724 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001725 }
1726
Nan Zhang71bbe632018-09-17 14:32:21 -07001727 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001728 if len(d.Javadoc.properties.Out) > 0 {
1729 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1730 }
1731
1732 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1733 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1734 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1735
1736 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001737
Nan Zhang86b06202018-09-21 17:09:21 -07001738 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1739 // since there's cron job downstream that fetch this .zip file periodically.
1740 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001741 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1742 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1743
Nan Zhang71bbe632018-09-17 14:32:21 -07001744 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001745
Colin Cross33961b52019-07-11 11:01:22 -07001746 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1747 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001748
Colin Cross33961b52019-07-11 11:01:22 -07001749 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1750
Colin Crossdaa4c672019-07-15 22:53:46 -07001751 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001752 deps.bootClasspath, deps.classpath, d.sourcepaths)
1753
1754 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001755 Flag("-XDignore.symbol.file").
1756 FlagWithArg("-doclet ", "jdiff.JDiff").
1757 FlagWithInput("-docletpath ", jdiff).
1758 Flag("-quiet").
1759 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1760 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1761 Implicit(d.apiXmlFile).
1762 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1763 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1764 Implicit(d.lastReleasedApiXmlFile)
1765
Colin Cross33961b52019-07-11 11:01:22 -07001766 rule.Command().
1767 BuiltTool(ctx, "soong_zip").
1768 Flag("-write_if_changed").
1769 Flag("-d").
1770 FlagWithOutput("-o ", d.jdiffDocZip).
1771 FlagWithArg("-C ", outDir.String()).
1772 FlagWithArg("-D ", outDir.String())
1773
1774 rule.Command().
1775 BuiltTool(ctx, "soong_zip").
1776 Flag("-write_if_changed").
1777 Flag("-jar").
1778 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1779 FlagWithArg("-C ", stubsDir.String()).
1780 FlagWithArg("-D ", stubsDir.String())
1781
1782 rule.Restat()
1783
1784 zipSyncCleanupCmd(rule, srcJarDir)
1785
1786 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001787 }
Nan Zhang581fd212018-01-10 16:06:12 -08001788}
Dan Willemsencc090972018-02-26 14:33:31 -08001789
Nan Zhanga40da042018-08-01 12:48:00 -07001790//
Nan Zhangf4936b02018-08-01 15:00:28 -07001791// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001792//
Dan Willemsencc090972018-02-26 14:33:31 -08001793var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001794var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001795var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001796var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001797
Nan Zhangf4936b02018-08-01 15:00:28 -07001798type ExportedDroiddocDirProperties struct {
1799 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001800 Path *string
1801}
1802
Nan Zhangf4936b02018-08-01 15:00:28 -07001803type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001804 android.ModuleBase
1805
Nan Zhangf4936b02018-08-01 15:00:28 -07001806 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001807
1808 deps android.Paths
1809 dir android.Path
1810}
1811
Colin Crossa3002fc2019-07-08 16:48:04 -07001812// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001813func ExportedDroiddocDirFactory() android.Module {
1814 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001815 module.AddProperties(&module.properties)
1816 android.InitAndroidModule(module)
1817 return module
1818}
1819
Nan Zhangf4936b02018-08-01 15:00:28 -07001820func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001821
Nan Zhangf4936b02018-08-01 15:00:28 -07001822func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001823 path := String(d.properties.Path)
1824 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001825 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001826}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001827
1828//
1829// Defaults
1830//
1831type DocDefaults struct {
1832 android.ModuleBase
1833 android.DefaultsModuleBase
1834}
1835
Nan Zhangb2b33de2018-02-23 11:18:47 -08001836func DocDefaultsFactory() android.Module {
1837 module := &DocDefaults{}
1838
1839 module.AddProperties(
1840 &JavadocProperties{},
1841 &DroiddocProperties{},
1842 )
1843
1844 android.InitDefaultsModule(module)
1845
1846 return module
1847}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001848
1849func StubsDefaultsFactory() android.Module {
1850 module := &DocDefaults{}
1851
1852 module.AddProperties(
1853 &JavadocProperties{},
1854 &DroidstubsProperties{},
1855 )
1856
1857 android.InitDefaultsModule(module)
1858
1859 return module
1860}
Colin Cross33961b52019-07-11 11:01:22 -07001861
1862func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1863 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1864
1865 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1866 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1867 srcJarList := srcJarDir.Join(ctx, "list")
1868
1869 rule.Temporary(srcJarList)
1870
1871 rule.Command().BuiltTool(ctx, "zipsync").
1872 FlagWithArg("-d ", srcJarDir.String()).
1873 FlagWithOutput("-l ", srcJarList).
1874 FlagWithArg("-f ", `"*.java"`).
1875 Inputs(srcJars)
1876
1877 return srcJarList
1878}
1879
1880func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1881 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1882}