blob: aab61c5a7de323f1778b38fd128ef634a33ddfd0 [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 Zhang581fd212018-01-10 16:06:12 -080020 "strings"
21
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080029 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070030 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080031
Nan Zhang581fd212018-01-10 16:06:12 -080032 android.RegisterModuleType("droiddoc", DroiddocFactory)
33 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070034 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080035 android.RegisterModuleType("javadoc", JavadocFactory)
36 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070037
38 android.RegisterModuleType("droidstubs", DroidstubsFactory)
39 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080040}
41
Colin Crossa1ce2a02018-06-20 15:19:39 -070042var (
43 srcsLibTag = dependencyTag{name: "sources from javalib"}
44)
45
Nan Zhang581fd212018-01-10 16:06:12 -080046type JavadocProperties struct {
47 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
48 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080049 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080050
51 // list of directories rooted at the Android.bp file that will
52 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080053 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080054
55 // list of source files that should not be used to build the Java module.
56 // This is most useful in the arch/multilib variants to remove non-common files
57 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080058 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080059
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090060 // list of package names that should actually be used. If this property is left unspecified,
61 // all the sources from the srcs property is used.
62 Filter_packages []string
63
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080065 Libs []string `android:"arch_variant"`
66
67 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080068 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080069
70 // if not blank, set to the version of the sdk to compile against
71 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090072
73 Aidl struct {
74 // Top level directories to pass to aidl tool
75 Include_dirs []string
76
77 // Directories rooted at the Android.bp file to pass to aidl tool
78 Local_include_dirs []string
79 }
Nan Zhang357466b2018-04-17 17:38:36 -070080
81 // If not blank, set the java version passed to javadoc as -source
82 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070083
84 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080085 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070086
87 // user customized droiddoc args.
88 // Available variables for substitution:
89 //
90 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070091 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070092 Args *string
93
94 // names of the output files used in args that will be generated
95 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080096}
97
Nan Zhang61819ce2018-05-04 18:49:16 -070098type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +090099 // path to the API txt file that the new API extracted from source code is checked
100 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800101 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700102
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900103 // path to the API txt file that the new @removed API extractd from source code is
104 // checked against. The path can be local to the module or from other module (via
105 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800106 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700107
Adrian Roos14f75a92019-08-12 17:54:09 +0200108 // If not blank, path to the baseline txt file for approved API check violations.
109 Baseline_file *string `android:"path"`
110
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900111 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700112 Args *string
113}
114
Nan Zhang581fd212018-01-10 16:06:12 -0800115type DroiddocProperties struct {
116 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800117 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800118
Nan Zhanga40da042018-08-01 12:48:00 -0700119 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800121
122 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
125 // proofread file contains all of the text content of the javadocs concatenated into one file,
126 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700127 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800128
129 // a todo file lists the program elements that are missing documentation.
130 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800131 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800132
133 // directory under current module source that provide additional resources (images).
134 Resourcesdir *string
135
136 // resources output directory under out/soong/.intermediates.
137 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800138
Nan Zhange2ba5d42018-07-11 15:16:55 -0700139 // if set to true, collect the values used by the Dev tools and
140 // write them in files packaged with the SDK. Defaults to false.
141 Write_sdk_values *bool
142
143 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800144 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145
146 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800147 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700148
Nan Zhang581fd212018-01-10 16:06:12 -0800149 // a list of files under current module source dir which contains known tags in Java sources.
150 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800151 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700152
153 // the tag name used to distinguish if the API files belong to public/system/test.
154 Api_tag_name *string
155
156 // the generated public API filename by Doclava.
157 Api_filename *string
158
David Brazdilfbe4cc32018-05-31 13:56:46 +0100159 // the generated public Dex API filename by Doclava.
160 Dex_api_filename *string
161
Nan Zhang28c68b92018-03-13 16:17:01 -0700162 // the generated private API filename by Doclava.
163 Private_api_filename *string
164
165 // the generated private Dex API filename by Doclava.
166 Private_dex_api_filename *string
167
168 // the generated removed API filename by Doclava.
169 Removed_api_filename *string
170
David Brazdilaac0c3c2018-04-24 16:23:29 +0100171 // the generated removed Dex API filename by Doclava.
172 Removed_dex_api_filename *string
173
Mathew Inwood76c3de12018-06-22 15:28:11 +0100174 // mapping of dex signatures to source file and line number. This is a temporary property and
175 // will be deleted; you probably shouldn't be using it.
176 Dex_mapping_filename *string
177
Nan Zhang28c68b92018-03-13 16:17:01 -0700178 // the generated exact API filename by Doclava.
179 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700180
Nan Zhang66dc2362018-08-14 20:41:04 -0700181 // the generated proguard filename by Doclava.
182 Proguard_filename *string
183
Nan Zhang853f4202018-04-12 16:55:56 -0700184 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
185 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700186
187 Check_api struct {
188 Last_released ApiToCheck
189
190 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900191
192 // do not perform API check against Last_released, in the case that both two specified API
193 // files by Last_released are modules which don't exist.
194 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700195 }
Nan Zhang79614d12018-04-19 18:03:39 -0700196
Nan Zhang1598a9e2018-09-04 17:14:32 -0700197 // if set to true, generate docs through Dokka instead of Doclava.
198 Dokka_enabled *bool
199}
200
201type DroidstubsProperties struct {
202 // the tag name used to distinguish if the API files belong to public/system/test.
203 Api_tag_name *string
204
Nan Zhang199645c2018-09-19 12:40:06 -0700205 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206 Api_filename *string
207
Nan Zhang199645c2018-09-19 12:40:06 -0700208 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Dex_api_filename *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Private_api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Private_dex_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Removed_api_filename *string
219
Nan Zhang199645c2018-09-19 12:40:06 -0700220 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700221 Removed_dex_api_filename *string
222
Nan Zhang9c69a122018-08-22 10:22:08 -0700223 // mapping of dex signatures to source file and line number. This is a temporary property and
224 // will be deleted; you probably shouldn't be using it.
225 Dex_mapping_filename *string
226
Nan Zhang199645c2018-09-19 12:40:06 -0700227 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700228 Exact_api_filename *string
229
Nan Zhang199645c2018-09-19 12:40:06 -0700230 // the generated proguard filename by Metalava.
231 Proguard_filename *string
232
Nan Zhang1598a9e2018-09-04 17:14:32 -0700233 Check_api struct {
234 Last_released ApiToCheck
235
236 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900237
238 // do not perform API check against Last_released, in the case that both two specified API
239 // files by Last_released are modules which don't exist.
240 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700241 }
Nan Zhang79614d12018-04-19 18:03:39 -0700242
243 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800244 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700245
246 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700247 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700248
Pete Gillin77167902018-09-19 18:16:26 +0100249 // 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 -0700250 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700251
Pete Gillin77167902018-09-19 18:16:26 +0100252 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
253 Merge_inclusion_annotations_dirs []string
254
Pete Gillinc382a562018-11-14 18:45:46 +0000255 // a file containing a list of classes to do nullability validation for.
256 Validate_nullability_from_list *string
257
Pete Gillin581d6082018-10-22 15:55:04 +0100258 // a file containing expected warnings produced by validation of nullability annotations.
259 Check_nullability_warnings *string
260
Nan Zhang1598a9e2018-09-04 17:14:32 -0700261 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
262 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700263
264 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
265 Api_levels_annotations_enabled *bool
266
267 // the dirs which Metalava extracts API levels annotations from.
268 Api_levels_annotations_dirs []string
269
270 // if set to true, collect the values used by the Dev tools and
271 // write them in files packaged with the SDK. Defaults to false.
272 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700273
274 // If set to true, .xml based public API file will be also generated, and
275 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
276 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800277}
278
Nan Zhanga40da042018-08-01 12:48:00 -0700279//
280// Common flags passed down to build rule
281//
282type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700283 bootClasspathArgs string
284 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700285 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700286 dokkaClasspathArgs string
287 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700288 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700289
Nan Zhanga40da042018-08-01 12:48:00 -0700290 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700291 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700292 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700293}
294
295func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
296 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
297 android.InitDefaultableModule(module)
298}
299
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200300func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
301 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
302 return false
303 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700304 return true
305 } else if String(apiToCheck.Api_file) != "" {
306 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
307 } else if String(apiToCheck.Removed_api_file) != "" {
308 panic("for " + apiVersionTag + " api_file has to be non-empty!")
309 }
310
311 return false
312}
313
Inseob Kim38449af2019-02-28 14:24:05 +0900314func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
315 api_file := String(apiToCheck.Api_file)
316 removed_api_file := String(apiToCheck.Removed_api_file)
317
318 api_module := android.SrcIsModule(api_file)
319 removed_api_module := android.SrcIsModule(removed_api_file)
320
321 if api_module == "" || removed_api_module == "" {
322 return
323 }
324
325 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
326 return
327 }
328
329 apiToCheck.Api_file = nil
330 apiToCheck.Removed_api_file = nil
331}
332
Nan Zhang1598a9e2018-09-04 17:14:32 -0700333type ApiFilePath interface {
334 ApiFilePath() android.Path
335}
336
Nan Zhanga40da042018-08-01 12:48:00 -0700337//
338// Javadoc
339//
Nan Zhang581fd212018-01-10 16:06:12 -0800340type Javadoc struct {
341 android.ModuleBase
342 android.DefaultableModuleBase
343
344 properties JavadocProperties
345
346 srcJars android.Paths
347 srcFiles android.Paths
348 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700349 argFiles android.Paths
350
351 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800352
Nan Zhangccff0f72018-03-08 17:26:16 -0800353 docZip android.WritablePath
354 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800355}
356
Colin Cross41955e82019-05-29 14:40:35 -0700357func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
358 switch tag {
359 case "":
360 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700361 case ".docs.zip":
362 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700363 default:
364 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
365 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800366}
367
Colin Crossa3002fc2019-07-08 16:48:04 -0700368// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800369func JavadocFactory() android.Module {
370 module := &Javadoc{}
371
372 module.AddProperties(&module.properties)
373
374 InitDroiddocModule(module, android.HostAndDeviceSupported)
375 return module
376}
377
Colin Crossa3002fc2019-07-08 16:48:04 -0700378// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800379func JavadocHostFactory() android.Module {
380 module := &Javadoc{}
381
382 module.AddProperties(&module.properties)
383
384 InitDroiddocModule(module, android.HostSupported)
385 return module
386}
387
Colin Cross41955e82019-05-29 14:40:35 -0700388var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800389
Colin Cross83bb3162018-06-25 15:48:06 -0700390func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900391 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700392}
393
394func (j *Javadoc) minSdkVersion() string {
395 return j.sdkVersion()
396}
397
Dan Willemsen419290a2018-10-31 15:28:47 -0700398func (j *Javadoc) targetSdkVersion() string {
399 return j.sdkVersion()
400}
401
Nan Zhang581fd212018-01-10 16:06:12 -0800402func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
403 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100404 sdkDep := decodeSdkDep(ctx, sdkContext(j))
405 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700406 if sdkDep.useDefaultLibs {
407 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
408 if ctx.Config().TargetOpenJDK9() {
409 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
410 }
Paul Duffin250e6192019-06-07 10:44:37 +0100411 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700412 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
413 }
414 } else if sdkDep.useModule {
415 if ctx.Config().TargetOpenJDK9() {
416 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
417 }
418 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700419 }
Nan Zhang581fd212018-01-10 16:06:12 -0800420 }
421 }
422
Colin Cross42d48b72018-08-29 14:10:52 -0700423 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800424}
425
Nan Zhanga40da042018-08-01 12:48:00 -0700426func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
427 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900428
Colin Cross3047fa22019-04-18 10:56:44 -0700429 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900430
431 return flags
432}
433
434func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700435 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900436
437 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
438 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
439
440 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700441 var deps android.Paths
442
Jiyong Park1e440682018-05-23 18:42:04 +0900443 if aidlPreprocess.Valid() {
444 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700445 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900446 } else {
447 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
448 }
449
450 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
451 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
452 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
453 flags = append(flags, "-I"+src.String())
454 }
455
Colin Cross3047fa22019-04-18 10:56:44 -0700456 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900457}
458
Jiyong Parkd90d7412019-08-20 22:49:19 +0900459// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900460func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700461 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900462
463 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700464 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900465
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":
Colin Crossc0806172019-06-14 18:51:47 -0700471 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900472 case ".logtags":
473 javaFile := genLogtags(ctx, srcFile)
474 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900475 default:
476 outSrcFiles = append(outSrcFiles, srcFile)
477 }
478 }
479
Colin Crossc0806172019-06-14 18:51:47 -0700480 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
481 if len(aidlSrcs) > 0 {
482 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
483 outSrcFiles = append(outSrcFiles, srcJarFiles...)
484 }
485
Jiyong Park1e440682018-05-23 18:42:04 +0900486 return outSrcFiles
487}
488
Nan Zhang581fd212018-01-10 16:06:12 -0800489func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
490 var deps deps
491
Colin Cross83bb3162018-06-25 15:48:06 -0700492 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800493 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700494 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800495 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700496 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800497 }
498
499 ctx.VisitDirectDeps(func(module android.Module) {
500 otherName := ctx.OtherModuleName(module)
501 tag := ctx.OtherModuleDependencyTag(module)
502
Colin Cross2d24c1b2018-05-23 10:59:18 -0700503 switch tag {
504 case bootClasspathTag:
505 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800506 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700507 } else {
508 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
509 }
510 case libTag:
511 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800512 case SdkLibraryDependency:
513 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700514 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900515 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900516 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700517 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800518 checkProducesJars(ctx, dep)
519 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800520 default:
521 ctx.ModuleErrorf("depends on non-java module %q", otherName)
522 }
Nan Zhang357466b2018-04-17 17:38:36 -0700523 case systemModulesTag:
524 if deps.systemModules != nil {
525 panic("Found two system module dependencies")
526 }
527 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000528 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700529 panic("Missing directory for system module dependency")
530 }
Colin Crossb77043e2019-07-16 13:57:13 -0700531 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800532 }
533 })
534 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
535 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800536 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900537
538 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
539 if filterPackages == nil {
540 return srcs
541 }
542 filtered := []android.Path{}
543 for _, src := range srcs {
544 if src.Ext() != ".java" {
545 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
546 // but otherwise metalava emits stub sources having references to the generated AIDL classes
547 // in filtered-out pacages (e.g. com.android.internal.*).
548 // TODO(b/141149570) We need to fix this by introducing default private constructors or
549 // fixing metalava to not emit constructors having references to unknown classes.
550 filtered = append(filtered, src)
551 continue
552 }
553 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
554 for _, pkg := range filterPackages {
555 if strings.HasPrefix(packageName, pkg) {
556 filtered = append(filtered, src)
557 break
558 }
559 }
560 }
561 return filtered
562 }
563 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
564
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 Zhang443fa522018-08-20 20:58:28 -0700727 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
728 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
729 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700730 cmd.FlagWithArg("-source ", "1.8").
731 Flag("-J-Xmx1600m").
732 Flag("-J-XX:-OmitStackTraceInFastThrow").
733 Flag("-XDignore.symbol.file").
734 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
735 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
736 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700737 FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700738
Nan Zhanga40da042018-08-01 12:48:00 -0700739 if String(d.properties.Custom_template) == "" {
740 // TODO: This is almost always droiddoc-templates-sdk
741 ctx.PropertyErrorf("custom_template", "must specify a template")
742 }
743
744 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700745 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700746 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700747 } else {
748 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
749 }
750 })
751
752 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700753 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
754 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
755 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700756 }
757
758 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700759 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
760 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
761 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700762 }
763
764 if len(d.properties.Html_dirs) > 2 {
765 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
766 }
767
Colin Cross8a497952019-03-05 22:25:09 -0800768 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700769 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700770
Colin Crossab054432019-07-15 16:13:59 -0700771 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700772
773 if String(d.properties.Proofread_file) != "" {
774 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700775 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700776 }
777
778 if String(d.properties.Todo_file) != "" {
779 // tricky part:
780 // we should not compute full path for todo_file through PathForModuleOut().
781 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700782 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
783 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700784 }
785
786 if String(d.properties.Resourcesdir) != "" {
787 // TODO: should we add files under resourcesDir to the implicits? It seems that
788 // resourcesDir is one sub dir of htmlDir
789 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700790 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700791 }
792
793 if String(d.properties.Resourcesoutdir) != "" {
794 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700795 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700796 }
Nan Zhanga40da042018-08-01 12:48:00 -0700797}
798
Colin Crossab054432019-07-15 16:13:59 -0700799func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200800 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
801 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700802 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700803
Nan Zhanga40da042018-08-01 12:48:00 -0700804 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700805 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700806 d.apiFilePath = d.apiFile
807 }
808
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200809 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
810 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700811 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700812 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700813 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700814 }
815
816 if String(d.properties.Private_api_filename) != "" {
817 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700818 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700819 }
820
821 if String(d.properties.Dex_api_filename) != "" {
822 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 }
825
826 if String(d.properties.Private_dex_api_filename) != "" {
827 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700828 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700829 }
830
831 if String(d.properties.Removed_dex_api_filename) != "" {
832 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700834 }
835
836 if String(d.properties.Exact_api_filename) != "" {
837 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700838 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
841 if String(d.properties.Dex_mapping_filename) != "" {
842 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700843 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700844 }
845
Nan Zhang66dc2362018-08-14 20:41:04 -0700846 if String(d.properties.Proguard_filename) != "" {
847 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700848 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700849 }
850
Nan Zhanga40da042018-08-01 12:48:00 -0700851 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700852 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700853 }
854
855 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700856 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700857 }
Nan Zhanga40da042018-08-01 12:48:00 -0700858}
859
Colin Crossab054432019-07-15 16:13:59 -0700860func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700861 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700862 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
863 rule.Command().Text("cp").
864 Input(staticDocIndexRedirect).
865 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700866 }
867
868 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700869 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
870 rule.Command().Text("cp").
871 Input(staticDocProperties).
872 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700873 }
Nan Zhanga40da042018-08-01 12:48:00 -0700874}
875
Colin Crossab054432019-07-15 16:13:59 -0700876func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700877 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700878
879 cmd := rule.Command().
880 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
881 Flag(config.JavacVmFlags).
882 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700883 FlagWithRspFileInputList("@", srcs).
884 FlagWithInput("@", srcJarList)
885
Colin Crossab054432019-07-15 16:13:59 -0700886 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
887 // based stubs generation.
888 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
889 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
890 // the correct package name base path.
891 if len(sourcepaths) > 0 {
892 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
893 } else {
894 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
895 }
896
897 cmd.FlagWithArg("-d ", outDir.String()).
898 Flag("-quiet")
899
900 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700901}
902
Colin Crossdaa4c672019-07-15 22:53:46 -0700903func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
904 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
905 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
906
907 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
908
909 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
910 cmd.Flag(flag).Implicits(deps)
911
912 cmd.FlagWithArg("--patch-module ", "java.base=.")
913
914 if len(classpath) > 0 {
915 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
916 }
917
918 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700919}
920
Colin Crossdaa4c672019-07-15 22:53:46 -0700921func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
922 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
923 sourcepaths android.Paths) *android.RuleBuilderCommand {
924
925 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
926
927 if len(bootclasspath) == 0 && ctx.Device() {
928 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
929 // ensure java does not fall back to the default bootclasspath.
930 cmd.FlagWithArg("-bootclasspath ", `""`)
931 } else if len(bootclasspath) > 0 {
932 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
933 }
934
935 if len(classpath) > 0 {
936 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
937 }
938
939 return cmd
940}
941
Colin Crossab054432019-07-15 16:13:59 -0700942func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
943 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700944
Colin Crossab054432019-07-15 16:13:59 -0700945 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
946 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
947
948 return rule.Command().
949 BuiltTool(ctx, "dokka").
950 Flag(config.JavacVmFlags).
951 Flag(srcJarDir.String()).
952 FlagWithInputList("-classpath ", dokkaClasspath, ":").
953 FlagWithArg("-format ", "dac").
954 FlagWithArg("-dacRoot ", "/reference/kotlin").
955 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700956}
957
958func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
959 deps := d.Javadoc.collectDeps(ctx)
960
Colin Crossdaa4c672019-07-15 22:53:46 -0700961 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
962 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
963
Nan Zhang1598a9e2018-09-04 17:14:32 -0700964 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
965 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
966 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
967 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
968
Colin Crossab054432019-07-15 16:13:59 -0700969 outDir := android.PathForModuleOut(ctx, "out")
970 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
971 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700972
Colin Crossab054432019-07-15 16:13:59 -0700973 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700974
Colin Crossab054432019-07-15 16:13:59 -0700975 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
976 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700977
Colin Crossab054432019-07-15 16:13:59 -0700978 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
979
980 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700981 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700982 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700983 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700984 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700985 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700986 }
987
Colin Crossab054432019-07-15 16:13:59 -0700988 d.stubsFlags(ctx, cmd, stubsDir)
989
990 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
991
992 var desc string
993 if Bool(d.properties.Dokka_enabled) {
994 desc = "dokka"
995 } else {
996 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
997
998 for _, o := range d.Javadoc.properties.Out {
999 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1000 }
1001
1002 d.postDoclavaCmds(ctx, rule)
1003 desc = "doclava"
1004 }
1005
1006 rule.Command().
1007 BuiltTool(ctx, "soong_zip").
1008 Flag("-write_if_changed").
1009 Flag("-d").
1010 FlagWithOutput("-o ", d.docZip).
1011 FlagWithArg("-C ", outDir.String()).
1012 FlagWithArg("-D ", outDir.String())
1013
1014 rule.Command().
1015 BuiltTool(ctx, "soong_zip").
1016 Flag("-write_if_changed").
1017 Flag("-jar").
1018 FlagWithOutput("-o ", d.stubsSrcJar).
1019 FlagWithArg("-C ", stubsDir.String()).
1020 FlagWithArg("-D ", stubsDir.String())
1021
1022 rule.Restat()
1023
1024 zipSyncCleanupCmd(rule, srcJarDir)
1025
1026 rule.Build(pctx, ctx, "javadoc", desc)
1027
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001028 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001029 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001030
1031 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1032 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001033
1034 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001035
1036 rule := android.NewRuleBuilder()
1037
1038 rule.Command().Text("( true")
1039
1040 rule.Command().
1041 BuiltTool(ctx, "apicheck").
1042 Flag("-JXmx1024m").
1043 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1044 OptionalFlag(d.properties.Check_api.Current.Args).
1045 Input(apiFile).
1046 Input(d.apiFile).
1047 Input(removedApiFile).
1048 Input(d.removedApiFile)
1049
1050 msg := fmt.Sprintf(`\n******************************\n`+
1051 `You have tried to change the API from what has been previously approved.\n\n`+
1052 `To make these errors go away, you have two choices:\n`+
1053 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1054 ` errors above.\n\n`+
1055 ` 2. You can update current.txt by executing the following command:\n`+
1056 ` make %s-update-current-api\n\n`+
1057 ` To submit the revised current.txt to the main Android repository,\n`+
1058 ` you will need approval.\n`+
1059 `******************************\n`, ctx.ModuleName())
1060
1061 rule.Command().
1062 Text("touch").Output(d.checkCurrentApiTimestamp).
1063 Text(") || (").
1064 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1065 Text("; exit 38").
1066 Text(")")
1067
1068 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001069
1070 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001071
1072 // update API rule
1073 rule = android.NewRuleBuilder()
1074
1075 rule.Command().Text("( true")
1076
1077 rule.Command().
1078 Text("cp").Flag("-f").
1079 Input(d.apiFile).Flag(apiFile.String())
1080
1081 rule.Command().
1082 Text("cp").Flag("-f").
1083 Input(d.removedApiFile).Flag(removedApiFile.String())
1084
1085 msg = "failed to update public API"
1086
1087 rule.Command().
1088 Text("touch").Output(d.updateCurrentApiTimestamp).
1089 Text(") || (").
1090 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1091 Text("; exit 38").
1092 Text(")")
1093
1094 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001095 }
1096
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001097 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001098 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001099
1100 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1101 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001102
1103 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001104
1105 rule := android.NewRuleBuilder()
1106
1107 rule.Command().
1108 Text("(").
1109 BuiltTool(ctx, "apicheck").
1110 Flag("-JXmx1024m").
1111 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1112 OptionalFlag(d.properties.Check_api.Last_released.Args).
1113 Input(apiFile).
1114 Input(d.apiFile).
1115 Input(removedApiFile).
1116 Input(d.removedApiFile)
1117
1118 msg := `\n******************************\n` +
1119 `You have tried to change the API from what has been previously released in\n` +
1120 `an SDK. Please fix the errors listed above.\n` +
1121 `******************************\n`
1122
1123 rule.Command().
1124 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1125 Text(") || (").
1126 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1127 Text("; exit 38").
1128 Text(")")
1129
1130 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001131 }
1132}
1133
1134//
1135// Droidstubs
1136//
1137type Droidstubs struct {
1138 Javadoc
1139
Pete Gillin581d6082018-10-22 15:55:04 +01001140 properties DroidstubsProperties
1141 apiFile android.WritablePath
1142 apiXmlFile android.WritablePath
1143 lastReleasedApiXmlFile android.WritablePath
1144 dexApiFile android.WritablePath
1145 privateApiFile android.WritablePath
1146 privateDexApiFile android.WritablePath
1147 removedApiFile android.WritablePath
1148 removedDexApiFile android.WritablePath
1149 apiMappingFile android.WritablePath
1150 exactApiFile android.WritablePath
1151 proguardFile android.WritablePath
1152 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001153
1154 checkCurrentApiTimestamp android.WritablePath
1155 updateCurrentApiTimestamp android.WritablePath
1156 checkLastReleasedApiTimestamp android.WritablePath
1157
Pete Gillin581d6082018-10-22 15:55:04 +01001158 checkNullabilityWarningsTimestamp android.WritablePath
1159
Nan Zhang1598a9e2018-09-04 17:14:32 -07001160 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001161 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001162
1163 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001164
1165 jdiffDocZip android.WritablePath
1166 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001167}
1168
Colin Crossa3002fc2019-07-08 16:48:04 -07001169// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1170// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1171// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001172func DroidstubsFactory() android.Module {
1173 module := &Droidstubs{}
1174
1175 module.AddProperties(&module.properties,
1176 &module.Javadoc.properties)
1177
1178 InitDroiddocModule(module, android.HostAndDeviceSupported)
1179 return module
1180}
1181
Colin Crossa3002fc2019-07-08 16:48:04 -07001182// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1183// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1184// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1185// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001186func DroidstubsHostFactory() android.Module {
1187 module := &Droidstubs{}
1188
1189 module.AddProperties(&module.properties,
1190 &module.Javadoc.properties)
1191
1192 InitDroiddocModule(module, android.HostSupported)
1193 return module
1194}
1195
1196func (d *Droidstubs) ApiFilePath() android.Path {
1197 return d.apiFilePath
1198}
1199
1200func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1201 d.Javadoc.addDeps(ctx)
1202
Inseob Kim38449af2019-02-28 14:24:05 +09001203 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1204 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1205 }
1206
Nan Zhang1598a9e2018-09-04 17:14:32 -07001207 if len(d.properties.Merge_annotations_dirs) != 0 {
1208 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1209 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1210 }
1211 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001212
Pete Gillin77167902018-09-19 18:16:26 +01001213 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1214 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1215 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1216 }
1217 }
1218
Nan Zhang9c69a122018-08-22 10:22:08 -07001219 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1220 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1221 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1222 }
1223 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001224}
1225
Colin Cross33961b52019-07-11 11:01:22 -07001226func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001227 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1228 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001229 String(d.properties.Api_filename) != "" {
1230 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001231 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001232 d.apiFilePath = d.apiFile
1233 }
1234
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001235 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1236 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001237 String(d.properties.Removed_api_filename) != "" {
1238 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001239 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001240 }
1241
1242 if String(d.properties.Private_api_filename) != "" {
1243 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001244 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001245 }
1246
1247 if String(d.properties.Dex_api_filename) != "" {
1248 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001249 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250 }
1251
1252 if String(d.properties.Private_dex_api_filename) != "" {
1253 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001254 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255 }
1256
1257 if String(d.properties.Removed_dex_api_filename) != "" {
1258 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001259 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260 }
1261
1262 if String(d.properties.Exact_api_filename) != "" {
1263 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001264 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265 }
1266
Nan Zhang9c69a122018-08-22 10:22:08 -07001267 if String(d.properties.Dex_mapping_filename) != "" {
1268 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001269 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001270 }
1271
Nan Zhang199645c2018-09-19 12:40:06 -07001272 if String(d.properties.Proguard_filename) != "" {
1273 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001274 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001275 }
1276
Nan Zhang9c69a122018-08-22 10:22:08 -07001277 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001278 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001279 }
1280
Nan Zhang1598a9e2018-09-04 17:14:32 -07001281 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001282 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001283 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001285 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001286}
1287
Colin Cross33961b52019-07-11 11:01:22 -07001288func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001289 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001290 cmd.Flag("--include-annotations")
1291
Pete Gillinc382a562018-11-14 18:45:46 +00001292 validatingNullability :=
1293 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1294 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001295 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001296
Pete Gillina262c052018-09-14 14:25:48 +01001297 if !(migratingNullability || validatingNullability) {
1298 ctx.PropertyErrorf("previous_api",
1299 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001300 }
Colin Cross33961b52019-07-11 11:01:22 -07001301
Pete Gillina262c052018-09-14 14:25:48 +01001302 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001303 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001304 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001305 }
Colin Cross33961b52019-07-11 11:01:22 -07001306
Pete Gillinc382a562018-11-14 18:45:46 +00001307 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001308 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001309 }
Colin Cross33961b52019-07-11 11:01:22 -07001310
Pete Gillina262c052018-09-14 14:25:48 +01001311 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001312 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001313 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001314 }
Nan Zhanga40da042018-08-01 12:48:00 -07001315
1316 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001317 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001318
Nan Zhang1598a9e2018-09-04 17:14:32 -07001319 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001320 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001321 "has to be non-empty if annotations was enabled!")
1322 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001323
Colin Cross33961b52019-07-11 11:01:22 -07001324 d.mergeAnnoDirFlags(ctx, cmd)
1325
1326 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1327 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1328 FlagWithArg("--hide ", "SuperfluousPrefix").
1329 FlagWithArg("--hide ", "AnnotationExtraction")
1330 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001331}
1332
Colin Cross33961b52019-07-11 11:01:22 -07001333func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1334 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1335 if t, ok := m.(*ExportedDroiddocDir); ok {
1336 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1337 } else {
1338 ctx.PropertyErrorf("merge_annotations_dirs",
1339 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1340 }
1341 })
1342}
1343
1344func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001345 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1346 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001347 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001348 } else {
1349 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1350 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1351 }
1352 })
Nan Zhanga40da042018-08-01 12:48:00 -07001353}
1354
Colin Cross33961b52019-07-11 11:01:22 -07001355func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001356 if Bool(d.properties.Api_levels_annotations_enabled) {
1357 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001358
1359 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1360 ctx.PropertyErrorf("api_levels_annotations_dirs",
1361 "has to be non-empty if api levels annotations was enabled!")
1362 }
1363
Colin Cross33961b52019-07-11 11:01:22 -07001364 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1365 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1366 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1367 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001368
1369 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1370 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001371 for _, dep := range t.deps {
1372 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001373 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001374 }
1375 }
Colin Cross33961b52019-07-11 11:01:22 -07001376 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001377 } else {
1378 ctx.PropertyErrorf("api_levels_annotations_dirs",
1379 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1380 }
1381 })
1382
1383 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001384}
1385
Colin Cross33961b52019-07-11 11:01:22 -07001386func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001387 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1388 if d.apiFile.String() == "" {
1389 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1390 }
1391
1392 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001393 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001394
1395 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1396 ctx.PropertyErrorf("check_api.last_released.api_file",
1397 "has to be non-empty if jdiff was enabled!")
1398 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001399
Colin Cross33961b52019-07-11 11:01:22 -07001400 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001401 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001402 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1403 }
1404}
Nan Zhang71bbe632018-09-17 14:32:21 -07001405
Colin Cross33961b52019-07-11 11:01:22 -07001406func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1407 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1408 cmd := rule.Command().BuiltTool(ctx, "metalava").
1409 Flag(config.JavacVmFlags).
1410 FlagWithArg("-encoding ", "UTF-8").
1411 FlagWithArg("-source ", javaVersion).
1412 FlagWithRspFileInputList("@", srcs).
1413 FlagWithInput("@", srcJarList)
1414
1415 if len(bootclasspath) > 0 {
1416 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001417 }
1418
Colin Cross33961b52019-07-11 11:01:22 -07001419 if len(classpath) > 0 {
1420 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1421 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001422
Colin Cross33961b52019-07-11 11:01:22 -07001423 if len(sourcepaths) > 0 {
1424 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1425 } else {
1426 cmd.FlagWithArg("-sourcepath ", `""`)
1427 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001428
Colin Cross33961b52019-07-11 11:01:22 -07001429 cmd.Flag("--no-banner").
1430 Flag("--color").
1431 Flag("--quiet").
1432 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001433
Colin Cross33961b52019-07-11 11:01:22 -07001434 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001435}
1436
Nan Zhang1598a9e2018-09-04 17:14:32 -07001437func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001438 deps := d.Javadoc.collectDeps(ctx)
1439
1440 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001441
Colin Cross33961b52019-07-11 11:01:22 -07001442 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001443
Colin Crossdaa4c672019-07-15 22:53:46 -07001444 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001445
Colin Cross33961b52019-07-11 11:01:22 -07001446 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1447 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001448
Colin Cross33961b52019-07-11 11:01:22 -07001449 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001450
Colin Cross33961b52019-07-11 11:01:22 -07001451 rule.Command().Text("rm -rf").Text(stubsDir.String())
1452 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001453
Colin Cross33961b52019-07-11 11:01:22 -07001454 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1455
1456 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1457 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1458
1459 d.stubsFlags(ctx, cmd, stubsDir)
1460
1461 d.annotationsFlags(ctx, cmd)
1462 d.inclusionAnnotationsFlags(ctx, cmd)
1463 d.apiLevelsAnnotationsFlags(ctx, cmd)
1464 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001465
Nan Zhang1598a9e2018-09-04 17:14:32 -07001466 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1467 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1468 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1469 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1470 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001471 }
Colin Cross33961b52019-07-11 11:01:22 -07001472
1473 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1474 for _, o := range d.Javadoc.properties.Out {
1475 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1476 }
1477
1478 rule.Command().
1479 BuiltTool(ctx, "soong_zip").
1480 Flag("-write_if_changed").
1481 Flag("-jar").
1482 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1483 FlagWithArg("-C ", stubsDir.String()).
1484 FlagWithArg("-D ", stubsDir.String())
1485 rule.Restat()
1486
1487 zipSyncCleanupCmd(rule, srcJarDir)
1488
1489 rule.Build(pctx, ctx, "metalava", "metalava")
1490
1491 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001492
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001493 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001494 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001495
1496 if len(d.Javadoc.properties.Out) > 0 {
1497 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1498 }
1499
1500 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1501 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001502 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1503 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001504
Nan Zhang2760dfc2018-08-24 17:32:54 +00001505 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001506
Colin Cross33961b52019-07-11 11:01:22 -07001507 rule := android.NewRuleBuilder()
1508
1509 rule.Command().Text("( true")
1510
1511 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1512 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1513
1514 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1515 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1516
1517 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1518 FlagWithInput("--check-compatibility:api:current ", apiFile).
1519 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1520
1521 d.inclusionAnnotationsFlags(ctx, cmd)
1522 d.mergeAnnoDirFlags(ctx, cmd)
1523
Adrian Roos14f75a92019-08-12 17:54:09 +02001524 if baselineFile.Valid() {
1525 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1526 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1527 }
1528
Colin Cross33961b52019-07-11 11:01:22 -07001529 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
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001578 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001579 !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))
Adrian Roos14f75a92019-08-12 17:54:09 +02001587 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1588 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001589
Nan Zhang2760dfc2018-08-24 17:32:54 +00001590 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001591
Colin Cross33961b52019-07-11 11:01:22 -07001592 rule := android.NewRuleBuilder()
1593
1594 rule.Command().Text("( true")
1595
1596 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1597 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1598
1599 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1600 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1601
1602 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1603 FlagWithInput("--check-compatibility:api:released ", apiFile)
1604
1605 d.inclusionAnnotationsFlags(ctx, cmd)
1606
1607 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1608
1609 d.mergeAnnoDirFlags(ctx, cmd)
1610
Adrian Roos14f75a92019-08-12 17:54:09 +02001611 if baselineFile.Valid() {
1612 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1613 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1614 }
1615
Colin Cross33961b52019-07-11 11:01:22 -07001616 zipSyncCleanupCmd(rule, srcJarDir)
1617
1618 msg := `\n******************************\n` +
1619 `You have tried to change the API from what has been previously released in\n` +
1620 `an SDK. Please fix the errors listed above.\n` +
1621 `******************************\n`
1622 rule.Command().
1623 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1624 Text(") || (").
1625 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1626 Text("; exit 38").
1627 Text(")")
1628
1629 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001630 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001631
Pete Gillin581d6082018-10-22 15:55:04 +01001632 if String(d.properties.Check_nullability_warnings) != "" {
1633 if d.nullabilityWarningsFile == nil {
1634 ctx.PropertyErrorf("check_nullability_warnings",
1635 "Cannot specify check_nullability_warnings unless validating nullability")
1636 }
Colin Cross33961b52019-07-11 11:01:22 -07001637
1638 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1639
Pete Gillin581d6082018-10-22 15:55:04 +01001640 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001641
Pete Gillin581d6082018-10-22 15:55:04 +01001642 msg := fmt.Sprintf(`\n******************************\n`+
1643 `The warnings encountered during nullability annotation validation did\n`+
1644 `not match the checked in file of expected warnings. The diffs are shown\n`+
1645 `above. You have two options:\n`+
1646 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1647 ` 2. Update the file of expected warnings by running:\n`+
1648 ` cp %s %s\n`+
1649 ` and submitting the updated file as part of your change.`,
1650 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001651
1652 rule := android.NewRuleBuilder()
1653
1654 rule.Command().
1655 Text("(").
1656 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1657 Text("&&").
1658 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1659 Text(") || (").
1660 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1661 Text("; exit 38").
1662 Text(")")
1663
1664 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001665 }
1666
Nan Zhang71bbe632018-09-17 14:32:21 -07001667 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001668 if len(d.Javadoc.properties.Out) > 0 {
1669 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1670 }
1671
1672 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1673 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1674 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1675
1676 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001677
Nan Zhang86b06202018-09-21 17:09:21 -07001678 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1679 // since there's cron job downstream that fetch this .zip file periodically.
1680 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001681 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1682 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1683
Nan Zhang71bbe632018-09-17 14:32:21 -07001684 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001685
Colin Cross33961b52019-07-11 11:01:22 -07001686 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1687 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001688
Colin Cross33961b52019-07-11 11:01:22 -07001689 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1690
Colin Crossdaa4c672019-07-15 22:53:46 -07001691 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001692 deps.bootClasspath, deps.classpath, d.sourcepaths)
1693
1694 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001695 Flag("-XDignore.symbol.file").
1696 FlagWithArg("-doclet ", "jdiff.JDiff").
1697 FlagWithInput("-docletpath ", jdiff).
1698 Flag("-quiet").
1699 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1700 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1701 Implicit(d.apiXmlFile).
1702 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1703 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1704 Implicit(d.lastReleasedApiXmlFile)
1705
Colin Cross33961b52019-07-11 11:01:22 -07001706 rule.Command().
1707 BuiltTool(ctx, "soong_zip").
1708 Flag("-write_if_changed").
1709 Flag("-d").
1710 FlagWithOutput("-o ", d.jdiffDocZip).
1711 FlagWithArg("-C ", outDir.String()).
1712 FlagWithArg("-D ", outDir.String())
1713
1714 rule.Command().
1715 BuiltTool(ctx, "soong_zip").
1716 Flag("-write_if_changed").
1717 Flag("-jar").
1718 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1719 FlagWithArg("-C ", stubsDir.String()).
1720 FlagWithArg("-D ", stubsDir.String())
1721
1722 rule.Restat()
1723
1724 zipSyncCleanupCmd(rule, srcJarDir)
1725
1726 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001727 }
Nan Zhang581fd212018-01-10 16:06:12 -08001728}
Dan Willemsencc090972018-02-26 14:33:31 -08001729
Nan Zhanga40da042018-08-01 12:48:00 -07001730//
Nan Zhangf4936b02018-08-01 15:00:28 -07001731// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001732//
Dan Willemsencc090972018-02-26 14:33:31 -08001733var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001734var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001735var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001736var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001737
Nan Zhangf4936b02018-08-01 15:00:28 -07001738type ExportedDroiddocDirProperties struct {
1739 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001740 Path *string
1741}
1742
Nan Zhangf4936b02018-08-01 15:00:28 -07001743type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001744 android.ModuleBase
1745
Nan Zhangf4936b02018-08-01 15:00:28 -07001746 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001747
1748 deps android.Paths
1749 dir android.Path
1750}
1751
Colin Crossa3002fc2019-07-08 16:48:04 -07001752// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001753func ExportedDroiddocDirFactory() android.Module {
1754 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001755 module.AddProperties(&module.properties)
1756 android.InitAndroidModule(module)
1757 return module
1758}
1759
Nan Zhangf4936b02018-08-01 15:00:28 -07001760func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001761
Nan Zhangf4936b02018-08-01 15:00:28 -07001762func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001763 path := String(d.properties.Path)
1764 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001765 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001766}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001767
1768//
1769// Defaults
1770//
1771type DocDefaults struct {
1772 android.ModuleBase
1773 android.DefaultsModuleBase
1774}
1775
Nan Zhangb2b33de2018-02-23 11:18:47 -08001776func DocDefaultsFactory() android.Module {
1777 module := &DocDefaults{}
1778
1779 module.AddProperties(
1780 &JavadocProperties{},
1781 &DroiddocProperties{},
1782 )
1783
1784 android.InitDefaultsModule(module)
1785
1786 return module
1787}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001788
1789func StubsDefaultsFactory() android.Module {
1790 module := &DocDefaults{}
1791
1792 module.AddProperties(
1793 &JavadocProperties{},
1794 &DroidstubsProperties{},
1795 )
1796
1797 android.InitDefaultsModule(module)
1798
1799 return module
1800}
Colin Cross33961b52019-07-11 11:01:22 -07001801
1802func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1803 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1804
1805 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1806 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1807 srcJarList := srcJarDir.Join(ctx, "list")
1808
1809 rule.Temporary(srcJarList)
1810
1811 rule.Command().BuiltTool(ctx, "zipsync").
1812 FlagWithArg("-d ", srcJarDir.String()).
1813 FlagWithOutput("-l ", srcJarList).
1814 FlagWithArg("-f ", `"*.java"`).
1815 Inputs(srcJars)
1816
1817 return srcJarList
1818}
1819
1820func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1821 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1822}