blob: 5c51479ac070a04eacf97ff1bc02a309db66c834 [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
Jiyong Park1112c4c2019-08-16 21:12:10 +090067 // List of packages to document from srcs_lib
Nan Zhangb2b33de2018-02-23 11:18:47 -080068 Srcs_lib_whitelist_pkgs []string
69
Nan Zhang581fd212018-01-10 16:06:12 -080070 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080071 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080072
73 // if not blank, set to the version of the sdk to compile against
74 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090075
76 Aidl struct {
77 // Top level directories to pass to aidl tool
78 Include_dirs []string
79
80 // Directories rooted at the Android.bp file to pass to aidl tool
81 Local_include_dirs []string
82 }
Nan Zhang357466b2018-04-17 17:38:36 -070083
84 // If not blank, set the java version passed to javadoc as -source
85 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070086
87 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080088 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070089
90 // user customized droiddoc args.
91 // Available variables for substitution:
92 //
93 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070094 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070095 Args *string
96
97 // names of the output files used in args that will be generated
98 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080099}
100
Nan Zhang61819ce2018-05-04 18:49:16 -0700101type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900102 // path to the API txt file that the new API extracted from source code is checked
103 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800104 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700105
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900106 // path to the API txt file that the new @removed API extractd from source code is
107 // checked against. The path can be local to the module or from other module (via
108 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800109 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700110
Adrian Roos14f75a92019-08-12 17:54:09 +0200111 // If not blank, path to the baseline txt file for approved API check violations.
112 Baseline_file *string `android:"path"`
113
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 Zhanga40da042018-08-01 12:48:00 -0700428func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
429 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900430
Colin Cross3047fa22019-04-18 10:56:44 -0700431 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900432
433 return flags
434}
435
436func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700437 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900438
439 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
440 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
441
442 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700443 var deps android.Paths
444
Jiyong Park1e440682018-05-23 18:42:04 +0900445 if aidlPreprocess.Valid() {
446 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700447 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900448 } else {
449 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
450 }
451
452 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
453 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
454 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
455 flags = append(flags, "-I"+src.String())
456 }
457
Colin Cross3047fa22019-04-18 10:56:44 -0700458 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900459}
460
461func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700462 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900463
464 outSrcFiles := make(android.Paths, 0, len(srcFiles))
465
Jiyong Park1112c4c2019-08-16 21:12:10 +0900466 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
467
Jiyong Park1e440682018-05-23 18:42:04 +0900468 for _, srcFile := range srcFiles {
469 switch srcFile.Ext() {
470 case ".aidl":
Jiyong Park1112c4c2019-08-16 21:12:10 +0900471 javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900472 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900473 case ".sysprop":
474 javaFile := genSysprop(ctx, srcFile)
475 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900476 default:
477 outSrcFiles = append(outSrcFiles, srcFile)
478 }
479 }
480
481 return outSrcFiles
482}
483
Nan Zhang581fd212018-01-10 16:06:12 -0800484func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
485 var deps deps
486
Colin Cross83bb3162018-06-25 15:48:06 -0700487 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800488 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700489 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800490 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700491 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800492 }
493
494 ctx.VisitDirectDeps(func(module android.Module) {
495 otherName := ctx.OtherModuleName(module)
496 tag := ctx.OtherModuleDependencyTag(module)
497
Colin Cross2d24c1b2018-05-23 10:59:18 -0700498 switch tag {
499 case bootClasspathTag:
500 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800501 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700502 } else {
503 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
504 }
505 case libTag:
506 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800507 case SdkLibraryDependency:
508 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700509 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900510 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900511 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700512 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800513 checkProducesJars(ctx, dep)
514 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800515 default:
516 ctx.ModuleErrorf("depends on non-java module %q", otherName)
517 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700518 case srcsLibTag:
519 switch dep := module.(type) {
520 case Dependency:
521 srcs := dep.(SrcDependency).CompiledSrcs()
Colin Crossa1ce2a02018-06-20 15:19:39 -0700522 for _, src := range srcs {
523 if _, ok := src.(android.WritablePath); ok { // generated sources
524 deps.srcs = append(deps.srcs, src)
525 } else { // select source path for documentation based on whitelist path prefixs.
Jiyong Park1112c4c2019-08-16 21:12:10 +0900526 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
527 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
528 if strings.HasPrefix(src.Rel(), pkgAsPath) {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700529 deps.srcs = append(deps.srcs, src)
530 break
531 }
532 }
533 }
534 }
535 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
536 default:
537 ctx.ModuleErrorf("depends on non-java module %q", otherName)
538 }
Nan Zhang357466b2018-04-17 17:38:36 -0700539 case systemModulesTag:
540 if deps.systemModules != nil {
541 panic("Found two system module dependencies")
542 }
543 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000544 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700545 panic("Missing directory for system module dependency")
546 }
Colin Crossb77043e2019-07-16 13:57:13 -0700547 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800548 }
549 })
550 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
551 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800552 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700553 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900554 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800555
556 // srcs may depend on some genrule output.
557 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800558 j.srcJars = append(j.srcJars, deps.srcJars...)
559
Nan Zhang581fd212018-01-10 16:06:12 -0800560 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800561 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800562
Nan Zhang9c69a122018-08-22 10:22:08 -0700563 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800564 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
565 }
566 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800567
Colin Cross8a497952019-03-05 22:25:09 -0800568 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000569 argFilesMap := map[string]string{}
570 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700571
Paul Duffin99e4a502019-02-11 15:38:42 +0000572 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800573 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000574 if _, exists := argFilesMap[label]; !exists {
575 argFilesMap[label] = strings.Join(paths.Strings(), " ")
576 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700577 } else {
578 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000579 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700580 }
581 }
582
583 var err error
Colin Cross15638152019-07-11 11:11:35 -0700584 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700585 if strings.HasPrefix(name, "location ") {
586 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000587 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700588 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700589 } else {
Colin Cross15638152019-07-11 11:11:35 -0700590 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000591 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700592 }
593 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700594 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700595 }
Colin Cross15638152019-07-11 11:11:35 -0700596 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700597 })
598
599 if err != nil {
600 ctx.PropertyErrorf("args", "%s", err.Error())
601 }
602
Nan Zhang581fd212018-01-10 16:06:12 -0800603 return deps
604}
605
606func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
607 j.addDeps(ctx)
608}
609
610func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
611 deps := j.collectDeps(ctx)
612
Colin Crossdaa4c672019-07-15 22:53:46 -0700613 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800614
Colin Crossdaa4c672019-07-15 22:53:46 -0700615 outDir := android.PathForModuleOut(ctx, "out")
616 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
617
618 j.stubsSrcJar = nil
619
620 rule := android.NewRuleBuilder()
621
622 rule.Command().Text("rm -rf").Text(outDir.String())
623 rule.Command().Text("mkdir -p").Text(outDir.String())
624
625 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700626
Colin Cross83bb3162018-06-25 15:48:06 -0700627 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800628
Colin Crossdaa4c672019-07-15 22:53:46 -0700629 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
630 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800631
Colin Crossdaa4c672019-07-15 22:53:46 -0700632 cmd.FlagWithArg("-source ", javaVersion).
633 Flag("-J-Xmx1024m").
634 Flag("-XDignore.symbol.file").
635 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800636
Colin Crossdaa4c672019-07-15 22:53:46 -0700637 rule.Command().
638 BuiltTool(ctx, "soong_zip").
639 Flag("-write_if_changed").
640 Flag("-d").
641 FlagWithOutput("-o ", j.docZip).
642 FlagWithArg("-C ", outDir.String()).
643 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700644
Colin Crossdaa4c672019-07-15 22:53:46 -0700645 rule.Restat()
646
647 zipSyncCleanupCmd(rule, srcJarDir)
648
649 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800650}
651
Nan Zhanga40da042018-08-01 12:48:00 -0700652//
653// Droiddoc
654//
655type Droiddoc struct {
656 Javadoc
657
658 properties DroiddocProperties
659 apiFile android.WritablePath
660 dexApiFile android.WritablePath
661 privateApiFile android.WritablePath
662 privateDexApiFile android.WritablePath
663 removedApiFile android.WritablePath
664 removedDexApiFile android.WritablePath
665 exactApiFile android.WritablePath
666 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700667 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700668
669 checkCurrentApiTimestamp android.WritablePath
670 updateCurrentApiTimestamp android.WritablePath
671 checkLastReleasedApiTimestamp android.WritablePath
672
Nan Zhanga40da042018-08-01 12:48:00 -0700673 apiFilePath android.Path
674}
675
Colin Crossa3002fc2019-07-08 16:48:04 -0700676// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700677func DroiddocFactory() android.Module {
678 module := &Droiddoc{}
679
680 module.AddProperties(&module.properties,
681 &module.Javadoc.properties)
682
683 InitDroiddocModule(module, android.HostAndDeviceSupported)
684 return module
685}
686
Colin Crossa3002fc2019-07-08 16:48:04 -0700687// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700688func DroiddocHostFactory() android.Module {
689 module := &Droiddoc{}
690
691 module.AddProperties(&module.properties,
692 &module.Javadoc.properties)
693
694 InitDroiddocModule(module, android.HostSupported)
695 return module
696}
697
698func (d *Droiddoc) ApiFilePath() android.Path {
699 return d.apiFilePath
700}
701
Nan Zhang581fd212018-01-10 16:06:12 -0800702func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
703 d.Javadoc.addDeps(ctx)
704
Inseob Kim38449af2019-02-28 14:24:05 +0900705 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
706 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
707 }
708
Nan Zhang79614d12018-04-19 18:03:39 -0700709 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800710 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
711 }
Nan Zhang581fd212018-01-10 16:06:12 -0800712}
713
Colin Crossab054432019-07-15 16:13:59 -0700714func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700715 var date string
716 if runtime.GOOS == "darwin" {
717 date = `date -r`
718 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700719 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700720 }
721
Nan Zhang443fa522018-08-20 20:58:28 -0700722 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
723 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
724 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700725 cmd.FlagWithArg("-source ", "1.8").
726 Flag("-J-Xmx1600m").
727 Flag("-J-XX:-OmitStackTraceInFastThrow").
728 Flag("-XDignore.symbol.file").
729 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
730 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
731 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700732 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700733
Nan Zhanga40da042018-08-01 12:48:00 -0700734 if String(d.properties.Custom_template) == "" {
735 // TODO: This is almost always droiddoc-templates-sdk
736 ctx.PropertyErrorf("custom_template", "must specify a template")
737 }
738
739 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700740 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700741 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700742 } else {
743 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
744 }
745 })
746
747 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700748 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
749 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
750 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700751 }
752
753 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700754 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
755 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
756 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700757 }
758
759 if len(d.properties.Html_dirs) > 2 {
760 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
761 }
762
Colin Cross8a497952019-03-05 22:25:09 -0800763 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700764 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700765
Colin Crossab054432019-07-15 16:13:59 -0700766 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700767
768 if String(d.properties.Proofread_file) != "" {
769 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700770 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700771 }
772
773 if String(d.properties.Todo_file) != "" {
774 // tricky part:
775 // we should not compute full path for todo_file through PathForModuleOut().
776 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700777 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
778 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700779 }
780
781 if String(d.properties.Resourcesdir) != "" {
782 // TODO: should we add files under resourcesDir to the implicits? It seems that
783 // resourcesDir is one sub dir of htmlDir
784 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700785 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700786 }
787
788 if String(d.properties.Resourcesoutdir) != "" {
789 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700790 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700791 }
Nan Zhanga40da042018-08-01 12:48:00 -0700792}
793
Colin Crossab054432019-07-15 16:13:59 -0700794func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700795 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
796 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
797 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700798
Nan Zhanga40da042018-08-01 12:48:00 -0700799 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700800 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700801 d.apiFilePath = d.apiFile
802 }
803
Nan Zhang1598a9e2018-09-04 17:14:32 -0700804 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
805 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
806 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700807 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700808 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700809 }
810
811 if String(d.properties.Private_api_filename) != "" {
812 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700813 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700814 }
815
816 if String(d.properties.Dex_api_filename) != "" {
817 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700818 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700819 }
820
821 if String(d.properties.Private_dex_api_filename) != "" {
822 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 }
825
826 if String(d.properties.Removed_dex_api_filename) != "" {
827 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700828 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700829 }
830
831 if String(d.properties.Exact_api_filename) != "" {
832 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700834 }
835
836 if String(d.properties.Dex_mapping_filename) != "" {
837 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700838 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
Nan Zhang66dc2362018-08-14 20:41:04 -0700841 if String(d.properties.Proguard_filename) != "" {
842 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700843 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700844 }
845
Nan Zhanga40da042018-08-01 12:48:00 -0700846 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700847 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700848 }
849
850 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700851 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700852 }
Nan Zhanga40da042018-08-01 12:48:00 -0700853}
854
Colin Crossab054432019-07-15 16:13:59 -0700855func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700856 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700857 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
858 rule.Command().Text("cp").
859 Input(staticDocIndexRedirect).
860 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700861 }
862
863 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700864 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
865 rule.Command().Text("cp").
866 Input(staticDocProperties).
867 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700868 }
Nan Zhanga40da042018-08-01 12:48:00 -0700869}
870
Colin Crossab054432019-07-15 16:13:59 -0700871func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700872 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700873
874 cmd := rule.Command().
875 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
876 Flag(config.JavacVmFlags).
877 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700878 FlagWithRspFileInputList("@", srcs).
879 FlagWithInput("@", srcJarList)
880
Colin Crossab054432019-07-15 16:13:59 -0700881 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
882 // based stubs generation.
883 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
884 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
885 // the correct package name base path.
886 if len(sourcepaths) > 0 {
887 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
888 } else {
889 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
890 }
891
892 cmd.FlagWithArg("-d ", outDir.String()).
893 Flag("-quiet")
894
895 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700896}
897
Colin Crossdaa4c672019-07-15 22:53:46 -0700898func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
899 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
900 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
901
902 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
903
904 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
905 cmd.Flag(flag).Implicits(deps)
906
907 cmd.FlagWithArg("--patch-module ", "java.base=.")
908
909 if len(classpath) > 0 {
910 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
911 }
912
913 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700914}
915
Colin Crossdaa4c672019-07-15 22:53:46 -0700916func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
917 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
918 sourcepaths android.Paths) *android.RuleBuilderCommand {
919
920 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
921
922 if len(bootclasspath) == 0 && ctx.Device() {
923 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
924 // ensure java does not fall back to the default bootclasspath.
925 cmd.FlagWithArg("-bootclasspath ", `""`)
926 } else if len(bootclasspath) > 0 {
927 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
928 }
929
930 if len(classpath) > 0 {
931 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
932 }
933
934 return cmd
935}
936
Colin Crossab054432019-07-15 16:13:59 -0700937func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
938 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700939
Colin Crossab054432019-07-15 16:13:59 -0700940 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
941 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
942
943 return rule.Command().
944 BuiltTool(ctx, "dokka").
945 Flag(config.JavacVmFlags).
946 Flag(srcJarDir.String()).
947 FlagWithInputList("-classpath ", dokkaClasspath, ":").
948 FlagWithArg("-format ", "dac").
949 FlagWithArg("-dacRoot ", "/reference/kotlin").
950 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700951}
952
953func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
954 deps := d.Javadoc.collectDeps(ctx)
955
Colin Crossdaa4c672019-07-15 22:53:46 -0700956 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
957 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
958
Nan Zhang1598a9e2018-09-04 17:14:32 -0700959 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
960 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
961 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
962 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
963
Colin Crossab054432019-07-15 16:13:59 -0700964 outDir := android.PathForModuleOut(ctx, "out")
965 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
966 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700967
Colin Crossab054432019-07-15 16:13:59 -0700968 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700969
Colin Crossab054432019-07-15 16:13:59 -0700970 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
971 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700972
Colin Crossab054432019-07-15 16:13:59 -0700973 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
974
975 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700976 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700977 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700978 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700979 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700980 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700981 }
982
Colin Crossab054432019-07-15 16:13:59 -0700983 d.stubsFlags(ctx, cmd, stubsDir)
984
985 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
986
987 var desc string
988 if Bool(d.properties.Dokka_enabled) {
989 desc = "dokka"
990 } else {
991 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
992
993 for _, o := range d.Javadoc.properties.Out {
994 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
995 }
996
997 d.postDoclavaCmds(ctx, rule)
998 desc = "doclava"
999 }
1000
1001 rule.Command().
1002 BuiltTool(ctx, "soong_zip").
1003 Flag("-write_if_changed").
1004 Flag("-d").
1005 FlagWithOutput("-o ", d.docZip).
1006 FlagWithArg("-C ", outDir.String()).
1007 FlagWithArg("-D ", outDir.String())
1008
1009 rule.Command().
1010 BuiltTool(ctx, "soong_zip").
1011 Flag("-write_if_changed").
1012 Flag("-jar").
1013 FlagWithOutput("-o ", d.stubsSrcJar).
1014 FlagWithArg("-C ", stubsDir.String()).
1015 FlagWithArg("-D ", stubsDir.String())
1016
1017 rule.Restat()
1018
1019 zipSyncCleanupCmd(rule, srcJarDir)
1020
1021 rule.Build(pctx, ctx, "javadoc", desc)
1022
Nan Zhang1598a9e2018-09-04 17:14:32 -07001023 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1024 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001025
1026 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1027 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001028
1029 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001030
1031 rule := android.NewRuleBuilder()
1032
1033 rule.Command().Text("( true")
1034
1035 rule.Command().
1036 BuiltTool(ctx, "apicheck").
1037 Flag("-JXmx1024m").
1038 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1039 OptionalFlag(d.properties.Check_api.Current.Args).
1040 Input(apiFile).
1041 Input(d.apiFile).
1042 Input(removedApiFile).
1043 Input(d.removedApiFile)
1044
1045 msg := fmt.Sprintf(`\n******************************\n`+
1046 `You have tried to change the API from what has been previously approved.\n\n`+
1047 `To make these errors go away, you have two choices:\n`+
1048 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1049 ` errors above.\n\n`+
1050 ` 2. You can update current.txt by executing the following command:\n`+
1051 ` make %s-update-current-api\n\n`+
1052 ` To submit the revised current.txt to the main Android repository,\n`+
1053 ` you will need approval.\n`+
1054 `******************************\n`, ctx.ModuleName())
1055
1056 rule.Command().
1057 Text("touch").Output(d.checkCurrentApiTimestamp).
1058 Text(") || (").
1059 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1060 Text("; exit 38").
1061 Text(")")
1062
1063 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001064
1065 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001066
1067 // update API rule
1068 rule = android.NewRuleBuilder()
1069
1070 rule.Command().Text("( true")
1071
1072 rule.Command().
1073 Text("cp").Flag("-f").
1074 Input(d.apiFile).Flag(apiFile.String())
1075
1076 rule.Command().
1077 Text("cp").Flag("-f").
1078 Input(d.removedApiFile).Flag(removedApiFile.String())
1079
1080 msg = "failed to update public API"
1081
1082 rule.Command().
1083 Text("touch").Output(d.updateCurrentApiTimestamp).
1084 Text(") || (").
1085 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1086 Text("; exit 38").
1087 Text(")")
1088
1089 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001090 }
1091
1092 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1093 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001094
1095 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1096 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001097
1098 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001099
1100 rule := android.NewRuleBuilder()
1101
1102 rule.Command().
1103 Text("(").
1104 BuiltTool(ctx, "apicheck").
1105 Flag("-JXmx1024m").
1106 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1107 OptionalFlag(d.properties.Check_api.Last_released.Args).
1108 Input(apiFile).
1109 Input(d.apiFile).
1110 Input(removedApiFile).
1111 Input(d.removedApiFile)
1112
1113 msg := `\n******************************\n` +
1114 `You have tried to change the API from what has been previously released in\n` +
1115 `an SDK. Please fix the errors listed above.\n` +
1116 `******************************\n`
1117
1118 rule.Command().
1119 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1120 Text(") || (").
1121 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1122 Text("; exit 38").
1123 Text(")")
1124
1125 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001126 }
1127}
1128
1129//
1130// Droidstubs
1131//
1132type Droidstubs struct {
1133 Javadoc
1134
Pete Gillin581d6082018-10-22 15:55:04 +01001135 properties DroidstubsProperties
1136 apiFile android.WritablePath
1137 apiXmlFile android.WritablePath
1138 lastReleasedApiXmlFile android.WritablePath
1139 dexApiFile android.WritablePath
1140 privateApiFile android.WritablePath
1141 privateDexApiFile android.WritablePath
1142 removedApiFile android.WritablePath
1143 removedDexApiFile android.WritablePath
1144 apiMappingFile android.WritablePath
1145 exactApiFile android.WritablePath
1146 proguardFile android.WritablePath
1147 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001148
1149 checkCurrentApiTimestamp android.WritablePath
1150 updateCurrentApiTimestamp android.WritablePath
1151 checkLastReleasedApiTimestamp android.WritablePath
1152
Pete Gillin581d6082018-10-22 15:55:04 +01001153 checkNullabilityWarningsTimestamp android.WritablePath
1154
Nan Zhang1598a9e2018-09-04 17:14:32 -07001155 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001156 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001157
1158 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001159
1160 jdiffDocZip android.WritablePath
1161 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001162}
1163
Colin Crossa3002fc2019-07-08 16:48:04 -07001164// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1165// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1166// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001167func DroidstubsFactory() android.Module {
1168 module := &Droidstubs{}
1169
1170 module.AddProperties(&module.properties,
1171 &module.Javadoc.properties)
1172
1173 InitDroiddocModule(module, android.HostAndDeviceSupported)
1174 return module
1175}
1176
Colin Crossa3002fc2019-07-08 16:48:04 -07001177// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1178// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1179// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1180// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001181func DroidstubsHostFactory() android.Module {
1182 module := &Droidstubs{}
1183
1184 module.AddProperties(&module.properties,
1185 &module.Javadoc.properties)
1186
1187 InitDroiddocModule(module, android.HostSupported)
1188 return module
1189}
1190
1191func (d *Droidstubs) ApiFilePath() android.Path {
1192 return d.apiFilePath
1193}
1194
1195func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1196 d.Javadoc.addDeps(ctx)
1197
Inseob Kim38449af2019-02-28 14:24:05 +09001198 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1199 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1200 }
1201
Nan Zhang1598a9e2018-09-04 17:14:32 -07001202 if len(d.properties.Merge_annotations_dirs) != 0 {
1203 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1204 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1205 }
1206 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001207
Pete Gillin77167902018-09-19 18:16:26 +01001208 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1209 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1210 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1211 }
1212 }
1213
Nan Zhang9c69a122018-08-22 10:22:08 -07001214 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1215 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1216 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1217 }
1218 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001219}
1220
Colin Cross33961b52019-07-11 11:01:22 -07001221func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001222 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1223 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1224 String(d.properties.Api_filename) != "" {
1225 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001226 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001227 d.apiFilePath = d.apiFile
1228 }
1229
1230 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1231 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1232 String(d.properties.Removed_api_filename) != "" {
1233 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001234 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001235 }
1236
1237 if String(d.properties.Private_api_filename) != "" {
1238 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001239 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001240 }
1241
1242 if String(d.properties.Dex_api_filename) != "" {
1243 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001244 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001245 }
1246
1247 if String(d.properties.Private_dex_api_filename) != "" {
1248 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001249 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250 }
1251
1252 if String(d.properties.Removed_dex_api_filename) != "" {
1253 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001254 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255 }
1256
1257 if String(d.properties.Exact_api_filename) != "" {
1258 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001259 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260 }
1261
Nan Zhang9c69a122018-08-22 10:22:08 -07001262 if String(d.properties.Dex_mapping_filename) != "" {
1263 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001264 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001265 }
1266
Nan Zhang199645c2018-09-19 12:40:06 -07001267 if String(d.properties.Proguard_filename) != "" {
1268 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001269 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001270 }
1271
Nan Zhang9c69a122018-08-22 10:22:08 -07001272 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001273 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001274 }
1275
Nan Zhang1598a9e2018-09-04 17:14:32 -07001276 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001277 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001278 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001279 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001280 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001281}
1282
Colin Cross33961b52019-07-11 11:01:22 -07001283func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001284 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.Flag("--include-annotations")
1286
Pete Gillinc382a562018-11-14 18:45:46 +00001287 validatingNullability :=
1288 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1289 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001290 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001291
Pete Gillina262c052018-09-14 14:25:48 +01001292 if !(migratingNullability || validatingNullability) {
1293 ctx.PropertyErrorf("previous_api",
1294 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001295 }
Colin Cross33961b52019-07-11 11:01:22 -07001296
Pete Gillina262c052018-09-14 14:25:48 +01001297 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001298 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001299 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001300 }
Colin Cross33961b52019-07-11 11:01:22 -07001301
Pete Gillinc382a562018-11-14 18:45:46 +00001302 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001303 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001304 }
Colin Cross33961b52019-07-11 11:01:22 -07001305
Pete Gillina262c052018-09-14 14:25:48 +01001306 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001307 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001308 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001309 }
Nan Zhanga40da042018-08-01 12:48:00 -07001310
1311 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001312 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001313
Nan Zhang1598a9e2018-09-04 17:14:32 -07001314 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001315 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001316 "has to be non-empty if annotations was enabled!")
1317 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001318
Colin Cross33961b52019-07-11 11:01:22 -07001319 d.mergeAnnoDirFlags(ctx, cmd)
1320
1321 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1322 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1323 FlagWithArg("--hide ", "SuperfluousPrefix").
1324 FlagWithArg("--hide ", "AnnotationExtraction")
1325 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001326}
1327
Colin Cross33961b52019-07-11 11:01:22 -07001328func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1329 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1330 if t, ok := m.(*ExportedDroiddocDir); ok {
1331 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1332 } else {
1333 ctx.PropertyErrorf("merge_annotations_dirs",
1334 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1335 }
1336 })
1337}
1338
1339func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001340 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1341 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001342 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001343 } else {
1344 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1345 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1346 }
1347 })
Nan Zhanga40da042018-08-01 12:48:00 -07001348}
1349
Colin Cross33961b52019-07-11 11:01:22 -07001350func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001351 if Bool(d.properties.Api_levels_annotations_enabled) {
1352 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001353
1354 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1355 ctx.PropertyErrorf("api_levels_annotations_dirs",
1356 "has to be non-empty if api levels annotations was enabled!")
1357 }
1358
Colin Cross33961b52019-07-11 11:01:22 -07001359 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1360 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1361 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1362 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001363
1364 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1365 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001366 for _, dep := range t.deps {
1367 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001368 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001369 }
1370 }
Colin Cross33961b52019-07-11 11:01:22 -07001371 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001372 } else {
1373 ctx.PropertyErrorf("api_levels_annotations_dirs",
1374 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1375 }
1376 })
1377
1378 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001379}
1380
Colin Cross33961b52019-07-11 11:01:22 -07001381func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001382 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1383 if d.apiFile.String() == "" {
1384 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1385 }
1386
1387 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001388 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001389
1390 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1391 ctx.PropertyErrorf("check_api.last_released.api_file",
1392 "has to be non-empty if jdiff was enabled!")
1393 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001394
Colin Cross33961b52019-07-11 11:01:22 -07001395 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001396 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001397 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1398 }
1399}
Nan Zhang71bbe632018-09-17 14:32:21 -07001400
Colin Cross33961b52019-07-11 11:01:22 -07001401func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1402 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1403 cmd := rule.Command().BuiltTool(ctx, "metalava").
1404 Flag(config.JavacVmFlags).
1405 FlagWithArg("-encoding ", "UTF-8").
1406 FlagWithArg("-source ", javaVersion).
1407 FlagWithRspFileInputList("@", srcs).
1408 FlagWithInput("@", srcJarList)
1409
1410 if len(bootclasspath) > 0 {
1411 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001412 }
1413
Colin Cross33961b52019-07-11 11:01:22 -07001414 if len(classpath) > 0 {
1415 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1416 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001417
Colin Cross33961b52019-07-11 11:01:22 -07001418 if len(sourcepaths) > 0 {
1419 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1420 } else {
1421 cmd.FlagWithArg("-sourcepath ", `""`)
1422 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001423
Colin Cross33961b52019-07-11 11:01:22 -07001424 cmd.Flag("--no-banner").
1425 Flag("--color").
1426 Flag("--quiet").
1427 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001428
Colin Cross33961b52019-07-11 11:01:22 -07001429 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001430}
1431
Nan Zhang1598a9e2018-09-04 17:14:32 -07001432func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001433 deps := d.Javadoc.collectDeps(ctx)
1434
1435 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001436
Colin Cross33961b52019-07-11 11:01:22 -07001437 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001438
Colin Crossdaa4c672019-07-15 22:53:46 -07001439 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001440
Colin Cross33961b52019-07-11 11:01:22 -07001441 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1442 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001443
Colin Cross33961b52019-07-11 11:01:22 -07001444 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001445
Colin Cross33961b52019-07-11 11:01:22 -07001446 rule.Command().Text("rm -rf").Text(stubsDir.String())
1447 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001448
Colin Cross33961b52019-07-11 11:01:22 -07001449 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1450
1451 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1452 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1453
1454 d.stubsFlags(ctx, cmd, stubsDir)
1455
1456 d.annotationsFlags(ctx, cmd)
1457 d.inclusionAnnotationsFlags(ctx, cmd)
1458 d.apiLevelsAnnotationsFlags(ctx, cmd)
1459 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001460
Nan Zhang1598a9e2018-09-04 17:14:32 -07001461 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1462 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1463 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1464 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1465 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001466 }
Colin Cross33961b52019-07-11 11:01:22 -07001467
1468 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1469 for _, o := range d.Javadoc.properties.Out {
1470 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1471 }
1472
1473 rule.Command().
1474 BuiltTool(ctx, "soong_zip").
1475 Flag("-write_if_changed").
1476 Flag("-jar").
1477 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1478 FlagWithArg("-C ", stubsDir.String()).
1479 FlagWithArg("-D ", stubsDir.String())
1480 rule.Restat()
1481
1482 zipSyncCleanupCmd(rule, srcJarDir)
1483
1484 rule.Build(pctx, ctx, "metalava", "metalava")
1485
1486 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001487
Nan Zhang1598a9e2018-09-04 17:14:32 -07001488 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1489 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001490
1491 if len(d.Javadoc.properties.Out) > 0 {
1492 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1493 }
1494
1495 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1496 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001497 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1498 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001499
Nan Zhang2760dfc2018-08-24 17:32:54 +00001500 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001501
Colin Cross33961b52019-07-11 11:01:22 -07001502 rule := android.NewRuleBuilder()
1503
1504 rule.Command().Text("( true")
1505
1506 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1507 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1508
1509 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1510 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1511
1512 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1513 FlagWithInput("--check-compatibility:api:current ", apiFile).
1514 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1515
1516 d.inclusionAnnotationsFlags(ctx, cmd)
1517 d.mergeAnnoDirFlags(ctx, cmd)
1518
Adrian Roos14f75a92019-08-12 17:54:09 +02001519 if baselineFile.Valid() {
1520 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1521 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1522 }
1523
Colin Cross33961b52019-07-11 11:01:22 -07001524 zipSyncCleanupCmd(rule, srcJarDir)
1525
1526 msg := fmt.Sprintf(`\n******************************\n`+
1527 `You have tried to change the API from what has been previously approved.\n\n`+
1528 `To make these errors go away, you have two choices:\n`+
1529 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1530 ` errors above.\n\n`+
1531 ` 2. You can update current.txt by executing the following command:\n`+
1532 ` make %s-update-current-api\n\n`+
1533 ` To submit the revised current.txt to the main Android repository,\n`+
1534 ` you will need approval.\n`+
1535 `******************************\n`, ctx.ModuleName())
1536
1537 rule.Command().
1538 Text("touch").Output(d.checkCurrentApiTimestamp).
1539 Text(") || (").
1540 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1541 Text("; exit 38").
1542 Text(")")
1543
1544 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001545
1546 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001547
1548 // update API rule
1549 rule = android.NewRuleBuilder()
1550
1551 rule.Command().Text("( true")
1552
1553 rule.Command().
1554 Text("cp").Flag("-f").
1555 Input(d.apiFile).Flag(apiFile.String())
1556
1557 rule.Command().
1558 Text("cp").Flag("-f").
1559 Input(d.removedApiFile).Flag(removedApiFile.String())
1560
1561 msg = "failed to update public API"
1562
1563 rule.Command().
1564 Text("touch").Output(d.updateCurrentApiTimestamp).
1565 Text(") || (").
1566 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1567 Text("; exit 38").
1568 Text(")")
1569
1570 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001571 }
Nan Zhanga40da042018-08-01 12:48:00 -07001572
Nan Zhang1598a9e2018-09-04 17:14:32 -07001573 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1574 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001575
1576 if len(d.Javadoc.properties.Out) > 0 {
1577 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1578 }
1579
1580 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1581 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001582 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1583 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001584
Nan Zhang2760dfc2018-08-24 17:32:54 +00001585 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001586
Colin Cross33961b52019-07-11 11:01:22 -07001587 rule := android.NewRuleBuilder()
1588
1589 rule.Command().Text("( true")
1590
1591 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1592 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1593
1594 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1595 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1596
1597 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1598 FlagWithInput("--check-compatibility:api:released ", apiFile)
1599
1600 d.inclusionAnnotationsFlags(ctx, cmd)
1601
1602 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1603
1604 d.mergeAnnoDirFlags(ctx, cmd)
1605
Adrian Roos14f75a92019-08-12 17:54:09 +02001606 if baselineFile.Valid() {
1607 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1608 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1609 }
1610
Colin Cross33961b52019-07-11 11:01:22 -07001611 zipSyncCleanupCmd(rule, srcJarDir)
1612
1613 msg := `\n******************************\n` +
1614 `You have tried to change the API from what has been previously released in\n` +
1615 `an SDK. Please fix the errors listed above.\n` +
1616 `******************************\n`
1617 rule.Command().
1618 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1619 Text(") || (").
1620 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1621 Text("; exit 38").
1622 Text(")")
1623
1624 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001625 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001626
Pete Gillin581d6082018-10-22 15:55:04 +01001627 if String(d.properties.Check_nullability_warnings) != "" {
1628 if d.nullabilityWarningsFile == nil {
1629 ctx.PropertyErrorf("check_nullability_warnings",
1630 "Cannot specify check_nullability_warnings unless validating nullability")
1631 }
Colin Cross33961b52019-07-11 11:01:22 -07001632
1633 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1634
Pete Gillin581d6082018-10-22 15:55:04 +01001635 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001636
Pete Gillin581d6082018-10-22 15:55:04 +01001637 msg := fmt.Sprintf(`\n******************************\n`+
1638 `The warnings encountered during nullability annotation validation did\n`+
1639 `not match the checked in file of expected warnings. The diffs are shown\n`+
1640 `above. You have two options:\n`+
1641 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1642 ` 2. Update the file of expected warnings by running:\n`+
1643 ` cp %s %s\n`+
1644 ` and submitting the updated file as part of your change.`,
1645 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001646
1647 rule := android.NewRuleBuilder()
1648
1649 rule.Command().
1650 Text("(").
1651 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1652 Text("&&").
1653 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1654 Text(") || (").
1655 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1656 Text("; exit 38").
1657 Text(")")
1658
1659 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001660 }
1661
Nan Zhang71bbe632018-09-17 14:32:21 -07001662 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001663 if len(d.Javadoc.properties.Out) > 0 {
1664 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1665 }
1666
1667 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1668 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1669 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1670
1671 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001672
Nan Zhang86b06202018-09-21 17:09:21 -07001673 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1674 // since there's cron job downstream that fetch this .zip file periodically.
1675 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001676 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1677 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1678
Nan Zhang71bbe632018-09-17 14:32:21 -07001679 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001680
Colin Cross33961b52019-07-11 11:01:22 -07001681 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1682 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001683
Colin Cross33961b52019-07-11 11:01:22 -07001684 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1685
Colin Crossdaa4c672019-07-15 22:53:46 -07001686 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001687 deps.bootClasspath, deps.classpath, d.sourcepaths)
1688
1689 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001690 Flag("-XDignore.symbol.file").
1691 FlagWithArg("-doclet ", "jdiff.JDiff").
1692 FlagWithInput("-docletpath ", jdiff).
1693 Flag("-quiet").
1694 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1695 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1696 Implicit(d.apiXmlFile).
1697 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1698 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1699 Implicit(d.lastReleasedApiXmlFile)
1700
Colin Cross33961b52019-07-11 11:01:22 -07001701 rule.Command().
1702 BuiltTool(ctx, "soong_zip").
1703 Flag("-write_if_changed").
1704 Flag("-d").
1705 FlagWithOutput("-o ", d.jdiffDocZip).
1706 FlagWithArg("-C ", outDir.String()).
1707 FlagWithArg("-D ", outDir.String())
1708
1709 rule.Command().
1710 BuiltTool(ctx, "soong_zip").
1711 Flag("-write_if_changed").
1712 Flag("-jar").
1713 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1714 FlagWithArg("-C ", stubsDir.String()).
1715 FlagWithArg("-D ", stubsDir.String())
1716
1717 rule.Restat()
1718
1719 zipSyncCleanupCmd(rule, srcJarDir)
1720
1721 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001722 }
Nan Zhang581fd212018-01-10 16:06:12 -08001723}
Dan Willemsencc090972018-02-26 14:33:31 -08001724
Nan Zhanga40da042018-08-01 12:48:00 -07001725//
Nan Zhangf4936b02018-08-01 15:00:28 -07001726// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001727//
Dan Willemsencc090972018-02-26 14:33:31 -08001728var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001729var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001730var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001731var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001732
Nan Zhangf4936b02018-08-01 15:00:28 -07001733type ExportedDroiddocDirProperties struct {
1734 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001735 Path *string
1736}
1737
Nan Zhangf4936b02018-08-01 15:00:28 -07001738type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001739 android.ModuleBase
1740
Nan Zhangf4936b02018-08-01 15:00:28 -07001741 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001742
1743 deps android.Paths
1744 dir android.Path
1745}
1746
Colin Crossa3002fc2019-07-08 16:48:04 -07001747// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001748func ExportedDroiddocDirFactory() android.Module {
1749 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001750 module.AddProperties(&module.properties)
1751 android.InitAndroidModule(module)
1752 return module
1753}
1754
Nan Zhangf4936b02018-08-01 15:00:28 -07001755func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001756
Nan Zhangf4936b02018-08-01 15:00:28 -07001757func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001758 path := String(d.properties.Path)
1759 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001760 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001761}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001762
1763//
1764// Defaults
1765//
1766type DocDefaults struct {
1767 android.ModuleBase
1768 android.DefaultsModuleBase
1769}
1770
Nan Zhangb2b33de2018-02-23 11:18:47 -08001771func DocDefaultsFactory() android.Module {
1772 module := &DocDefaults{}
1773
1774 module.AddProperties(
1775 &JavadocProperties{},
1776 &DroiddocProperties{},
1777 )
1778
1779 android.InitDefaultsModule(module)
1780
1781 return module
1782}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001783
1784func StubsDefaultsFactory() android.Module {
1785 module := &DocDefaults{}
1786
1787 module.AddProperties(
1788 &JavadocProperties{},
1789 &DroidstubsProperties{},
1790 )
1791
1792 android.InitDefaultsModule(module)
1793
1794 return module
1795}
Colin Cross33961b52019-07-11 11:01:22 -07001796
1797func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1798 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1799
1800 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1801 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1802 srcJarList := srcJarDir.Join(ctx, "list")
1803
1804 rule.Temporary(srcJarList)
1805
1806 rule.Command().BuiltTool(ctx, "zipsync").
1807 FlagWithArg("-d ", srcJarDir.String()).
1808 FlagWithOutput("-l ", srcJarList).
1809 FlagWithArg("-f ", `"*.java"`).
1810 Inputs(srcJars)
1811
1812 return srcJarList
1813}
1814
1815func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1816 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1817}