blob: 26b8ac68445a31ab4889c44c5f0b6f3fb6b33055 [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"
Colin Crossab054432019-07-15 16:13:59 -070024
25 "android/soong/android"
26 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
Nan Zhang581fd212018-01-10 16:06:12 -080029func 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
362 default:
363 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
364 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800365}
366
Colin Crossa3002fc2019-07-08 16:48:04 -0700367// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800368func JavadocFactory() android.Module {
369 module := &Javadoc{}
370
371 module.AddProperties(&module.properties)
372
373 InitDroiddocModule(module, android.HostAndDeviceSupported)
374 return module
375}
376
Colin Crossa3002fc2019-07-08 16:48:04 -0700377// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800378func JavadocHostFactory() android.Module {
379 module := &Javadoc{}
380
381 module.AddProperties(&module.properties)
382
383 InitDroiddocModule(module, android.HostSupported)
384 return module
385}
386
Colin Cross41955e82019-05-29 14:40:35 -0700387var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800388
Colin Cross83bb3162018-06-25 15:48:06 -0700389func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900390 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700391}
392
393func (j *Javadoc) minSdkVersion() string {
394 return j.sdkVersion()
395}
396
Dan Willemsen419290a2018-10-31 15:28:47 -0700397func (j *Javadoc) targetSdkVersion() string {
398 return j.sdkVersion()
399}
400
Nan Zhang581fd212018-01-10 16:06:12 -0800401func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
402 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100403 sdkDep := decodeSdkDep(ctx, sdkContext(j))
404 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700405 if sdkDep.useDefaultLibs {
406 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
407 if ctx.Config().TargetOpenJDK9() {
408 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
409 }
Paul Duffin250e6192019-06-07 10:44:37 +0100410 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700411 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
412 }
413 } else if sdkDep.useModule {
414 if ctx.Config().TargetOpenJDK9() {
415 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
416 }
417 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700418 }
Nan Zhang581fd212018-01-10 16:06:12 -0800419 }
420 }
421
Colin Cross42d48b72018-08-29 14:10:52 -0700422 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700423 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700424 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700425 }
Nan Zhang581fd212018-01-10 16:06:12 -0800426}
427
Nan Zhangb2b33de2018-02-23 11:18:47 -0800428func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
429 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
430 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900431 // convert foo.bar.baz to foo/bar/baz
432 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
433 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800434 if _, found := whitelistPathPrefixes[prefix]; !found {
435 whitelistPathPrefixes[prefix] = true
436 }
437 }
438 }
439}
440
Nan Zhanga40da042018-08-01 12:48:00 -0700441func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
442 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900443
Colin Cross3047fa22019-04-18 10:56:44 -0700444 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900445
446 return flags
447}
448
449func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700450 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900451
452 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
453 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
454
455 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700456 var deps android.Paths
457
Jiyong Park1e440682018-05-23 18:42:04 +0900458 if aidlPreprocess.Valid() {
459 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700460 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900461 } else {
462 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
463 }
464
465 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
466 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
467 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
468 flags = append(flags, "-I"+src.String())
469 }
470
Colin Cross3047fa22019-04-18 10:56:44 -0700471 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900472}
473
474func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700475 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900476
477 outSrcFiles := make(android.Paths, 0, len(srcFiles))
478
479 for _, srcFile := range srcFiles {
480 switch srcFile.Ext() {
481 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700482 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900483 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900484 case ".sysprop":
485 javaFile := genSysprop(ctx, srcFile)
486 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900487 default:
488 outSrcFiles = append(outSrcFiles, srcFile)
489 }
490 }
491
492 return outSrcFiles
493}
494
Nan Zhang581fd212018-01-10 16:06:12 -0800495func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
496 var deps deps
497
Colin Cross83bb3162018-06-25 15:48:06 -0700498 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800499 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700500 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800501 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700502 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800503 }
504
505 ctx.VisitDirectDeps(func(module android.Module) {
506 otherName := ctx.OtherModuleName(module)
507 tag := ctx.OtherModuleDependencyTag(module)
508
Colin Cross2d24c1b2018-05-23 10:59:18 -0700509 switch tag {
510 case bootClasspathTag:
511 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800512 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700513 } else {
514 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
515 }
516 case libTag:
517 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800518 case SdkLibraryDependency:
519 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700520 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900521 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700522 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800523 checkProducesJars(ctx, dep)
524 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800525 default:
526 ctx.ModuleErrorf("depends on non-java module %q", otherName)
527 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700528 case srcsLibTag:
529 switch dep := module.(type) {
530 case Dependency:
531 srcs := dep.(SrcDependency).CompiledSrcs()
532 whitelistPathPrefixes := make(map[string]bool)
533 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
534 for _, src := range srcs {
535 if _, ok := src.(android.WritablePath); ok { // generated sources
536 deps.srcs = append(deps.srcs, src)
537 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700538 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700539 if strings.HasPrefix(src.Rel(), k) {
540 deps.srcs = append(deps.srcs, src)
541 break
542 }
543 }
544 }
545 }
546 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
547 default:
548 ctx.ModuleErrorf("depends on non-java module %q", otherName)
549 }
Nan Zhang357466b2018-04-17 17:38:36 -0700550 case systemModulesTag:
551 if deps.systemModules != nil {
552 panic("Found two system module dependencies")
553 }
554 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000555 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700556 panic("Missing directory for system module dependency")
557 }
Colin Crossb77043e2019-07-16 13:57:13 -0700558 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800559 }
560 })
561 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
562 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800563 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700564 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900565 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800566
567 // srcs may depend on some genrule output.
568 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800569 j.srcJars = append(j.srcJars, deps.srcJars...)
570
Nan Zhang581fd212018-01-10 16:06:12 -0800571 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800572 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800573
Nan Zhang9c69a122018-08-22 10:22:08 -0700574 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800575 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
576 }
577 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800578
Colin Cross8a497952019-03-05 22:25:09 -0800579 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000580 argFilesMap := map[string]string{}
581 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700582
Paul Duffin99e4a502019-02-11 15:38:42 +0000583 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800584 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000585 if _, exists := argFilesMap[label]; !exists {
586 argFilesMap[label] = strings.Join(paths.Strings(), " ")
587 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700588 } else {
589 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000590 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700591 }
592 }
593
594 var err error
Colin Cross15638152019-07-11 11:11:35 -0700595 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700596 if strings.HasPrefix(name, "location ") {
597 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000598 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700599 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700600 } else {
Colin Cross15638152019-07-11 11:11:35 -0700601 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000602 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700603 }
604 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700605 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700606 }
Colin Cross15638152019-07-11 11:11:35 -0700607 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700608 })
609
610 if err != nil {
611 ctx.PropertyErrorf("args", "%s", err.Error())
612 }
613
Nan Zhang581fd212018-01-10 16:06:12 -0800614 return deps
615}
616
617func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
618 j.addDeps(ctx)
619}
620
621func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
622 deps := j.collectDeps(ctx)
623
Colin Crossdaa4c672019-07-15 22:53:46 -0700624 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800625
Colin Crossdaa4c672019-07-15 22:53:46 -0700626 outDir := android.PathForModuleOut(ctx, "out")
627 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
628
629 j.stubsSrcJar = nil
630
631 rule := android.NewRuleBuilder()
632
633 rule.Command().Text("rm -rf").Text(outDir.String())
634 rule.Command().Text("mkdir -p").Text(outDir.String())
635
636 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700637
Colin Cross83bb3162018-06-25 15:48:06 -0700638 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800639
Colin Crossdaa4c672019-07-15 22:53:46 -0700640 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
641 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800642
Colin Crossdaa4c672019-07-15 22:53:46 -0700643 cmd.FlagWithArg("-source ", javaVersion).
644 Flag("-J-Xmx1024m").
645 Flag("-XDignore.symbol.file").
646 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800647
Colin Crossdaa4c672019-07-15 22:53:46 -0700648 rule.Command().
649 BuiltTool(ctx, "soong_zip").
650 Flag("-write_if_changed").
651 Flag("-d").
652 FlagWithOutput("-o ", j.docZip).
653 FlagWithArg("-C ", outDir.String()).
654 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700655
Colin Crossdaa4c672019-07-15 22:53:46 -0700656 rule.Restat()
657
658 zipSyncCleanupCmd(rule, srcJarDir)
659
660 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800661}
662
Nan Zhanga40da042018-08-01 12:48:00 -0700663//
664// Droiddoc
665//
666type Droiddoc struct {
667 Javadoc
668
669 properties DroiddocProperties
670 apiFile android.WritablePath
671 dexApiFile android.WritablePath
672 privateApiFile android.WritablePath
673 privateDexApiFile android.WritablePath
674 removedApiFile android.WritablePath
675 removedDexApiFile android.WritablePath
676 exactApiFile android.WritablePath
677 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700678 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700679
680 checkCurrentApiTimestamp android.WritablePath
681 updateCurrentApiTimestamp android.WritablePath
682 checkLastReleasedApiTimestamp android.WritablePath
683
Nan Zhanga40da042018-08-01 12:48:00 -0700684 apiFilePath android.Path
685}
686
Colin Crossa3002fc2019-07-08 16:48:04 -0700687// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700688func DroiddocFactory() android.Module {
689 module := &Droiddoc{}
690
691 module.AddProperties(&module.properties,
692 &module.Javadoc.properties)
693
694 InitDroiddocModule(module, android.HostAndDeviceSupported)
695 return module
696}
697
Colin Crossa3002fc2019-07-08 16:48:04 -0700698// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700699func DroiddocHostFactory() android.Module {
700 module := &Droiddoc{}
701
702 module.AddProperties(&module.properties,
703 &module.Javadoc.properties)
704
705 InitDroiddocModule(module, android.HostSupported)
706 return module
707}
708
709func (d *Droiddoc) ApiFilePath() android.Path {
710 return d.apiFilePath
711}
712
Nan Zhang581fd212018-01-10 16:06:12 -0800713func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
714 d.Javadoc.addDeps(ctx)
715
Inseob Kim38449af2019-02-28 14:24:05 +0900716 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
717 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
718 }
719
Nan Zhang79614d12018-04-19 18:03:39 -0700720 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800721 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
722 }
Nan Zhang581fd212018-01-10 16:06:12 -0800723}
724
Colin Crossab054432019-07-15 16:13:59 -0700725func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700726 var date string
727 if runtime.GOOS == "darwin" {
728 date = `date -r`
729 } else {
730 date = `date -d`
731 }
732
Nan Zhang443fa522018-08-20 20:58:28 -0700733 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
734 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
735 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700736 cmd.FlagWithArg("-source ", "1.8").
737 Flag("-J-Xmx1600m").
738 Flag("-J-XX:-OmitStackTraceInFastThrow").
739 Flag("-XDignore.symbol.file").
740 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
741 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
742 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
743 FlagWithArg("-hdf page.now ", `"$(`+date+` @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700744
Nan Zhanga40da042018-08-01 12:48:00 -0700745 if String(d.properties.Custom_template) == "" {
746 // TODO: This is almost always droiddoc-templates-sdk
747 ctx.PropertyErrorf("custom_template", "must specify a template")
748 }
749
750 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700751 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700752 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700753 } else {
754 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
755 }
756 })
757
758 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700759 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
760 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
761 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700762 }
763
764 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700765 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
766 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
767 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700768 }
769
770 if len(d.properties.Html_dirs) > 2 {
771 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
772 }
773
Colin Cross8a497952019-03-05 22:25:09 -0800774 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700775 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700776
Colin Crossab054432019-07-15 16:13:59 -0700777 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700778
779 if String(d.properties.Proofread_file) != "" {
780 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700781 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700782 }
783
784 if String(d.properties.Todo_file) != "" {
785 // tricky part:
786 // we should not compute full path for todo_file through PathForModuleOut().
787 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700788 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
789 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700790 }
791
792 if String(d.properties.Resourcesdir) != "" {
793 // TODO: should we add files under resourcesDir to the implicits? It seems that
794 // resourcesDir is one sub dir of htmlDir
795 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700796 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700797 }
798
799 if String(d.properties.Resourcesoutdir) != "" {
800 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700801 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700802 }
Nan Zhanga40da042018-08-01 12:48:00 -0700803}
804
Colin Crossab054432019-07-15 16:13:59 -0700805func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700806 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
807 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
808 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700809
Nan Zhanga40da042018-08-01 12:48:00 -0700810 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700811 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700812 d.apiFilePath = d.apiFile
813 }
814
Nan Zhang1598a9e2018-09-04 17:14:32 -0700815 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
816 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
817 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700818 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700819 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700820 }
821
822 if String(d.properties.Private_api_filename) != "" {
823 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700824 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700825 }
826
827 if String(d.properties.Dex_api_filename) != "" {
828 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700829 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700830 }
831
832 if String(d.properties.Private_dex_api_filename) != "" {
833 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700834 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700835 }
836
837 if String(d.properties.Removed_dex_api_filename) != "" {
838 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700839 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700840 }
841
842 if String(d.properties.Exact_api_filename) != "" {
843 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700844 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700845 }
846
847 if String(d.properties.Dex_mapping_filename) != "" {
848 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700849 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700850 }
851
Nan Zhang66dc2362018-08-14 20:41:04 -0700852 if String(d.properties.Proguard_filename) != "" {
853 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700854 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700855 }
856
Nan Zhanga40da042018-08-01 12:48:00 -0700857 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700858 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700859 }
860
861 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700862 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700863 }
Nan Zhanga40da042018-08-01 12:48:00 -0700864}
865
Colin Crossab054432019-07-15 16:13:59 -0700866func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700867 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700868 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
869 rule.Command().Text("cp").
870 Input(staticDocIndexRedirect).
871 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700872 }
873
874 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700875 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
876 rule.Command().Text("cp").
877 Input(staticDocProperties).
878 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700879 }
Nan Zhanga40da042018-08-01 12:48:00 -0700880}
881
Colin Crossab054432019-07-15 16:13:59 -0700882func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700883 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700884
885 cmd := rule.Command().
886 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
887 Flag(config.JavacVmFlags).
888 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700889 FlagWithRspFileInputList("@", srcs).
890 FlagWithInput("@", srcJarList)
891
Colin Crossab054432019-07-15 16:13:59 -0700892 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
893 // based stubs generation.
894 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
895 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
896 // the correct package name base path.
897 if len(sourcepaths) > 0 {
898 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
899 } else {
900 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
901 }
902
903 cmd.FlagWithArg("-d ", outDir.String()).
904 Flag("-quiet")
905
906 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700907}
908
Colin Crossdaa4c672019-07-15 22:53:46 -0700909func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
910 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
911 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
912
913 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
914
915 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
916 cmd.Flag(flag).Implicits(deps)
917
918 cmd.FlagWithArg("--patch-module ", "java.base=.")
919
920 if len(classpath) > 0 {
921 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
922 }
923
924 return cmd
925}
926
927func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
928 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
929 sourcepaths android.Paths) *android.RuleBuilderCommand {
930
931 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
932
933 if len(bootclasspath) == 0 && ctx.Device() {
934 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
935 // ensure java does not fall back to the default bootclasspath.
936 cmd.FlagWithArg("-bootclasspath ", `""`)
937 } else if len(bootclasspath) > 0 {
938 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
939 }
940
941 if len(classpath) > 0 {
942 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
943 }
944
945 return cmd
946}
947
Colin Crossab054432019-07-15 16:13:59 -0700948func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
949 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700950
Colin Crossab054432019-07-15 16:13:59 -0700951 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
952 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
953
954 return rule.Command().
955 BuiltTool(ctx, "dokka").
956 Flag(config.JavacVmFlags).
957 Flag(srcJarDir.String()).
958 FlagWithInputList("-classpath ", dokkaClasspath, ":").
959 FlagWithArg("-format ", "dac").
960 FlagWithArg("-dacRoot ", "/reference/kotlin").
961 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700962}
963
964func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
965 deps := d.Javadoc.collectDeps(ctx)
966
Colin Crossdaa4c672019-07-15 22:53:46 -0700967 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
968 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
969
Nan Zhang1598a9e2018-09-04 17:14:32 -0700970 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
971 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
972 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
973 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
974
Colin Crossab054432019-07-15 16:13:59 -0700975 outDir := android.PathForModuleOut(ctx, "out")
976 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
977 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700978
Colin Crossab054432019-07-15 16:13:59 -0700979 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700980
Colin Crossab054432019-07-15 16:13:59 -0700981 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
982 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700983
Colin Crossab054432019-07-15 16:13:59 -0700984 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
985
986 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700987 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700988 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700989 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700990 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700991 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700992 }
993
Colin Crossab054432019-07-15 16:13:59 -0700994 d.stubsFlags(ctx, cmd, stubsDir)
995
996 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
997
998 var desc string
999 if Bool(d.properties.Dokka_enabled) {
1000 desc = "dokka"
1001 } else {
1002 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1003
1004 for _, o := range d.Javadoc.properties.Out {
1005 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1006 }
1007
1008 d.postDoclavaCmds(ctx, rule)
1009 desc = "doclava"
1010 }
1011
1012 rule.Command().
1013 BuiltTool(ctx, "soong_zip").
1014 Flag("-write_if_changed").
1015 Flag("-d").
1016 FlagWithOutput("-o ", d.docZip).
1017 FlagWithArg("-C ", outDir.String()).
1018 FlagWithArg("-D ", outDir.String())
1019
1020 rule.Command().
1021 BuiltTool(ctx, "soong_zip").
1022 Flag("-write_if_changed").
1023 Flag("-jar").
1024 FlagWithOutput("-o ", d.stubsSrcJar).
1025 FlagWithArg("-C ", stubsDir.String()).
1026 FlagWithArg("-D ", stubsDir.String())
1027
1028 rule.Restat()
1029
1030 zipSyncCleanupCmd(rule, srcJarDir)
1031
1032 rule.Build(pctx, ctx, "javadoc", desc)
1033
Nan Zhang1598a9e2018-09-04 17:14:32 -07001034 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1035 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001036
1037 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1038 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001039
1040 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001041
1042 rule := android.NewRuleBuilder()
1043
1044 rule.Command().Text("( true")
1045
1046 rule.Command().
1047 BuiltTool(ctx, "apicheck").
1048 Flag("-JXmx1024m").
1049 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1050 OptionalFlag(d.properties.Check_api.Current.Args).
1051 Input(apiFile).
1052 Input(d.apiFile).
1053 Input(removedApiFile).
1054 Input(d.removedApiFile)
1055
1056 msg := fmt.Sprintf(`\n******************************\n`+
1057 `You have tried to change the API from what has been previously approved.\n\n`+
1058 `To make these errors go away, you have two choices:\n`+
1059 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1060 ` errors above.\n\n`+
1061 ` 2. You can update current.txt by executing the following command:\n`+
1062 ` make %s-update-current-api\n\n`+
1063 ` To submit the revised current.txt to the main Android repository,\n`+
1064 ` you will need approval.\n`+
1065 `******************************\n`, ctx.ModuleName())
1066
1067 rule.Command().
1068 Text("touch").Output(d.checkCurrentApiTimestamp).
1069 Text(") || (").
1070 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1071 Text("; exit 38").
1072 Text(")")
1073
1074 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001075
1076 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001077
1078 // update API rule
1079 rule = android.NewRuleBuilder()
1080
1081 rule.Command().Text("( true")
1082
1083 rule.Command().
1084 Text("cp").Flag("-f").
1085 Input(d.apiFile).Flag(apiFile.String())
1086
1087 rule.Command().
1088 Text("cp").Flag("-f").
1089 Input(d.removedApiFile).Flag(removedApiFile.String())
1090
1091 msg = "failed to update public API"
1092
1093 rule.Command().
1094 Text("touch").Output(d.updateCurrentApiTimestamp).
1095 Text(") || (").
1096 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1097 Text("; exit 38").
1098 Text(")")
1099
1100 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001101 }
1102
1103 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1104 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001105
1106 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1107 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001108
1109 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001110
1111 rule := android.NewRuleBuilder()
1112
1113 rule.Command().
1114 Text("(").
1115 BuiltTool(ctx, "apicheck").
1116 Flag("-JXmx1024m").
1117 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1118 OptionalFlag(d.properties.Check_api.Last_released.Args).
1119 Input(apiFile).
1120 Input(d.apiFile).
1121 Input(removedApiFile).
1122 Input(d.removedApiFile)
1123
1124 msg := `\n******************************\n` +
1125 `You have tried to change the API from what has been previously released in\n` +
1126 `an SDK. Please fix the errors listed above.\n` +
1127 `******************************\n`
1128
1129 rule.Command().
1130 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1131 Text(") || (").
1132 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1133 Text("; exit 38").
1134 Text(")")
1135
1136 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001137 }
1138}
1139
1140//
1141// Droidstubs
1142//
1143type Droidstubs struct {
1144 Javadoc
1145
Pete Gillin581d6082018-10-22 15:55:04 +01001146 properties DroidstubsProperties
1147 apiFile android.WritablePath
1148 apiXmlFile android.WritablePath
1149 lastReleasedApiXmlFile android.WritablePath
1150 dexApiFile android.WritablePath
1151 privateApiFile android.WritablePath
1152 privateDexApiFile android.WritablePath
1153 removedApiFile android.WritablePath
1154 removedDexApiFile android.WritablePath
1155 apiMappingFile android.WritablePath
1156 exactApiFile android.WritablePath
1157 proguardFile android.WritablePath
1158 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001159
1160 checkCurrentApiTimestamp android.WritablePath
1161 updateCurrentApiTimestamp android.WritablePath
1162 checkLastReleasedApiTimestamp android.WritablePath
1163
Pete Gillin581d6082018-10-22 15:55:04 +01001164 checkNullabilityWarningsTimestamp android.WritablePath
1165
Nan Zhang1598a9e2018-09-04 17:14:32 -07001166 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001167 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001168
1169 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001170
1171 jdiffDocZip android.WritablePath
1172 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001173}
1174
Colin Crossa3002fc2019-07-08 16:48:04 -07001175// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1176// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1177// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001178func DroidstubsFactory() android.Module {
1179 module := &Droidstubs{}
1180
1181 module.AddProperties(&module.properties,
1182 &module.Javadoc.properties)
1183
1184 InitDroiddocModule(module, android.HostAndDeviceSupported)
1185 return module
1186}
1187
Colin Crossa3002fc2019-07-08 16:48:04 -07001188// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1189// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1190// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1191// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001192func DroidstubsHostFactory() android.Module {
1193 module := &Droidstubs{}
1194
1195 module.AddProperties(&module.properties,
1196 &module.Javadoc.properties)
1197
1198 InitDroiddocModule(module, android.HostSupported)
1199 return module
1200}
1201
1202func (d *Droidstubs) ApiFilePath() android.Path {
1203 return d.apiFilePath
1204}
1205
1206func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1207 d.Javadoc.addDeps(ctx)
1208
Inseob Kim38449af2019-02-28 14:24:05 +09001209 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1210 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1211 }
1212
Nan Zhang1598a9e2018-09-04 17:14:32 -07001213 if len(d.properties.Merge_annotations_dirs) != 0 {
1214 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1215 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1216 }
1217 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001218
Pete Gillin77167902018-09-19 18:16:26 +01001219 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1220 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1221 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1222 }
1223 }
1224
Nan Zhang9c69a122018-08-22 10:22:08 -07001225 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1226 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1227 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1228 }
1229 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001230}
1231
Colin Cross33961b52019-07-11 11:01:22 -07001232func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001233 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1234 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1235 String(d.properties.Api_filename) != "" {
1236 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001237 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001238 d.apiFilePath = d.apiFile
1239 }
1240
1241 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1242 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1243 String(d.properties.Removed_api_filename) != "" {
1244 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001245 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001246 }
1247
1248 if String(d.properties.Private_api_filename) != "" {
1249 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001250 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 }
1252
1253 if String(d.properties.Dex_api_filename) != "" {
1254 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001255 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256 }
1257
1258 if String(d.properties.Private_dex_api_filename) != "" {
1259 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001260 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261 }
1262
1263 if String(d.properties.Removed_dex_api_filename) != "" {
1264 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001265 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001266 }
1267
1268 if String(d.properties.Exact_api_filename) != "" {
1269 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001270 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001271 }
1272
Nan Zhang9c69a122018-08-22 10:22:08 -07001273 if String(d.properties.Dex_mapping_filename) != "" {
1274 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001275 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001276 }
1277
Nan Zhang199645c2018-09-19 12:40:06 -07001278 if String(d.properties.Proguard_filename) != "" {
1279 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001280 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001281 }
1282
Nan Zhang9c69a122018-08-22 10:22:08 -07001283 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001285 }
1286
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001288 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001289 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001290 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001291 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292}
1293
Colin Cross33961b52019-07-11 11:01:22 -07001294func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001296 cmd.Flag("--include-annotations")
1297
Pete Gillinc382a562018-11-14 18:45:46 +00001298 validatingNullability :=
1299 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1300 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001301 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001302
Pete Gillina262c052018-09-14 14:25:48 +01001303 if !(migratingNullability || validatingNullability) {
1304 ctx.PropertyErrorf("previous_api",
1305 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001306 }
Colin Cross33961b52019-07-11 11:01:22 -07001307
Pete Gillina262c052018-09-14 14:25:48 +01001308 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001309 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001310 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001311 }
Colin Cross33961b52019-07-11 11:01:22 -07001312
Pete Gillinc382a562018-11-14 18:45:46 +00001313 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001314 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001315 }
Colin Cross33961b52019-07-11 11:01:22 -07001316
Pete Gillina262c052018-09-14 14:25:48 +01001317 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001318 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001319 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001320 }
Nan Zhanga40da042018-08-01 12:48:00 -07001321
1322 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001323 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001324
Nan Zhang1598a9e2018-09-04 17:14:32 -07001325 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001326 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001327 "has to be non-empty if annotations was enabled!")
1328 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001329
Colin Cross33961b52019-07-11 11:01:22 -07001330 d.mergeAnnoDirFlags(ctx, cmd)
1331
1332 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1333 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1334 FlagWithArg("--hide ", "SuperfluousPrefix").
1335 FlagWithArg("--hide ", "AnnotationExtraction")
1336 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001337}
1338
Colin Cross33961b52019-07-11 11:01:22 -07001339func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1340 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1341 if t, ok := m.(*ExportedDroiddocDir); ok {
1342 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1343 } else {
1344 ctx.PropertyErrorf("merge_annotations_dirs",
1345 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1346 }
1347 })
1348}
1349
1350func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001351 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1352 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001353 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001354 } else {
1355 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1356 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1357 }
1358 })
Nan Zhanga40da042018-08-01 12:48:00 -07001359}
1360
Colin Cross33961b52019-07-11 11:01:22 -07001361func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001362 if Bool(d.properties.Api_levels_annotations_enabled) {
1363 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001364
1365 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1366 ctx.PropertyErrorf("api_levels_annotations_dirs",
1367 "has to be non-empty if api levels annotations was enabled!")
1368 }
1369
Colin Cross33961b52019-07-11 11:01:22 -07001370 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1371 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1372 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1373 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001374
1375 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1376 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001377 for _, dep := range t.deps {
1378 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001379 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001380 }
1381 }
Colin Cross33961b52019-07-11 11:01:22 -07001382 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001383 } else {
1384 ctx.PropertyErrorf("api_levels_annotations_dirs",
1385 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1386 }
1387 })
1388
1389 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001390}
1391
Colin Cross33961b52019-07-11 11:01:22 -07001392func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001393 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1394 if d.apiFile.String() == "" {
1395 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1396 }
1397
1398 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001399 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001400
1401 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1402 ctx.PropertyErrorf("check_api.last_released.api_file",
1403 "has to be non-empty if jdiff was enabled!")
1404 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001405
Colin Cross33961b52019-07-11 11:01:22 -07001406 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001407 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001408 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1409 }
1410}
Nan Zhang71bbe632018-09-17 14:32:21 -07001411
Colin Cross33961b52019-07-11 11:01:22 -07001412func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1413 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1414 cmd := rule.Command().BuiltTool(ctx, "metalava").
1415 Flag(config.JavacVmFlags).
1416 FlagWithArg("-encoding ", "UTF-8").
1417 FlagWithArg("-source ", javaVersion).
1418 FlagWithRspFileInputList("@", srcs).
1419 FlagWithInput("@", srcJarList)
1420
1421 if len(bootclasspath) > 0 {
1422 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001423 }
1424
Colin Cross33961b52019-07-11 11:01:22 -07001425 if len(classpath) > 0 {
1426 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1427 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001428
Colin Cross33961b52019-07-11 11:01:22 -07001429 if len(sourcepaths) > 0 {
1430 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1431 } else {
1432 cmd.FlagWithArg("-sourcepath ", `""`)
1433 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001434
Colin Cross33961b52019-07-11 11:01:22 -07001435 cmd.Flag("--no-banner").
1436 Flag("--color").
1437 Flag("--quiet").
1438 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001439
Colin Cross33961b52019-07-11 11:01:22 -07001440 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001441}
1442
Nan Zhang1598a9e2018-09-04 17:14:32 -07001443func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001444 deps := d.Javadoc.collectDeps(ctx)
1445
1446 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001447
Colin Cross33961b52019-07-11 11:01:22 -07001448 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001449
Colin Crossdaa4c672019-07-15 22:53:46 -07001450 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1451
Colin Cross33961b52019-07-11 11:01:22 -07001452 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1453 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhanga40da042018-08-01 12:48:00 -07001454
Colin Cross33961b52019-07-11 11:01:22 -07001455 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 rule.Command().Text("rm -rf").Text(stubsDir.String())
1458 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001459
Colin Cross33961b52019-07-11 11:01:22 -07001460 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1461
1462 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1463 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1464
1465 d.stubsFlags(ctx, cmd, stubsDir)
1466
1467 d.annotationsFlags(ctx, cmd)
1468 d.inclusionAnnotationsFlags(ctx, cmd)
1469 d.apiLevelsAnnotationsFlags(ctx, cmd)
1470 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001471
Nan Zhang1598a9e2018-09-04 17:14:32 -07001472 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1473 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1474 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1475 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1476 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001477 }
Colin Cross33961b52019-07-11 11:01:22 -07001478
1479 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1480 for _, o := range d.Javadoc.properties.Out {
1481 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1482 }
1483
1484 rule.Command().
1485 BuiltTool(ctx, "soong_zip").
1486 Flag("-write_if_changed").
1487 Flag("-jar").
1488 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1489 FlagWithArg("-C ", stubsDir.String()).
1490 FlagWithArg("-D ", stubsDir.String())
1491 rule.Restat()
1492
1493 zipSyncCleanupCmd(rule, srcJarDir)
1494
1495 rule.Build(pctx, ctx, "metalava", "metalava")
1496
1497 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001498
Nan Zhang1598a9e2018-09-04 17:14:32 -07001499 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1500 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001501
1502 if len(d.Javadoc.properties.Out) > 0 {
1503 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1504 }
1505
1506 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1507 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001508
Nan Zhang2760dfc2018-08-24 17:32:54 +00001509 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001510
Colin Cross33961b52019-07-11 11:01:22 -07001511 rule := android.NewRuleBuilder()
1512
1513 rule.Command().Text("( true")
1514
1515 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1516 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1517
1518 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1519 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1520
1521 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1522 FlagWithInput("--check-compatibility:api:current ", apiFile).
1523 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1524
1525 d.inclusionAnnotationsFlags(ctx, cmd)
1526 d.mergeAnnoDirFlags(ctx, cmd)
1527
1528 zipSyncCleanupCmd(rule, srcJarDir)
1529
1530 msg := fmt.Sprintf(`\n******************************\n`+
1531 `You have tried to change the API from what has been previously approved.\n\n`+
1532 `To make these errors go away, you have two choices:\n`+
1533 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1534 ` errors above.\n\n`+
1535 ` 2. You can update current.txt by executing the following command:\n`+
1536 ` make %s-update-current-api\n\n`+
1537 ` To submit the revised current.txt to the main Android repository,\n`+
1538 ` you will need approval.\n`+
1539 `******************************\n`, ctx.ModuleName())
1540
1541 rule.Command().
1542 Text("touch").Output(d.checkCurrentApiTimestamp).
1543 Text(") || (").
1544 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1545 Text("; exit 38").
1546 Text(")")
1547
1548 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001549
1550 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001551
1552 // update API rule
1553 rule = android.NewRuleBuilder()
1554
1555 rule.Command().Text("( true")
1556
1557 rule.Command().
1558 Text("cp").Flag("-f").
1559 Input(d.apiFile).Flag(apiFile.String())
1560
1561 rule.Command().
1562 Text("cp").Flag("-f").
1563 Input(d.removedApiFile).Flag(removedApiFile.String())
1564
1565 msg = "failed to update public API"
1566
1567 rule.Command().
1568 Text("touch").Output(d.updateCurrentApiTimestamp).
1569 Text(") || (").
1570 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1571 Text("; exit 38").
1572 Text(")")
1573
1574 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001575 }
Nan Zhanga40da042018-08-01 12:48:00 -07001576
Nan Zhang1598a9e2018-09-04 17:14:32 -07001577 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1578 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001579
1580 if len(d.Javadoc.properties.Out) > 0 {
1581 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1582 }
1583
1584 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1585 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001586
Nan Zhang2760dfc2018-08-24 17:32:54 +00001587 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001588
Colin Cross33961b52019-07-11 11:01:22 -07001589 rule := android.NewRuleBuilder()
1590
1591 rule.Command().Text("( true")
1592
1593 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1594 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1595
1596 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1597 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1598
1599 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1600 FlagWithInput("--check-compatibility:api:released ", apiFile)
1601
1602 d.inclusionAnnotationsFlags(ctx, cmd)
1603
1604 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1605
1606 d.mergeAnnoDirFlags(ctx, cmd)
1607
1608 zipSyncCleanupCmd(rule, srcJarDir)
1609
1610 msg := `\n******************************\n` +
1611 `You have tried to change the API from what has been previously released in\n` +
1612 `an SDK. Please fix the errors listed above.\n` +
1613 `******************************\n`
1614 rule.Command().
1615 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1616 Text(") || (").
1617 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1618 Text("; exit 38").
1619 Text(")")
1620
1621 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001622 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001623
Pete Gillin581d6082018-10-22 15:55:04 +01001624 if String(d.properties.Check_nullability_warnings) != "" {
1625 if d.nullabilityWarningsFile == nil {
1626 ctx.PropertyErrorf("check_nullability_warnings",
1627 "Cannot specify check_nullability_warnings unless validating nullability")
1628 }
Colin Cross33961b52019-07-11 11:01:22 -07001629
1630 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1631
Pete Gillin581d6082018-10-22 15:55:04 +01001632 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001633
Pete Gillin581d6082018-10-22 15:55:04 +01001634 msg := fmt.Sprintf(`\n******************************\n`+
1635 `The warnings encountered during nullability annotation validation did\n`+
1636 `not match the checked in file of expected warnings. The diffs are shown\n`+
1637 `above. You have two options:\n`+
1638 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1639 ` 2. Update the file of expected warnings by running:\n`+
1640 ` cp %s %s\n`+
1641 ` and submitting the updated file as part of your change.`,
1642 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001643
1644 rule := android.NewRuleBuilder()
1645
1646 rule.Command().
1647 Text("(").
1648 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1649 Text("&&").
1650 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1651 Text(") || (").
1652 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1653 Text("; exit 38").
1654 Text(")")
1655
1656 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001657 }
1658
Nan Zhang71bbe632018-09-17 14:32:21 -07001659 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001660 if len(d.Javadoc.properties.Out) > 0 {
1661 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1662 }
1663
1664 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1665 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1666 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1667
1668 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001669
Nan Zhang86b06202018-09-21 17:09:21 -07001670 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1671 // since there's cron job downstream that fetch this .zip file periodically.
1672 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001673 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1674 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1675
Nan Zhang71bbe632018-09-17 14:32:21 -07001676 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001677
Colin Cross33961b52019-07-11 11:01:22 -07001678 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1679 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001680
Colin Cross33961b52019-07-11 11:01:22 -07001681 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1682
Colin Crossdaa4c672019-07-15 22:53:46 -07001683 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001684 deps.bootClasspath, deps.classpath, d.sourcepaths)
1685
1686 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001687 Flag("-XDignore.symbol.file").
1688 FlagWithArg("-doclet ", "jdiff.JDiff").
1689 FlagWithInput("-docletpath ", jdiff).
1690 Flag("-quiet").
1691 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1692 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1693 Implicit(d.apiXmlFile).
1694 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1695 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1696 Implicit(d.lastReleasedApiXmlFile)
1697
Colin Cross33961b52019-07-11 11:01:22 -07001698 rule.Command().
1699 BuiltTool(ctx, "soong_zip").
1700 Flag("-write_if_changed").
1701 Flag("-d").
1702 FlagWithOutput("-o ", d.jdiffDocZip).
1703 FlagWithArg("-C ", outDir.String()).
1704 FlagWithArg("-D ", outDir.String())
1705
1706 rule.Command().
1707 BuiltTool(ctx, "soong_zip").
1708 Flag("-write_if_changed").
1709 Flag("-jar").
1710 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1711 FlagWithArg("-C ", stubsDir.String()).
1712 FlagWithArg("-D ", stubsDir.String())
1713
1714 rule.Restat()
1715
1716 zipSyncCleanupCmd(rule, srcJarDir)
1717
1718 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001719 }
Nan Zhang581fd212018-01-10 16:06:12 -08001720}
Dan Willemsencc090972018-02-26 14:33:31 -08001721
Nan Zhanga40da042018-08-01 12:48:00 -07001722//
Nan Zhangf4936b02018-08-01 15:00:28 -07001723// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001724//
Dan Willemsencc090972018-02-26 14:33:31 -08001725var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001726var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001727var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001728var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001729
Nan Zhangf4936b02018-08-01 15:00:28 -07001730type ExportedDroiddocDirProperties struct {
1731 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001732 Path *string
1733}
1734
Nan Zhangf4936b02018-08-01 15:00:28 -07001735type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001736 android.ModuleBase
1737
Nan Zhangf4936b02018-08-01 15:00:28 -07001738 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001739
1740 deps android.Paths
1741 dir android.Path
1742}
1743
Colin Crossa3002fc2019-07-08 16:48:04 -07001744// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001745func ExportedDroiddocDirFactory() android.Module {
1746 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001747 module.AddProperties(&module.properties)
1748 android.InitAndroidModule(module)
1749 return module
1750}
1751
Nan Zhangf4936b02018-08-01 15:00:28 -07001752func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001753
Nan Zhangf4936b02018-08-01 15:00:28 -07001754func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001755 path := String(d.properties.Path)
1756 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001757 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001758}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001759
1760//
1761// Defaults
1762//
1763type DocDefaults struct {
1764 android.ModuleBase
1765 android.DefaultsModuleBase
1766}
1767
Nan Zhangb2b33de2018-02-23 11:18:47 -08001768func DocDefaultsFactory() android.Module {
1769 module := &DocDefaults{}
1770
1771 module.AddProperties(
1772 &JavadocProperties{},
1773 &DroiddocProperties{},
1774 )
1775
1776 android.InitDefaultsModule(module)
1777
1778 return module
1779}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001780
1781func StubsDefaultsFactory() android.Module {
1782 module := &DocDefaults{}
1783
1784 module.AddProperties(
1785 &JavadocProperties{},
1786 &DroidstubsProperties{},
1787 )
1788
1789 android.InitDefaultsModule(module)
1790
1791 return module
1792}
Colin Cross33961b52019-07-11 11:01:22 -07001793
1794func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1795 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1796
1797 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1798 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1799 srcJarList := srcJarDir.Join(ctx, "list")
1800
1801 rule.Temporary(srcJarList)
1802
1803 rule.Command().BuiltTool(ctx, "zipsync").
1804 FlagWithArg("-d ", srcJarDir.String()).
1805 FlagWithOutput("-l ", srcJarList).
1806 FlagWithArg("-f ", `"*.java"`).
1807 Inputs(srcJars)
1808
1809 return srcJarList
1810}
1811
1812func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1813 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1814}