blob: 118b62c215f0487df2d2b67421535b82d7cd6c1b [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070020 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080021 "strings"
22
Jeongik Cha6bd33c12019-06-25 16:26:18 +090023 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080024
Colin Crossab054432019-07-15 16:13:59 -070025 "android/soong/android"
26 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080030 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070031 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080032
Nan Zhang581fd212018-01-10 16:06:12 -080033 android.RegisterModuleType("droiddoc", DroiddocFactory)
34 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070035 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080036 android.RegisterModuleType("javadoc", JavadocFactory)
37 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070038
39 android.RegisterModuleType("droidstubs", DroidstubsFactory)
40 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080041}
42
Colin Crossa1ce2a02018-06-20 15:19:39 -070043var (
44 srcsLibTag = dependencyTag{name: "sources from javalib"}
45)
46
Nan Zhang581fd212018-01-10 16:06:12 -080047type JavadocProperties struct {
48 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
49 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080051
52 // list of directories rooted at the Android.bp file that will
53 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080054 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080055
56 // list of source files that should not be used to build the Java module.
57 // This is most useful in the arch/multilib variants to remove non-common files
58 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080059 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080060
Nan Zhangb2b33de2018-02-23 11:18:47 -080061 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080062 Libs []string `android:"arch_variant"`
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // the java library (in classpath) for documentation that provides java srcs and srcjars.
65 Srcs_lib *string
66
67 // the base dirs under srcs_lib will be scanned for java srcs.
68 Srcs_lib_whitelist_dirs []string
69
70 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
71 Srcs_lib_whitelist_pkgs []string
72
Nan Zhang581fd212018-01-10 16:06:12 -080073 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080074 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080075
76 // if not blank, set to the version of the sdk to compile against
77 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090078
79 Aidl struct {
80 // Top level directories to pass to aidl tool
81 Include_dirs []string
82
83 // Directories rooted at the Android.bp file to pass to aidl tool
84 Local_include_dirs []string
85 }
Nan Zhang357466b2018-04-17 17:38:36 -070086
87 // If not blank, set the java version passed to javadoc as -source
88 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080091 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070092
93 // user customized droiddoc args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070097 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070098 Args *string
99
100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // if set to true, collect the values used by the Dev tools and
146 // write them in files packaged with the SDK. Defaults to false.
147 Write_sdk_values *bool
148
149 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
152 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700154
Nan Zhang581fd212018-01-10 16:06:12 -0800155 // a list of files under current module source dir which contains known tags in Java sources.
156 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800157 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700158
159 // the tag name used to distinguish if the API files belong to public/system/test.
160 Api_tag_name *string
161
162 // the generated public API filename by Doclava.
163 Api_filename *string
164
David Brazdilfbe4cc32018-05-31 13:56:46 +0100165 // the generated public Dex API filename by Doclava.
166 Dex_api_filename *string
167
Nan Zhang28c68b92018-03-13 16:17:01 -0700168 // the generated private API filename by Doclava.
169 Private_api_filename *string
170
171 // the generated private Dex API filename by Doclava.
172 Private_dex_api_filename *string
173
174 // the generated removed API filename by Doclava.
175 Removed_api_filename *string
176
David Brazdilaac0c3c2018-04-24 16:23:29 +0100177 // the generated removed Dex API filename by Doclava.
178 Removed_dex_api_filename *string
179
Mathew Inwood76c3de12018-06-22 15:28:11 +0100180 // mapping of dex signatures to source file and line number. This is a temporary property and
181 // will be deleted; you probably shouldn't be using it.
182 Dex_mapping_filename *string
183
Nan Zhang28c68b92018-03-13 16:17:01 -0700184 // the generated exact API filename by Doclava.
185 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700186
Nan Zhang66dc2362018-08-14 20:41:04 -0700187 // the generated proguard filename by Doclava.
188 Proguard_filename *string
189
Nan Zhang853f4202018-04-12 16:55:56 -0700190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900197
198 // do not perform API check against Last_released, in the case that both two specified API
199 // files by Last_released are modules which don't exist.
200 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700201 }
Nan Zhang79614d12018-04-19 18:03:39 -0700202
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 // if set to true, generate docs through Dokka instead of Doclava.
204 Dokka_enabled *bool
205}
206
207type DroidstubsProperties struct {
208 // the tag name used to distinguish if the API files belong to public/system/test.
209 Api_tag_name *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Private_dex_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 Removed_dex_api_filename *string
228
Nan Zhang9c69a122018-08-22 10:22:08 -0700229 // mapping of dex signatures to source file and line number. This is a temporary property and
230 // will be deleted; you probably shouldn't be using it.
231 Dex_mapping_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700234 Exact_api_filename *string
235
Nan Zhang199645c2018-09-19 12:40:06 -0700236 // the generated proguard filename by Metalava.
237 Proguard_filename *string
238
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Check_api struct {
240 Last_released ApiToCheck
241
242 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900243
244 // do not perform API check against Last_released, in the case that both two specified API
245 // files by Last_released are modules which don't exist.
246 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700247 }
Nan Zhang79614d12018-04-19 18:03:39 -0700248
249 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800250 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700251
252 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700253 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700254
Pete Gillin77167902018-09-19 18:16:26 +0100255 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700256 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700257
Pete Gillin77167902018-09-19 18:16:26 +0100258 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
259 Merge_inclusion_annotations_dirs []string
260
Pete Gillinc382a562018-11-14 18:45:46 +0000261 // a file containing a list of classes to do nullability validation for.
262 Validate_nullability_from_list *string
263
Pete Gillin581d6082018-10-22 15:55:04 +0100264 // a file containing expected warnings produced by validation of nullability annotations.
265 Check_nullability_warnings *string
266
Nan Zhang1598a9e2018-09-04 17:14:32 -0700267 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
268 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700269
270 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
271 Api_levels_annotations_enabled *bool
272
273 // the dirs which Metalava extracts API levels annotations from.
274 Api_levels_annotations_dirs []string
275
276 // if set to true, collect the values used by the Dev tools and
277 // write them in files packaged with the SDK. Defaults to false.
278 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700279
280 // If set to true, .xml based public API file will be also generated, and
281 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
282 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800283}
284
Nan Zhanga40da042018-08-01 12:48:00 -0700285//
286// Common flags passed down to build rule
287//
288type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700289 bootClasspathArgs string
290 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700291 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700292 dokkaClasspathArgs string
293 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700294 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700295
Nan Zhanga40da042018-08-01 12:48:00 -0700296 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700297 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700298 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700299}
300
301func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
302 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
303 android.InitDefaultableModule(module)
304}
305
Nan Zhang1598a9e2018-09-04 17:14:32 -0700306func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
307 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
308 return true
309 } else if String(apiToCheck.Api_file) != "" {
310 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
311 } else if String(apiToCheck.Removed_api_file) != "" {
312 panic("for " + apiVersionTag + " api_file has to be non-empty!")
313 }
314
315 return false
316}
317
Inseob Kim38449af2019-02-28 14:24:05 +0900318func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
319 api_file := String(apiToCheck.Api_file)
320 removed_api_file := String(apiToCheck.Removed_api_file)
321
322 api_module := android.SrcIsModule(api_file)
323 removed_api_module := android.SrcIsModule(removed_api_file)
324
325 if api_module == "" || removed_api_module == "" {
326 return
327 }
328
329 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
330 return
331 }
332
333 apiToCheck.Api_file = nil
334 apiToCheck.Removed_api_file = nil
335}
336
Nan Zhang1598a9e2018-09-04 17:14:32 -0700337type ApiFilePath interface {
338 ApiFilePath() android.Path
339}
340
Nan Zhanga40da042018-08-01 12:48:00 -0700341//
342// Javadoc
343//
Nan Zhang581fd212018-01-10 16:06:12 -0800344type Javadoc struct {
345 android.ModuleBase
346 android.DefaultableModuleBase
347
348 properties JavadocProperties
349
350 srcJars android.Paths
351 srcFiles android.Paths
352 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700353 argFiles android.Paths
354
355 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800356
Nan Zhangccff0f72018-03-08 17:26:16 -0800357 docZip android.WritablePath
358 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800359}
360
Colin Cross41955e82019-05-29 14:40:35 -0700361func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
362 switch tag {
363 case "":
364 return android.Paths{j.stubsSrcJar}, nil
365 default:
366 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
367 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800368}
369
Colin Crossa3002fc2019-07-08 16:48:04 -0700370// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800371func JavadocFactory() android.Module {
372 module := &Javadoc{}
373
374 module.AddProperties(&module.properties)
375
376 InitDroiddocModule(module, android.HostAndDeviceSupported)
377 return module
378}
379
Colin Crossa3002fc2019-07-08 16:48:04 -0700380// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800381func JavadocHostFactory() android.Module {
382 module := &Javadoc{}
383
384 module.AddProperties(&module.properties)
385
386 InitDroiddocModule(module, android.HostSupported)
387 return module
388}
389
Colin Cross41955e82019-05-29 14:40:35 -0700390var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800391
Colin Cross83bb3162018-06-25 15:48:06 -0700392func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900393 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700394}
395
396func (j *Javadoc) minSdkVersion() string {
397 return j.sdkVersion()
398}
399
Dan Willemsen419290a2018-10-31 15:28:47 -0700400func (j *Javadoc) targetSdkVersion() string {
401 return j.sdkVersion()
402}
403
Nan Zhang581fd212018-01-10 16:06:12 -0800404func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
405 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100406 sdkDep := decodeSdkDep(ctx, sdkContext(j))
407 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700408 if sdkDep.useDefaultLibs {
409 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
410 if ctx.Config().TargetOpenJDK9() {
411 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
412 }
Paul Duffin250e6192019-06-07 10:44:37 +0100413 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700414 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
415 }
416 } else if sdkDep.useModule {
417 if ctx.Config().TargetOpenJDK9() {
418 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
419 }
420 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700421 }
Nan Zhang581fd212018-01-10 16:06:12 -0800422 }
423 }
424
Colin Cross42d48b72018-08-29 14:10:52 -0700425 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700426 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700427 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700428 }
Nan Zhang581fd212018-01-10 16:06:12 -0800429}
430
Nan Zhangb2b33de2018-02-23 11:18:47 -0800431func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
432 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
433 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900434 // convert foo.bar.baz to foo/bar/baz
435 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
436 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800437 if _, found := whitelistPathPrefixes[prefix]; !found {
438 whitelistPathPrefixes[prefix] = true
439 }
440 }
441 }
442}
443
Nan Zhanga40da042018-08-01 12:48:00 -0700444func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
445 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900446
Colin Cross3047fa22019-04-18 10:56:44 -0700447 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900448
449 return flags
450}
451
452func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700453 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900454
455 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
456 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
457
458 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700459 var deps android.Paths
460
Jiyong Park1e440682018-05-23 18:42:04 +0900461 if aidlPreprocess.Valid() {
462 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700463 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900464 } else {
465 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
466 }
467
468 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
469 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
470 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
471 flags = append(flags, "-I"+src.String())
472 }
473
Colin Cross3047fa22019-04-18 10:56:44 -0700474 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900475}
476
Jiyong Parkd90d7412019-08-20 22:49:19 +0900477// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900478func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700479 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900480
481 outSrcFiles := make(android.Paths, 0, len(srcFiles))
482
483 for _, srcFile := range srcFiles {
484 switch srcFile.Ext() {
485 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700486 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900487 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900488 case ".logtags":
489 javaFile := genLogtags(ctx, srcFile)
490 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900491 default:
492 outSrcFiles = append(outSrcFiles, srcFile)
493 }
494 }
495
496 return outSrcFiles
497}
498
Nan Zhang581fd212018-01-10 16:06:12 -0800499func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
500 var deps deps
501
Colin Cross83bb3162018-06-25 15:48:06 -0700502 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800503 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700504 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800505 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700506 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800507 }
508
509 ctx.VisitDirectDeps(func(module android.Module) {
510 otherName := ctx.OtherModuleName(module)
511 tag := ctx.OtherModuleDependencyTag(module)
512
Colin Cross2d24c1b2018-05-23 10:59:18 -0700513 switch tag {
514 case bootClasspathTag:
515 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800516 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700517 } else {
518 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
519 }
520 case libTag:
521 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800522 case SdkLibraryDependency:
523 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700524 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900525 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900526 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700527 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800528 checkProducesJars(ctx, dep)
529 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800530 default:
531 ctx.ModuleErrorf("depends on non-java module %q", otherName)
532 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700533 case srcsLibTag:
534 switch dep := module.(type) {
535 case Dependency:
536 srcs := dep.(SrcDependency).CompiledSrcs()
537 whitelistPathPrefixes := make(map[string]bool)
538 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
539 for _, src := range srcs {
540 if _, ok := src.(android.WritablePath); ok { // generated sources
541 deps.srcs = append(deps.srcs, src)
542 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700543 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700544 if strings.HasPrefix(src.Rel(), k) {
545 deps.srcs = append(deps.srcs, src)
546 break
547 }
548 }
549 }
550 }
551 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
552 default:
553 ctx.ModuleErrorf("depends on non-java module %q", otherName)
554 }
Nan Zhang357466b2018-04-17 17:38:36 -0700555 case systemModulesTag:
556 if deps.systemModules != nil {
557 panic("Found two system module dependencies")
558 }
559 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000560 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700561 panic("Missing directory for system module dependency")
562 }
Colin Crossb77043e2019-07-16 13:57:13 -0700563 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800564 }
565 })
566 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
567 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800568 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700569 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900570 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800571
572 // srcs may depend on some genrule output.
573 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800574 j.srcJars = append(j.srcJars, deps.srcJars...)
575
Nan Zhang581fd212018-01-10 16:06:12 -0800576 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800577 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800578
Nan Zhang9c69a122018-08-22 10:22:08 -0700579 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800580 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
581 }
582 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800583
Colin Cross8a497952019-03-05 22:25:09 -0800584 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000585 argFilesMap := map[string]string{}
586 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700587
Paul Duffin99e4a502019-02-11 15:38:42 +0000588 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800589 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000590 if _, exists := argFilesMap[label]; !exists {
591 argFilesMap[label] = strings.Join(paths.Strings(), " ")
592 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700593 } else {
594 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000595 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700596 }
597 }
598
599 var err error
Colin Cross15638152019-07-11 11:11:35 -0700600 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700601 if strings.HasPrefix(name, "location ") {
602 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000603 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700604 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700605 } else {
Colin Cross15638152019-07-11 11:11:35 -0700606 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000607 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700608 }
609 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700610 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700611 }
Colin Cross15638152019-07-11 11:11:35 -0700612 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700613 })
614
615 if err != nil {
616 ctx.PropertyErrorf("args", "%s", err.Error())
617 }
618
Nan Zhang581fd212018-01-10 16:06:12 -0800619 return deps
620}
621
622func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
623 j.addDeps(ctx)
624}
625
626func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
627 deps := j.collectDeps(ctx)
628
Colin Crossdaa4c672019-07-15 22:53:46 -0700629 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800630
Colin Crossdaa4c672019-07-15 22:53:46 -0700631 outDir := android.PathForModuleOut(ctx, "out")
632 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
633
634 j.stubsSrcJar = nil
635
636 rule := android.NewRuleBuilder()
637
638 rule.Command().Text("rm -rf").Text(outDir.String())
639 rule.Command().Text("mkdir -p").Text(outDir.String())
640
641 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700642
Colin Cross83bb3162018-06-25 15:48:06 -0700643 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800644
Colin Crossdaa4c672019-07-15 22:53:46 -0700645 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
646 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800647
Colin Crossdaa4c672019-07-15 22:53:46 -0700648 cmd.FlagWithArg("-source ", javaVersion).
649 Flag("-J-Xmx1024m").
650 Flag("-XDignore.symbol.file").
651 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800652
Colin Crossdaa4c672019-07-15 22:53:46 -0700653 rule.Command().
654 BuiltTool(ctx, "soong_zip").
655 Flag("-write_if_changed").
656 Flag("-d").
657 FlagWithOutput("-o ", j.docZip).
658 FlagWithArg("-C ", outDir.String()).
659 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700660
Colin Crossdaa4c672019-07-15 22:53:46 -0700661 rule.Restat()
662
663 zipSyncCleanupCmd(rule, srcJarDir)
664
665 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800666}
667
Nan Zhanga40da042018-08-01 12:48:00 -0700668//
669// Droiddoc
670//
671type Droiddoc struct {
672 Javadoc
673
674 properties DroiddocProperties
675 apiFile android.WritablePath
676 dexApiFile android.WritablePath
677 privateApiFile android.WritablePath
678 privateDexApiFile android.WritablePath
679 removedApiFile android.WritablePath
680 removedDexApiFile android.WritablePath
681 exactApiFile android.WritablePath
682 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700683 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700684
685 checkCurrentApiTimestamp android.WritablePath
686 updateCurrentApiTimestamp android.WritablePath
687 checkLastReleasedApiTimestamp android.WritablePath
688
Nan Zhanga40da042018-08-01 12:48:00 -0700689 apiFilePath android.Path
690}
691
Colin Crossa3002fc2019-07-08 16:48:04 -0700692// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700693func DroiddocFactory() android.Module {
694 module := &Droiddoc{}
695
696 module.AddProperties(&module.properties,
697 &module.Javadoc.properties)
698
699 InitDroiddocModule(module, android.HostAndDeviceSupported)
700 return module
701}
702
Colin Crossa3002fc2019-07-08 16:48:04 -0700703// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700704func DroiddocHostFactory() android.Module {
705 module := &Droiddoc{}
706
707 module.AddProperties(&module.properties,
708 &module.Javadoc.properties)
709
710 InitDroiddocModule(module, android.HostSupported)
711 return module
712}
713
714func (d *Droiddoc) ApiFilePath() android.Path {
715 return d.apiFilePath
716}
717
Nan Zhang581fd212018-01-10 16:06:12 -0800718func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
719 d.Javadoc.addDeps(ctx)
720
Inseob Kim38449af2019-02-28 14:24:05 +0900721 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
722 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
723 }
724
Nan Zhang79614d12018-04-19 18:03:39 -0700725 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800726 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
727 }
Nan Zhang581fd212018-01-10 16:06:12 -0800728}
729
Colin Crossab054432019-07-15 16:13:59 -0700730func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700731 var date string
732 if runtime.GOOS == "darwin" {
733 date = `date -r`
734 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700735 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700736 }
737
Nan Zhang443fa522018-08-20 20:58:28 -0700738 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
739 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
740 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700741 cmd.FlagWithArg("-source ", "1.8").
742 Flag("-J-Xmx1600m").
743 Flag("-J-XX:-OmitStackTraceInFastThrow").
744 Flag("-XDignore.symbol.file").
745 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
746 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
747 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700748 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700749
Nan Zhanga40da042018-08-01 12:48:00 -0700750 if String(d.properties.Custom_template) == "" {
751 // TODO: This is almost always droiddoc-templates-sdk
752 ctx.PropertyErrorf("custom_template", "must specify a template")
753 }
754
755 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700756 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700757 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700758 } else {
759 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
760 }
761 })
762
763 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700764 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
765 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
766 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700767 }
768
769 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700770 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
771 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
772 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700773 }
774
775 if len(d.properties.Html_dirs) > 2 {
776 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
777 }
778
Colin Cross8a497952019-03-05 22:25:09 -0800779 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700780 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700781
Colin Crossab054432019-07-15 16:13:59 -0700782 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700783
784 if String(d.properties.Proofread_file) != "" {
785 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700786 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700787 }
788
789 if String(d.properties.Todo_file) != "" {
790 // tricky part:
791 // we should not compute full path for todo_file through PathForModuleOut().
792 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700793 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
794 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700795 }
796
797 if String(d.properties.Resourcesdir) != "" {
798 // TODO: should we add files under resourcesDir to the implicits? It seems that
799 // resourcesDir is one sub dir of htmlDir
800 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700801 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700802 }
803
804 if String(d.properties.Resourcesoutdir) != "" {
805 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700806 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700807 }
Nan Zhanga40da042018-08-01 12:48:00 -0700808}
809
Colin Crossab054432019-07-15 16:13:59 -0700810func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700811 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
812 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
813 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700814
Nan Zhanga40da042018-08-01 12:48:00 -0700815 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700816 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700817 d.apiFilePath = d.apiFile
818 }
819
Nan Zhang1598a9e2018-09-04 17:14:32 -0700820 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
821 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
822 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700823 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700824 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700825 }
826
827 if String(d.properties.Private_api_filename) != "" {
828 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700829 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700830 }
831
832 if String(d.properties.Dex_api_filename) != "" {
833 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700834 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700835 }
836
837 if String(d.properties.Private_dex_api_filename) != "" {
838 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700839 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700840 }
841
842 if String(d.properties.Removed_dex_api_filename) != "" {
843 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700844 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700845 }
846
847 if String(d.properties.Exact_api_filename) != "" {
848 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700849 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700850 }
851
852 if String(d.properties.Dex_mapping_filename) != "" {
853 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700854 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700855 }
856
Nan Zhang66dc2362018-08-14 20:41:04 -0700857 if String(d.properties.Proguard_filename) != "" {
858 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700859 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700860 }
861
Nan Zhanga40da042018-08-01 12:48:00 -0700862 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700863 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700864 }
865
866 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700867 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700868 }
Nan Zhanga40da042018-08-01 12:48:00 -0700869}
870
Colin Crossab054432019-07-15 16:13:59 -0700871func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700872 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700873 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
874 rule.Command().Text("cp").
875 Input(staticDocIndexRedirect).
876 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700877 }
878
879 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700880 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
881 rule.Command().Text("cp").
882 Input(staticDocProperties).
883 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700884 }
Nan Zhanga40da042018-08-01 12:48:00 -0700885}
886
Colin Crossab054432019-07-15 16:13:59 -0700887func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700888 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700889
890 cmd := rule.Command().
891 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
892 Flag(config.JavacVmFlags).
893 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700894 FlagWithRspFileInputList("@", srcs).
895 FlagWithInput("@", srcJarList)
896
Colin Crossab054432019-07-15 16:13:59 -0700897 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
898 // based stubs generation.
899 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
900 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
901 // the correct package name base path.
902 if len(sourcepaths) > 0 {
903 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
904 } else {
905 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
906 }
907
908 cmd.FlagWithArg("-d ", outDir.String()).
909 Flag("-quiet")
910
911 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700912}
913
Colin Crossdaa4c672019-07-15 22:53:46 -0700914func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
915 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
916 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
917
918 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
919
920 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
921 cmd.Flag(flag).Implicits(deps)
922
923 cmd.FlagWithArg("--patch-module ", "java.base=.")
924
925 if len(classpath) > 0 {
926 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
927 }
928
929 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700930}
931
Colin Crossdaa4c672019-07-15 22:53:46 -0700932func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
933 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
934 sourcepaths android.Paths) *android.RuleBuilderCommand {
935
936 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
937
938 if len(bootclasspath) == 0 && ctx.Device() {
939 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
940 // ensure java does not fall back to the default bootclasspath.
941 cmd.FlagWithArg("-bootclasspath ", `""`)
942 } else if len(bootclasspath) > 0 {
943 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
944 }
945
946 if len(classpath) > 0 {
947 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
948 }
949
950 return cmd
951}
952
Colin Crossab054432019-07-15 16:13:59 -0700953func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
954 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700955
Colin Crossab054432019-07-15 16:13:59 -0700956 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
957 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
958
959 return rule.Command().
960 BuiltTool(ctx, "dokka").
961 Flag(config.JavacVmFlags).
962 Flag(srcJarDir.String()).
963 FlagWithInputList("-classpath ", dokkaClasspath, ":").
964 FlagWithArg("-format ", "dac").
965 FlagWithArg("-dacRoot ", "/reference/kotlin").
966 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700967}
968
969func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
970 deps := d.Javadoc.collectDeps(ctx)
971
Colin Crossdaa4c672019-07-15 22:53:46 -0700972 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
973 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
974
Nan Zhang1598a9e2018-09-04 17:14:32 -0700975 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
976 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
977 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
978 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
979
Colin Crossab054432019-07-15 16:13:59 -0700980 outDir := android.PathForModuleOut(ctx, "out")
981 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
982 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700983
Colin Crossab054432019-07-15 16:13:59 -0700984 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700985
Colin Crossab054432019-07-15 16:13:59 -0700986 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
987 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700988
Colin Crossab054432019-07-15 16:13:59 -0700989 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
990
991 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700992 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700993 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700994 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700995 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700996 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700997 }
998
Colin Crossab054432019-07-15 16:13:59 -0700999 d.stubsFlags(ctx, cmd, stubsDir)
1000
1001 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1002
1003 var desc string
1004 if Bool(d.properties.Dokka_enabled) {
1005 desc = "dokka"
1006 } else {
1007 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1008
1009 for _, o := range d.Javadoc.properties.Out {
1010 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1011 }
1012
1013 d.postDoclavaCmds(ctx, rule)
1014 desc = "doclava"
1015 }
1016
1017 rule.Command().
1018 BuiltTool(ctx, "soong_zip").
1019 Flag("-write_if_changed").
1020 Flag("-d").
1021 FlagWithOutput("-o ", d.docZip).
1022 FlagWithArg("-C ", outDir.String()).
1023 FlagWithArg("-D ", outDir.String())
1024
1025 rule.Command().
1026 BuiltTool(ctx, "soong_zip").
1027 Flag("-write_if_changed").
1028 Flag("-jar").
1029 FlagWithOutput("-o ", d.stubsSrcJar).
1030 FlagWithArg("-C ", stubsDir.String()).
1031 FlagWithArg("-D ", stubsDir.String())
1032
1033 rule.Restat()
1034
1035 zipSyncCleanupCmd(rule, srcJarDir)
1036
1037 rule.Build(pctx, ctx, "javadoc", desc)
1038
Nan Zhang1598a9e2018-09-04 17:14:32 -07001039 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1040 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001041
1042 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1043 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001044
1045 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001046
1047 rule := android.NewRuleBuilder()
1048
1049 rule.Command().Text("( true")
1050
1051 rule.Command().
1052 BuiltTool(ctx, "apicheck").
1053 Flag("-JXmx1024m").
1054 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1055 OptionalFlag(d.properties.Check_api.Current.Args).
1056 Input(apiFile).
1057 Input(d.apiFile).
1058 Input(removedApiFile).
1059 Input(d.removedApiFile)
1060
1061 msg := fmt.Sprintf(`\n******************************\n`+
1062 `You have tried to change the API from what has been previously approved.\n\n`+
1063 `To make these errors go away, you have two choices:\n`+
1064 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1065 ` errors above.\n\n`+
1066 ` 2. You can update current.txt by executing the following command:\n`+
1067 ` make %s-update-current-api\n\n`+
1068 ` To submit the revised current.txt to the main Android repository,\n`+
1069 ` you will need approval.\n`+
1070 `******************************\n`, ctx.ModuleName())
1071
1072 rule.Command().
1073 Text("touch").Output(d.checkCurrentApiTimestamp).
1074 Text(") || (").
1075 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1076 Text("; exit 38").
1077 Text(")")
1078
1079 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001080
1081 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001082
1083 // update API rule
1084 rule = android.NewRuleBuilder()
1085
1086 rule.Command().Text("( true")
1087
1088 rule.Command().
1089 Text("cp").Flag("-f").
1090 Input(d.apiFile).Flag(apiFile.String())
1091
1092 rule.Command().
1093 Text("cp").Flag("-f").
1094 Input(d.removedApiFile).Flag(removedApiFile.String())
1095
1096 msg = "failed to update public API"
1097
1098 rule.Command().
1099 Text("touch").Output(d.updateCurrentApiTimestamp).
1100 Text(") || (").
1101 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1102 Text("; exit 38").
1103 Text(")")
1104
1105 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001106 }
1107
1108 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1109 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001110
1111 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1112 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001113
1114 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001115
1116 rule := android.NewRuleBuilder()
1117
1118 rule.Command().
1119 Text("(").
1120 BuiltTool(ctx, "apicheck").
1121 Flag("-JXmx1024m").
1122 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1123 OptionalFlag(d.properties.Check_api.Last_released.Args).
1124 Input(apiFile).
1125 Input(d.apiFile).
1126 Input(removedApiFile).
1127 Input(d.removedApiFile)
1128
1129 msg := `\n******************************\n` +
1130 `You have tried to change the API from what has been previously released in\n` +
1131 `an SDK. Please fix the errors listed above.\n` +
1132 `******************************\n`
1133
1134 rule.Command().
1135 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1136 Text(") || (").
1137 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1138 Text("; exit 38").
1139 Text(")")
1140
1141 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001142 }
1143}
1144
1145//
1146// Droidstubs
1147//
1148type Droidstubs struct {
1149 Javadoc
1150
Pete Gillin581d6082018-10-22 15:55:04 +01001151 properties DroidstubsProperties
1152 apiFile android.WritablePath
1153 apiXmlFile android.WritablePath
1154 lastReleasedApiXmlFile android.WritablePath
1155 dexApiFile android.WritablePath
1156 privateApiFile android.WritablePath
1157 privateDexApiFile android.WritablePath
1158 removedApiFile android.WritablePath
1159 removedDexApiFile android.WritablePath
1160 apiMappingFile android.WritablePath
1161 exactApiFile android.WritablePath
1162 proguardFile android.WritablePath
1163 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001164
1165 checkCurrentApiTimestamp android.WritablePath
1166 updateCurrentApiTimestamp android.WritablePath
1167 checkLastReleasedApiTimestamp android.WritablePath
1168
Pete Gillin581d6082018-10-22 15:55:04 +01001169 checkNullabilityWarningsTimestamp android.WritablePath
1170
Nan Zhang1598a9e2018-09-04 17:14:32 -07001171 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001172 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001173
1174 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001175
1176 jdiffDocZip android.WritablePath
1177 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001178}
1179
Colin Crossa3002fc2019-07-08 16:48:04 -07001180// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1181// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1182// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001183func DroidstubsFactory() android.Module {
1184 module := &Droidstubs{}
1185
1186 module.AddProperties(&module.properties,
1187 &module.Javadoc.properties)
1188
1189 InitDroiddocModule(module, android.HostAndDeviceSupported)
1190 return module
1191}
1192
Colin Crossa3002fc2019-07-08 16:48:04 -07001193// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1194// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1195// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1196// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001197func DroidstubsHostFactory() android.Module {
1198 module := &Droidstubs{}
1199
1200 module.AddProperties(&module.properties,
1201 &module.Javadoc.properties)
1202
1203 InitDroiddocModule(module, android.HostSupported)
1204 return module
1205}
1206
1207func (d *Droidstubs) ApiFilePath() android.Path {
1208 return d.apiFilePath
1209}
1210
1211func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1212 d.Javadoc.addDeps(ctx)
1213
Inseob Kim38449af2019-02-28 14:24:05 +09001214 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1215 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1216 }
1217
Nan Zhang1598a9e2018-09-04 17:14:32 -07001218 if len(d.properties.Merge_annotations_dirs) != 0 {
1219 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1220 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1221 }
1222 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001223
Pete Gillin77167902018-09-19 18:16:26 +01001224 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1225 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1226 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1227 }
1228 }
1229
Nan Zhang9c69a122018-08-22 10:22:08 -07001230 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1231 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1232 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1233 }
1234 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001235}
1236
Colin Cross33961b52019-07-11 11:01:22 -07001237func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001238 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1239 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1240 String(d.properties.Api_filename) != "" {
1241 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001242 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001243 d.apiFilePath = d.apiFile
1244 }
1245
1246 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1247 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1248 String(d.properties.Removed_api_filename) != "" {
1249 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001250 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 }
1252
1253 if String(d.properties.Private_api_filename) != "" {
1254 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001255 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256 }
1257
1258 if String(d.properties.Dex_api_filename) != "" {
1259 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001260 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261 }
1262
1263 if String(d.properties.Private_dex_api_filename) != "" {
1264 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001265 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001266 }
1267
1268 if String(d.properties.Removed_dex_api_filename) != "" {
1269 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001270 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001271 }
1272
1273 if String(d.properties.Exact_api_filename) != "" {
1274 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001275 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001276 }
1277
Nan Zhang9c69a122018-08-22 10:22:08 -07001278 if String(d.properties.Dex_mapping_filename) != "" {
1279 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001280 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001281 }
1282
Nan Zhang199645c2018-09-19 12:40:06 -07001283 if String(d.properties.Proguard_filename) != "" {
1284 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001286 }
1287
Nan Zhang9c69a122018-08-22 10:22:08 -07001288 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001289 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001290 }
1291
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001293 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001294 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001295 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001297}
1298
Colin Cross33961b52019-07-11 11:01:22 -07001299func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001300 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001301 cmd.Flag("--include-annotations")
1302
Pete Gillinc382a562018-11-14 18:45:46 +00001303 validatingNullability :=
1304 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1305 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001306 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001307
Pete Gillina262c052018-09-14 14:25:48 +01001308 if !(migratingNullability || validatingNullability) {
1309 ctx.PropertyErrorf("previous_api",
1310 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001311 }
Colin Cross33961b52019-07-11 11:01:22 -07001312
Pete Gillina262c052018-09-14 14:25:48 +01001313 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001314 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001316 }
Colin Cross33961b52019-07-11 11:01:22 -07001317
Pete Gillinc382a562018-11-14 18:45:46 +00001318 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001320 }
Colin Cross33961b52019-07-11 11:01:22 -07001321
Pete Gillina262c052018-09-14 14:25:48 +01001322 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001323 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001324 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001325 }
Nan Zhanga40da042018-08-01 12:48:00 -07001326
1327 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001328 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001329
Nan Zhang1598a9e2018-09-04 17:14:32 -07001330 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001331 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001332 "has to be non-empty if annotations was enabled!")
1333 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001334
Colin Cross33961b52019-07-11 11:01:22 -07001335 d.mergeAnnoDirFlags(ctx, cmd)
1336
1337 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1338 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1339 FlagWithArg("--hide ", "SuperfluousPrefix").
1340 FlagWithArg("--hide ", "AnnotationExtraction")
1341 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001342}
1343
Colin Cross33961b52019-07-11 11:01:22 -07001344func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1345 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1346 if t, ok := m.(*ExportedDroiddocDir); ok {
1347 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1348 } else {
1349 ctx.PropertyErrorf("merge_annotations_dirs",
1350 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1351 }
1352 })
1353}
1354
1355func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001356 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1357 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001358 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001359 } else {
1360 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1361 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1362 }
1363 })
Nan Zhanga40da042018-08-01 12:48:00 -07001364}
1365
Colin Cross33961b52019-07-11 11:01:22 -07001366func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001367 if Bool(d.properties.Api_levels_annotations_enabled) {
1368 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001369
1370 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1371 ctx.PropertyErrorf("api_levels_annotations_dirs",
1372 "has to be non-empty if api levels annotations was enabled!")
1373 }
1374
Colin Cross33961b52019-07-11 11:01:22 -07001375 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1376 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1377 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1378 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001379
1380 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1381 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001382 for _, dep := range t.deps {
1383 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001384 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001385 }
1386 }
Colin Cross33961b52019-07-11 11:01:22 -07001387 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001388 } else {
1389 ctx.PropertyErrorf("api_levels_annotations_dirs",
1390 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1391 }
1392 })
1393
1394 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001395}
1396
Colin Cross33961b52019-07-11 11:01:22 -07001397func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001398 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1399 if d.apiFile.String() == "" {
1400 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1401 }
1402
1403 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001404 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001405
1406 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1407 ctx.PropertyErrorf("check_api.last_released.api_file",
1408 "has to be non-empty if jdiff was enabled!")
1409 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001410
Colin Cross33961b52019-07-11 11:01:22 -07001411 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001412 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001413 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1414 }
1415}
Nan Zhang71bbe632018-09-17 14:32:21 -07001416
Colin Cross33961b52019-07-11 11:01:22 -07001417func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1418 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1419 cmd := rule.Command().BuiltTool(ctx, "metalava").
1420 Flag(config.JavacVmFlags).
1421 FlagWithArg("-encoding ", "UTF-8").
1422 FlagWithArg("-source ", javaVersion).
1423 FlagWithRspFileInputList("@", srcs).
1424 FlagWithInput("@", srcJarList)
1425
1426 if len(bootclasspath) > 0 {
1427 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001428 }
1429
Colin Cross33961b52019-07-11 11:01:22 -07001430 if len(classpath) > 0 {
1431 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1432 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001433
Colin Cross33961b52019-07-11 11:01:22 -07001434 if len(sourcepaths) > 0 {
1435 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1436 } else {
1437 cmd.FlagWithArg("-sourcepath ", `""`)
1438 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001439
Colin Cross33961b52019-07-11 11:01:22 -07001440 cmd.Flag("--no-banner").
1441 Flag("--color").
1442 Flag("--quiet").
1443 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001444
Colin Cross33961b52019-07-11 11:01:22 -07001445 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001446}
1447
Nan Zhang1598a9e2018-09-04 17:14:32 -07001448func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001449 deps := d.Javadoc.collectDeps(ctx)
1450
1451 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001452
Colin Cross33961b52019-07-11 11:01:22 -07001453 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001454
Colin Crossdaa4c672019-07-15 22:53:46 -07001455 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1458 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001461
Colin Cross33961b52019-07-11 11:01:22 -07001462 rule.Command().Text("rm -rf").Text(stubsDir.String())
1463 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001464
Colin Cross33961b52019-07-11 11:01:22 -07001465 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1466
1467 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1468 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1469
1470 d.stubsFlags(ctx, cmd, stubsDir)
1471
1472 d.annotationsFlags(ctx, cmd)
1473 d.inclusionAnnotationsFlags(ctx, cmd)
1474 d.apiLevelsAnnotationsFlags(ctx, cmd)
1475 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001476
Nan Zhang1598a9e2018-09-04 17:14:32 -07001477 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1478 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1479 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1480 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1481 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001482 }
Colin Cross33961b52019-07-11 11:01:22 -07001483
1484 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1485 for _, o := range d.Javadoc.properties.Out {
1486 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1487 }
1488
1489 rule.Command().
1490 BuiltTool(ctx, "soong_zip").
1491 Flag("-write_if_changed").
1492 Flag("-jar").
1493 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1494 FlagWithArg("-C ", stubsDir.String()).
1495 FlagWithArg("-D ", stubsDir.String())
1496 rule.Restat()
1497
1498 zipSyncCleanupCmd(rule, srcJarDir)
1499
1500 rule.Build(pctx, ctx, "metalava", "metalava")
1501
1502 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001503
Nan Zhang1598a9e2018-09-04 17:14:32 -07001504 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1505 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001506
1507 if len(d.Javadoc.properties.Out) > 0 {
1508 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1509 }
1510
1511 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1512 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001513 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1514 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001515
Nan Zhang2760dfc2018-08-24 17:32:54 +00001516 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001517
Colin Cross33961b52019-07-11 11:01:22 -07001518 rule := android.NewRuleBuilder()
1519
1520 rule.Command().Text("( true")
1521
1522 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1523 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1524
1525 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1526 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1527
1528 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1529 FlagWithInput("--check-compatibility:api:current ", apiFile).
1530 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1531
1532 d.inclusionAnnotationsFlags(ctx, cmd)
1533 d.mergeAnnoDirFlags(ctx, cmd)
1534
Adrian Roos14f75a92019-08-12 17:54:09 +02001535 if baselineFile.Valid() {
1536 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1537 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1538 }
1539
Colin Cross33961b52019-07-11 11:01:22 -07001540 zipSyncCleanupCmd(rule, srcJarDir)
1541
1542 msg := fmt.Sprintf(`\n******************************\n`+
1543 `You have tried to change the API from what has been previously approved.\n\n`+
1544 `To make these errors go away, you have two choices:\n`+
1545 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1546 ` errors above.\n\n`+
1547 ` 2. You can update current.txt by executing the following command:\n`+
1548 ` make %s-update-current-api\n\n`+
1549 ` To submit the revised current.txt to the main Android repository,\n`+
1550 ` you will need approval.\n`+
1551 `******************************\n`, ctx.ModuleName())
1552
1553 rule.Command().
1554 Text("touch").Output(d.checkCurrentApiTimestamp).
1555 Text(") || (").
1556 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1557 Text("; exit 38").
1558 Text(")")
1559
1560 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001561
1562 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001563
1564 // update API rule
1565 rule = android.NewRuleBuilder()
1566
1567 rule.Command().Text("( true")
1568
1569 rule.Command().
1570 Text("cp").Flag("-f").
1571 Input(d.apiFile).Flag(apiFile.String())
1572
1573 rule.Command().
1574 Text("cp").Flag("-f").
1575 Input(d.removedApiFile).Flag(removedApiFile.String())
1576
1577 msg = "failed to update public API"
1578
1579 rule.Command().
1580 Text("touch").Output(d.updateCurrentApiTimestamp).
1581 Text(") || (").
1582 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1583 Text("; exit 38").
1584 Text(")")
1585
1586 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001587 }
Nan Zhanga40da042018-08-01 12:48:00 -07001588
Nan Zhang1598a9e2018-09-04 17:14:32 -07001589 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1590 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001591
1592 if len(d.Javadoc.properties.Out) > 0 {
1593 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1594 }
1595
1596 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1597 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001598 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1599 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001600
Nan Zhang2760dfc2018-08-24 17:32:54 +00001601 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001602
Colin Cross33961b52019-07-11 11:01:22 -07001603 rule := android.NewRuleBuilder()
1604
1605 rule.Command().Text("( true")
1606
1607 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1608 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1609
1610 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1611 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1612
1613 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1614 FlagWithInput("--check-compatibility:api:released ", apiFile)
1615
1616 d.inclusionAnnotationsFlags(ctx, cmd)
1617
1618 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1619
1620 d.mergeAnnoDirFlags(ctx, cmd)
1621
Adrian Roos14f75a92019-08-12 17:54:09 +02001622 if baselineFile.Valid() {
1623 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1624 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1625 }
1626
Colin Cross33961b52019-07-11 11:01:22 -07001627 zipSyncCleanupCmd(rule, srcJarDir)
1628
1629 msg := `\n******************************\n` +
1630 `You have tried to change the API from what has been previously released in\n` +
1631 `an SDK. Please fix the errors listed above.\n` +
1632 `******************************\n`
1633 rule.Command().
1634 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1635 Text(") || (").
1636 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1637 Text("; exit 38").
1638 Text(")")
1639
1640 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001641 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001642
Pete Gillin581d6082018-10-22 15:55:04 +01001643 if String(d.properties.Check_nullability_warnings) != "" {
1644 if d.nullabilityWarningsFile == nil {
1645 ctx.PropertyErrorf("check_nullability_warnings",
1646 "Cannot specify check_nullability_warnings unless validating nullability")
1647 }
Colin Cross33961b52019-07-11 11:01:22 -07001648
1649 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1650
Pete Gillin581d6082018-10-22 15:55:04 +01001651 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001652
Pete Gillin581d6082018-10-22 15:55:04 +01001653 msg := fmt.Sprintf(`\n******************************\n`+
1654 `The warnings encountered during nullability annotation validation did\n`+
1655 `not match the checked in file of expected warnings. The diffs are shown\n`+
1656 `above. You have two options:\n`+
1657 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1658 ` 2. Update the file of expected warnings by running:\n`+
1659 ` cp %s %s\n`+
1660 ` and submitting the updated file as part of your change.`,
1661 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001662
1663 rule := android.NewRuleBuilder()
1664
1665 rule.Command().
1666 Text("(").
1667 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1668 Text("&&").
1669 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1670 Text(") || (").
1671 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1672 Text("; exit 38").
1673 Text(")")
1674
1675 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001676 }
1677
Nan Zhang71bbe632018-09-17 14:32:21 -07001678 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001679 if len(d.Javadoc.properties.Out) > 0 {
1680 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1681 }
1682
1683 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1684 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1685 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1686
1687 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001688
Nan Zhang86b06202018-09-21 17:09:21 -07001689 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1690 // since there's cron job downstream that fetch this .zip file periodically.
1691 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001692 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1693 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1694
Nan Zhang71bbe632018-09-17 14:32:21 -07001695 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001696
Colin Cross33961b52019-07-11 11:01:22 -07001697 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1698 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001699
Colin Cross33961b52019-07-11 11:01:22 -07001700 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1701
Colin Crossdaa4c672019-07-15 22:53:46 -07001702 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001703 deps.bootClasspath, deps.classpath, d.sourcepaths)
1704
1705 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001706 Flag("-XDignore.symbol.file").
1707 FlagWithArg("-doclet ", "jdiff.JDiff").
1708 FlagWithInput("-docletpath ", jdiff).
1709 Flag("-quiet").
1710 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1711 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1712 Implicit(d.apiXmlFile).
1713 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1714 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1715 Implicit(d.lastReleasedApiXmlFile)
1716
Colin Cross33961b52019-07-11 11:01:22 -07001717 rule.Command().
1718 BuiltTool(ctx, "soong_zip").
1719 Flag("-write_if_changed").
1720 Flag("-d").
1721 FlagWithOutput("-o ", d.jdiffDocZip).
1722 FlagWithArg("-C ", outDir.String()).
1723 FlagWithArg("-D ", outDir.String())
1724
1725 rule.Command().
1726 BuiltTool(ctx, "soong_zip").
1727 Flag("-write_if_changed").
1728 Flag("-jar").
1729 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1730 FlagWithArg("-C ", stubsDir.String()).
1731 FlagWithArg("-D ", stubsDir.String())
1732
1733 rule.Restat()
1734
1735 zipSyncCleanupCmd(rule, srcJarDir)
1736
1737 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001738 }
Nan Zhang581fd212018-01-10 16:06:12 -08001739}
Dan Willemsencc090972018-02-26 14:33:31 -08001740
Nan Zhanga40da042018-08-01 12:48:00 -07001741//
Nan Zhangf4936b02018-08-01 15:00:28 -07001742// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001743//
Dan Willemsencc090972018-02-26 14:33:31 -08001744var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001745var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001746var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001747var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001748
Nan Zhangf4936b02018-08-01 15:00:28 -07001749type ExportedDroiddocDirProperties struct {
1750 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001751 Path *string
1752}
1753
Nan Zhangf4936b02018-08-01 15:00:28 -07001754type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001755 android.ModuleBase
1756
Nan Zhangf4936b02018-08-01 15:00:28 -07001757 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001758
1759 deps android.Paths
1760 dir android.Path
1761}
1762
Colin Crossa3002fc2019-07-08 16:48:04 -07001763// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001764func ExportedDroiddocDirFactory() android.Module {
1765 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001766 module.AddProperties(&module.properties)
1767 android.InitAndroidModule(module)
1768 return module
1769}
1770
Nan Zhangf4936b02018-08-01 15:00:28 -07001771func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001772
Nan Zhangf4936b02018-08-01 15:00:28 -07001773func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001774 path := String(d.properties.Path)
1775 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001776 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001777}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001778
1779//
1780// Defaults
1781//
1782type DocDefaults struct {
1783 android.ModuleBase
1784 android.DefaultsModuleBase
1785}
1786
Nan Zhangb2b33de2018-02-23 11:18:47 -08001787func DocDefaultsFactory() android.Module {
1788 module := &DocDefaults{}
1789
1790 module.AddProperties(
1791 &JavadocProperties{},
1792 &DroiddocProperties{},
1793 )
1794
1795 android.InitDefaultsModule(module)
1796
1797 return module
1798}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001799
1800func StubsDefaultsFactory() android.Module {
1801 module := &DocDefaults{}
1802
1803 module.AddProperties(
1804 &JavadocProperties{},
1805 &DroidstubsProperties{},
1806 )
1807
1808 android.InitDefaultsModule(module)
1809
1810 return module
1811}
Colin Cross33961b52019-07-11 11:01:22 -07001812
1813func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1814 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1815
1816 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1817 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1818 srcJarList := srcJarDir.Join(ctx, "list")
1819
1820 rule.Temporary(srcJarList)
1821
1822 rule.Command().BuiltTool(ctx, "zipsync").
1823 FlagWithArg("-d ", srcJarDir.String()).
1824 FlagWithOutput("-l ", srcJarList).
1825 FlagWithArg("-f ", `"*.java"`).
1826 Inputs(srcJars)
1827
1828 return srcJarList
1829}
1830
1831func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1832 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1833}