blob: 9956270c9c41871366051b3b976a304be5fb0403 [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
477func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700478 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900479
480 outSrcFiles := make(android.Paths, 0, len(srcFiles))
481
482 for _, srcFile := range srcFiles {
483 switch srcFile.Ext() {
484 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700485 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900486 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900487 case ".sysprop":
488 javaFile := genSysprop(ctx, srcFile)
489 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900490 default:
491 outSrcFiles = append(outSrcFiles, srcFile)
492 }
493 }
494
495 return outSrcFiles
496}
497
Nan Zhang581fd212018-01-10 16:06:12 -0800498func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
499 var deps deps
500
Colin Cross83bb3162018-06-25 15:48:06 -0700501 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800502 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700503 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800504 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700505 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800506 }
507
508 ctx.VisitDirectDeps(func(module android.Module) {
509 otherName := ctx.OtherModuleName(module)
510 tag := ctx.OtherModuleDependencyTag(module)
511
Colin Cross2d24c1b2018-05-23 10:59:18 -0700512 switch tag {
513 case bootClasspathTag:
514 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800515 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700516 } else {
517 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
518 }
519 case libTag:
520 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800521 case SdkLibraryDependency:
522 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700523 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900524 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900525 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700526 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800527 checkProducesJars(ctx, dep)
528 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800529 default:
530 ctx.ModuleErrorf("depends on non-java module %q", otherName)
531 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700532 case srcsLibTag:
533 switch dep := module.(type) {
534 case Dependency:
535 srcs := dep.(SrcDependency).CompiledSrcs()
536 whitelistPathPrefixes := make(map[string]bool)
537 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
538 for _, src := range srcs {
539 if _, ok := src.(android.WritablePath); ok { // generated sources
540 deps.srcs = append(deps.srcs, src)
541 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700542 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700543 if strings.HasPrefix(src.Rel(), k) {
544 deps.srcs = append(deps.srcs, src)
545 break
546 }
547 }
548 }
549 }
550 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
551 default:
552 ctx.ModuleErrorf("depends on non-java module %q", otherName)
553 }
Nan Zhang357466b2018-04-17 17:38:36 -0700554 case systemModulesTag:
555 if deps.systemModules != nil {
556 panic("Found two system module dependencies")
557 }
558 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000559 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700560 panic("Missing directory for system module dependency")
561 }
Colin Crossb77043e2019-07-16 13:57:13 -0700562 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800563 }
564 })
565 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
566 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800567 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700568 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900569 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800570
571 // srcs may depend on some genrule output.
572 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800573 j.srcJars = append(j.srcJars, deps.srcJars...)
574
Nan Zhang581fd212018-01-10 16:06:12 -0800575 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800576 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800577
Nan Zhang9c69a122018-08-22 10:22:08 -0700578 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800579 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
580 }
581 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800582
Colin Cross8a497952019-03-05 22:25:09 -0800583 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000584 argFilesMap := map[string]string{}
585 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700586
Paul Duffin99e4a502019-02-11 15:38:42 +0000587 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800588 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000589 if _, exists := argFilesMap[label]; !exists {
590 argFilesMap[label] = strings.Join(paths.Strings(), " ")
591 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700592 } else {
593 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000594 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700595 }
596 }
597
598 var err error
Colin Cross15638152019-07-11 11:11:35 -0700599 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700600 if strings.HasPrefix(name, "location ") {
601 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000602 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700603 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700604 } else {
Colin Cross15638152019-07-11 11:11:35 -0700605 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000606 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700607 }
608 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700609 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700610 }
Colin Cross15638152019-07-11 11:11:35 -0700611 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700612 })
613
614 if err != nil {
615 ctx.PropertyErrorf("args", "%s", err.Error())
616 }
617
Nan Zhang581fd212018-01-10 16:06:12 -0800618 return deps
619}
620
621func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
622 j.addDeps(ctx)
623}
624
625func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
626 deps := j.collectDeps(ctx)
627
Colin Crossdaa4c672019-07-15 22:53:46 -0700628 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800629
Colin Crossdaa4c672019-07-15 22:53:46 -0700630 outDir := android.PathForModuleOut(ctx, "out")
631 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
632
633 j.stubsSrcJar = nil
634
635 rule := android.NewRuleBuilder()
636
637 rule.Command().Text("rm -rf").Text(outDir.String())
638 rule.Command().Text("mkdir -p").Text(outDir.String())
639
640 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700641
Colin Cross83bb3162018-06-25 15:48:06 -0700642 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800643
Colin Crossdaa4c672019-07-15 22:53:46 -0700644 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
645 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800646
Colin Crossdaa4c672019-07-15 22:53:46 -0700647 cmd.FlagWithArg("-source ", javaVersion).
648 Flag("-J-Xmx1024m").
649 Flag("-XDignore.symbol.file").
650 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800651
Colin Crossdaa4c672019-07-15 22:53:46 -0700652 rule.Command().
653 BuiltTool(ctx, "soong_zip").
654 Flag("-write_if_changed").
655 Flag("-d").
656 FlagWithOutput("-o ", j.docZip).
657 FlagWithArg("-C ", outDir.String()).
658 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700659
Colin Crossdaa4c672019-07-15 22:53:46 -0700660 rule.Restat()
661
662 zipSyncCleanupCmd(rule, srcJarDir)
663
664 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800665}
666
Nan Zhanga40da042018-08-01 12:48:00 -0700667//
668// Droiddoc
669//
670type Droiddoc struct {
671 Javadoc
672
673 properties DroiddocProperties
674 apiFile android.WritablePath
675 dexApiFile android.WritablePath
676 privateApiFile android.WritablePath
677 privateDexApiFile android.WritablePath
678 removedApiFile android.WritablePath
679 removedDexApiFile android.WritablePath
680 exactApiFile android.WritablePath
681 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700682 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700683
684 checkCurrentApiTimestamp android.WritablePath
685 updateCurrentApiTimestamp android.WritablePath
686 checkLastReleasedApiTimestamp android.WritablePath
687
Nan Zhanga40da042018-08-01 12:48:00 -0700688 apiFilePath android.Path
689}
690
Colin Crossa3002fc2019-07-08 16:48:04 -0700691// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700692func DroiddocFactory() android.Module {
693 module := &Droiddoc{}
694
695 module.AddProperties(&module.properties,
696 &module.Javadoc.properties)
697
698 InitDroiddocModule(module, android.HostAndDeviceSupported)
699 return module
700}
701
Colin Crossa3002fc2019-07-08 16:48:04 -0700702// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700703func DroiddocHostFactory() android.Module {
704 module := &Droiddoc{}
705
706 module.AddProperties(&module.properties,
707 &module.Javadoc.properties)
708
709 InitDroiddocModule(module, android.HostSupported)
710 return module
711}
712
713func (d *Droiddoc) ApiFilePath() android.Path {
714 return d.apiFilePath
715}
716
Nan Zhang581fd212018-01-10 16:06:12 -0800717func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
718 d.Javadoc.addDeps(ctx)
719
Inseob Kim38449af2019-02-28 14:24:05 +0900720 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
721 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
722 }
723
Nan Zhang79614d12018-04-19 18:03:39 -0700724 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800725 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
726 }
Nan Zhang581fd212018-01-10 16:06:12 -0800727}
728
Colin Crossab054432019-07-15 16:13:59 -0700729func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700730 var date string
731 if runtime.GOOS == "darwin" {
732 date = `date -r`
733 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700734 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700735 }
736
Nan Zhang443fa522018-08-20 20:58:28 -0700737 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
738 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
739 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700740 cmd.FlagWithArg("-source ", "1.8").
741 Flag("-J-Xmx1600m").
742 Flag("-J-XX:-OmitStackTraceInFastThrow").
743 Flag("-XDignore.symbol.file").
744 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
745 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
746 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700747 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700748
Nan Zhanga40da042018-08-01 12:48:00 -0700749 if String(d.properties.Custom_template) == "" {
750 // TODO: This is almost always droiddoc-templates-sdk
751 ctx.PropertyErrorf("custom_template", "must specify a template")
752 }
753
754 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700755 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700756 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700757 } else {
758 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
759 }
760 })
761
762 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700763 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
764 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
765 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700766 }
767
768 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700769 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
770 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
771 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700772 }
773
774 if len(d.properties.Html_dirs) > 2 {
775 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
776 }
777
Colin Cross8a497952019-03-05 22:25:09 -0800778 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700779 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700780
Colin Crossab054432019-07-15 16:13:59 -0700781 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700782
783 if String(d.properties.Proofread_file) != "" {
784 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700785 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700786 }
787
788 if String(d.properties.Todo_file) != "" {
789 // tricky part:
790 // we should not compute full path for todo_file through PathForModuleOut().
791 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700792 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
793 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700794 }
795
796 if String(d.properties.Resourcesdir) != "" {
797 // TODO: should we add files under resourcesDir to the implicits? It seems that
798 // resourcesDir is one sub dir of htmlDir
799 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700800 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700801 }
802
803 if String(d.properties.Resourcesoutdir) != "" {
804 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700805 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700806 }
Nan Zhanga40da042018-08-01 12:48:00 -0700807}
808
Colin Crossab054432019-07-15 16:13:59 -0700809func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700810 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
811 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
812 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700813
Nan Zhanga40da042018-08-01 12:48:00 -0700814 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700815 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700816 d.apiFilePath = d.apiFile
817 }
818
Nan Zhang1598a9e2018-09-04 17:14:32 -0700819 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
820 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
821 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700822 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 }
825
826 if String(d.properties.Private_api_filename) != "" {
827 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700828 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700829 }
830
831 if String(d.properties.Dex_api_filename) != "" {
832 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700834 }
835
836 if String(d.properties.Private_dex_api_filename) != "" {
837 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700838 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
841 if String(d.properties.Removed_dex_api_filename) != "" {
842 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700843 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700844 }
845
846 if String(d.properties.Exact_api_filename) != "" {
847 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700848 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700849 }
850
851 if String(d.properties.Dex_mapping_filename) != "" {
852 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700853 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700854 }
855
Nan Zhang66dc2362018-08-14 20:41:04 -0700856 if String(d.properties.Proguard_filename) != "" {
857 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700858 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700859 }
860
Nan Zhanga40da042018-08-01 12:48:00 -0700861 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700862 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700863 }
864
865 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700866 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700867 }
Nan Zhanga40da042018-08-01 12:48:00 -0700868}
869
Colin Crossab054432019-07-15 16:13:59 -0700870func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700871 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700872 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
873 rule.Command().Text("cp").
874 Input(staticDocIndexRedirect).
875 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700876 }
877
878 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700879 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
880 rule.Command().Text("cp").
881 Input(staticDocProperties).
882 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700883 }
Nan Zhanga40da042018-08-01 12:48:00 -0700884}
885
Colin Crossab054432019-07-15 16:13:59 -0700886func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700887 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700888
889 cmd := rule.Command().
890 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
891 Flag(config.JavacVmFlags).
892 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700893 FlagWithRspFileInputList("@", srcs).
894 FlagWithInput("@", srcJarList)
895
Colin Crossab054432019-07-15 16:13:59 -0700896 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
897 // based stubs generation.
898 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
899 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
900 // the correct package name base path.
901 if len(sourcepaths) > 0 {
902 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
903 } else {
904 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
905 }
906
907 cmd.FlagWithArg("-d ", outDir.String()).
908 Flag("-quiet")
909
910 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700911}
912
Colin Crossdaa4c672019-07-15 22:53:46 -0700913func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
914 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
915 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
916
917 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
918
919 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
920 cmd.Flag(flag).Implicits(deps)
921
922 cmd.FlagWithArg("--patch-module ", "java.base=.")
923
924 if len(classpath) > 0 {
925 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
926 }
927
928 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700929}
930
Colin Crossdaa4c672019-07-15 22:53:46 -0700931func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
932 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
933 sourcepaths android.Paths) *android.RuleBuilderCommand {
934
935 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
936
937 if len(bootclasspath) == 0 && ctx.Device() {
938 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
939 // ensure java does not fall back to the default bootclasspath.
940 cmd.FlagWithArg("-bootclasspath ", `""`)
941 } else if len(bootclasspath) > 0 {
942 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
943 }
944
945 if len(classpath) > 0 {
946 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
947 }
948
949 return cmd
950}
951
Colin Crossab054432019-07-15 16:13:59 -0700952func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
953 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700954
Colin Crossab054432019-07-15 16:13:59 -0700955 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
956 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
957
958 return rule.Command().
959 BuiltTool(ctx, "dokka").
960 Flag(config.JavacVmFlags).
961 Flag(srcJarDir.String()).
962 FlagWithInputList("-classpath ", dokkaClasspath, ":").
963 FlagWithArg("-format ", "dac").
964 FlagWithArg("-dacRoot ", "/reference/kotlin").
965 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700966}
967
968func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
969 deps := d.Javadoc.collectDeps(ctx)
970
Colin Crossdaa4c672019-07-15 22:53:46 -0700971 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
972 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
973
Nan Zhang1598a9e2018-09-04 17:14:32 -0700974 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
975 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
976 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
977 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
978
Colin Crossab054432019-07-15 16:13:59 -0700979 outDir := android.PathForModuleOut(ctx, "out")
980 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
981 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700982
Colin Crossab054432019-07-15 16:13:59 -0700983 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700984
Colin Crossab054432019-07-15 16:13:59 -0700985 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
986 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700987
Colin Crossab054432019-07-15 16:13:59 -0700988 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
989
990 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700992 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700993 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700994 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700995 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700996 }
997
Colin Crossab054432019-07-15 16:13:59 -0700998 d.stubsFlags(ctx, cmd, stubsDir)
999
1000 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1001
1002 var desc string
1003 if Bool(d.properties.Dokka_enabled) {
1004 desc = "dokka"
1005 } else {
1006 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1007
1008 for _, o := range d.Javadoc.properties.Out {
1009 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1010 }
1011
1012 d.postDoclavaCmds(ctx, rule)
1013 desc = "doclava"
1014 }
1015
1016 rule.Command().
1017 BuiltTool(ctx, "soong_zip").
1018 Flag("-write_if_changed").
1019 Flag("-d").
1020 FlagWithOutput("-o ", d.docZip).
1021 FlagWithArg("-C ", outDir.String()).
1022 FlagWithArg("-D ", outDir.String())
1023
1024 rule.Command().
1025 BuiltTool(ctx, "soong_zip").
1026 Flag("-write_if_changed").
1027 Flag("-jar").
1028 FlagWithOutput("-o ", d.stubsSrcJar).
1029 FlagWithArg("-C ", stubsDir.String()).
1030 FlagWithArg("-D ", stubsDir.String())
1031
1032 rule.Restat()
1033
1034 zipSyncCleanupCmd(rule, srcJarDir)
1035
1036 rule.Build(pctx, ctx, "javadoc", desc)
1037
Nan Zhang1598a9e2018-09-04 17:14:32 -07001038 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1039 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001040
1041 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1042 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001043
1044 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001045
1046 rule := android.NewRuleBuilder()
1047
1048 rule.Command().Text("( true")
1049
1050 rule.Command().
1051 BuiltTool(ctx, "apicheck").
1052 Flag("-JXmx1024m").
1053 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1054 OptionalFlag(d.properties.Check_api.Current.Args).
1055 Input(apiFile).
1056 Input(d.apiFile).
1057 Input(removedApiFile).
1058 Input(d.removedApiFile)
1059
1060 msg := fmt.Sprintf(`\n******************************\n`+
1061 `You have tried to change the API from what has been previously approved.\n\n`+
1062 `To make these errors go away, you have two choices:\n`+
1063 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1064 ` errors above.\n\n`+
1065 ` 2. You can update current.txt by executing the following command:\n`+
1066 ` make %s-update-current-api\n\n`+
1067 ` To submit the revised current.txt to the main Android repository,\n`+
1068 ` you will need approval.\n`+
1069 `******************************\n`, ctx.ModuleName())
1070
1071 rule.Command().
1072 Text("touch").Output(d.checkCurrentApiTimestamp).
1073 Text(") || (").
1074 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1075 Text("; exit 38").
1076 Text(")")
1077
1078 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001079
1080 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001081
1082 // update API rule
1083 rule = android.NewRuleBuilder()
1084
1085 rule.Command().Text("( true")
1086
1087 rule.Command().
1088 Text("cp").Flag("-f").
1089 Input(d.apiFile).Flag(apiFile.String())
1090
1091 rule.Command().
1092 Text("cp").Flag("-f").
1093 Input(d.removedApiFile).Flag(removedApiFile.String())
1094
1095 msg = "failed to update public API"
1096
1097 rule.Command().
1098 Text("touch").Output(d.updateCurrentApiTimestamp).
1099 Text(") || (").
1100 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1101 Text("; exit 38").
1102 Text(")")
1103
1104 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001105 }
1106
1107 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1108 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001109
1110 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1111 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001112
1113 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001114
1115 rule := android.NewRuleBuilder()
1116
1117 rule.Command().
1118 Text("(").
1119 BuiltTool(ctx, "apicheck").
1120 Flag("-JXmx1024m").
1121 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1122 OptionalFlag(d.properties.Check_api.Last_released.Args).
1123 Input(apiFile).
1124 Input(d.apiFile).
1125 Input(removedApiFile).
1126 Input(d.removedApiFile)
1127
1128 msg := `\n******************************\n` +
1129 `You have tried to change the API from what has been previously released in\n` +
1130 `an SDK. Please fix the errors listed above.\n` +
1131 `******************************\n`
1132
1133 rule.Command().
1134 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1135 Text(") || (").
1136 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1137 Text("; exit 38").
1138 Text(")")
1139
1140 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001141 }
1142}
1143
1144//
1145// Droidstubs
1146//
1147type Droidstubs struct {
1148 Javadoc
1149
Pete Gillin581d6082018-10-22 15:55:04 +01001150 properties DroidstubsProperties
1151 apiFile android.WritablePath
1152 apiXmlFile android.WritablePath
1153 lastReleasedApiXmlFile android.WritablePath
1154 dexApiFile android.WritablePath
1155 privateApiFile android.WritablePath
1156 privateDexApiFile android.WritablePath
1157 removedApiFile android.WritablePath
1158 removedDexApiFile android.WritablePath
1159 apiMappingFile android.WritablePath
1160 exactApiFile android.WritablePath
1161 proguardFile android.WritablePath
1162 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001163
1164 checkCurrentApiTimestamp android.WritablePath
1165 updateCurrentApiTimestamp android.WritablePath
1166 checkLastReleasedApiTimestamp android.WritablePath
1167
Pete Gillin581d6082018-10-22 15:55:04 +01001168 checkNullabilityWarningsTimestamp android.WritablePath
1169
Nan Zhang1598a9e2018-09-04 17:14:32 -07001170 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001171 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001172
1173 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001174
1175 jdiffDocZip android.WritablePath
1176 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001177}
1178
Colin Crossa3002fc2019-07-08 16:48:04 -07001179// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1180// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1181// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001182func DroidstubsFactory() android.Module {
1183 module := &Droidstubs{}
1184
1185 module.AddProperties(&module.properties,
1186 &module.Javadoc.properties)
1187
1188 InitDroiddocModule(module, android.HostAndDeviceSupported)
1189 return module
1190}
1191
Colin Crossa3002fc2019-07-08 16:48:04 -07001192// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1193// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1194// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1195// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001196func DroidstubsHostFactory() android.Module {
1197 module := &Droidstubs{}
1198
1199 module.AddProperties(&module.properties,
1200 &module.Javadoc.properties)
1201
1202 InitDroiddocModule(module, android.HostSupported)
1203 return module
1204}
1205
1206func (d *Droidstubs) ApiFilePath() android.Path {
1207 return d.apiFilePath
1208}
1209
1210func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1211 d.Javadoc.addDeps(ctx)
1212
Inseob Kim38449af2019-02-28 14:24:05 +09001213 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1214 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1215 }
1216
Nan Zhang1598a9e2018-09-04 17:14:32 -07001217 if len(d.properties.Merge_annotations_dirs) != 0 {
1218 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1219 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1220 }
1221 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001222
Pete Gillin77167902018-09-19 18:16:26 +01001223 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1224 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1225 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1226 }
1227 }
1228
Nan Zhang9c69a122018-08-22 10:22:08 -07001229 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1230 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1231 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1232 }
1233 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001234}
1235
Colin Cross33961b52019-07-11 11:01:22 -07001236func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001237 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1238 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1239 String(d.properties.Api_filename) != "" {
1240 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001241 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001242 d.apiFilePath = d.apiFile
1243 }
1244
1245 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1246 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1247 String(d.properties.Removed_api_filename) != "" {
1248 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001249 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250 }
1251
1252 if String(d.properties.Private_api_filename) != "" {
1253 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001254 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255 }
1256
1257 if String(d.properties.Dex_api_filename) != "" {
1258 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001259 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260 }
1261
1262 if String(d.properties.Private_dex_api_filename) != "" {
1263 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001264 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265 }
1266
1267 if String(d.properties.Removed_dex_api_filename) != "" {
1268 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001269 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001270 }
1271
1272 if String(d.properties.Exact_api_filename) != "" {
1273 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001274 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001275 }
1276
Nan Zhang9c69a122018-08-22 10:22:08 -07001277 if String(d.properties.Dex_mapping_filename) != "" {
1278 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001279 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001280 }
1281
Nan Zhang199645c2018-09-19 12:40:06 -07001282 if String(d.properties.Proguard_filename) != "" {
1283 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001285 }
1286
Nan Zhang9c69a122018-08-22 10:22:08 -07001287 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001288 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001289 }
1290
Nan Zhang1598a9e2018-09-04 17:14:32 -07001291 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001292 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001293 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001294 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296}
1297
Colin Cross33961b52019-07-11 11:01:22 -07001298func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001299 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001300 cmd.Flag("--include-annotations")
1301
Pete Gillinc382a562018-11-14 18:45:46 +00001302 validatingNullability :=
1303 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1304 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001305 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001306
Pete Gillina262c052018-09-14 14:25:48 +01001307 if !(migratingNullability || validatingNullability) {
1308 ctx.PropertyErrorf("previous_api",
1309 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001310 }
Colin Cross33961b52019-07-11 11:01:22 -07001311
Pete Gillina262c052018-09-14 14:25:48 +01001312 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001313 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001314 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001315 }
Colin Cross33961b52019-07-11 11:01:22 -07001316
Pete Gillinc382a562018-11-14 18:45:46 +00001317 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001318 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001319 }
Colin Cross33961b52019-07-11 11:01:22 -07001320
Pete Gillina262c052018-09-14 14:25:48 +01001321 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001322 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001323 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001324 }
Nan Zhanga40da042018-08-01 12:48:00 -07001325
1326 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001328
Nan Zhang1598a9e2018-09-04 17:14:32 -07001329 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001330 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001331 "has to be non-empty if annotations was enabled!")
1332 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001333
Colin Cross33961b52019-07-11 11:01:22 -07001334 d.mergeAnnoDirFlags(ctx, cmd)
1335
1336 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1337 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1338 FlagWithArg("--hide ", "SuperfluousPrefix").
1339 FlagWithArg("--hide ", "AnnotationExtraction")
1340 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001341}
1342
Colin Cross33961b52019-07-11 11:01:22 -07001343func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1344 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1345 if t, ok := m.(*ExportedDroiddocDir); ok {
1346 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1347 } else {
1348 ctx.PropertyErrorf("merge_annotations_dirs",
1349 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1350 }
1351 })
1352}
1353
1354func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001355 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1356 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001357 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001358 } else {
1359 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1360 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1361 }
1362 })
Nan Zhanga40da042018-08-01 12:48:00 -07001363}
1364
Colin Cross33961b52019-07-11 11:01:22 -07001365func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001366 if Bool(d.properties.Api_levels_annotations_enabled) {
1367 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001368
1369 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1370 ctx.PropertyErrorf("api_levels_annotations_dirs",
1371 "has to be non-empty if api levels annotations was enabled!")
1372 }
1373
Colin Cross33961b52019-07-11 11:01:22 -07001374 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1375 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1376 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1377 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001378
1379 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1380 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001381 for _, dep := range t.deps {
1382 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001383 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001384 }
1385 }
Colin Cross33961b52019-07-11 11:01:22 -07001386 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001387 } else {
1388 ctx.PropertyErrorf("api_levels_annotations_dirs",
1389 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1390 }
1391 })
1392
1393 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001394}
1395
Colin Cross33961b52019-07-11 11:01:22 -07001396func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001397 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1398 if d.apiFile.String() == "" {
1399 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1400 }
1401
1402 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001403 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001404
1405 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1406 ctx.PropertyErrorf("check_api.last_released.api_file",
1407 "has to be non-empty if jdiff was enabled!")
1408 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001409
Colin Cross33961b52019-07-11 11:01:22 -07001410 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001411 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001412 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1413 }
1414}
Nan Zhang71bbe632018-09-17 14:32:21 -07001415
Colin Cross33961b52019-07-11 11:01:22 -07001416func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1417 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1418 cmd := rule.Command().BuiltTool(ctx, "metalava").
1419 Flag(config.JavacVmFlags).
1420 FlagWithArg("-encoding ", "UTF-8").
1421 FlagWithArg("-source ", javaVersion).
1422 FlagWithRspFileInputList("@", srcs).
1423 FlagWithInput("@", srcJarList)
1424
1425 if len(bootclasspath) > 0 {
1426 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001427 }
1428
Colin Cross33961b52019-07-11 11:01:22 -07001429 if len(classpath) > 0 {
1430 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1431 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001432
Colin Cross33961b52019-07-11 11:01:22 -07001433 if len(sourcepaths) > 0 {
1434 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1435 } else {
1436 cmd.FlagWithArg("-sourcepath ", `""`)
1437 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001438
Colin Cross33961b52019-07-11 11:01:22 -07001439 cmd.Flag("--no-banner").
1440 Flag("--color").
1441 Flag("--quiet").
1442 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001443
Colin Cross33961b52019-07-11 11:01:22 -07001444 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001445}
1446
Nan Zhang1598a9e2018-09-04 17:14:32 -07001447func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001448 deps := d.Javadoc.collectDeps(ctx)
1449
1450 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001451
Colin Cross33961b52019-07-11 11:01:22 -07001452 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001453
Colin Crossdaa4c672019-07-15 22:53:46 -07001454 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001455
Colin Cross33961b52019-07-11 11:01:22 -07001456 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1457 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001458
Colin Cross33961b52019-07-11 11:01:22 -07001459 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001460
Colin Cross33961b52019-07-11 11:01:22 -07001461 rule.Command().Text("rm -rf").Text(stubsDir.String())
1462 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001463
Colin Cross33961b52019-07-11 11:01:22 -07001464 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1465
1466 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1467 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1468
1469 d.stubsFlags(ctx, cmd, stubsDir)
1470
1471 d.annotationsFlags(ctx, cmd)
1472 d.inclusionAnnotationsFlags(ctx, cmd)
1473 d.apiLevelsAnnotationsFlags(ctx, cmd)
1474 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001475
Nan Zhang1598a9e2018-09-04 17:14:32 -07001476 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1477 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1478 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1479 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1480 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001481 }
Colin Cross33961b52019-07-11 11:01:22 -07001482
1483 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1484 for _, o := range d.Javadoc.properties.Out {
1485 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1486 }
1487
1488 rule.Command().
1489 BuiltTool(ctx, "soong_zip").
1490 Flag("-write_if_changed").
1491 Flag("-jar").
1492 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1493 FlagWithArg("-C ", stubsDir.String()).
1494 FlagWithArg("-D ", stubsDir.String())
1495 rule.Restat()
1496
1497 zipSyncCleanupCmd(rule, srcJarDir)
1498
1499 rule.Build(pctx, ctx, "metalava", "metalava")
1500
1501 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001502
Nan Zhang1598a9e2018-09-04 17:14:32 -07001503 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1504 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001505
1506 if len(d.Javadoc.properties.Out) > 0 {
1507 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1508 }
1509
1510 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1511 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001512 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1513 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001514
Nan Zhang2760dfc2018-08-24 17:32:54 +00001515 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001516
Colin Cross33961b52019-07-11 11:01:22 -07001517 rule := android.NewRuleBuilder()
1518
1519 rule.Command().Text("( true")
1520
1521 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1522 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1523
1524 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1525 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1526
1527 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1528 FlagWithInput("--check-compatibility:api:current ", apiFile).
1529 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1530
1531 d.inclusionAnnotationsFlags(ctx, cmd)
1532 d.mergeAnnoDirFlags(ctx, cmd)
1533
Adrian Roos14f75a92019-08-12 17:54:09 +02001534 if baselineFile.Valid() {
1535 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1536 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1537 }
1538
Colin Cross33961b52019-07-11 11:01:22 -07001539 zipSyncCleanupCmd(rule, srcJarDir)
1540
1541 msg := fmt.Sprintf(`\n******************************\n`+
1542 `You have tried to change the API from what has been previously approved.\n\n`+
1543 `To make these errors go away, you have two choices:\n`+
1544 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1545 ` errors above.\n\n`+
1546 ` 2. You can update current.txt by executing the following command:\n`+
1547 ` make %s-update-current-api\n\n`+
1548 ` To submit the revised current.txt to the main Android repository,\n`+
1549 ` you will need approval.\n`+
1550 `******************************\n`, ctx.ModuleName())
1551
1552 rule.Command().
1553 Text("touch").Output(d.checkCurrentApiTimestamp).
1554 Text(") || (").
1555 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1556 Text("; exit 38").
1557 Text(")")
1558
1559 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001560
1561 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001562
1563 // update API rule
1564 rule = android.NewRuleBuilder()
1565
1566 rule.Command().Text("( true")
1567
1568 rule.Command().
1569 Text("cp").Flag("-f").
1570 Input(d.apiFile).Flag(apiFile.String())
1571
1572 rule.Command().
1573 Text("cp").Flag("-f").
1574 Input(d.removedApiFile).Flag(removedApiFile.String())
1575
1576 msg = "failed to update public API"
1577
1578 rule.Command().
1579 Text("touch").Output(d.updateCurrentApiTimestamp).
1580 Text(") || (").
1581 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1582 Text("; exit 38").
1583 Text(")")
1584
1585 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001586 }
Nan Zhanga40da042018-08-01 12:48:00 -07001587
Nan Zhang1598a9e2018-09-04 17:14:32 -07001588 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1589 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001590
1591 if len(d.Javadoc.properties.Out) > 0 {
1592 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1593 }
1594
1595 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1596 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001597 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1598 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001599
Nan Zhang2760dfc2018-08-24 17:32:54 +00001600 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001601
Colin Cross33961b52019-07-11 11:01:22 -07001602 rule := android.NewRuleBuilder()
1603
1604 rule.Command().Text("( true")
1605
1606 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1607 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1608
1609 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1610 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1611
1612 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1613 FlagWithInput("--check-compatibility:api:released ", apiFile)
1614
1615 d.inclusionAnnotationsFlags(ctx, cmd)
1616
1617 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1618
1619 d.mergeAnnoDirFlags(ctx, cmd)
1620
Adrian Roos14f75a92019-08-12 17:54:09 +02001621 if baselineFile.Valid() {
1622 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1623 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1624 }
1625
Colin Cross33961b52019-07-11 11:01:22 -07001626 zipSyncCleanupCmd(rule, srcJarDir)
1627
1628 msg := `\n******************************\n` +
1629 `You have tried to change the API from what has been previously released in\n` +
1630 `an SDK. Please fix the errors listed above.\n` +
1631 `******************************\n`
1632 rule.Command().
1633 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1634 Text(") || (").
1635 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1636 Text("; exit 38").
1637 Text(")")
1638
1639 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001640 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001641
Pete Gillin581d6082018-10-22 15:55:04 +01001642 if String(d.properties.Check_nullability_warnings) != "" {
1643 if d.nullabilityWarningsFile == nil {
1644 ctx.PropertyErrorf("check_nullability_warnings",
1645 "Cannot specify check_nullability_warnings unless validating nullability")
1646 }
Colin Cross33961b52019-07-11 11:01:22 -07001647
1648 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1649
Pete Gillin581d6082018-10-22 15:55:04 +01001650 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001651
Pete Gillin581d6082018-10-22 15:55:04 +01001652 msg := fmt.Sprintf(`\n******************************\n`+
1653 `The warnings encountered during nullability annotation validation did\n`+
1654 `not match the checked in file of expected warnings. The diffs are shown\n`+
1655 `above. You have two options:\n`+
1656 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1657 ` 2. Update the file of expected warnings by running:\n`+
1658 ` cp %s %s\n`+
1659 ` and submitting the updated file as part of your change.`,
1660 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001661
1662 rule := android.NewRuleBuilder()
1663
1664 rule.Command().
1665 Text("(").
1666 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1667 Text("&&").
1668 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1669 Text(") || (").
1670 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1671 Text("; exit 38").
1672 Text(")")
1673
1674 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001675 }
1676
Nan Zhang71bbe632018-09-17 14:32:21 -07001677 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001678 if len(d.Javadoc.properties.Out) > 0 {
1679 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1680 }
1681
1682 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1683 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1684 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1685
1686 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001687
Nan Zhang86b06202018-09-21 17:09:21 -07001688 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1689 // since there's cron job downstream that fetch this .zip file periodically.
1690 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001691 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1692 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1693
Nan Zhang71bbe632018-09-17 14:32:21 -07001694 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001695
Colin Cross33961b52019-07-11 11:01:22 -07001696 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1697 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001698
Colin Cross33961b52019-07-11 11:01:22 -07001699 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1700
Colin Crossdaa4c672019-07-15 22:53:46 -07001701 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001702 deps.bootClasspath, deps.classpath, d.sourcepaths)
1703
1704 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001705 Flag("-XDignore.symbol.file").
1706 FlagWithArg("-doclet ", "jdiff.JDiff").
1707 FlagWithInput("-docletpath ", jdiff).
1708 Flag("-quiet").
1709 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1710 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1711 Implicit(d.apiXmlFile).
1712 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1713 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1714 Implicit(d.lastReleasedApiXmlFile)
1715
Colin Cross33961b52019-07-11 11:01:22 -07001716 rule.Command().
1717 BuiltTool(ctx, "soong_zip").
1718 Flag("-write_if_changed").
1719 Flag("-d").
1720 FlagWithOutput("-o ", d.jdiffDocZip).
1721 FlagWithArg("-C ", outDir.String()).
1722 FlagWithArg("-D ", outDir.String())
1723
1724 rule.Command().
1725 BuiltTool(ctx, "soong_zip").
1726 Flag("-write_if_changed").
1727 Flag("-jar").
1728 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1729 FlagWithArg("-C ", stubsDir.String()).
1730 FlagWithArg("-D ", stubsDir.String())
1731
1732 rule.Restat()
1733
1734 zipSyncCleanupCmd(rule, srcJarDir)
1735
1736 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001737 }
Nan Zhang581fd212018-01-10 16:06:12 -08001738}
Dan Willemsencc090972018-02-26 14:33:31 -08001739
Nan Zhanga40da042018-08-01 12:48:00 -07001740//
Nan Zhangf4936b02018-08-01 15:00:28 -07001741// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001742//
Dan Willemsencc090972018-02-26 14:33:31 -08001743var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001744var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001745var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001746var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001747
Nan Zhangf4936b02018-08-01 15:00:28 -07001748type ExportedDroiddocDirProperties struct {
1749 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001750 Path *string
1751}
1752
Nan Zhangf4936b02018-08-01 15:00:28 -07001753type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001754 android.ModuleBase
1755
Nan Zhangf4936b02018-08-01 15:00:28 -07001756 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001757
1758 deps android.Paths
1759 dir android.Path
1760}
1761
Colin Crossa3002fc2019-07-08 16:48:04 -07001762// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001763func ExportedDroiddocDirFactory() android.Module {
1764 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001765 module.AddProperties(&module.properties)
1766 android.InitAndroidModule(module)
1767 return module
1768}
1769
Nan Zhangf4936b02018-08-01 15:00:28 -07001770func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001771
Nan Zhangf4936b02018-08-01 15:00:28 -07001772func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001773 path := String(d.properties.Path)
1774 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001775 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001776}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001777
1778//
1779// Defaults
1780//
1781type DocDefaults struct {
1782 android.ModuleBase
1783 android.DefaultsModuleBase
1784}
1785
Nan Zhangb2b33de2018-02-23 11:18:47 -08001786func DocDefaultsFactory() android.Module {
1787 module := &DocDefaults{}
1788
1789 module.AddProperties(
1790 &JavadocProperties{},
1791 &DroiddocProperties{},
1792 )
1793
1794 android.InitDefaultsModule(module)
1795
1796 return module
1797}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001798
1799func StubsDefaultsFactory() android.Module {
1800 module := &DocDefaults{}
1801
1802 module.AddProperties(
1803 &JavadocProperties{},
1804 &DroidstubsProperties{},
1805 )
1806
1807 android.InitDefaultsModule(module)
1808
1809 return module
1810}
Colin Cross33961b52019-07-11 11:01:22 -07001811
1812func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1813 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1814
1815 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1816 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1817 srcJarList := srcJarDir.Join(ctx, "list")
1818
1819 rule.Temporary(srcJarList)
1820
1821 rule.Command().BuiltTool(ctx, "zipsync").
1822 FlagWithArg("-d ", srcJarDir.String()).
1823 FlagWithOutput("-l ", srcJarList).
1824 FlagWithArg("-f ", `"*.java"`).
1825 Inputs(srcJars)
1826
1827 return srcJarList
1828}
1829
1830func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1831 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1832}