blob: 78bfa80d26587f0cb504ab1a077227c51edec40e [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
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()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900522 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700523 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800524 checkProducesJars(ctx, dep)
525 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800526 default:
527 ctx.ModuleErrorf("depends on non-java module %q", otherName)
528 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700529 case srcsLibTag:
530 switch dep := module.(type) {
531 case Dependency:
532 srcs := dep.(SrcDependency).CompiledSrcs()
533 whitelistPathPrefixes := make(map[string]bool)
534 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
535 for _, src := range srcs {
536 if _, ok := src.(android.WritablePath); ok { // generated sources
537 deps.srcs = append(deps.srcs, src)
538 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700539 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700540 if strings.HasPrefix(src.Rel(), k) {
541 deps.srcs = append(deps.srcs, src)
542 break
543 }
544 }
545 }
546 }
547 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
548 default:
549 ctx.ModuleErrorf("depends on non-java module %q", otherName)
550 }
Nan Zhang357466b2018-04-17 17:38:36 -0700551 case systemModulesTag:
552 if deps.systemModules != nil {
553 panic("Found two system module dependencies")
554 }
555 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000556 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700557 panic("Missing directory for system module dependency")
558 }
Colin Crossb77043e2019-07-16 13:57:13 -0700559 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800560 }
561 })
562 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
563 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800564 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700565 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900566 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800567
568 // srcs may depend on some genrule output.
569 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800570 j.srcJars = append(j.srcJars, deps.srcJars...)
571
Nan Zhang581fd212018-01-10 16:06:12 -0800572 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800573 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800574
Nan Zhang9c69a122018-08-22 10:22:08 -0700575 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800576 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
577 }
578 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800579
Colin Cross8a497952019-03-05 22:25:09 -0800580 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000581 argFilesMap := map[string]string{}
582 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700583
Paul Duffin99e4a502019-02-11 15:38:42 +0000584 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800585 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000586 if _, exists := argFilesMap[label]; !exists {
587 argFilesMap[label] = strings.Join(paths.Strings(), " ")
588 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700589 } else {
590 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000591 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700592 }
593 }
594
595 var err error
Colin Cross15638152019-07-11 11:11:35 -0700596 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700597 if strings.HasPrefix(name, "location ") {
598 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000599 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700600 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700601 } else {
Colin Cross15638152019-07-11 11:11:35 -0700602 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000603 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700604 }
605 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700606 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700607 }
Colin Cross15638152019-07-11 11:11:35 -0700608 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700609 })
610
611 if err != nil {
612 ctx.PropertyErrorf("args", "%s", err.Error())
613 }
614
Nan Zhang581fd212018-01-10 16:06:12 -0800615 return deps
616}
617
618func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
619 j.addDeps(ctx)
620}
621
622func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
623 deps := j.collectDeps(ctx)
624
Colin Crossdaa4c672019-07-15 22:53:46 -0700625 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800626
Colin Crossdaa4c672019-07-15 22:53:46 -0700627 outDir := android.PathForModuleOut(ctx, "out")
628 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
629
630 j.stubsSrcJar = nil
631
632 rule := android.NewRuleBuilder()
633
634 rule.Command().Text("rm -rf").Text(outDir.String())
635 rule.Command().Text("mkdir -p").Text(outDir.String())
636
637 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700638
Colin Cross83bb3162018-06-25 15:48:06 -0700639 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800640
Colin Crossdaa4c672019-07-15 22:53:46 -0700641 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
642 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800643
Colin Crossdaa4c672019-07-15 22:53:46 -0700644 cmd.FlagWithArg("-source ", javaVersion).
645 Flag("-J-Xmx1024m").
646 Flag("-XDignore.symbol.file").
647 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800648
Colin Crossdaa4c672019-07-15 22:53:46 -0700649 rule.Command().
650 BuiltTool(ctx, "soong_zip").
651 Flag("-write_if_changed").
652 Flag("-d").
653 FlagWithOutput("-o ", j.docZip).
654 FlagWithArg("-C ", outDir.String()).
655 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700656
Colin Crossdaa4c672019-07-15 22:53:46 -0700657 rule.Restat()
658
659 zipSyncCleanupCmd(rule, srcJarDir)
660
661 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800662}
663
Nan Zhanga40da042018-08-01 12:48:00 -0700664//
665// Droiddoc
666//
667type Droiddoc struct {
668 Javadoc
669
670 properties DroiddocProperties
671 apiFile android.WritablePath
672 dexApiFile android.WritablePath
673 privateApiFile android.WritablePath
674 privateDexApiFile android.WritablePath
675 removedApiFile android.WritablePath
676 removedDexApiFile android.WritablePath
677 exactApiFile android.WritablePath
678 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700679 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700680
681 checkCurrentApiTimestamp android.WritablePath
682 updateCurrentApiTimestamp android.WritablePath
683 checkLastReleasedApiTimestamp android.WritablePath
684
Nan Zhanga40da042018-08-01 12:48:00 -0700685 apiFilePath android.Path
686}
687
Colin Crossa3002fc2019-07-08 16:48:04 -0700688// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700689func DroiddocFactory() android.Module {
690 module := &Droiddoc{}
691
692 module.AddProperties(&module.properties,
693 &module.Javadoc.properties)
694
695 InitDroiddocModule(module, android.HostAndDeviceSupported)
696 return module
697}
698
Colin Crossa3002fc2019-07-08 16:48:04 -0700699// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700700func DroiddocHostFactory() android.Module {
701 module := &Droiddoc{}
702
703 module.AddProperties(&module.properties,
704 &module.Javadoc.properties)
705
706 InitDroiddocModule(module, android.HostSupported)
707 return module
708}
709
710func (d *Droiddoc) ApiFilePath() android.Path {
711 return d.apiFilePath
712}
713
Nan Zhang581fd212018-01-10 16:06:12 -0800714func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
715 d.Javadoc.addDeps(ctx)
716
Inseob Kim38449af2019-02-28 14:24:05 +0900717 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
718 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
719 }
720
Nan Zhang79614d12018-04-19 18:03:39 -0700721 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800722 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
723 }
Nan Zhang581fd212018-01-10 16:06:12 -0800724}
725
Colin Crossab054432019-07-15 16:13:59 -0700726func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700727 var date string
728 if runtime.GOOS == "darwin" {
729 date = `date -r`
730 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700731 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700732 }
733
Nan Zhang443fa522018-08-20 20:58:28 -0700734 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
735 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
736 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700737 cmd.FlagWithArg("-source ", "1.8").
738 Flag("-J-Xmx1600m").
739 Flag("-J-XX:-OmitStackTraceInFastThrow").
740 Flag("-XDignore.symbol.file").
741 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
742 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
743 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700744 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700745
Nan Zhanga40da042018-08-01 12:48:00 -0700746 if String(d.properties.Custom_template) == "" {
747 // TODO: This is almost always droiddoc-templates-sdk
748 ctx.PropertyErrorf("custom_template", "must specify a template")
749 }
750
751 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700752 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700753 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700754 } else {
755 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
756 }
757 })
758
759 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700760 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
761 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
762 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700763 }
764
765 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700766 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
767 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
768 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700769 }
770
771 if len(d.properties.Html_dirs) > 2 {
772 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
773 }
774
Colin Cross8a497952019-03-05 22:25:09 -0800775 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700776 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700777
Colin Crossab054432019-07-15 16:13:59 -0700778 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700779
780 if String(d.properties.Proofread_file) != "" {
781 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700782 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700783 }
784
785 if String(d.properties.Todo_file) != "" {
786 // tricky part:
787 // we should not compute full path for todo_file through PathForModuleOut().
788 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700789 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
790 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700791 }
792
793 if String(d.properties.Resourcesdir) != "" {
794 // TODO: should we add files under resourcesDir to the implicits? It seems that
795 // resourcesDir is one sub dir of htmlDir
796 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700797 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700798 }
799
800 if String(d.properties.Resourcesoutdir) != "" {
801 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700802 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700803 }
Nan Zhanga40da042018-08-01 12:48:00 -0700804}
805
Colin Crossab054432019-07-15 16:13:59 -0700806func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700807 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
808 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
809 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700810
Nan Zhanga40da042018-08-01 12:48:00 -0700811 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700812 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700813 d.apiFilePath = d.apiFile
814 }
815
Nan Zhang1598a9e2018-09-04 17:14:32 -0700816 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
817 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
818 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700819 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700820 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700821 }
822
823 if String(d.properties.Private_api_filename) != "" {
824 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700825 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700826 }
827
828 if String(d.properties.Dex_api_filename) != "" {
829 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700830 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700831 }
832
833 if String(d.properties.Private_dex_api_filename) != "" {
834 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700835 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700836 }
837
838 if String(d.properties.Removed_dex_api_filename) != "" {
839 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700840 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700841 }
842
843 if String(d.properties.Exact_api_filename) != "" {
844 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700845 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700846 }
847
848 if String(d.properties.Dex_mapping_filename) != "" {
849 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700850 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700851 }
852
Nan Zhang66dc2362018-08-14 20:41:04 -0700853 if String(d.properties.Proguard_filename) != "" {
854 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700855 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700856 }
857
Nan Zhanga40da042018-08-01 12:48:00 -0700858 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700859 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700860 }
861
862 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700863 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700864 }
Nan Zhanga40da042018-08-01 12:48:00 -0700865}
866
Colin Crossab054432019-07-15 16:13:59 -0700867func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700868 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700869 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
870 rule.Command().Text("cp").
871 Input(staticDocIndexRedirect).
872 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700873 }
874
875 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700876 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
877 rule.Command().Text("cp").
878 Input(staticDocProperties).
879 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700880 }
Nan Zhanga40da042018-08-01 12:48:00 -0700881}
882
Colin Crossab054432019-07-15 16:13:59 -0700883func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700884 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700885
886 cmd := rule.Command().
887 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
888 Flag(config.JavacVmFlags).
889 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700890 FlagWithRspFileInputList("@", srcs).
891 FlagWithInput("@", srcJarList)
892
Colin Crossab054432019-07-15 16:13:59 -0700893 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
894 // based stubs generation.
895 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
896 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
897 // the correct package name base path.
898 if len(sourcepaths) > 0 {
899 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
900 } else {
901 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
902 }
903
904 cmd.FlagWithArg("-d ", outDir.String()).
905 Flag("-quiet")
906
907 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700908}
909
Colin Crossdaa4c672019-07-15 22:53:46 -0700910func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
911 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
912 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
913
914 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
915
916 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
917 cmd.Flag(flag).Implicits(deps)
918
919 cmd.FlagWithArg("--patch-module ", "java.base=.")
920
921 if len(classpath) > 0 {
922 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
923 }
924
925 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700926}
927
Colin Crossdaa4c672019-07-15 22:53:46 -0700928func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
929 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
930 sourcepaths android.Paths) *android.RuleBuilderCommand {
931
932 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
933
934 if len(bootclasspath) == 0 && ctx.Device() {
935 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
936 // ensure java does not fall back to the default bootclasspath.
937 cmd.FlagWithArg("-bootclasspath ", `""`)
938 } else if len(bootclasspath) > 0 {
939 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
940 }
941
942 if len(classpath) > 0 {
943 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
944 }
945
946 return cmd
947}
948
Colin Crossab054432019-07-15 16:13:59 -0700949func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
950 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700951
Colin Crossab054432019-07-15 16:13:59 -0700952 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
953 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
954
955 return rule.Command().
956 BuiltTool(ctx, "dokka").
957 Flag(config.JavacVmFlags).
958 Flag(srcJarDir.String()).
959 FlagWithInputList("-classpath ", dokkaClasspath, ":").
960 FlagWithArg("-format ", "dac").
961 FlagWithArg("-dacRoot ", "/reference/kotlin").
962 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700963}
964
965func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
966 deps := d.Javadoc.collectDeps(ctx)
967
Colin Crossdaa4c672019-07-15 22:53:46 -0700968 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
969 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
970
Nan Zhang1598a9e2018-09-04 17:14:32 -0700971 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
972 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
973 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
974 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
975
Colin Crossab054432019-07-15 16:13:59 -0700976 outDir := android.PathForModuleOut(ctx, "out")
977 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
978 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700979
Colin Crossab054432019-07-15 16:13:59 -0700980 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700981
Colin Crossab054432019-07-15 16:13:59 -0700982 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
983 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700984
Colin Crossab054432019-07-15 16:13:59 -0700985 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
986
987 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700988 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700989 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700990 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700991 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700992 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700993 }
994
Colin Crossab054432019-07-15 16:13:59 -0700995 d.stubsFlags(ctx, cmd, stubsDir)
996
997 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
998
999 var desc string
1000 if Bool(d.properties.Dokka_enabled) {
1001 desc = "dokka"
1002 } else {
1003 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1004
1005 for _, o := range d.Javadoc.properties.Out {
1006 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1007 }
1008
1009 d.postDoclavaCmds(ctx, rule)
1010 desc = "doclava"
1011 }
1012
1013 rule.Command().
1014 BuiltTool(ctx, "soong_zip").
1015 Flag("-write_if_changed").
1016 Flag("-d").
1017 FlagWithOutput("-o ", d.docZip).
1018 FlagWithArg("-C ", outDir.String()).
1019 FlagWithArg("-D ", outDir.String())
1020
1021 rule.Command().
1022 BuiltTool(ctx, "soong_zip").
1023 Flag("-write_if_changed").
1024 Flag("-jar").
1025 FlagWithOutput("-o ", d.stubsSrcJar).
1026 FlagWithArg("-C ", stubsDir.String()).
1027 FlagWithArg("-D ", stubsDir.String())
1028
1029 rule.Restat()
1030
1031 zipSyncCleanupCmd(rule, srcJarDir)
1032
1033 rule.Build(pctx, ctx, "javadoc", desc)
1034
Nan Zhang1598a9e2018-09-04 17:14:32 -07001035 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1036 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001037
1038 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1039 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001040
1041 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001042
1043 rule := android.NewRuleBuilder()
1044
1045 rule.Command().Text("( true")
1046
1047 rule.Command().
1048 BuiltTool(ctx, "apicheck").
1049 Flag("-JXmx1024m").
1050 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1051 OptionalFlag(d.properties.Check_api.Current.Args).
1052 Input(apiFile).
1053 Input(d.apiFile).
1054 Input(removedApiFile).
1055 Input(d.removedApiFile)
1056
1057 msg := fmt.Sprintf(`\n******************************\n`+
1058 `You have tried to change the API from what has been previously approved.\n\n`+
1059 `To make these errors go away, you have two choices:\n`+
1060 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1061 ` errors above.\n\n`+
1062 ` 2. You can update current.txt by executing the following command:\n`+
1063 ` make %s-update-current-api\n\n`+
1064 ` To submit the revised current.txt to the main Android repository,\n`+
1065 ` you will need approval.\n`+
1066 `******************************\n`, ctx.ModuleName())
1067
1068 rule.Command().
1069 Text("touch").Output(d.checkCurrentApiTimestamp).
1070 Text(") || (").
1071 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1072 Text("; exit 38").
1073 Text(")")
1074
1075 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001076
1077 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001078
1079 // update API rule
1080 rule = android.NewRuleBuilder()
1081
1082 rule.Command().Text("( true")
1083
1084 rule.Command().
1085 Text("cp").Flag("-f").
1086 Input(d.apiFile).Flag(apiFile.String())
1087
1088 rule.Command().
1089 Text("cp").Flag("-f").
1090 Input(d.removedApiFile).Flag(removedApiFile.String())
1091
1092 msg = "failed to update public API"
1093
1094 rule.Command().
1095 Text("touch").Output(d.updateCurrentApiTimestamp).
1096 Text(") || (").
1097 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1098 Text("; exit 38").
1099 Text(")")
1100
1101 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001102 }
1103
1104 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1105 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001106
1107 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1108 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001109
1110 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001111
1112 rule := android.NewRuleBuilder()
1113
1114 rule.Command().
1115 Text("(").
1116 BuiltTool(ctx, "apicheck").
1117 Flag("-JXmx1024m").
1118 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1119 OptionalFlag(d.properties.Check_api.Last_released.Args).
1120 Input(apiFile).
1121 Input(d.apiFile).
1122 Input(removedApiFile).
1123 Input(d.removedApiFile)
1124
1125 msg := `\n******************************\n` +
1126 `You have tried to change the API from what has been previously released in\n` +
1127 `an SDK. Please fix the errors listed above.\n` +
1128 `******************************\n`
1129
1130 rule.Command().
1131 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1132 Text(") || (").
1133 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1134 Text("; exit 38").
1135 Text(")")
1136
1137 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001138 }
1139}
1140
1141//
1142// Droidstubs
1143//
1144type Droidstubs struct {
1145 Javadoc
1146
Pete Gillin581d6082018-10-22 15:55:04 +01001147 properties DroidstubsProperties
1148 apiFile android.WritablePath
1149 apiXmlFile android.WritablePath
1150 lastReleasedApiXmlFile android.WritablePath
1151 dexApiFile android.WritablePath
1152 privateApiFile android.WritablePath
1153 privateDexApiFile android.WritablePath
1154 removedApiFile android.WritablePath
1155 removedDexApiFile android.WritablePath
1156 apiMappingFile android.WritablePath
1157 exactApiFile android.WritablePath
1158 proguardFile android.WritablePath
1159 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001160
1161 checkCurrentApiTimestamp android.WritablePath
1162 updateCurrentApiTimestamp android.WritablePath
1163 checkLastReleasedApiTimestamp android.WritablePath
1164
Pete Gillin581d6082018-10-22 15:55:04 +01001165 checkNullabilityWarningsTimestamp android.WritablePath
1166
Nan Zhang1598a9e2018-09-04 17:14:32 -07001167 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001168 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001169
1170 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001171
1172 jdiffDocZip android.WritablePath
1173 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001174}
1175
Colin Crossa3002fc2019-07-08 16:48:04 -07001176// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1177// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1178// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001179func DroidstubsFactory() android.Module {
1180 module := &Droidstubs{}
1181
1182 module.AddProperties(&module.properties,
1183 &module.Javadoc.properties)
1184
1185 InitDroiddocModule(module, android.HostAndDeviceSupported)
1186 return module
1187}
1188
Colin Crossa3002fc2019-07-08 16:48:04 -07001189// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1190// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1191// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1192// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001193func DroidstubsHostFactory() android.Module {
1194 module := &Droidstubs{}
1195
1196 module.AddProperties(&module.properties,
1197 &module.Javadoc.properties)
1198
1199 InitDroiddocModule(module, android.HostSupported)
1200 return module
1201}
1202
1203func (d *Droidstubs) ApiFilePath() android.Path {
1204 return d.apiFilePath
1205}
1206
1207func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1208 d.Javadoc.addDeps(ctx)
1209
Inseob Kim38449af2019-02-28 14:24:05 +09001210 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1211 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1212 }
1213
Nan Zhang1598a9e2018-09-04 17:14:32 -07001214 if len(d.properties.Merge_annotations_dirs) != 0 {
1215 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1216 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1217 }
1218 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001219
Pete Gillin77167902018-09-19 18:16:26 +01001220 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1221 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1222 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1223 }
1224 }
1225
Nan Zhang9c69a122018-08-22 10:22:08 -07001226 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1227 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1228 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1229 }
1230 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001231}
1232
Colin Cross33961b52019-07-11 11:01:22 -07001233func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001234 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1235 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1236 String(d.properties.Api_filename) != "" {
1237 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001238 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001239 d.apiFilePath = d.apiFile
1240 }
1241
1242 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1243 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1244 String(d.properties.Removed_api_filename) != "" {
1245 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001246 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001247 }
1248
1249 if String(d.properties.Private_api_filename) != "" {
1250 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001251 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001252 }
1253
1254 if String(d.properties.Dex_api_filename) != "" {
1255 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001256 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257 }
1258
1259 if String(d.properties.Private_dex_api_filename) != "" {
1260 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001261 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001262 }
1263
1264 if String(d.properties.Removed_dex_api_filename) != "" {
1265 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001266 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001267 }
1268
1269 if String(d.properties.Exact_api_filename) != "" {
1270 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001271 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001272 }
1273
Nan Zhang9c69a122018-08-22 10:22:08 -07001274 if String(d.properties.Dex_mapping_filename) != "" {
1275 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001277 }
1278
Nan Zhang199645c2018-09-19 12:40:06 -07001279 if String(d.properties.Proguard_filename) != "" {
1280 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001281 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001282 }
1283
Nan Zhang9c69a122018-08-22 10:22:08 -07001284 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001286 }
1287
Nan Zhang1598a9e2018-09-04 17:14:32 -07001288 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001289 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001290 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001291 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001293}
1294
Colin Cross33961b52019-07-11 11:01:22 -07001295func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001297 cmd.Flag("--include-annotations")
1298
Pete Gillinc382a562018-11-14 18:45:46 +00001299 validatingNullability :=
1300 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1301 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001302 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001303
Pete Gillina262c052018-09-14 14:25:48 +01001304 if !(migratingNullability || validatingNullability) {
1305 ctx.PropertyErrorf("previous_api",
1306 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001307 }
Colin Cross33961b52019-07-11 11:01:22 -07001308
Pete Gillina262c052018-09-14 14:25:48 +01001309 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001310 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001311 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001312 }
Colin Cross33961b52019-07-11 11:01:22 -07001313
Pete Gillinc382a562018-11-14 18:45:46 +00001314 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001316 }
Colin Cross33961b52019-07-11 11:01:22 -07001317
Pete Gillina262c052018-09-14 14:25:48 +01001318 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001319 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001320 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001321 }
Nan Zhanga40da042018-08-01 12:48:00 -07001322
1323 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001324 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001325
Nan Zhang1598a9e2018-09-04 17:14:32 -07001326 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001327 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001328 "has to be non-empty if annotations was enabled!")
1329 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001330
Colin Cross33961b52019-07-11 11:01:22 -07001331 d.mergeAnnoDirFlags(ctx, cmd)
1332
1333 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1334 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1335 FlagWithArg("--hide ", "SuperfluousPrefix").
1336 FlagWithArg("--hide ", "AnnotationExtraction")
1337 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001338}
1339
Colin Cross33961b52019-07-11 11:01:22 -07001340func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1341 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1342 if t, ok := m.(*ExportedDroiddocDir); ok {
1343 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1344 } else {
1345 ctx.PropertyErrorf("merge_annotations_dirs",
1346 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1347 }
1348 })
1349}
1350
1351func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001352 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1353 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001354 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001355 } else {
1356 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1357 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1358 }
1359 })
Nan Zhanga40da042018-08-01 12:48:00 -07001360}
1361
Colin Cross33961b52019-07-11 11:01:22 -07001362func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001363 if Bool(d.properties.Api_levels_annotations_enabled) {
1364 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001365
1366 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1367 ctx.PropertyErrorf("api_levels_annotations_dirs",
1368 "has to be non-empty if api levels annotations was enabled!")
1369 }
1370
Colin Cross33961b52019-07-11 11:01:22 -07001371 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1372 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1373 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1374 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001375
1376 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1377 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001378 for _, dep := range t.deps {
1379 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001380 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001381 }
1382 }
Colin Cross33961b52019-07-11 11:01:22 -07001383 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001384 } else {
1385 ctx.PropertyErrorf("api_levels_annotations_dirs",
1386 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1387 }
1388 })
1389
1390 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001391}
1392
Colin Cross33961b52019-07-11 11:01:22 -07001393func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001394 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1395 if d.apiFile.String() == "" {
1396 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1397 }
1398
1399 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001400 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001401
1402 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1403 ctx.PropertyErrorf("check_api.last_released.api_file",
1404 "has to be non-empty if jdiff was enabled!")
1405 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001406
Colin Cross33961b52019-07-11 11:01:22 -07001407 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001408 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001409 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1410 }
1411}
Nan Zhang71bbe632018-09-17 14:32:21 -07001412
Colin Cross33961b52019-07-11 11:01:22 -07001413func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1414 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1415 cmd := rule.Command().BuiltTool(ctx, "metalava").
1416 Flag(config.JavacVmFlags).
1417 FlagWithArg("-encoding ", "UTF-8").
1418 FlagWithArg("-source ", javaVersion).
1419 FlagWithRspFileInputList("@", srcs).
1420 FlagWithInput("@", srcJarList)
1421
1422 if len(bootclasspath) > 0 {
1423 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001424 }
1425
Colin Cross33961b52019-07-11 11:01:22 -07001426 if len(classpath) > 0 {
1427 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1428 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001429
Colin Cross33961b52019-07-11 11:01:22 -07001430 if len(sourcepaths) > 0 {
1431 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1432 } else {
1433 cmd.FlagWithArg("-sourcepath ", `""`)
1434 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001435
Colin Cross33961b52019-07-11 11:01:22 -07001436 cmd.Flag("--no-banner").
1437 Flag("--color").
1438 Flag("--quiet").
1439 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001440
Colin Cross33961b52019-07-11 11:01:22 -07001441 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001442}
1443
Nan Zhang1598a9e2018-09-04 17:14:32 -07001444func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001445 deps := d.Javadoc.collectDeps(ctx)
1446
1447 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001448
Colin Cross33961b52019-07-11 11:01:22 -07001449 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001450
Colin Crossdaa4c672019-07-15 22:53:46 -07001451 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001452
Colin Cross33961b52019-07-11 11:01:22 -07001453 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1454 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001455
Colin Cross33961b52019-07-11 11:01:22 -07001456 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001457
Colin Cross33961b52019-07-11 11:01:22 -07001458 rule.Command().Text("rm -rf").Text(stubsDir.String())
1459 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001460
Colin Cross33961b52019-07-11 11:01:22 -07001461 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1462
1463 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1464 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1465
1466 d.stubsFlags(ctx, cmd, stubsDir)
1467
1468 d.annotationsFlags(ctx, cmd)
1469 d.inclusionAnnotationsFlags(ctx, cmd)
1470 d.apiLevelsAnnotationsFlags(ctx, cmd)
1471 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001472
Nan Zhang1598a9e2018-09-04 17:14:32 -07001473 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1474 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1475 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1476 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1477 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001478 }
Colin Cross33961b52019-07-11 11:01:22 -07001479
1480 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1481 for _, o := range d.Javadoc.properties.Out {
1482 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1483 }
1484
1485 rule.Command().
1486 BuiltTool(ctx, "soong_zip").
1487 Flag("-write_if_changed").
1488 Flag("-jar").
1489 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1490 FlagWithArg("-C ", stubsDir.String()).
1491 FlagWithArg("-D ", stubsDir.String())
1492 rule.Restat()
1493
1494 zipSyncCleanupCmd(rule, srcJarDir)
1495
1496 rule.Build(pctx, ctx, "metalava", "metalava")
1497
1498 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001499
Nan Zhang1598a9e2018-09-04 17:14:32 -07001500 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1501 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001502
1503 if len(d.Javadoc.properties.Out) > 0 {
1504 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1505 }
1506
1507 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1508 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001509
Nan Zhang2760dfc2018-08-24 17:32:54 +00001510 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001511
Colin Cross33961b52019-07-11 11:01:22 -07001512 rule := android.NewRuleBuilder()
1513
1514 rule.Command().Text("( true")
1515
1516 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1517 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1518
1519 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1520 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1521
1522 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1523 FlagWithInput("--check-compatibility:api:current ", apiFile).
1524 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1525
1526 d.inclusionAnnotationsFlags(ctx, cmd)
1527 d.mergeAnnoDirFlags(ctx, cmd)
1528
1529 zipSyncCleanupCmd(rule, srcJarDir)
1530
1531 msg := fmt.Sprintf(`\n******************************\n`+
1532 `You have tried to change the API from what has been previously approved.\n\n`+
1533 `To make these errors go away, you have two choices:\n`+
1534 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1535 ` errors above.\n\n`+
1536 ` 2. You can update current.txt by executing the following command:\n`+
1537 ` make %s-update-current-api\n\n`+
1538 ` To submit the revised current.txt to the main Android repository,\n`+
1539 ` you will need approval.\n`+
1540 `******************************\n`, ctx.ModuleName())
1541
1542 rule.Command().
1543 Text("touch").Output(d.checkCurrentApiTimestamp).
1544 Text(") || (").
1545 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1546 Text("; exit 38").
1547 Text(")")
1548
1549 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001550
1551 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001552
1553 // update API rule
1554 rule = android.NewRuleBuilder()
1555
1556 rule.Command().Text("( true")
1557
1558 rule.Command().
1559 Text("cp").Flag("-f").
1560 Input(d.apiFile).Flag(apiFile.String())
1561
1562 rule.Command().
1563 Text("cp").Flag("-f").
1564 Input(d.removedApiFile).Flag(removedApiFile.String())
1565
1566 msg = "failed to update public API"
1567
1568 rule.Command().
1569 Text("touch").Output(d.updateCurrentApiTimestamp).
1570 Text(") || (").
1571 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1572 Text("; exit 38").
1573 Text(")")
1574
1575 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001576 }
Nan Zhanga40da042018-08-01 12:48:00 -07001577
Nan Zhang1598a9e2018-09-04 17:14:32 -07001578 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1579 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001580
1581 if len(d.Javadoc.properties.Out) > 0 {
1582 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1583 }
1584
1585 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1586 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001587
Nan Zhang2760dfc2018-08-24 17:32:54 +00001588 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001589
Colin Cross33961b52019-07-11 11:01:22 -07001590 rule := android.NewRuleBuilder()
1591
1592 rule.Command().Text("( true")
1593
1594 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1595 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1596
1597 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1598 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1599
1600 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1601 FlagWithInput("--check-compatibility:api:released ", apiFile)
1602
1603 d.inclusionAnnotationsFlags(ctx, cmd)
1604
1605 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1606
1607 d.mergeAnnoDirFlags(ctx, cmd)
1608
1609 zipSyncCleanupCmd(rule, srcJarDir)
1610
1611 msg := `\n******************************\n` +
1612 `You have tried to change the API from what has been previously released in\n` +
1613 `an SDK. Please fix the errors listed above.\n` +
1614 `******************************\n`
1615 rule.Command().
1616 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1617 Text(") || (").
1618 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1619 Text("; exit 38").
1620 Text(")")
1621
1622 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001623 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001624
Pete Gillin581d6082018-10-22 15:55:04 +01001625 if String(d.properties.Check_nullability_warnings) != "" {
1626 if d.nullabilityWarningsFile == nil {
1627 ctx.PropertyErrorf("check_nullability_warnings",
1628 "Cannot specify check_nullability_warnings unless validating nullability")
1629 }
Colin Cross33961b52019-07-11 11:01:22 -07001630
1631 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1632
Pete Gillin581d6082018-10-22 15:55:04 +01001633 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001634
Pete Gillin581d6082018-10-22 15:55:04 +01001635 msg := fmt.Sprintf(`\n******************************\n`+
1636 `The warnings encountered during nullability annotation validation did\n`+
1637 `not match the checked in file of expected warnings. The diffs are shown\n`+
1638 `above. You have two options:\n`+
1639 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1640 ` 2. Update the file of expected warnings by running:\n`+
1641 ` cp %s %s\n`+
1642 ` and submitting the updated file as part of your change.`,
1643 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001644
1645 rule := android.NewRuleBuilder()
1646
1647 rule.Command().
1648 Text("(").
1649 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1650 Text("&&").
1651 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1652 Text(") || (").
1653 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1654 Text("; exit 38").
1655 Text(")")
1656
1657 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001658 }
1659
Nan Zhang71bbe632018-09-17 14:32:21 -07001660 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001661 if len(d.Javadoc.properties.Out) > 0 {
1662 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1663 }
1664
1665 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1666 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1667 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1668
1669 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001670
Nan Zhang86b06202018-09-21 17:09:21 -07001671 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1672 // since there's cron job downstream that fetch this .zip file periodically.
1673 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001674 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1675 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1676
Nan Zhang71bbe632018-09-17 14:32:21 -07001677 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001678
Colin Cross33961b52019-07-11 11:01:22 -07001679 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1680 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001681
Colin Cross33961b52019-07-11 11:01:22 -07001682 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1683
Colin Crossdaa4c672019-07-15 22:53:46 -07001684 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001685 deps.bootClasspath, deps.classpath, d.sourcepaths)
1686
1687 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001688 Flag("-XDignore.symbol.file").
1689 FlagWithArg("-doclet ", "jdiff.JDiff").
1690 FlagWithInput("-docletpath ", jdiff).
1691 Flag("-quiet").
1692 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1693 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1694 Implicit(d.apiXmlFile).
1695 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1696 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1697 Implicit(d.lastReleasedApiXmlFile)
1698
Colin Cross33961b52019-07-11 11:01:22 -07001699 rule.Command().
1700 BuiltTool(ctx, "soong_zip").
1701 Flag("-write_if_changed").
1702 Flag("-d").
1703 FlagWithOutput("-o ", d.jdiffDocZip).
1704 FlagWithArg("-C ", outDir.String()).
1705 FlagWithArg("-D ", outDir.String())
1706
1707 rule.Command().
1708 BuiltTool(ctx, "soong_zip").
1709 Flag("-write_if_changed").
1710 Flag("-jar").
1711 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1712 FlagWithArg("-C ", stubsDir.String()).
1713 FlagWithArg("-D ", stubsDir.String())
1714
1715 rule.Restat()
1716
1717 zipSyncCleanupCmd(rule, srcJarDir)
1718
1719 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001720 }
Nan Zhang581fd212018-01-10 16:06:12 -08001721}
Dan Willemsencc090972018-02-26 14:33:31 -08001722
Nan Zhanga40da042018-08-01 12:48:00 -07001723//
Nan Zhangf4936b02018-08-01 15:00:28 -07001724// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001725//
Dan Willemsencc090972018-02-26 14:33:31 -08001726var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001727var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001728var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001729var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001730
Nan Zhangf4936b02018-08-01 15:00:28 -07001731type ExportedDroiddocDirProperties struct {
1732 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001733 Path *string
1734}
1735
Nan Zhangf4936b02018-08-01 15:00:28 -07001736type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001737 android.ModuleBase
1738
Nan Zhangf4936b02018-08-01 15:00:28 -07001739 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001740
1741 deps android.Paths
1742 dir android.Path
1743}
1744
Colin Crossa3002fc2019-07-08 16:48:04 -07001745// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001746func ExportedDroiddocDirFactory() android.Module {
1747 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001748 module.AddProperties(&module.properties)
1749 android.InitAndroidModule(module)
1750 return module
1751}
1752
Nan Zhangf4936b02018-08-01 15:00:28 -07001753func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001754
Nan Zhangf4936b02018-08-01 15:00:28 -07001755func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001756 path := String(d.properties.Path)
1757 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001758 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001759}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001760
1761//
1762// Defaults
1763//
1764type DocDefaults struct {
1765 android.ModuleBase
1766 android.DefaultsModuleBase
1767}
1768
Nan Zhangb2b33de2018-02-23 11:18:47 -08001769func DocDefaultsFactory() android.Module {
1770 module := &DocDefaults{}
1771
1772 module.AddProperties(
1773 &JavadocProperties{},
1774 &DroiddocProperties{},
1775 )
1776
1777 android.InitDefaultsModule(module)
1778
1779 return module
1780}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001781
1782func StubsDefaultsFactory() android.Module {
1783 module := &DocDefaults{}
1784
1785 module.AddProperties(
1786 &JavadocProperties{},
1787 &DroidstubsProperties{},
1788 )
1789
1790 android.InitDefaultsModule(module)
1791
1792 return module
1793}
Colin Cross33961b52019-07-11 11:01:22 -07001794
1795func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1796 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1797
1798 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1799 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1800 srcJarList := srcJarDir.Join(ctx, "list")
1801
1802 rule.Temporary(srcJarList)
1803
1804 rule.Command().BuiltTool(ctx, "zipsync").
1805 FlagWithArg("-d ", srcJarDir.String()).
1806 FlagWithOutput("-l ", srcJarList).
1807 FlagWithArg("-f ", `"*.java"`).
1808 Inputs(srcJars)
1809
1810 return srcJarList
1811}
1812
1813func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1814 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1815}