blob: 3e565825c0906976311c5af5b2fc7af31d97c626 [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
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900114 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700115 Args *string
116}
117
Nan Zhang581fd212018-01-10 16:06:12 -0800118type DroiddocProperties struct {
119 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800121
Nan Zhanga40da042018-08-01 12:48:00 -0700122 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
125 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // proofread file contains all of the text content of the javadocs concatenated into one file,
129 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700130 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800131
132 // a todo file lists the program elements that are missing documentation.
133 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800134 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800135
136 // directory under current module source that provide additional resources (images).
137 Resourcesdir *string
138
139 // resources output directory under out/soong/.intermediates.
140 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800141
Nan Zhange2ba5d42018-07-11 15:16:55 -0700142 // if set to true, collect the values used by the Dev tools and
143 // write them in files packaged with the SDK. Defaults to false.
144 Write_sdk_values *bool
145
146 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800147 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700148
149 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800150 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700151
Nan Zhang581fd212018-01-10 16:06:12 -0800152 // a list of files under current module source dir which contains known tags in Java sources.
153 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800154 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700155
156 // the tag name used to distinguish if the API files belong to public/system/test.
157 Api_tag_name *string
158
159 // the generated public API filename by Doclava.
160 Api_filename *string
161
David Brazdilfbe4cc32018-05-31 13:56:46 +0100162 // the generated public Dex API filename by Doclava.
163 Dex_api_filename *string
164
Nan Zhang28c68b92018-03-13 16:17:01 -0700165 // the generated private API filename by Doclava.
166 Private_api_filename *string
167
168 // the generated private Dex API filename by Doclava.
169 Private_dex_api_filename *string
170
171 // the generated removed API filename by Doclava.
172 Removed_api_filename *string
173
David Brazdilaac0c3c2018-04-24 16:23:29 +0100174 // the generated removed Dex API filename by Doclava.
175 Removed_dex_api_filename *string
176
Mathew Inwood76c3de12018-06-22 15:28:11 +0100177 // mapping of dex signatures to source file and line number. This is a temporary property and
178 // will be deleted; you probably shouldn't be using it.
179 Dex_mapping_filename *string
180
Nan Zhang28c68b92018-03-13 16:17:01 -0700181 // the generated exact API filename by Doclava.
182 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700183
Nan Zhang66dc2362018-08-14 20:41:04 -0700184 // the generated proguard filename by Doclava.
185 Proguard_filename *string
186
Nan Zhang853f4202018-04-12 16:55:56 -0700187 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
188 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700189
190 Check_api struct {
191 Last_released ApiToCheck
192
193 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900194
195 // do not perform API check against Last_released, in the case that both two specified API
196 // files by Last_released are modules which don't exist.
197 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700198 }
Nan Zhang79614d12018-04-19 18:03:39 -0700199
Nan Zhang1598a9e2018-09-04 17:14:32 -0700200 // if set to true, generate docs through Dokka instead of Doclava.
201 Dokka_enabled *bool
202}
203
204type DroidstubsProperties struct {
205 // the tag name used to distinguish if the API files belong to public/system/test.
206 Api_tag_name *string
207
Nan Zhang199645c2018-09-19 12:40:06 -0700208 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Api_filename *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Dex_api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Private_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Private_dex_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Removed_api_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Removed_dex_api_filename *string
225
Nan Zhang9c69a122018-08-22 10:22:08 -0700226 // mapping of dex signatures to source file and line number. This is a temporary property and
227 // will be deleted; you probably shouldn't be using it.
228 Dex_mapping_filename *string
229
Nan Zhang199645c2018-09-19 12:40:06 -0700230 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700231 Exact_api_filename *string
232
Nan Zhang199645c2018-09-19 12:40:06 -0700233 // the generated proguard filename by Metalava.
234 Proguard_filename *string
235
Nan Zhang1598a9e2018-09-04 17:14:32 -0700236 Check_api struct {
237 Last_released ApiToCheck
238
239 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900240
241 // do not perform API check against Last_released, in the case that both two specified API
242 // files by Last_released are modules which don't exist.
243 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700244 }
Nan Zhang79614d12018-04-19 18:03:39 -0700245
246 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800247 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700248
249 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700250 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700251
Pete Gillin77167902018-09-19 18:16:26 +0100252 // 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 -0700253 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700254
Pete Gillin77167902018-09-19 18:16:26 +0100255 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
256 Merge_inclusion_annotations_dirs []string
257
Pete Gillinc382a562018-11-14 18:45:46 +0000258 // a file containing a list of classes to do nullability validation for.
259 Validate_nullability_from_list *string
260
Pete Gillin581d6082018-10-22 15:55:04 +0100261 // a file containing expected warnings produced by validation of nullability annotations.
262 Check_nullability_warnings *string
263
Nan Zhang1598a9e2018-09-04 17:14:32 -0700264 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
265 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700266
267 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
268 Api_levels_annotations_enabled *bool
269
270 // the dirs which Metalava extracts API levels annotations from.
271 Api_levels_annotations_dirs []string
272
273 // if set to true, collect the values used by the Dev tools and
274 // write them in files packaged with the SDK. Defaults to false.
275 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700276
277 // If set to true, .xml based public API file will be also generated, and
278 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
279 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800280}
281
Nan Zhanga40da042018-08-01 12:48:00 -0700282//
283// Common flags passed down to build rule
284//
285type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700286 bootClasspathArgs string
287 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700288 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700289 dokkaClasspathArgs string
290 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700291 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700292
Nan Zhanga40da042018-08-01 12:48:00 -0700293 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700294 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700295 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700296}
297
298func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
299 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
300 android.InitDefaultableModule(module)
301}
302
Nan Zhang1598a9e2018-09-04 17:14:32 -0700303func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
304 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
305 return true
306 } else if String(apiToCheck.Api_file) != "" {
307 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
308 } else if String(apiToCheck.Removed_api_file) != "" {
309 panic("for " + apiVersionTag + " api_file has to be non-empty!")
310 }
311
312 return false
313}
314
Inseob Kim38449af2019-02-28 14:24:05 +0900315func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
316 api_file := String(apiToCheck.Api_file)
317 removed_api_file := String(apiToCheck.Removed_api_file)
318
319 api_module := android.SrcIsModule(api_file)
320 removed_api_module := android.SrcIsModule(removed_api_file)
321
322 if api_module == "" || removed_api_module == "" {
323 return
324 }
325
326 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
327 return
328 }
329
330 apiToCheck.Api_file = nil
331 apiToCheck.Removed_api_file = nil
332}
333
Nan Zhang1598a9e2018-09-04 17:14:32 -0700334type ApiFilePath interface {
335 ApiFilePath() android.Path
336}
337
Nan Zhanga40da042018-08-01 12:48:00 -0700338//
339// Javadoc
340//
Nan Zhang581fd212018-01-10 16:06:12 -0800341type Javadoc struct {
342 android.ModuleBase
343 android.DefaultableModuleBase
344
345 properties JavadocProperties
346
347 srcJars android.Paths
348 srcFiles android.Paths
349 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700350 argFiles android.Paths
351
352 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800353
Nan Zhangccff0f72018-03-08 17:26:16 -0800354 docZip android.WritablePath
355 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800356}
357
Colin Cross41955e82019-05-29 14:40:35 -0700358func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
359 switch tag {
360 case "":
361 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700362 case ".docs.zip":
363 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700364 default:
365 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
366 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800367}
368
Colin Crossa3002fc2019-07-08 16:48:04 -0700369// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800370func JavadocFactory() android.Module {
371 module := &Javadoc{}
372
373 module.AddProperties(&module.properties)
374
375 InitDroiddocModule(module, android.HostAndDeviceSupported)
376 return module
377}
378
Colin Crossa3002fc2019-07-08 16:48:04 -0700379// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800380func JavadocHostFactory() android.Module {
381 module := &Javadoc{}
382
383 module.AddProperties(&module.properties)
384
385 InitDroiddocModule(module, android.HostSupported)
386 return module
387}
388
Colin Cross41955e82019-05-29 14:40:35 -0700389var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800390
Colin Cross83bb3162018-06-25 15:48:06 -0700391func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900392 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700393}
394
395func (j *Javadoc) minSdkVersion() string {
396 return j.sdkVersion()
397}
398
Dan Willemsen419290a2018-10-31 15:28:47 -0700399func (j *Javadoc) targetSdkVersion() string {
400 return j.sdkVersion()
401}
402
Nan Zhang581fd212018-01-10 16:06:12 -0800403func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
404 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100405 sdkDep := decodeSdkDep(ctx, sdkContext(j))
406 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700407 if sdkDep.useDefaultLibs {
408 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
409 if ctx.Config().TargetOpenJDK9() {
410 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
411 }
Paul Duffin250e6192019-06-07 10:44:37 +0100412 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700413 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
414 }
415 } else if sdkDep.useModule {
416 if ctx.Config().TargetOpenJDK9() {
417 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
418 }
419 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700420 }
Nan Zhang581fd212018-01-10 16:06:12 -0800421 }
422 }
423
Colin Cross42d48b72018-08-29 14:10:52 -0700424 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700425 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700426 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700427 }
Nan Zhang581fd212018-01-10 16:06:12 -0800428}
429
Nan Zhangb2b33de2018-02-23 11:18:47 -0800430func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
431 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
432 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900433 // convert foo.bar.baz to foo/bar/baz
434 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
435 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800436 if _, found := whitelistPathPrefixes[prefix]; !found {
437 whitelistPathPrefixes[prefix] = true
438 }
439 }
440 }
441}
442
Nan Zhanga40da042018-08-01 12:48:00 -0700443func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
444 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900445
Colin Cross3047fa22019-04-18 10:56:44 -0700446 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900447
448 return flags
449}
450
451func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700452 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900453
454 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
455 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
456
457 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700458 var deps android.Paths
459
Jiyong Park1e440682018-05-23 18:42:04 +0900460 if aidlPreprocess.Valid() {
461 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700462 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900463 } else {
464 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
465 }
466
467 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
468 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
469 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
470 flags = append(flags, "-I"+src.String())
471 }
472
Colin Cross3047fa22019-04-18 10:56:44 -0700473 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900474}
475
476func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700477 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900478
479 outSrcFiles := make(android.Paths, 0, len(srcFiles))
480
481 for _, srcFile := range srcFiles {
482 switch srcFile.Ext() {
483 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700484 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900485 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900486 case ".sysprop":
487 javaFile := genSysprop(ctx, srcFile)
488 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900489 default:
490 outSrcFiles = append(outSrcFiles, srcFile)
491 }
492 }
493
494 return outSrcFiles
495}
496
Nan Zhang581fd212018-01-10 16:06:12 -0800497func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
498 var deps deps
499
Colin Cross83bb3162018-06-25 15:48:06 -0700500 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800501 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700502 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800503 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700504 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800505 }
506
507 ctx.VisitDirectDeps(func(module android.Module) {
508 otherName := ctx.OtherModuleName(module)
509 tag := ctx.OtherModuleDependencyTag(module)
510
Colin Cross2d24c1b2018-05-23 10:59:18 -0700511 switch tag {
512 case bootClasspathTag:
513 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800514 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700515 } else {
516 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
517 }
518 case libTag:
519 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800520 case SdkLibraryDependency:
521 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700522 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900523 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900524 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700525 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800526 checkProducesJars(ctx, dep)
527 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800528 default:
529 ctx.ModuleErrorf("depends on non-java module %q", otherName)
530 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700531 case srcsLibTag:
532 switch dep := module.(type) {
533 case Dependency:
534 srcs := dep.(SrcDependency).CompiledSrcs()
535 whitelistPathPrefixes := make(map[string]bool)
536 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
537 for _, src := range srcs {
538 if _, ok := src.(android.WritablePath); ok { // generated sources
539 deps.srcs = append(deps.srcs, src)
540 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700541 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700542 if strings.HasPrefix(src.Rel(), k) {
543 deps.srcs = append(deps.srcs, src)
544 break
545 }
546 }
547 }
548 }
549 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
550 default:
551 ctx.ModuleErrorf("depends on non-java module %q", otherName)
552 }
Nan Zhang357466b2018-04-17 17:38:36 -0700553 case systemModulesTag:
554 if deps.systemModules != nil {
555 panic("Found two system module dependencies")
556 }
557 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000558 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700559 panic("Missing directory for system module dependency")
560 }
Colin Crossb77043e2019-07-16 13:57:13 -0700561 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800562 }
563 })
564 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
565 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800566 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700567 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900568 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800569
570 // srcs may depend on some genrule output.
571 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800572 j.srcJars = append(j.srcJars, deps.srcJars...)
573
Nan Zhang581fd212018-01-10 16:06:12 -0800574 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800575 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800576
Nan Zhang9c69a122018-08-22 10:22:08 -0700577 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800578 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
579 }
580 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800581
Colin Cross8a497952019-03-05 22:25:09 -0800582 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000583 argFilesMap := map[string]string{}
584 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700585
Paul Duffin99e4a502019-02-11 15:38:42 +0000586 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800587 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000588 if _, exists := argFilesMap[label]; !exists {
589 argFilesMap[label] = strings.Join(paths.Strings(), " ")
590 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700591 } else {
592 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000593 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700594 }
595 }
596
597 var err error
Colin Cross15638152019-07-11 11:11:35 -0700598 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700599 if strings.HasPrefix(name, "location ") {
600 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000601 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700602 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700603 } else {
Colin Cross15638152019-07-11 11:11:35 -0700604 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000605 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700606 }
607 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700608 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700609 }
Colin Cross15638152019-07-11 11:11:35 -0700610 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700611 })
612
613 if err != nil {
614 ctx.PropertyErrorf("args", "%s", err.Error())
615 }
616
Nan Zhang581fd212018-01-10 16:06:12 -0800617 return deps
618}
619
620func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
621 j.addDeps(ctx)
622}
623
624func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
625 deps := j.collectDeps(ctx)
626
Colin Crossdaa4c672019-07-15 22:53:46 -0700627 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800628
Colin Crossdaa4c672019-07-15 22:53:46 -0700629 outDir := android.PathForModuleOut(ctx, "out")
630 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
631
632 j.stubsSrcJar = nil
633
634 rule := android.NewRuleBuilder()
635
636 rule.Command().Text("rm -rf").Text(outDir.String())
637 rule.Command().Text("mkdir -p").Text(outDir.String())
638
639 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700640
Colin Cross83bb3162018-06-25 15:48:06 -0700641 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800642
Colin Crossdaa4c672019-07-15 22:53:46 -0700643 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
644 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800645
Colin Crossdaa4c672019-07-15 22:53:46 -0700646 cmd.FlagWithArg("-source ", javaVersion).
647 Flag("-J-Xmx1024m").
648 Flag("-XDignore.symbol.file").
649 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800650
Colin Crossdaa4c672019-07-15 22:53:46 -0700651 rule.Command().
652 BuiltTool(ctx, "soong_zip").
653 Flag("-write_if_changed").
654 Flag("-d").
655 FlagWithOutput("-o ", j.docZip).
656 FlagWithArg("-C ", outDir.String()).
657 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700658
Colin Crossdaa4c672019-07-15 22:53:46 -0700659 rule.Restat()
660
661 zipSyncCleanupCmd(rule, srcJarDir)
662
663 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800664}
665
Nan Zhanga40da042018-08-01 12:48:00 -0700666//
667// Droiddoc
668//
669type Droiddoc struct {
670 Javadoc
671
672 properties DroiddocProperties
673 apiFile android.WritablePath
674 dexApiFile android.WritablePath
675 privateApiFile android.WritablePath
676 privateDexApiFile android.WritablePath
677 removedApiFile android.WritablePath
678 removedDexApiFile android.WritablePath
679 exactApiFile android.WritablePath
680 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700681 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700682
683 checkCurrentApiTimestamp android.WritablePath
684 updateCurrentApiTimestamp android.WritablePath
685 checkLastReleasedApiTimestamp android.WritablePath
686
Nan Zhanga40da042018-08-01 12:48:00 -0700687 apiFilePath android.Path
688}
689
Colin Crossa3002fc2019-07-08 16:48:04 -0700690// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700691func DroiddocFactory() android.Module {
692 module := &Droiddoc{}
693
694 module.AddProperties(&module.properties,
695 &module.Javadoc.properties)
696
697 InitDroiddocModule(module, android.HostAndDeviceSupported)
698 return module
699}
700
Colin Crossa3002fc2019-07-08 16:48:04 -0700701// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700702func DroiddocHostFactory() android.Module {
703 module := &Droiddoc{}
704
705 module.AddProperties(&module.properties,
706 &module.Javadoc.properties)
707
708 InitDroiddocModule(module, android.HostSupported)
709 return module
710}
711
712func (d *Droiddoc) ApiFilePath() android.Path {
713 return d.apiFilePath
714}
715
Nan Zhang581fd212018-01-10 16:06:12 -0800716func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
717 d.Javadoc.addDeps(ctx)
718
Inseob Kim38449af2019-02-28 14:24:05 +0900719 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
720 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
721 }
722
Nan Zhang79614d12018-04-19 18:03:39 -0700723 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800724 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
725 }
Nan Zhang581fd212018-01-10 16:06:12 -0800726}
727
Colin Crossab054432019-07-15 16:13:59 -0700728func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700729 var date string
730 if runtime.GOOS == "darwin" {
731 date = `date -r`
732 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700733 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700734 }
735
Nan Zhang443fa522018-08-20 20:58:28 -0700736 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
737 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
738 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700739 cmd.FlagWithArg("-source ", "1.8").
740 Flag("-J-Xmx1600m").
741 Flag("-J-XX:-OmitStackTraceInFastThrow").
742 Flag("-XDignore.symbol.file").
743 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
744 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
745 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700746 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700747
Nan Zhanga40da042018-08-01 12:48:00 -0700748 if String(d.properties.Custom_template) == "" {
749 // TODO: This is almost always droiddoc-templates-sdk
750 ctx.PropertyErrorf("custom_template", "must specify a template")
751 }
752
753 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700754 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700755 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700756 } else {
757 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
758 }
759 })
760
761 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700762 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
763 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
764 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700765 }
766
767 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700768 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
769 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
770 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700771 }
772
773 if len(d.properties.Html_dirs) > 2 {
774 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
775 }
776
Colin Cross8a497952019-03-05 22:25:09 -0800777 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700778 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700779
Colin Crossab054432019-07-15 16:13:59 -0700780 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700781
782 if String(d.properties.Proofread_file) != "" {
783 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700784 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700785 }
786
787 if String(d.properties.Todo_file) != "" {
788 // tricky part:
789 // we should not compute full path for todo_file through PathForModuleOut().
790 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700791 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
792 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700793 }
794
795 if String(d.properties.Resourcesdir) != "" {
796 // TODO: should we add files under resourcesDir to the implicits? It seems that
797 // resourcesDir is one sub dir of htmlDir
798 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700799 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700800 }
801
802 if String(d.properties.Resourcesoutdir) != "" {
803 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700804 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700805 }
Nan Zhanga40da042018-08-01 12:48:00 -0700806}
807
Colin Crossab054432019-07-15 16:13:59 -0700808func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700809 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
810 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
811 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700812
Nan Zhanga40da042018-08-01 12:48:00 -0700813 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700814 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700815 d.apiFilePath = d.apiFile
816 }
817
Nan Zhang1598a9e2018-09-04 17:14:32 -0700818 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
819 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
820 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700821 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700822 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700823 }
824
825 if String(d.properties.Private_api_filename) != "" {
826 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700827 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700828 }
829
830 if String(d.properties.Dex_api_filename) != "" {
831 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700833 }
834
835 if String(d.properties.Private_dex_api_filename) != "" {
836 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700837 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700838 }
839
840 if String(d.properties.Removed_dex_api_filename) != "" {
841 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700842 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700843 }
844
845 if String(d.properties.Exact_api_filename) != "" {
846 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700847 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700848 }
849
850 if String(d.properties.Dex_mapping_filename) != "" {
851 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700852 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700853 }
854
Nan Zhang66dc2362018-08-14 20:41:04 -0700855 if String(d.properties.Proguard_filename) != "" {
856 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700857 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700858 }
859
Nan Zhanga40da042018-08-01 12:48:00 -0700860 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700861 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700862 }
863
864 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700865 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700866 }
Nan Zhanga40da042018-08-01 12:48:00 -0700867}
868
Colin Crossab054432019-07-15 16:13:59 -0700869func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700870 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700871 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
872 rule.Command().Text("cp").
873 Input(staticDocIndexRedirect).
874 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700875 }
876
877 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700878 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
879 rule.Command().Text("cp").
880 Input(staticDocProperties).
881 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700882 }
Nan Zhanga40da042018-08-01 12:48:00 -0700883}
884
Colin Crossab054432019-07-15 16:13:59 -0700885func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700886 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700887
888 cmd := rule.Command().
889 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
890 Flag(config.JavacVmFlags).
891 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700892 FlagWithRspFileInputList("@", srcs).
893 FlagWithInput("@", srcJarList)
894
Colin Crossab054432019-07-15 16:13:59 -0700895 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
896 // based stubs generation.
897 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
898 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
899 // the correct package name base path.
900 if len(sourcepaths) > 0 {
901 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
902 } else {
903 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
904 }
905
906 cmd.FlagWithArg("-d ", outDir.String()).
907 Flag("-quiet")
908
909 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700910}
911
Colin Crossdaa4c672019-07-15 22:53:46 -0700912func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
913 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
914 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
915
916 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
917
918 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
919 cmd.Flag(flag).Implicits(deps)
920
921 cmd.FlagWithArg("--patch-module ", "java.base=.")
922
923 if len(classpath) > 0 {
924 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
925 }
926
927 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700928}
929
Colin Crossdaa4c672019-07-15 22:53:46 -0700930func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
931 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
932 sourcepaths android.Paths) *android.RuleBuilderCommand {
933
934 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
935
936 if len(bootclasspath) == 0 && ctx.Device() {
937 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
938 // ensure java does not fall back to the default bootclasspath.
939 cmd.FlagWithArg("-bootclasspath ", `""`)
940 } else if len(bootclasspath) > 0 {
941 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
942 }
943
944 if len(classpath) > 0 {
945 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
946 }
947
948 return cmd
949}
950
Colin Crossab054432019-07-15 16:13:59 -0700951func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
952 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700953
Colin Crossab054432019-07-15 16:13:59 -0700954 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
955 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
956
957 return rule.Command().
958 BuiltTool(ctx, "dokka").
959 Flag(config.JavacVmFlags).
960 Flag(srcJarDir.String()).
961 FlagWithInputList("-classpath ", dokkaClasspath, ":").
962 FlagWithArg("-format ", "dac").
963 FlagWithArg("-dacRoot ", "/reference/kotlin").
964 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700965}
966
967func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
968 deps := d.Javadoc.collectDeps(ctx)
969
Colin Crossdaa4c672019-07-15 22:53:46 -0700970 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
971 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
972
Nan Zhang1598a9e2018-09-04 17:14:32 -0700973 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
974 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
975 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
976 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
977
Colin Crossab054432019-07-15 16:13:59 -0700978 outDir := android.PathForModuleOut(ctx, "out")
979 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
980 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700981
Colin Crossab054432019-07-15 16:13:59 -0700982 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700983
Colin Crossab054432019-07-15 16:13:59 -0700984 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
985 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700986
Colin Crossab054432019-07-15 16:13:59 -0700987 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
988
989 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700990 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700991 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700992 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700993 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700994 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995 }
996
Colin Crossab054432019-07-15 16:13:59 -0700997 d.stubsFlags(ctx, cmd, stubsDir)
998
999 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1000
1001 var desc string
1002 if Bool(d.properties.Dokka_enabled) {
1003 desc = "dokka"
1004 } else {
1005 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1006
1007 for _, o := range d.Javadoc.properties.Out {
1008 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1009 }
1010
1011 d.postDoclavaCmds(ctx, rule)
1012 desc = "doclava"
1013 }
1014
1015 rule.Command().
1016 BuiltTool(ctx, "soong_zip").
1017 Flag("-write_if_changed").
1018 Flag("-d").
1019 FlagWithOutput("-o ", d.docZip).
1020 FlagWithArg("-C ", outDir.String()).
1021 FlagWithArg("-D ", outDir.String())
1022
1023 rule.Command().
1024 BuiltTool(ctx, "soong_zip").
1025 Flag("-write_if_changed").
1026 Flag("-jar").
1027 FlagWithOutput("-o ", d.stubsSrcJar).
1028 FlagWithArg("-C ", stubsDir.String()).
1029 FlagWithArg("-D ", stubsDir.String())
1030
1031 rule.Restat()
1032
1033 zipSyncCleanupCmd(rule, srcJarDir)
1034
1035 rule.Build(pctx, ctx, "javadoc", desc)
1036
Nan Zhang1598a9e2018-09-04 17:14:32 -07001037 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1038 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001039
1040 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1041 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001042
1043 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001044
1045 rule := android.NewRuleBuilder()
1046
1047 rule.Command().Text("( true")
1048
1049 rule.Command().
1050 BuiltTool(ctx, "apicheck").
1051 Flag("-JXmx1024m").
1052 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1053 OptionalFlag(d.properties.Check_api.Current.Args).
1054 Input(apiFile).
1055 Input(d.apiFile).
1056 Input(removedApiFile).
1057 Input(d.removedApiFile)
1058
1059 msg := fmt.Sprintf(`\n******************************\n`+
1060 `You have tried to change the API from what has been previously approved.\n\n`+
1061 `To make these errors go away, you have two choices:\n`+
1062 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1063 ` errors above.\n\n`+
1064 ` 2. You can update current.txt by executing the following command:\n`+
1065 ` make %s-update-current-api\n\n`+
1066 ` To submit the revised current.txt to the main Android repository,\n`+
1067 ` you will need approval.\n`+
1068 `******************************\n`, ctx.ModuleName())
1069
1070 rule.Command().
1071 Text("touch").Output(d.checkCurrentApiTimestamp).
1072 Text(") || (").
1073 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1074 Text("; exit 38").
1075 Text(")")
1076
1077 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001078
1079 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001080
1081 // update API rule
1082 rule = android.NewRuleBuilder()
1083
1084 rule.Command().Text("( true")
1085
1086 rule.Command().
1087 Text("cp").Flag("-f").
1088 Input(d.apiFile).Flag(apiFile.String())
1089
1090 rule.Command().
1091 Text("cp").Flag("-f").
1092 Input(d.removedApiFile).Flag(removedApiFile.String())
1093
1094 msg = "failed to update public API"
1095
1096 rule.Command().
1097 Text("touch").Output(d.updateCurrentApiTimestamp).
1098 Text(") || (").
1099 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1100 Text("; exit 38").
1101 Text(")")
1102
1103 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001104 }
1105
1106 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1107 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001108
1109 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1110 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001111
1112 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001113
1114 rule := android.NewRuleBuilder()
1115
1116 rule.Command().
1117 Text("(").
1118 BuiltTool(ctx, "apicheck").
1119 Flag("-JXmx1024m").
1120 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1121 OptionalFlag(d.properties.Check_api.Last_released.Args).
1122 Input(apiFile).
1123 Input(d.apiFile).
1124 Input(removedApiFile).
1125 Input(d.removedApiFile)
1126
1127 msg := `\n******************************\n` +
1128 `You have tried to change the API from what has been previously released in\n` +
1129 `an SDK. Please fix the errors listed above.\n` +
1130 `******************************\n`
1131
1132 rule.Command().
1133 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1134 Text(") || (").
1135 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1136 Text("; exit 38").
1137 Text(")")
1138
1139 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001140 }
1141}
1142
1143//
1144// Droidstubs
1145//
1146type Droidstubs struct {
1147 Javadoc
1148
Pete Gillin581d6082018-10-22 15:55:04 +01001149 properties DroidstubsProperties
1150 apiFile android.WritablePath
1151 apiXmlFile android.WritablePath
1152 lastReleasedApiXmlFile android.WritablePath
1153 dexApiFile android.WritablePath
1154 privateApiFile android.WritablePath
1155 privateDexApiFile android.WritablePath
1156 removedApiFile android.WritablePath
1157 removedDexApiFile android.WritablePath
1158 apiMappingFile android.WritablePath
1159 exactApiFile android.WritablePath
1160 proguardFile android.WritablePath
1161 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001162
1163 checkCurrentApiTimestamp android.WritablePath
1164 updateCurrentApiTimestamp android.WritablePath
1165 checkLastReleasedApiTimestamp android.WritablePath
1166
Pete Gillin581d6082018-10-22 15:55:04 +01001167 checkNullabilityWarningsTimestamp android.WritablePath
1168
Nan Zhang1598a9e2018-09-04 17:14:32 -07001169 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001170 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001171
1172 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001173
1174 jdiffDocZip android.WritablePath
1175 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001176}
1177
Colin Crossa3002fc2019-07-08 16:48:04 -07001178// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1179// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1180// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001181func DroidstubsFactory() android.Module {
1182 module := &Droidstubs{}
1183
1184 module.AddProperties(&module.properties,
1185 &module.Javadoc.properties)
1186
1187 InitDroiddocModule(module, android.HostAndDeviceSupported)
1188 return module
1189}
1190
Colin Crossa3002fc2019-07-08 16:48:04 -07001191// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1192// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1193// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1194// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001195func DroidstubsHostFactory() android.Module {
1196 module := &Droidstubs{}
1197
1198 module.AddProperties(&module.properties,
1199 &module.Javadoc.properties)
1200
1201 InitDroiddocModule(module, android.HostSupported)
1202 return module
1203}
1204
1205func (d *Droidstubs) ApiFilePath() android.Path {
1206 return d.apiFilePath
1207}
1208
1209func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1210 d.Javadoc.addDeps(ctx)
1211
Inseob Kim38449af2019-02-28 14:24:05 +09001212 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1213 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1214 }
1215
Nan Zhang1598a9e2018-09-04 17:14:32 -07001216 if len(d.properties.Merge_annotations_dirs) != 0 {
1217 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1218 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1219 }
1220 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001221
Pete Gillin77167902018-09-19 18:16:26 +01001222 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1223 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1224 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1225 }
1226 }
1227
Nan Zhang9c69a122018-08-22 10:22:08 -07001228 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1229 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1230 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1231 }
1232 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001233}
1234
Colin Cross33961b52019-07-11 11:01:22 -07001235func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001236 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1237 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1238 String(d.properties.Api_filename) != "" {
1239 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001240 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001241 d.apiFilePath = d.apiFile
1242 }
1243
1244 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1245 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1246 String(d.properties.Removed_api_filename) != "" {
1247 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001248 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001249 }
1250
1251 if String(d.properties.Private_api_filename) != "" {
1252 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001253 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254 }
1255
1256 if String(d.properties.Dex_api_filename) != "" {
1257 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001258 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 }
1260
1261 if String(d.properties.Private_dex_api_filename) != "" {
1262 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001263 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264 }
1265
1266 if String(d.properties.Removed_dex_api_filename) != "" {
1267 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001268 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001269 }
1270
1271 if String(d.properties.Exact_api_filename) != "" {
1272 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001273 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001274 }
1275
Nan Zhang9c69a122018-08-22 10:22:08 -07001276 if String(d.properties.Dex_mapping_filename) != "" {
1277 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001278 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001279 }
1280
Nan Zhang199645c2018-09-19 12:40:06 -07001281 if String(d.properties.Proguard_filename) != "" {
1282 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001283 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001284 }
1285
Nan Zhang9c69a122018-08-22 10:22:08 -07001286 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001287 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001288 }
1289
Nan Zhang1598a9e2018-09-04 17:14:32 -07001290 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001291 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001293 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001294 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295}
1296
Colin Cross33961b52019-07-11 11:01:22 -07001297func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001298 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001299 cmd.Flag("--include-annotations")
1300
Pete Gillinc382a562018-11-14 18:45:46 +00001301 validatingNullability :=
1302 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1303 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001304 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001305
Pete Gillina262c052018-09-14 14:25:48 +01001306 if !(migratingNullability || validatingNullability) {
1307 ctx.PropertyErrorf("previous_api",
1308 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001309 }
Colin Cross33961b52019-07-11 11:01:22 -07001310
Pete Gillina262c052018-09-14 14:25:48 +01001311 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001312 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001313 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001314 }
Colin Cross33961b52019-07-11 11:01:22 -07001315
Pete Gillinc382a562018-11-14 18:45:46 +00001316 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001317 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001318 }
Colin Cross33961b52019-07-11 11:01:22 -07001319
Pete Gillina262c052018-09-14 14:25:48 +01001320 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001321 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001322 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001323 }
Nan Zhanga40da042018-08-01 12:48:00 -07001324
1325 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001326 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001327
Nan Zhang1598a9e2018-09-04 17:14:32 -07001328 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001329 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001330 "has to be non-empty if annotations was enabled!")
1331 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001332
Colin Cross33961b52019-07-11 11:01:22 -07001333 d.mergeAnnoDirFlags(ctx, cmd)
1334
1335 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1336 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1337 FlagWithArg("--hide ", "SuperfluousPrefix").
1338 FlagWithArg("--hide ", "AnnotationExtraction")
1339 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001340}
1341
Colin Cross33961b52019-07-11 11:01:22 -07001342func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1343 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1344 if t, ok := m.(*ExportedDroiddocDir); ok {
1345 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1346 } else {
1347 ctx.PropertyErrorf("merge_annotations_dirs",
1348 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1349 }
1350 })
1351}
1352
1353func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001354 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1355 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001356 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001357 } else {
1358 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1359 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1360 }
1361 })
Nan Zhanga40da042018-08-01 12:48:00 -07001362}
1363
Colin Cross33961b52019-07-11 11:01:22 -07001364func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001365 if Bool(d.properties.Api_levels_annotations_enabled) {
1366 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001367
1368 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1369 ctx.PropertyErrorf("api_levels_annotations_dirs",
1370 "has to be non-empty if api levels annotations was enabled!")
1371 }
1372
Colin Cross33961b52019-07-11 11:01:22 -07001373 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1374 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1375 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1376 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001377
1378 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1379 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001380 for _, dep := range t.deps {
1381 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001382 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001383 }
1384 }
Colin Cross33961b52019-07-11 11:01:22 -07001385 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001386 } else {
1387 ctx.PropertyErrorf("api_levels_annotations_dirs",
1388 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1389 }
1390 })
1391
1392 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001393}
1394
Colin Cross33961b52019-07-11 11:01:22 -07001395func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001396 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1397 if d.apiFile.String() == "" {
1398 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1399 }
1400
1401 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001402 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001403
1404 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1405 ctx.PropertyErrorf("check_api.last_released.api_file",
1406 "has to be non-empty if jdiff was enabled!")
1407 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001408
Colin Cross33961b52019-07-11 11:01:22 -07001409 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001410 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001411 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1412 }
1413}
Nan Zhang71bbe632018-09-17 14:32:21 -07001414
Colin Cross33961b52019-07-11 11:01:22 -07001415func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1416 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1417 cmd := rule.Command().BuiltTool(ctx, "metalava").
1418 Flag(config.JavacVmFlags).
1419 FlagWithArg("-encoding ", "UTF-8").
1420 FlagWithArg("-source ", javaVersion).
1421 FlagWithRspFileInputList("@", srcs).
1422 FlagWithInput("@", srcJarList)
1423
1424 if len(bootclasspath) > 0 {
1425 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001426 }
1427
Colin Cross33961b52019-07-11 11:01:22 -07001428 if len(classpath) > 0 {
1429 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1430 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001431
Colin Cross33961b52019-07-11 11:01:22 -07001432 if len(sourcepaths) > 0 {
1433 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1434 } else {
1435 cmd.FlagWithArg("-sourcepath ", `""`)
1436 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001437
Colin Cross33961b52019-07-11 11:01:22 -07001438 cmd.Flag("--no-banner").
1439 Flag("--color").
1440 Flag("--quiet").
1441 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001442
Colin Cross33961b52019-07-11 11:01:22 -07001443 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001444}
1445
Nan Zhang1598a9e2018-09-04 17:14:32 -07001446func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001447 deps := d.Javadoc.collectDeps(ctx)
1448
1449 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001450
Colin Cross33961b52019-07-11 11:01:22 -07001451 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001452
Colin Crossdaa4c672019-07-15 22:53:46 -07001453 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001454
Colin Cross33961b52019-07-11 11:01:22 -07001455 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1456 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001457
Colin Cross33961b52019-07-11 11:01:22 -07001458 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 rule.Command().Text("rm -rf").Text(stubsDir.String())
1461 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001462
Colin Cross33961b52019-07-11 11:01:22 -07001463 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1464
1465 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1466 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1467
1468 d.stubsFlags(ctx, cmd, stubsDir)
1469
1470 d.annotationsFlags(ctx, cmd)
1471 d.inclusionAnnotationsFlags(ctx, cmd)
1472 d.apiLevelsAnnotationsFlags(ctx, cmd)
1473 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001474
Nan Zhang1598a9e2018-09-04 17:14:32 -07001475 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1476 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1477 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1478 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1479 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001480 }
Colin Cross33961b52019-07-11 11:01:22 -07001481
1482 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1483 for _, o := range d.Javadoc.properties.Out {
1484 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1485 }
1486
1487 rule.Command().
1488 BuiltTool(ctx, "soong_zip").
1489 Flag("-write_if_changed").
1490 Flag("-jar").
1491 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1492 FlagWithArg("-C ", stubsDir.String()).
1493 FlagWithArg("-D ", stubsDir.String())
1494 rule.Restat()
1495
1496 zipSyncCleanupCmd(rule, srcJarDir)
1497
1498 rule.Build(pctx, ctx, "metalava", "metalava")
1499
1500 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001501
Nan Zhang1598a9e2018-09-04 17:14:32 -07001502 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1503 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001504
1505 if len(d.Javadoc.properties.Out) > 0 {
1506 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1507 }
1508
1509 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1510 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001511
Nan Zhang2760dfc2018-08-24 17:32:54 +00001512 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001513
Colin Cross33961b52019-07-11 11:01:22 -07001514 rule := android.NewRuleBuilder()
1515
1516 rule.Command().Text("( true")
1517
1518 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1519 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1520
1521 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1522 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1523
1524 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1525 FlagWithInput("--check-compatibility:api:current ", apiFile).
1526 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1527
1528 d.inclusionAnnotationsFlags(ctx, cmd)
1529 d.mergeAnnoDirFlags(ctx, cmd)
1530
1531 zipSyncCleanupCmd(rule, srcJarDir)
1532
1533 msg := fmt.Sprintf(`\n******************************\n`+
1534 `You have tried to change the API from what has been previously approved.\n\n`+
1535 `To make these errors go away, you have two choices:\n`+
1536 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1537 ` errors above.\n\n`+
1538 ` 2. You can update current.txt by executing the following command:\n`+
1539 ` make %s-update-current-api\n\n`+
1540 ` To submit the revised current.txt to the main Android repository,\n`+
1541 ` you will need approval.\n`+
1542 `******************************\n`, ctx.ModuleName())
1543
1544 rule.Command().
1545 Text("touch").Output(d.checkCurrentApiTimestamp).
1546 Text(") || (").
1547 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1548 Text("; exit 38").
1549 Text(")")
1550
1551 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001552
1553 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001554
1555 // update API rule
1556 rule = android.NewRuleBuilder()
1557
1558 rule.Command().Text("( true")
1559
1560 rule.Command().
1561 Text("cp").Flag("-f").
1562 Input(d.apiFile).Flag(apiFile.String())
1563
1564 rule.Command().
1565 Text("cp").Flag("-f").
1566 Input(d.removedApiFile).Flag(removedApiFile.String())
1567
1568 msg = "failed to update public API"
1569
1570 rule.Command().
1571 Text("touch").Output(d.updateCurrentApiTimestamp).
1572 Text(") || (").
1573 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1574 Text("; exit 38").
1575 Text(")")
1576
1577 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001578 }
Nan Zhanga40da042018-08-01 12:48:00 -07001579
Nan Zhang1598a9e2018-09-04 17:14:32 -07001580 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1581 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001582
1583 if len(d.Javadoc.properties.Out) > 0 {
1584 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1585 }
1586
1587 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1588 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001589
Nan Zhang2760dfc2018-08-24 17:32:54 +00001590 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001591
Colin Cross33961b52019-07-11 11:01:22 -07001592 rule := android.NewRuleBuilder()
1593
1594 rule.Command().Text("( true")
1595
1596 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1597 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1598
1599 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1600 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1601
1602 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1603 FlagWithInput("--check-compatibility:api:released ", apiFile)
1604
1605 d.inclusionAnnotationsFlags(ctx, cmd)
1606
1607 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1608
1609 d.mergeAnnoDirFlags(ctx, cmd)
1610
1611 zipSyncCleanupCmd(rule, srcJarDir)
1612
1613 msg := `\n******************************\n` +
1614 `You have tried to change the API from what has been previously released in\n` +
1615 `an SDK. Please fix the errors listed above.\n` +
1616 `******************************\n`
1617 rule.Command().
1618 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1619 Text(") || (").
1620 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1621 Text("; exit 38").
1622 Text(")")
1623
1624 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001625 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001626
Pete Gillin581d6082018-10-22 15:55:04 +01001627 if String(d.properties.Check_nullability_warnings) != "" {
1628 if d.nullabilityWarningsFile == nil {
1629 ctx.PropertyErrorf("check_nullability_warnings",
1630 "Cannot specify check_nullability_warnings unless validating nullability")
1631 }
Colin Cross33961b52019-07-11 11:01:22 -07001632
1633 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1634
Pete Gillin581d6082018-10-22 15:55:04 +01001635 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001636
Pete Gillin581d6082018-10-22 15:55:04 +01001637 msg := fmt.Sprintf(`\n******************************\n`+
1638 `The warnings encountered during nullability annotation validation did\n`+
1639 `not match the checked in file of expected warnings. The diffs are shown\n`+
1640 `above. You have two options:\n`+
1641 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1642 ` 2. Update the file of expected warnings by running:\n`+
1643 ` cp %s %s\n`+
1644 ` and submitting the updated file as part of your change.`,
1645 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001646
1647 rule := android.NewRuleBuilder()
1648
1649 rule.Command().
1650 Text("(").
1651 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1652 Text("&&").
1653 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1654 Text(") || (").
1655 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1656 Text("; exit 38").
1657 Text(")")
1658
1659 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001660 }
1661
Nan Zhang71bbe632018-09-17 14:32:21 -07001662 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001663 if len(d.Javadoc.properties.Out) > 0 {
1664 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1665 }
1666
1667 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1668 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1669 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1670
1671 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001672
Nan Zhang86b06202018-09-21 17:09:21 -07001673 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1674 // since there's cron job downstream that fetch this .zip file periodically.
1675 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001676 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1677 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1678
Nan Zhang71bbe632018-09-17 14:32:21 -07001679 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001680
Colin Cross33961b52019-07-11 11:01:22 -07001681 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1682 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001683
Colin Cross33961b52019-07-11 11:01:22 -07001684 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1685
Colin Crossdaa4c672019-07-15 22:53:46 -07001686 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001687 deps.bootClasspath, deps.classpath, d.sourcepaths)
1688
1689 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001690 Flag("-XDignore.symbol.file").
1691 FlagWithArg("-doclet ", "jdiff.JDiff").
1692 FlagWithInput("-docletpath ", jdiff).
1693 Flag("-quiet").
1694 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1695 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1696 Implicit(d.apiXmlFile).
1697 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1698 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1699 Implicit(d.lastReleasedApiXmlFile)
1700
Colin Cross33961b52019-07-11 11:01:22 -07001701 rule.Command().
1702 BuiltTool(ctx, "soong_zip").
1703 Flag("-write_if_changed").
1704 Flag("-d").
1705 FlagWithOutput("-o ", d.jdiffDocZip).
1706 FlagWithArg("-C ", outDir.String()).
1707 FlagWithArg("-D ", outDir.String())
1708
1709 rule.Command().
1710 BuiltTool(ctx, "soong_zip").
1711 Flag("-write_if_changed").
1712 Flag("-jar").
1713 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1714 FlagWithArg("-C ", stubsDir.String()).
1715 FlagWithArg("-D ", stubsDir.String())
1716
1717 rule.Restat()
1718
1719 zipSyncCleanupCmd(rule, srcJarDir)
1720
1721 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001722 }
Nan Zhang581fd212018-01-10 16:06:12 -08001723}
Dan Willemsencc090972018-02-26 14:33:31 -08001724
Nan Zhanga40da042018-08-01 12:48:00 -07001725//
Nan Zhangf4936b02018-08-01 15:00:28 -07001726// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001727//
Dan Willemsencc090972018-02-26 14:33:31 -08001728var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001729var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001730var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001731var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001732
Nan Zhangf4936b02018-08-01 15:00:28 -07001733type ExportedDroiddocDirProperties struct {
1734 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001735 Path *string
1736}
1737
Nan Zhangf4936b02018-08-01 15:00:28 -07001738type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001739 android.ModuleBase
1740
Nan Zhangf4936b02018-08-01 15:00:28 -07001741 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001742
1743 deps android.Paths
1744 dir android.Path
1745}
1746
Colin Crossa3002fc2019-07-08 16:48:04 -07001747// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001748func ExportedDroiddocDirFactory() android.Module {
1749 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001750 module.AddProperties(&module.properties)
1751 android.InitAndroidModule(module)
1752 return module
1753}
1754
Nan Zhangf4936b02018-08-01 15:00:28 -07001755func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001756
Nan Zhangf4936b02018-08-01 15:00:28 -07001757func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001758 path := String(d.properties.Path)
1759 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001760 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001761}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001762
1763//
1764// Defaults
1765//
1766type DocDefaults struct {
1767 android.ModuleBase
1768 android.DefaultsModuleBase
1769}
1770
Nan Zhangb2b33de2018-02-23 11:18:47 -08001771func DocDefaultsFactory() android.Module {
1772 module := &DocDefaults{}
1773
1774 module.AddProperties(
1775 &JavadocProperties{},
1776 &DroiddocProperties{},
1777 )
1778
1779 android.InitDefaultsModule(module)
1780
1781 return module
1782}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001783
1784func StubsDefaultsFactory() android.Module {
1785 module := &DocDefaults{}
1786
1787 module.AddProperties(
1788 &JavadocProperties{},
1789 &DroidstubsProperties{},
1790 )
1791
1792 android.InitDefaultsModule(module)
1793
1794 return module
1795}
Colin Cross33961b52019-07-11 11:01:22 -07001796
1797func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1798 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1799
1800 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1801 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1802 srcJarList := srcJarDir.Join(ctx, "list")
1803
1804 rule.Temporary(srcJarList)
1805
1806 rule.Command().BuiltTool(ctx, "zipsync").
1807 FlagWithArg("-d ", srcJarDir.String()).
1808 FlagWithOutput("-l ", srcJarList).
1809 FlagWithArg("-f ", `"*.java"`).
1810 Inputs(srcJars)
1811
1812 return srcJarList
1813}
1814
1815func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1816 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1817}