blob: b47494893288f7b0a60b6d42db7f35bfd26bf558 [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 Zhang46130972018-06-04 11:28:01 -070020 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080021 "strings"
22
Jeongik Cha6bd33c12019-06-25 16:26:18 +090023 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080024
Colin Crossab054432019-07-15 16:13:59 -070025 "android/soong/android"
26 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080030 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070031 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080032
Nan Zhang581fd212018-01-10 16:06:12 -080033 android.RegisterModuleType("droiddoc", DroiddocFactory)
34 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070035 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080036 android.RegisterModuleType("javadoc", JavadocFactory)
37 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070038
39 android.RegisterModuleType("droidstubs", DroidstubsFactory)
40 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080041}
42
Colin Crossa1ce2a02018-06-20 15:19:39 -070043var (
44 srcsLibTag = dependencyTag{name: "sources from javalib"}
45)
46
Nan Zhang581fd212018-01-10 16:06:12 -080047type JavadocProperties struct {
48 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
49 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080051
52 // list of directories rooted at the Android.bp file that will
53 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080054 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080055
56 // list of source files that should not be used to build the Java module.
57 // This is most useful in the arch/multilib variants to remove non-common files
58 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080059 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080060
Nan Zhangb2b33de2018-02-23 11:18:47 -080061 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080062 Libs []string `android:"arch_variant"`
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // the java library (in classpath) for documentation that provides java srcs and srcjars.
65 Srcs_lib *string
66
67 // the base dirs under srcs_lib will be scanned for java srcs.
68 Srcs_lib_whitelist_dirs []string
69
70 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
71 Srcs_lib_whitelist_pkgs []string
72
Nan Zhang581fd212018-01-10 16:06:12 -080073 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080074 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080075
76 // if not blank, set to the version of the sdk to compile against
77 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090078
79 Aidl struct {
80 // Top level directories to pass to aidl tool
81 Include_dirs []string
82
83 // Directories rooted at the Android.bp file to pass to aidl tool
84 Local_include_dirs []string
85 }
Nan Zhang357466b2018-04-17 17:38:36 -070086
87 // If not blank, set the java version passed to javadoc as -source
88 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080091 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070092
93 // user customized droiddoc args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070097 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070098 Args *string
99
100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // if set to true, collect the values used by the Dev tools and
146 // write them in files packaged with the SDK. Defaults to false.
147 Write_sdk_values *bool
148
149 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
152 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700154
Nan Zhang581fd212018-01-10 16:06:12 -0800155 // a list of files under current module source dir which contains known tags in Java sources.
156 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800157 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700158
159 // the tag name used to distinguish if the API files belong to public/system/test.
160 Api_tag_name *string
161
162 // the generated public API filename by Doclava.
163 Api_filename *string
164
David Brazdilfbe4cc32018-05-31 13:56:46 +0100165 // the generated public Dex API filename by Doclava.
166 Dex_api_filename *string
167
Nan Zhang28c68b92018-03-13 16:17:01 -0700168 // the generated private API filename by Doclava.
169 Private_api_filename *string
170
171 // the generated private Dex API filename by Doclava.
172 Private_dex_api_filename *string
173
174 // the generated removed API filename by Doclava.
175 Removed_api_filename *string
176
David Brazdilaac0c3c2018-04-24 16:23:29 +0100177 // the generated removed Dex API filename by Doclava.
178 Removed_dex_api_filename *string
179
Mathew Inwood76c3de12018-06-22 15:28:11 +0100180 // mapping of dex signatures to source file and line number. This is a temporary property and
181 // will be deleted; you probably shouldn't be using it.
182 Dex_mapping_filename *string
183
Nan Zhang28c68b92018-03-13 16:17:01 -0700184 // the generated exact API filename by Doclava.
185 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700186
Nan Zhang66dc2362018-08-14 20:41:04 -0700187 // the generated proguard filename by Doclava.
188 Proguard_filename *string
189
Nan Zhang853f4202018-04-12 16:55:56 -0700190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900197
198 // do not perform API check against Last_released, in the case that both two specified API
199 // files by Last_released are modules which don't exist.
200 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700201 }
Nan Zhang79614d12018-04-19 18:03:39 -0700202
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 // if set to true, generate docs through Dokka instead of Doclava.
204 Dokka_enabled *bool
205}
206
207type DroidstubsProperties struct {
208 // the tag name used to distinguish if the API files belong to public/system/test.
209 Api_tag_name *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Private_dex_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 Removed_dex_api_filename *string
228
Nan Zhang9c69a122018-08-22 10:22:08 -0700229 // mapping of dex signatures to source file and line number. This is a temporary property and
230 // will be deleted; you probably shouldn't be using it.
231 Dex_mapping_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700234 Exact_api_filename *string
235
Nan Zhang199645c2018-09-19 12:40:06 -0700236 // the generated proguard filename by Metalava.
237 Proguard_filename *string
238
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Check_api struct {
240 Last_released ApiToCheck
241
242 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900243
244 // do not perform API check against Last_released, in the case that both two specified API
245 // files by Last_released are modules which don't exist.
246 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700247 }
Nan Zhang79614d12018-04-19 18:03:39 -0700248
249 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800250 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700251
252 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700253 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700254
Pete Gillin77167902018-09-19 18:16:26 +0100255 // 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 -0700256 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700257
Pete Gillin77167902018-09-19 18:16:26 +0100258 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
259 Merge_inclusion_annotations_dirs []string
260
Pete Gillinc382a562018-11-14 18:45:46 +0000261 // a file containing a list of classes to do nullability validation for.
262 Validate_nullability_from_list *string
263
Pete Gillin581d6082018-10-22 15:55:04 +0100264 // a file containing expected warnings produced by validation of nullability annotations.
265 Check_nullability_warnings *string
266
Nan Zhang1598a9e2018-09-04 17:14:32 -0700267 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
268 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700269
270 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
271 Api_levels_annotations_enabled *bool
272
273 // the dirs which Metalava extracts API levels annotations from.
274 Api_levels_annotations_dirs []string
275
276 // if set to true, collect the values used by the Dev tools and
277 // write them in files packaged with the SDK. Defaults to false.
278 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700279
280 // If set to true, .xml based public API file will be also generated, and
281 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
282 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800283}
284
Nan Zhanga40da042018-08-01 12:48:00 -0700285//
286// Common flags passed down to build rule
287//
288type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700289 bootClasspathArgs string
290 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700291 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700292 dokkaClasspathArgs string
293 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700294 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700295
Nan Zhanga40da042018-08-01 12:48:00 -0700296 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700297 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700298 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700299}
300
301func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
302 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
303 android.InitDefaultableModule(module)
304}
305
Nan Zhang1598a9e2018-09-04 17:14:32 -0700306func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
307 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
308 return true
309 } else if String(apiToCheck.Api_file) != "" {
310 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
311 } else if String(apiToCheck.Removed_api_file) != "" {
312 panic("for " + apiVersionTag + " api_file has to be non-empty!")
313 }
314
315 return false
316}
317
Inseob Kim38449af2019-02-28 14:24:05 +0900318func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
319 api_file := String(apiToCheck.Api_file)
320 removed_api_file := String(apiToCheck.Removed_api_file)
321
322 api_module := android.SrcIsModule(api_file)
323 removed_api_module := android.SrcIsModule(removed_api_file)
324
325 if api_module == "" || removed_api_module == "" {
326 return
327 }
328
329 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
330 return
331 }
332
333 apiToCheck.Api_file = nil
334 apiToCheck.Removed_api_file = nil
335}
336
Nan Zhang1598a9e2018-09-04 17:14:32 -0700337type ApiFilePath interface {
338 ApiFilePath() android.Path
339}
340
Nan Zhanga40da042018-08-01 12:48:00 -0700341//
342// Javadoc
343//
Nan Zhang581fd212018-01-10 16:06:12 -0800344type Javadoc struct {
345 android.ModuleBase
346 android.DefaultableModuleBase
347
348 properties JavadocProperties
349
350 srcJars android.Paths
351 srcFiles android.Paths
352 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700353 argFiles android.Paths
354
355 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800356
Nan Zhangccff0f72018-03-08 17:26:16 -0800357 docZip android.WritablePath
358 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800359}
360
Colin Cross41955e82019-05-29 14:40:35 -0700361func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
362 switch tag {
363 case "":
364 return android.Paths{j.stubsSrcJar}, nil
365 default:
366 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
367 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800368}
369
Colin Crossa3002fc2019-07-08 16:48:04 -0700370// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800371func JavadocFactory() android.Module {
372 module := &Javadoc{}
373
374 module.AddProperties(&module.properties)
375
376 InitDroiddocModule(module, android.HostAndDeviceSupported)
377 return module
378}
379
Colin Crossa3002fc2019-07-08 16:48:04 -0700380// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800381func JavadocHostFactory() android.Module {
382 module := &Javadoc{}
383
384 module.AddProperties(&module.properties)
385
386 InitDroiddocModule(module, android.HostSupported)
387 return module
388}
389
Colin Cross41955e82019-05-29 14:40:35 -0700390var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800391
Colin Cross83bb3162018-06-25 15:48:06 -0700392func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900393 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700394}
395
396func (j *Javadoc) minSdkVersion() string {
397 return j.sdkVersion()
398}
399
Dan Willemsen419290a2018-10-31 15:28:47 -0700400func (j *Javadoc) targetSdkVersion() string {
401 return j.sdkVersion()
402}
403
Nan Zhang581fd212018-01-10 16:06:12 -0800404func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
405 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100406 sdkDep := decodeSdkDep(ctx, sdkContext(j))
407 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700408 if sdkDep.useDefaultLibs {
409 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
410 if ctx.Config().TargetOpenJDK9() {
411 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
412 }
Paul Duffin250e6192019-06-07 10:44:37 +0100413 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700414 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
415 }
416 } else if sdkDep.useModule {
417 if ctx.Config().TargetOpenJDK9() {
418 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
419 }
420 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700421 }
Nan Zhang581fd212018-01-10 16:06:12 -0800422 }
423 }
424
Colin Cross42d48b72018-08-29 14:10:52 -0700425 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700426 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700427 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700428 }
Nan Zhang581fd212018-01-10 16:06:12 -0800429}
430
Nan Zhangb2b33de2018-02-23 11:18:47 -0800431func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
432 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
433 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900434 // convert foo.bar.baz to foo/bar/baz
435 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
436 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800437 if _, found := whitelistPathPrefixes[prefix]; !found {
438 whitelistPathPrefixes[prefix] = true
439 }
440 }
441 }
442}
443
Nan Zhanga40da042018-08-01 12:48:00 -0700444func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
445 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900446
Colin Cross3047fa22019-04-18 10:56:44 -0700447 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900448
449 return flags
450}
451
452func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700453 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900454
455 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
456 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
457
458 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700459 var deps android.Paths
460
Jiyong Park1e440682018-05-23 18:42:04 +0900461 if aidlPreprocess.Valid() {
462 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700463 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900464 } else {
465 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
466 }
467
468 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
469 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
470 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
471 flags = append(flags, "-I"+src.String())
472 }
473
Colin Cross3047fa22019-04-18 10:56:44 -0700474 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900475}
476
Jiyong Parkd90d7412019-08-20 22:49:19 +0900477// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900478func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700479 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900480
481 outSrcFiles := make(android.Paths, 0, len(srcFiles))
482
483 for _, srcFile := range srcFiles {
484 switch srcFile.Ext() {
485 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700486 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900487 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900488 case ".sysprop":
489 javaFile := genSysprop(ctx, srcFile)
490 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900491 case ".logtags":
492 javaFile := genLogtags(ctx, srcFile)
493 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900494 default:
495 outSrcFiles = append(outSrcFiles, srcFile)
496 }
497 }
498
499 return outSrcFiles
500}
501
Nan Zhang581fd212018-01-10 16:06:12 -0800502func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
503 var deps deps
504
Colin Cross83bb3162018-06-25 15:48:06 -0700505 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800506 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700507 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800508 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700509 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800510 }
511
512 ctx.VisitDirectDeps(func(module android.Module) {
513 otherName := ctx.OtherModuleName(module)
514 tag := ctx.OtherModuleDependencyTag(module)
515
Colin Cross2d24c1b2018-05-23 10:59:18 -0700516 switch tag {
517 case bootClasspathTag:
518 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800519 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700520 } else {
521 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
522 }
523 case libTag:
524 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800525 case SdkLibraryDependency:
526 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700527 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900528 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900529 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700530 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800531 checkProducesJars(ctx, dep)
532 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800533 default:
534 ctx.ModuleErrorf("depends on non-java module %q", otherName)
535 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700536 case srcsLibTag:
537 switch dep := module.(type) {
538 case Dependency:
539 srcs := dep.(SrcDependency).CompiledSrcs()
540 whitelistPathPrefixes := make(map[string]bool)
541 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
542 for _, src := range srcs {
543 if _, ok := src.(android.WritablePath); ok { // generated sources
544 deps.srcs = append(deps.srcs, src)
545 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700546 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700547 if strings.HasPrefix(src.Rel(), k) {
548 deps.srcs = append(deps.srcs, src)
549 break
550 }
551 }
552 }
553 }
554 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
555 default:
556 ctx.ModuleErrorf("depends on non-java module %q", otherName)
557 }
Nan Zhang357466b2018-04-17 17:38:36 -0700558 case systemModulesTag:
559 if deps.systemModules != nil {
560 panic("Found two system module dependencies")
561 }
562 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000563 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700564 panic("Missing directory for system module dependency")
565 }
Colin Crossb77043e2019-07-16 13:57:13 -0700566 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800567 }
568 })
569 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
570 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800571 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700572 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900573 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800574
575 // srcs may depend on some genrule output.
576 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800577 j.srcJars = append(j.srcJars, deps.srcJars...)
578
Nan Zhang581fd212018-01-10 16:06:12 -0800579 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800580 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800581
Nan Zhang9c69a122018-08-22 10:22:08 -0700582 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800583 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
584 }
585 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800586
Colin Cross8a497952019-03-05 22:25:09 -0800587 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000588 argFilesMap := map[string]string{}
589 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700590
Paul Duffin99e4a502019-02-11 15:38:42 +0000591 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800592 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000593 if _, exists := argFilesMap[label]; !exists {
594 argFilesMap[label] = strings.Join(paths.Strings(), " ")
595 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700596 } else {
597 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000598 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700599 }
600 }
601
602 var err error
Colin Cross15638152019-07-11 11:11:35 -0700603 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700604 if strings.HasPrefix(name, "location ") {
605 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000606 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700607 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700608 } else {
Colin Cross15638152019-07-11 11:11:35 -0700609 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000610 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700611 }
612 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700613 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700614 }
Colin Cross15638152019-07-11 11:11:35 -0700615 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700616 })
617
618 if err != nil {
619 ctx.PropertyErrorf("args", "%s", err.Error())
620 }
621
Nan Zhang581fd212018-01-10 16:06:12 -0800622 return deps
623}
624
625func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
626 j.addDeps(ctx)
627}
628
629func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
630 deps := j.collectDeps(ctx)
631
Colin Crossdaa4c672019-07-15 22:53:46 -0700632 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800633
Colin Crossdaa4c672019-07-15 22:53:46 -0700634 outDir := android.PathForModuleOut(ctx, "out")
635 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
636
637 j.stubsSrcJar = nil
638
639 rule := android.NewRuleBuilder()
640
641 rule.Command().Text("rm -rf").Text(outDir.String())
642 rule.Command().Text("mkdir -p").Text(outDir.String())
643
644 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700645
Colin Cross83bb3162018-06-25 15:48:06 -0700646 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800647
Colin Crossdaa4c672019-07-15 22:53:46 -0700648 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
649 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800650
Colin Crossdaa4c672019-07-15 22:53:46 -0700651 cmd.FlagWithArg("-source ", javaVersion).
652 Flag("-J-Xmx1024m").
653 Flag("-XDignore.symbol.file").
654 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800655
Colin Crossdaa4c672019-07-15 22:53:46 -0700656 rule.Command().
657 BuiltTool(ctx, "soong_zip").
658 Flag("-write_if_changed").
659 Flag("-d").
660 FlagWithOutput("-o ", j.docZip).
661 FlagWithArg("-C ", outDir.String()).
662 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700663
Colin Crossdaa4c672019-07-15 22:53:46 -0700664 rule.Restat()
665
666 zipSyncCleanupCmd(rule, srcJarDir)
667
668 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800669}
670
Nan Zhanga40da042018-08-01 12:48:00 -0700671//
672// Droiddoc
673//
674type Droiddoc struct {
675 Javadoc
676
677 properties DroiddocProperties
678 apiFile android.WritablePath
679 dexApiFile android.WritablePath
680 privateApiFile android.WritablePath
681 privateDexApiFile android.WritablePath
682 removedApiFile android.WritablePath
683 removedDexApiFile android.WritablePath
684 exactApiFile android.WritablePath
685 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700686 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700687
688 checkCurrentApiTimestamp android.WritablePath
689 updateCurrentApiTimestamp android.WritablePath
690 checkLastReleasedApiTimestamp android.WritablePath
691
Nan Zhanga40da042018-08-01 12:48:00 -0700692 apiFilePath android.Path
693}
694
Colin Crossa3002fc2019-07-08 16:48:04 -0700695// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700696func DroiddocFactory() android.Module {
697 module := &Droiddoc{}
698
699 module.AddProperties(&module.properties,
700 &module.Javadoc.properties)
701
702 InitDroiddocModule(module, android.HostAndDeviceSupported)
703 return module
704}
705
Colin Crossa3002fc2019-07-08 16:48:04 -0700706// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700707func DroiddocHostFactory() android.Module {
708 module := &Droiddoc{}
709
710 module.AddProperties(&module.properties,
711 &module.Javadoc.properties)
712
713 InitDroiddocModule(module, android.HostSupported)
714 return module
715}
716
717func (d *Droiddoc) ApiFilePath() android.Path {
718 return d.apiFilePath
719}
720
Nan Zhang581fd212018-01-10 16:06:12 -0800721func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
722 d.Javadoc.addDeps(ctx)
723
Inseob Kim38449af2019-02-28 14:24:05 +0900724 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
725 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
726 }
727
Nan Zhang79614d12018-04-19 18:03:39 -0700728 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800729 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
730 }
Nan Zhang581fd212018-01-10 16:06:12 -0800731}
732
Colin Crossab054432019-07-15 16:13:59 -0700733func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700734 var date string
735 if runtime.GOOS == "darwin" {
736 date = `date -r`
737 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700738 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700739 }
740
Nan Zhang443fa522018-08-20 20:58:28 -0700741 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
742 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
743 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700744 cmd.FlagWithArg("-source ", "1.8").
745 Flag("-J-Xmx1600m").
746 Flag("-J-XX:-OmitStackTraceInFastThrow").
747 Flag("-XDignore.symbol.file").
748 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
749 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
750 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700751 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700752
Nan Zhanga40da042018-08-01 12:48:00 -0700753 if String(d.properties.Custom_template) == "" {
754 // TODO: This is almost always droiddoc-templates-sdk
755 ctx.PropertyErrorf("custom_template", "must specify a template")
756 }
757
758 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700759 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700760 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700761 } else {
762 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
763 }
764 })
765
766 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700767 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
768 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
769 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700770 }
771
772 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700773 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
774 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
775 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700776 }
777
778 if len(d.properties.Html_dirs) > 2 {
779 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
780 }
781
Colin Cross8a497952019-03-05 22:25:09 -0800782 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700783 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700784
Colin Crossab054432019-07-15 16:13:59 -0700785 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700786
787 if String(d.properties.Proofread_file) != "" {
788 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700789 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700790 }
791
792 if String(d.properties.Todo_file) != "" {
793 // tricky part:
794 // we should not compute full path for todo_file through PathForModuleOut().
795 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700796 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
797 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700798 }
799
800 if String(d.properties.Resourcesdir) != "" {
801 // TODO: should we add files under resourcesDir to the implicits? It seems that
802 // resourcesDir is one sub dir of htmlDir
803 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700804 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700805 }
806
807 if String(d.properties.Resourcesoutdir) != "" {
808 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700809 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700810 }
Nan Zhanga40da042018-08-01 12:48:00 -0700811}
812
Colin Crossab054432019-07-15 16:13:59 -0700813func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700814 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
815 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
816 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700817
Nan Zhanga40da042018-08-01 12:48:00 -0700818 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700819 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700820 d.apiFilePath = d.apiFile
821 }
822
Nan Zhang1598a9e2018-09-04 17:14:32 -0700823 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
824 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
825 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700826 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700827 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700828 }
829
830 if String(d.properties.Private_api_filename) != "" {
831 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700833 }
834
835 if String(d.properties.Dex_api_filename) != "" {
836 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700837 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700838 }
839
840 if String(d.properties.Private_dex_api_filename) != "" {
841 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700842 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700843 }
844
845 if String(d.properties.Removed_dex_api_filename) != "" {
846 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700847 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700848 }
849
850 if String(d.properties.Exact_api_filename) != "" {
851 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700852 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700853 }
854
855 if String(d.properties.Dex_mapping_filename) != "" {
856 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700857 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700858 }
859
Nan Zhang66dc2362018-08-14 20:41:04 -0700860 if String(d.properties.Proguard_filename) != "" {
861 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700862 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700863 }
864
Nan Zhanga40da042018-08-01 12:48:00 -0700865 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700866 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700867 }
868
869 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700870 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700871 }
Nan Zhanga40da042018-08-01 12:48:00 -0700872}
873
Colin Crossab054432019-07-15 16:13:59 -0700874func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700875 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700876 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
877 rule.Command().Text("cp").
878 Input(staticDocIndexRedirect).
879 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700880 }
881
882 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700883 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
884 rule.Command().Text("cp").
885 Input(staticDocProperties).
886 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700887 }
Nan Zhanga40da042018-08-01 12:48:00 -0700888}
889
Colin Crossab054432019-07-15 16:13:59 -0700890func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700891 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700892
893 cmd := rule.Command().
894 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
895 Flag(config.JavacVmFlags).
896 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700897 FlagWithRspFileInputList("@", srcs).
898 FlagWithInput("@", srcJarList)
899
Colin Crossab054432019-07-15 16:13:59 -0700900 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
901 // based stubs generation.
902 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
903 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
904 // the correct package name base path.
905 if len(sourcepaths) > 0 {
906 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
907 } else {
908 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
909 }
910
911 cmd.FlagWithArg("-d ", outDir.String()).
912 Flag("-quiet")
913
914 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700915}
916
Colin Crossdaa4c672019-07-15 22:53:46 -0700917func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
918 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
919 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
920
921 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
922
923 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
924 cmd.Flag(flag).Implicits(deps)
925
926 cmd.FlagWithArg("--patch-module ", "java.base=.")
927
928 if len(classpath) > 0 {
929 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
930 }
931
932 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700933}
934
Colin Crossdaa4c672019-07-15 22:53:46 -0700935func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
936 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
937 sourcepaths android.Paths) *android.RuleBuilderCommand {
938
939 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
940
941 if len(bootclasspath) == 0 && ctx.Device() {
942 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
943 // ensure java does not fall back to the default bootclasspath.
944 cmd.FlagWithArg("-bootclasspath ", `""`)
945 } else if len(bootclasspath) > 0 {
946 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
947 }
948
949 if len(classpath) > 0 {
950 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
951 }
952
953 return cmd
954}
955
Colin Crossab054432019-07-15 16:13:59 -0700956func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
957 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700958
Colin Crossab054432019-07-15 16:13:59 -0700959 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
960 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
961
962 return rule.Command().
963 BuiltTool(ctx, "dokka").
964 Flag(config.JavacVmFlags).
965 Flag(srcJarDir.String()).
966 FlagWithInputList("-classpath ", dokkaClasspath, ":").
967 FlagWithArg("-format ", "dac").
968 FlagWithArg("-dacRoot ", "/reference/kotlin").
969 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700970}
971
972func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
973 deps := d.Javadoc.collectDeps(ctx)
974
Colin Crossdaa4c672019-07-15 22:53:46 -0700975 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
976 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
977
Nan Zhang1598a9e2018-09-04 17:14:32 -0700978 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
979 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
980 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
981 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
982
Colin Crossab054432019-07-15 16:13:59 -0700983 outDir := android.PathForModuleOut(ctx, "out")
984 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
985 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700986
Colin Crossab054432019-07-15 16:13:59 -0700987 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700988
Colin Crossab054432019-07-15 16:13:59 -0700989 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
990 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991
Colin Crossab054432019-07-15 16:13:59 -0700992 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
993
994 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700996 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700997 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700998 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700999 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001000 }
1001
Colin Crossab054432019-07-15 16:13:59 -07001002 d.stubsFlags(ctx, cmd, stubsDir)
1003
1004 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1005
1006 var desc string
1007 if Bool(d.properties.Dokka_enabled) {
1008 desc = "dokka"
1009 } else {
1010 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1011
1012 for _, o := range d.Javadoc.properties.Out {
1013 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1014 }
1015
1016 d.postDoclavaCmds(ctx, rule)
1017 desc = "doclava"
1018 }
1019
1020 rule.Command().
1021 BuiltTool(ctx, "soong_zip").
1022 Flag("-write_if_changed").
1023 Flag("-d").
1024 FlagWithOutput("-o ", d.docZip).
1025 FlagWithArg("-C ", outDir.String()).
1026 FlagWithArg("-D ", outDir.String())
1027
1028 rule.Command().
1029 BuiltTool(ctx, "soong_zip").
1030 Flag("-write_if_changed").
1031 Flag("-jar").
1032 FlagWithOutput("-o ", d.stubsSrcJar).
1033 FlagWithArg("-C ", stubsDir.String()).
1034 FlagWithArg("-D ", stubsDir.String())
1035
1036 rule.Restat()
1037
1038 zipSyncCleanupCmd(rule, srcJarDir)
1039
1040 rule.Build(pctx, ctx, "javadoc", desc)
1041
Nan Zhang1598a9e2018-09-04 17:14:32 -07001042 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1043 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001044
1045 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1046 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001047
1048 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001049
1050 rule := android.NewRuleBuilder()
1051
1052 rule.Command().Text("( true")
1053
1054 rule.Command().
1055 BuiltTool(ctx, "apicheck").
1056 Flag("-JXmx1024m").
1057 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1058 OptionalFlag(d.properties.Check_api.Current.Args).
1059 Input(apiFile).
1060 Input(d.apiFile).
1061 Input(removedApiFile).
1062 Input(d.removedApiFile)
1063
1064 msg := fmt.Sprintf(`\n******************************\n`+
1065 `You have tried to change the API from what has been previously approved.\n\n`+
1066 `To make these errors go away, you have two choices:\n`+
1067 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1068 ` errors above.\n\n`+
1069 ` 2. You can update current.txt by executing the following command:\n`+
1070 ` make %s-update-current-api\n\n`+
1071 ` To submit the revised current.txt to the main Android repository,\n`+
1072 ` you will need approval.\n`+
1073 `******************************\n`, ctx.ModuleName())
1074
1075 rule.Command().
1076 Text("touch").Output(d.checkCurrentApiTimestamp).
1077 Text(") || (").
1078 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1079 Text("; exit 38").
1080 Text(")")
1081
1082 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001083
1084 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001085
1086 // update API rule
1087 rule = android.NewRuleBuilder()
1088
1089 rule.Command().Text("( true")
1090
1091 rule.Command().
1092 Text("cp").Flag("-f").
1093 Input(d.apiFile).Flag(apiFile.String())
1094
1095 rule.Command().
1096 Text("cp").Flag("-f").
1097 Input(d.removedApiFile).Flag(removedApiFile.String())
1098
1099 msg = "failed to update public API"
1100
1101 rule.Command().
1102 Text("touch").Output(d.updateCurrentApiTimestamp).
1103 Text(") || (").
1104 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1105 Text("; exit 38").
1106 Text(")")
1107
1108 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001109 }
1110
1111 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1112 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001113
1114 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1115 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001116
1117 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001118
1119 rule := android.NewRuleBuilder()
1120
1121 rule.Command().
1122 Text("(").
1123 BuiltTool(ctx, "apicheck").
1124 Flag("-JXmx1024m").
1125 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1126 OptionalFlag(d.properties.Check_api.Last_released.Args).
1127 Input(apiFile).
1128 Input(d.apiFile).
1129 Input(removedApiFile).
1130 Input(d.removedApiFile)
1131
1132 msg := `\n******************************\n` +
1133 `You have tried to change the API from what has been previously released in\n` +
1134 `an SDK. Please fix the errors listed above.\n` +
1135 `******************************\n`
1136
1137 rule.Command().
1138 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1139 Text(") || (").
1140 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1141 Text("; exit 38").
1142 Text(")")
1143
1144 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001145 }
1146}
1147
1148//
1149// Droidstubs
1150//
1151type Droidstubs struct {
1152 Javadoc
1153
Pete Gillin581d6082018-10-22 15:55:04 +01001154 properties DroidstubsProperties
1155 apiFile android.WritablePath
1156 apiXmlFile android.WritablePath
1157 lastReleasedApiXmlFile android.WritablePath
1158 dexApiFile android.WritablePath
1159 privateApiFile android.WritablePath
1160 privateDexApiFile android.WritablePath
1161 removedApiFile android.WritablePath
1162 removedDexApiFile android.WritablePath
1163 apiMappingFile android.WritablePath
1164 exactApiFile android.WritablePath
1165 proguardFile android.WritablePath
1166 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001167
1168 checkCurrentApiTimestamp android.WritablePath
1169 updateCurrentApiTimestamp android.WritablePath
1170 checkLastReleasedApiTimestamp android.WritablePath
1171
Pete Gillin581d6082018-10-22 15:55:04 +01001172 checkNullabilityWarningsTimestamp android.WritablePath
1173
Nan Zhang1598a9e2018-09-04 17:14:32 -07001174 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001175 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001176
1177 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001178
1179 jdiffDocZip android.WritablePath
1180 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001181}
1182
Colin Crossa3002fc2019-07-08 16:48:04 -07001183// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1184// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1185// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001186func DroidstubsFactory() android.Module {
1187 module := &Droidstubs{}
1188
1189 module.AddProperties(&module.properties,
1190 &module.Javadoc.properties)
1191
1192 InitDroiddocModule(module, android.HostAndDeviceSupported)
1193 return module
1194}
1195
Colin Crossa3002fc2019-07-08 16:48:04 -07001196// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1197// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1198// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1199// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001200func DroidstubsHostFactory() android.Module {
1201 module := &Droidstubs{}
1202
1203 module.AddProperties(&module.properties,
1204 &module.Javadoc.properties)
1205
1206 InitDroiddocModule(module, android.HostSupported)
1207 return module
1208}
1209
1210func (d *Droidstubs) ApiFilePath() android.Path {
1211 return d.apiFilePath
1212}
1213
1214func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1215 d.Javadoc.addDeps(ctx)
1216
Inseob Kim38449af2019-02-28 14:24:05 +09001217 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1218 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1219 }
1220
Nan Zhang1598a9e2018-09-04 17:14:32 -07001221 if len(d.properties.Merge_annotations_dirs) != 0 {
1222 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1223 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1224 }
1225 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001226
Pete Gillin77167902018-09-19 18:16:26 +01001227 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1228 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1229 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1230 }
1231 }
1232
Nan Zhang9c69a122018-08-22 10:22:08 -07001233 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1234 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1235 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1236 }
1237 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001238}
1239
Colin Cross33961b52019-07-11 11:01:22 -07001240func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001241 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1242 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1243 String(d.properties.Api_filename) != "" {
1244 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001245 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001246 d.apiFilePath = d.apiFile
1247 }
1248
1249 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1250 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1251 String(d.properties.Removed_api_filename) != "" {
1252 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001253 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254 }
1255
1256 if String(d.properties.Private_api_filename) != "" {
1257 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001258 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 }
1260
1261 if String(d.properties.Dex_api_filename) != "" {
1262 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001263 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264 }
1265
1266 if String(d.properties.Private_dex_api_filename) != "" {
1267 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001268 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001269 }
1270
1271 if String(d.properties.Removed_dex_api_filename) != "" {
1272 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001273 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001274 }
1275
1276 if String(d.properties.Exact_api_filename) != "" {
1277 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001278 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001279 }
1280
Nan Zhang9c69a122018-08-22 10:22:08 -07001281 if String(d.properties.Dex_mapping_filename) != "" {
1282 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001283 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001284 }
1285
Nan Zhang199645c2018-09-19 12:40:06 -07001286 if String(d.properties.Proguard_filename) != "" {
1287 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001288 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001289 }
1290
Nan Zhang9c69a122018-08-22 10:22:08 -07001291 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001292 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001293 }
1294
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001296 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001297 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001298 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001299 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001300}
1301
Colin Cross33961b52019-07-11 11:01:22 -07001302func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001303 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001304 cmd.Flag("--include-annotations")
1305
Pete Gillinc382a562018-11-14 18:45:46 +00001306 validatingNullability :=
1307 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1308 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001309 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001310
Pete Gillina262c052018-09-14 14:25:48 +01001311 if !(migratingNullability || validatingNullability) {
1312 ctx.PropertyErrorf("previous_api",
1313 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001314 }
Colin Cross33961b52019-07-11 11:01:22 -07001315
Pete Gillina262c052018-09-14 14:25:48 +01001316 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001317 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001318 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001319 }
Colin Cross33961b52019-07-11 11:01:22 -07001320
Pete Gillinc382a562018-11-14 18:45:46 +00001321 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001322 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001323 }
Colin Cross33961b52019-07-11 11:01:22 -07001324
Pete Gillina262c052018-09-14 14:25:48 +01001325 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001326 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001328 }
Nan Zhanga40da042018-08-01 12:48:00 -07001329
1330 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001331 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001332
Nan Zhang1598a9e2018-09-04 17:14:32 -07001333 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001334 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001335 "has to be non-empty if annotations was enabled!")
1336 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001337
Colin Cross33961b52019-07-11 11:01:22 -07001338 d.mergeAnnoDirFlags(ctx, cmd)
1339
1340 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1341 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1342 FlagWithArg("--hide ", "SuperfluousPrefix").
1343 FlagWithArg("--hide ", "AnnotationExtraction")
1344 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001345}
1346
Colin Cross33961b52019-07-11 11:01:22 -07001347func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1348 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1349 if t, ok := m.(*ExportedDroiddocDir); ok {
1350 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1351 } else {
1352 ctx.PropertyErrorf("merge_annotations_dirs",
1353 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1354 }
1355 })
1356}
1357
1358func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001359 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1360 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001361 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001362 } else {
1363 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1364 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1365 }
1366 })
Nan Zhanga40da042018-08-01 12:48:00 -07001367}
1368
Colin Cross33961b52019-07-11 11:01:22 -07001369func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001370 if Bool(d.properties.Api_levels_annotations_enabled) {
1371 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001372
1373 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1374 ctx.PropertyErrorf("api_levels_annotations_dirs",
1375 "has to be non-empty if api levels annotations was enabled!")
1376 }
1377
Colin Cross33961b52019-07-11 11:01:22 -07001378 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1379 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1380 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1381 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001382
1383 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1384 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001385 for _, dep := range t.deps {
1386 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001387 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001388 }
1389 }
Colin Cross33961b52019-07-11 11:01:22 -07001390 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001391 } else {
1392 ctx.PropertyErrorf("api_levels_annotations_dirs",
1393 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1394 }
1395 })
1396
1397 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001398}
1399
Colin Cross33961b52019-07-11 11:01:22 -07001400func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001401 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1402 if d.apiFile.String() == "" {
1403 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1404 }
1405
1406 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001407 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001408
1409 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1410 ctx.PropertyErrorf("check_api.last_released.api_file",
1411 "has to be non-empty if jdiff was enabled!")
1412 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001413
Colin Cross33961b52019-07-11 11:01:22 -07001414 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001415 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001416 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1417 }
1418}
Nan Zhang71bbe632018-09-17 14:32:21 -07001419
Colin Cross33961b52019-07-11 11:01:22 -07001420func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1421 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1422 cmd := rule.Command().BuiltTool(ctx, "metalava").
1423 Flag(config.JavacVmFlags).
1424 FlagWithArg("-encoding ", "UTF-8").
1425 FlagWithArg("-source ", javaVersion).
1426 FlagWithRspFileInputList("@", srcs).
1427 FlagWithInput("@", srcJarList)
1428
1429 if len(bootclasspath) > 0 {
1430 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001431 }
1432
Colin Cross33961b52019-07-11 11:01:22 -07001433 if len(classpath) > 0 {
1434 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1435 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001436
Colin Cross33961b52019-07-11 11:01:22 -07001437 if len(sourcepaths) > 0 {
1438 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1439 } else {
1440 cmd.FlagWithArg("-sourcepath ", `""`)
1441 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001442
Colin Cross33961b52019-07-11 11:01:22 -07001443 cmd.Flag("--no-banner").
1444 Flag("--color").
1445 Flag("--quiet").
1446 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001447
Colin Cross33961b52019-07-11 11:01:22 -07001448 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001449}
1450
Nan Zhang1598a9e2018-09-04 17:14:32 -07001451func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001452 deps := d.Javadoc.collectDeps(ctx)
1453
1454 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001455
Colin Cross33961b52019-07-11 11:01:22 -07001456 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001457
Colin Crossdaa4c672019-07-15 22:53:46 -07001458 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1461 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001462
Colin Cross33961b52019-07-11 11:01:22 -07001463 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001464
Colin Cross33961b52019-07-11 11:01:22 -07001465 rule.Command().Text("rm -rf").Text(stubsDir.String())
1466 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001467
Colin Cross33961b52019-07-11 11:01:22 -07001468 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1469
1470 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1471 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1472
1473 d.stubsFlags(ctx, cmd, stubsDir)
1474
1475 d.annotationsFlags(ctx, cmd)
1476 d.inclusionAnnotationsFlags(ctx, cmd)
1477 d.apiLevelsAnnotationsFlags(ctx, cmd)
1478 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001479
Nan Zhang1598a9e2018-09-04 17:14:32 -07001480 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1481 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1482 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1483 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1484 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001485 }
Colin Cross33961b52019-07-11 11:01:22 -07001486
1487 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1488 for _, o := range d.Javadoc.properties.Out {
1489 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1490 }
1491
1492 rule.Command().
1493 BuiltTool(ctx, "soong_zip").
1494 Flag("-write_if_changed").
1495 Flag("-jar").
1496 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1497 FlagWithArg("-C ", stubsDir.String()).
1498 FlagWithArg("-D ", stubsDir.String())
1499 rule.Restat()
1500
1501 zipSyncCleanupCmd(rule, srcJarDir)
1502
1503 rule.Build(pctx, ctx, "metalava", "metalava")
1504
1505 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001506
Nan Zhang1598a9e2018-09-04 17:14:32 -07001507 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1508 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001509
1510 if len(d.Javadoc.properties.Out) > 0 {
1511 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1512 }
1513
1514 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1515 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001516 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1517 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001518
Nan Zhang2760dfc2018-08-24 17:32:54 +00001519 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001520
Colin Cross33961b52019-07-11 11:01:22 -07001521 rule := android.NewRuleBuilder()
1522
1523 rule.Command().Text("( true")
1524
1525 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1526 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1527
1528 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1529 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1530
1531 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1532 FlagWithInput("--check-compatibility:api:current ", apiFile).
1533 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1534
1535 d.inclusionAnnotationsFlags(ctx, cmd)
1536 d.mergeAnnoDirFlags(ctx, cmd)
1537
Adrian Roos14f75a92019-08-12 17:54:09 +02001538 if baselineFile.Valid() {
1539 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1540 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1541 }
1542
Colin Cross33961b52019-07-11 11:01:22 -07001543 zipSyncCleanupCmd(rule, srcJarDir)
1544
1545 msg := fmt.Sprintf(`\n******************************\n`+
1546 `You have tried to change the API from what has been previously approved.\n\n`+
1547 `To make these errors go away, you have two choices:\n`+
1548 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1549 ` errors above.\n\n`+
1550 ` 2. You can update current.txt by executing the following command:\n`+
1551 ` make %s-update-current-api\n\n`+
1552 ` To submit the revised current.txt to the main Android repository,\n`+
1553 ` you will need approval.\n`+
1554 `******************************\n`, ctx.ModuleName())
1555
1556 rule.Command().
1557 Text("touch").Output(d.checkCurrentApiTimestamp).
1558 Text(") || (").
1559 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1560 Text("; exit 38").
1561 Text(")")
1562
1563 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001564
1565 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001566
1567 // update API rule
1568 rule = android.NewRuleBuilder()
1569
1570 rule.Command().Text("( true")
1571
1572 rule.Command().
1573 Text("cp").Flag("-f").
1574 Input(d.apiFile).Flag(apiFile.String())
1575
1576 rule.Command().
1577 Text("cp").Flag("-f").
1578 Input(d.removedApiFile).Flag(removedApiFile.String())
1579
1580 msg = "failed to update public API"
1581
1582 rule.Command().
1583 Text("touch").Output(d.updateCurrentApiTimestamp).
1584 Text(") || (").
1585 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1586 Text("; exit 38").
1587 Text(")")
1588
1589 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001590 }
Nan Zhanga40da042018-08-01 12:48:00 -07001591
Nan Zhang1598a9e2018-09-04 17:14:32 -07001592 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1593 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001594
1595 if len(d.Javadoc.properties.Out) > 0 {
1596 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1597 }
1598
1599 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1600 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001601 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1602 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001603
Nan Zhang2760dfc2018-08-24 17:32:54 +00001604 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001605
Colin Cross33961b52019-07-11 11:01:22 -07001606 rule := android.NewRuleBuilder()
1607
1608 rule.Command().Text("( true")
1609
1610 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1611 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1612
1613 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1614 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1615
1616 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1617 FlagWithInput("--check-compatibility:api:released ", apiFile)
1618
1619 d.inclusionAnnotationsFlags(ctx, cmd)
1620
1621 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1622
1623 d.mergeAnnoDirFlags(ctx, cmd)
1624
Adrian Roos14f75a92019-08-12 17:54:09 +02001625 if baselineFile.Valid() {
1626 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1627 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1628 }
1629
Colin Cross33961b52019-07-11 11:01:22 -07001630 zipSyncCleanupCmd(rule, srcJarDir)
1631
1632 msg := `\n******************************\n` +
1633 `You have tried to change the API from what has been previously released in\n` +
1634 `an SDK. Please fix the errors listed above.\n` +
1635 `******************************\n`
1636 rule.Command().
1637 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1638 Text(") || (").
1639 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1640 Text("; exit 38").
1641 Text(")")
1642
1643 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001644 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001645
Pete Gillin581d6082018-10-22 15:55:04 +01001646 if String(d.properties.Check_nullability_warnings) != "" {
1647 if d.nullabilityWarningsFile == nil {
1648 ctx.PropertyErrorf("check_nullability_warnings",
1649 "Cannot specify check_nullability_warnings unless validating nullability")
1650 }
Colin Cross33961b52019-07-11 11:01:22 -07001651
1652 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1653
Pete Gillin581d6082018-10-22 15:55:04 +01001654 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001655
Pete Gillin581d6082018-10-22 15:55:04 +01001656 msg := fmt.Sprintf(`\n******************************\n`+
1657 `The warnings encountered during nullability annotation validation did\n`+
1658 `not match the checked in file of expected warnings. The diffs are shown\n`+
1659 `above. You have two options:\n`+
1660 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1661 ` 2. Update the file of expected warnings by running:\n`+
1662 ` cp %s %s\n`+
1663 ` and submitting the updated file as part of your change.`,
1664 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001665
1666 rule := android.NewRuleBuilder()
1667
1668 rule.Command().
1669 Text("(").
1670 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1671 Text("&&").
1672 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1673 Text(") || (").
1674 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1675 Text("; exit 38").
1676 Text(")")
1677
1678 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001679 }
1680
Nan Zhang71bbe632018-09-17 14:32:21 -07001681 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001682 if len(d.Javadoc.properties.Out) > 0 {
1683 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1684 }
1685
1686 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1687 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1688 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1689
1690 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001691
Nan Zhang86b06202018-09-21 17:09:21 -07001692 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1693 // since there's cron job downstream that fetch this .zip file periodically.
1694 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001695 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1696 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1697
Nan Zhang71bbe632018-09-17 14:32:21 -07001698 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001699
Colin Cross33961b52019-07-11 11:01:22 -07001700 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1701 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001702
Colin Cross33961b52019-07-11 11:01:22 -07001703 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1704
Colin Crossdaa4c672019-07-15 22:53:46 -07001705 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001706 deps.bootClasspath, deps.classpath, d.sourcepaths)
1707
1708 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001709 Flag("-XDignore.symbol.file").
1710 FlagWithArg("-doclet ", "jdiff.JDiff").
1711 FlagWithInput("-docletpath ", jdiff).
1712 Flag("-quiet").
1713 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1714 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1715 Implicit(d.apiXmlFile).
1716 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1717 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1718 Implicit(d.lastReleasedApiXmlFile)
1719
Colin Cross33961b52019-07-11 11:01:22 -07001720 rule.Command().
1721 BuiltTool(ctx, "soong_zip").
1722 Flag("-write_if_changed").
1723 Flag("-d").
1724 FlagWithOutput("-o ", d.jdiffDocZip).
1725 FlagWithArg("-C ", outDir.String()).
1726 FlagWithArg("-D ", outDir.String())
1727
1728 rule.Command().
1729 BuiltTool(ctx, "soong_zip").
1730 Flag("-write_if_changed").
1731 Flag("-jar").
1732 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1733 FlagWithArg("-C ", stubsDir.String()).
1734 FlagWithArg("-D ", stubsDir.String())
1735
1736 rule.Restat()
1737
1738 zipSyncCleanupCmd(rule, srcJarDir)
1739
1740 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001741 }
Nan Zhang581fd212018-01-10 16:06:12 -08001742}
Dan Willemsencc090972018-02-26 14:33:31 -08001743
Nan Zhanga40da042018-08-01 12:48:00 -07001744//
Nan Zhangf4936b02018-08-01 15:00:28 -07001745// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001746//
Dan Willemsencc090972018-02-26 14:33:31 -08001747var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001748var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001749var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001750var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001751
Nan Zhangf4936b02018-08-01 15:00:28 -07001752type ExportedDroiddocDirProperties struct {
1753 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001754 Path *string
1755}
1756
Nan Zhangf4936b02018-08-01 15:00:28 -07001757type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001758 android.ModuleBase
1759
Nan Zhangf4936b02018-08-01 15:00:28 -07001760 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001761
1762 deps android.Paths
1763 dir android.Path
1764}
1765
Colin Crossa3002fc2019-07-08 16:48:04 -07001766// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001767func ExportedDroiddocDirFactory() android.Module {
1768 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001769 module.AddProperties(&module.properties)
1770 android.InitAndroidModule(module)
1771 return module
1772}
1773
Nan Zhangf4936b02018-08-01 15:00:28 -07001774func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001775
Nan Zhangf4936b02018-08-01 15:00:28 -07001776func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001777 path := String(d.properties.Path)
1778 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001779 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001780}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001781
1782//
1783// Defaults
1784//
1785type DocDefaults struct {
1786 android.ModuleBase
1787 android.DefaultsModuleBase
1788}
1789
Nan Zhangb2b33de2018-02-23 11:18:47 -08001790func DocDefaultsFactory() android.Module {
1791 module := &DocDefaults{}
1792
1793 module.AddProperties(
1794 &JavadocProperties{},
1795 &DroiddocProperties{},
1796 )
1797
1798 android.InitDefaultsModule(module)
1799
1800 return module
1801}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001802
1803func StubsDefaultsFactory() android.Module {
1804 module := &DocDefaults{}
1805
1806 module.AddProperties(
1807 &JavadocProperties{},
1808 &DroidstubsProperties{},
1809 )
1810
1811 android.InitDefaultsModule(module)
1812
1813 return module
1814}
Colin Cross33961b52019-07-11 11:01:22 -07001815
1816func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1817 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1818
1819 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1820 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1821 srcJarList := srcJarDir.Join(ctx, "list")
1822
1823 rule.Temporary(srcJarList)
1824
1825 rule.Command().BuiltTool(ctx, "zipsync").
1826 FlagWithArg("-d ", srcJarDir.String()).
1827 FlagWithOutput("-l ", srcJarList).
1828 FlagWithArg("-f ", `"*.java"`).
1829 Inputs(srcJars)
1830
1831 return srcJarList
1832}
1833
1834func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1835 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1836}