blob: 1d5331e64f233c937afe62e448eab1965de2f81b [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))
464
Jiyong Park1112c4c2019-08-16 21:12:10 +0900465 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
466
Jiyong Park1e440682018-05-23 18:42:04 +0900467 for _, srcFile := range srcFiles {
468 switch srcFile.Ext() {
469 case ".aidl":
Jiyong Park1112c4c2019-08-16 21:12:10 +0900470 javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900471 outSrcFiles = append(outSrcFiles, javaFile)
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
480 return outSrcFiles
481}
482
Nan Zhang581fd212018-01-10 16:06:12 -0800483func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
484 var deps deps
485
Colin Cross83bb3162018-06-25 15:48:06 -0700486 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800487 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700488 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800489 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700490 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800491 }
492
493 ctx.VisitDirectDeps(func(module android.Module) {
494 otherName := ctx.OtherModuleName(module)
495 tag := ctx.OtherModuleDependencyTag(module)
496
Colin Cross2d24c1b2018-05-23 10:59:18 -0700497 switch tag {
498 case bootClasspathTag:
499 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800500 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700501 } else {
502 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
503 }
504 case libTag:
505 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800506 case SdkLibraryDependency:
507 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700508 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900509 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900510 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700511 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800512 checkProducesJars(ctx, dep)
513 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800514 default:
515 ctx.ModuleErrorf("depends on non-java module %q", otherName)
516 }
Nan Zhang357466b2018-04-17 17:38:36 -0700517 case systemModulesTag:
518 if deps.systemModules != nil {
519 panic("Found two system module dependencies")
520 }
521 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000522 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700523 panic("Missing directory for system module dependency")
524 }
Colin Crossb77043e2019-07-16 13:57:13 -0700525 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800526 }
527 })
528 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
529 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800530 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900531
532 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
533 if filterPackages == nil {
534 return srcs
535 }
536 filtered := []android.Path{}
537 for _, src := range srcs {
538 if src.Ext() != ".java" {
539 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
540 // but otherwise metalava emits stub sources having references to the generated AIDL classes
541 // in filtered-out pacages (e.g. com.android.internal.*).
542 // TODO(b/141149570) We need to fix this by introducing default private constructors or
543 // fixing metalava to not emit constructors having references to unknown classes.
544 filtered = append(filtered, src)
545 continue
546 }
547 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
548 for _, pkg := range filterPackages {
549 if strings.HasPrefix(packageName, pkg) {
550 filtered = append(filtered, src)
551 break
552 }
553 }
554 }
555 return filtered
556 }
557 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
558
Nan Zhanga40da042018-08-01 12:48:00 -0700559 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900560 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800561
562 // srcs may depend on some genrule output.
563 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800564 j.srcJars = append(j.srcJars, deps.srcJars...)
565
Nan Zhang581fd212018-01-10 16:06:12 -0800566 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800567 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800568
Nan Zhang9c69a122018-08-22 10:22:08 -0700569 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800570 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
571 }
572 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800573
Colin Cross8a497952019-03-05 22:25:09 -0800574 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000575 argFilesMap := map[string]string{}
576 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700577
Paul Duffin99e4a502019-02-11 15:38:42 +0000578 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800579 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000580 if _, exists := argFilesMap[label]; !exists {
581 argFilesMap[label] = strings.Join(paths.Strings(), " ")
582 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700583 } else {
584 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000585 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700586 }
587 }
588
589 var err error
Colin Cross15638152019-07-11 11:11:35 -0700590 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700591 if strings.HasPrefix(name, "location ") {
592 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000593 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700594 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700595 } else {
Colin Cross15638152019-07-11 11:11:35 -0700596 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000597 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700598 }
599 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700600 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700601 }
Colin Cross15638152019-07-11 11:11:35 -0700602 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700603 })
604
605 if err != nil {
606 ctx.PropertyErrorf("args", "%s", err.Error())
607 }
608
Nan Zhang581fd212018-01-10 16:06:12 -0800609 return deps
610}
611
612func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
613 j.addDeps(ctx)
614}
615
616func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
617 deps := j.collectDeps(ctx)
618
Colin Crossdaa4c672019-07-15 22:53:46 -0700619 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800620
Colin Crossdaa4c672019-07-15 22:53:46 -0700621 outDir := android.PathForModuleOut(ctx, "out")
622 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
623
624 j.stubsSrcJar = nil
625
626 rule := android.NewRuleBuilder()
627
628 rule.Command().Text("rm -rf").Text(outDir.String())
629 rule.Command().Text("mkdir -p").Text(outDir.String())
630
631 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700632
Colin Cross83bb3162018-06-25 15:48:06 -0700633 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800634
Colin Crossdaa4c672019-07-15 22:53:46 -0700635 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
636 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800637
Colin Crossdaa4c672019-07-15 22:53:46 -0700638 cmd.FlagWithArg("-source ", javaVersion).
639 Flag("-J-Xmx1024m").
640 Flag("-XDignore.symbol.file").
641 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800642
Colin Crossdaa4c672019-07-15 22:53:46 -0700643 rule.Command().
644 BuiltTool(ctx, "soong_zip").
645 Flag("-write_if_changed").
646 Flag("-d").
647 FlagWithOutput("-o ", j.docZip).
648 FlagWithArg("-C ", outDir.String()).
649 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700650
Colin Crossdaa4c672019-07-15 22:53:46 -0700651 rule.Restat()
652
653 zipSyncCleanupCmd(rule, srcJarDir)
654
655 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800656}
657
Nan Zhanga40da042018-08-01 12:48:00 -0700658//
659// Droiddoc
660//
661type Droiddoc struct {
662 Javadoc
663
664 properties DroiddocProperties
665 apiFile android.WritablePath
666 dexApiFile android.WritablePath
667 privateApiFile android.WritablePath
668 privateDexApiFile android.WritablePath
669 removedApiFile android.WritablePath
670 removedDexApiFile android.WritablePath
671 exactApiFile android.WritablePath
672 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700673 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700674
675 checkCurrentApiTimestamp android.WritablePath
676 updateCurrentApiTimestamp android.WritablePath
677 checkLastReleasedApiTimestamp android.WritablePath
678
Nan Zhanga40da042018-08-01 12:48:00 -0700679 apiFilePath android.Path
680}
681
Colin Crossa3002fc2019-07-08 16:48:04 -0700682// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700683func DroiddocFactory() android.Module {
684 module := &Droiddoc{}
685
686 module.AddProperties(&module.properties,
687 &module.Javadoc.properties)
688
689 InitDroiddocModule(module, android.HostAndDeviceSupported)
690 return module
691}
692
Colin Crossa3002fc2019-07-08 16:48:04 -0700693// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700694func DroiddocHostFactory() android.Module {
695 module := &Droiddoc{}
696
697 module.AddProperties(&module.properties,
698 &module.Javadoc.properties)
699
700 InitDroiddocModule(module, android.HostSupported)
701 return module
702}
703
704func (d *Droiddoc) ApiFilePath() android.Path {
705 return d.apiFilePath
706}
707
Nan Zhang581fd212018-01-10 16:06:12 -0800708func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
709 d.Javadoc.addDeps(ctx)
710
Inseob Kim38449af2019-02-28 14:24:05 +0900711 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
712 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
713 }
714
Nan Zhang79614d12018-04-19 18:03:39 -0700715 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800716 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
717 }
Nan Zhang581fd212018-01-10 16:06:12 -0800718}
719
Colin Crossab054432019-07-15 16:13:59 -0700720func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700721 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
722 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
723 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700724 cmd.FlagWithArg("-source ", "1.8").
725 Flag("-J-Xmx1600m").
726 Flag("-J-XX:-OmitStackTraceInFastThrow").
727 Flag("-XDignore.symbol.file").
728 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
729 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
730 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700731 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 -0700732
Nan Zhanga40da042018-08-01 12:48:00 -0700733 if String(d.properties.Custom_template) == "" {
734 // TODO: This is almost always droiddoc-templates-sdk
735 ctx.PropertyErrorf("custom_template", "must specify a template")
736 }
737
738 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700739 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700740 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700741 } else {
742 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
743 }
744 })
745
746 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700747 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
748 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
749 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700750 }
751
752 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700753 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
754 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
755 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700756 }
757
758 if len(d.properties.Html_dirs) > 2 {
759 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
760 }
761
Colin Cross8a497952019-03-05 22:25:09 -0800762 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700763 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700764
Colin Crossab054432019-07-15 16:13:59 -0700765 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700766
767 if String(d.properties.Proofread_file) != "" {
768 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700769 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700770 }
771
772 if String(d.properties.Todo_file) != "" {
773 // tricky part:
774 // we should not compute full path for todo_file through PathForModuleOut().
775 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700776 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
777 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700778 }
779
780 if String(d.properties.Resourcesdir) != "" {
781 // TODO: should we add files under resourcesDir to the implicits? It seems that
782 // resourcesDir is one sub dir of htmlDir
783 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700784 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700785 }
786
787 if String(d.properties.Resourcesoutdir) != "" {
788 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700789 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700790 }
Nan Zhanga40da042018-08-01 12:48:00 -0700791}
792
Colin Crossab054432019-07-15 16:13:59 -0700793func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200794 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
795 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700796 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700797
Nan Zhanga40da042018-08-01 12:48:00 -0700798 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700799 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700800 d.apiFilePath = d.apiFile
801 }
802
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200803 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
804 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700805 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700806 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700807 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700808 }
809
810 if String(d.properties.Private_api_filename) != "" {
811 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700812 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700813 }
814
815 if String(d.properties.Dex_api_filename) != "" {
816 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700817 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700818 }
819
820 if String(d.properties.Private_dex_api_filename) != "" {
821 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700822 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700823 }
824
825 if String(d.properties.Removed_dex_api_filename) != "" {
826 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700827 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700828 }
829
830 if String(d.properties.Exact_api_filename) != "" {
831 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700833 }
834
835 if String(d.properties.Dex_mapping_filename) != "" {
836 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700837 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700838 }
839
Nan Zhang66dc2362018-08-14 20:41:04 -0700840 if String(d.properties.Proguard_filename) != "" {
841 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700842 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700843 }
844
Nan Zhanga40da042018-08-01 12:48:00 -0700845 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700846 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700847 }
848
849 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700850 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700851 }
Nan Zhanga40da042018-08-01 12:48:00 -0700852}
853
Colin Crossab054432019-07-15 16:13:59 -0700854func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700855 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700856 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
857 rule.Command().Text("cp").
858 Input(staticDocIndexRedirect).
859 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700860 }
861
862 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700863 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
864 rule.Command().Text("cp").
865 Input(staticDocProperties).
866 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700867 }
Nan Zhanga40da042018-08-01 12:48:00 -0700868}
869
Colin Crossab054432019-07-15 16:13:59 -0700870func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700871 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700872
873 cmd := rule.Command().
874 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
875 Flag(config.JavacVmFlags).
876 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700877 FlagWithRspFileInputList("@", srcs).
878 FlagWithInput("@", srcJarList)
879
Colin Crossab054432019-07-15 16:13:59 -0700880 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
881 // based stubs generation.
882 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
883 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
884 // the correct package name base path.
885 if len(sourcepaths) > 0 {
886 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
887 } else {
888 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
889 }
890
891 cmd.FlagWithArg("-d ", outDir.String()).
892 Flag("-quiet")
893
894 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700895}
896
Colin Crossdaa4c672019-07-15 22:53:46 -0700897func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
898 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
899 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
900
901 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
902
903 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
904 cmd.Flag(flag).Implicits(deps)
905
906 cmd.FlagWithArg("--patch-module ", "java.base=.")
907
908 if len(classpath) > 0 {
909 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
910 }
911
912 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700913}
914
Colin Crossdaa4c672019-07-15 22:53:46 -0700915func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
916 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
917 sourcepaths android.Paths) *android.RuleBuilderCommand {
918
919 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
920
921 if len(bootclasspath) == 0 && ctx.Device() {
922 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
923 // ensure java does not fall back to the default bootclasspath.
924 cmd.FlagWithArg("-bootclasspath ", `""`)
925 } else if len(bootclasspath) > 0 {
926 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
927 }
928
929 if len(classpath) > 0 {
930 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
931 }
932
933 return cmd
934}
935
Colin Crossab054432019-07-15 16:13:59 -0700936func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
937 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700938
Colin Crossab054432019-07-15 16:13:59 -0700939 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
940 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
941
942 return rule.Command().
943 BuiltTool(ctx, "dokka").
944 Flag(config.JavacVmFlags).
945 Flag(srcJarDir.String()).
946 FlagWithInputList("-classpath ", dokkaClasspath, ":").
947 FlagWithArg("-format ", "dac").
948 FlagWithArg("-dacRoot ", "/reference/kotlin").
949 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700950}
951
952func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
953 deps := d.Javadoc.collectDeps(ctx)
954
Colin Crossdaa4c672019-07-15 22:53:46 -0700955 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
956 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
957
Nan Zhang1598a9e2018-09-04 17:14:32 -0700958 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
959 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
960 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
961 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
962
Colin Crossab054432019-07-15 16:13:59 -0700963 outDir := android.PathForModuleOut(ctx, "out")
964 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
965 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700966
Colin Crossab054432019-07-15 16:13:59 -0700967 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700968
Colin Crossab054432019-07-15 16:13:59 -0700969 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
970 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700971
Colin Crossab054432019-07-15 16:13:59 -0700972 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
973
974 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700975 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700976 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700977 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700978 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700979 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700980 }
981
Colin Crossab054432019-07-15 16:13:59 -0700982 d.stubsFlags(ctx, cmd, stubsDir)
983
984 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
985
986 var desc string
987 if Bool(d.properties.Dokka_enabled) {
988 desc = "dokka"
989 } else {
990 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
991
992 for _, o := range d.Javadoc.properties.Out {
993 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
994 }
995
996 d.postDoclavaCmds(ctx, rule)
997 desc = "doclava"
998 }
999
1000 rule.Command().
1001 BuiltTool(ctx, "soong_zip").
1002 Flag("-write_if_changed").
1003 Flag("-d").
1004 FlagWithOutput("-o ", d.docZip).
1005 FlagWithArg("-C ", outDir.String()).
1006 FlagWithArg("-D ", outDir.String())
1007
1008 rule.Command().
1009 BuiltTool(ctx, "soong_zip").
1010 Flag("-write_if_changed").
1011 Flag("-jar").
1012 FlagWithOutput("-o ", d.stubsSrcJar).
1013 FlagWithArg("-C ", stubsDir.String()).
1014 FlagWithArg("-D ", stubsDir.String())
1015
1016 rule.Restat()
1017
1018 zipSyncCleanupCmd(rule, srcJarDir)
1019
1020 rule.Build(pctx, ctx, "javadoc", desc)
1021
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001022 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001023 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001024
1025 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1026 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001027
1028 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001029
1030 rule := android.NewRuleBuilder()
1031
1032 rule.Command().Text("( true")
1033
1034 rule.Command().
1035 BuiltTool(ctx, "apicheck").
1036 Flag("-JXmx1024m").
1037 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1038 OptionalFlag(d.properties.Check_api.Current.Args).
1039 Input(apiFile).
1040 Input(d.apiFile).
1041 Input(removedApiFile).
1042 Input(d.removedApiFile)
1043
1044 msg := fmt.Sprintf(`\n******************************\n`+
1045 `You have tried to change the API from what has been previously approved.\n\n`+
1046 `To make these errors go away, you have two choices:\n`+
1047 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1048 ` errors above.\n\n`+
1049 ` 2. You can update current.txt by executing the following command:\n`+
1050 ` make %s-update-current-api\n\n`+
1051 ` To submit the revised current.txt to the main Android repository,\n`+
1052 ` you will need approval.\n`+
1053 `******************************\n`, ctx.ModuleName())
1054
1055 rule.Command().
1056 Text("touch").Output(d.checkCurrentApiTimestamp).
1057 Text(") || (").
1058 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1059 Text("; exit 38").
1060 Text(")")
1061
1062 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001063
1064 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001065
1066 // update API rule
1067 rule = android.NewRuleBuilder()
1068
1069 rule.Command().Text("( true")
1070
1071 rule.Command().
1072 Text("cp").Flag("-f").
1073 Input(d.apiFile).Flag(apiFile.String())
1074
1075 rule.Command().
1076 Text("cp").Flag("-f").
1077 Input(d.removedApiFile).Flag(removedApiFile.String())
1078
1079 msg = "failed to update public API"
1080
1081 rule.Command().
1082 Text("touch").Output(d.updateCurrentApiTimestamp).
1083 Text(") || (").
1084 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1085 Text("; exit 38").
1086 Text(")")
1087
1088 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001089 }
1090
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001091 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001092 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001093
1094 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1095 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001096
1097 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001098
1099 rule := android.NewRuleBuilder()
1100
1101 rule.Command().
1102 Text("(").
1103 BuiltTool(ctx, "apicheck").
1104 Flag("-JXmx1024m").
1105 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1106 OptionalFlag(d.properties.Check_api.Last_released.Args).
1107 Input(apiFile).
1108 Input(d.apiFile).
1109 Input(removedApiFile).
1110 Input(d.removedApiFile)
1111
1112 msg := `\n******************************\n` +
1113 `You have tried to change the API from what has been previously released in\n` +
1114 `an SDK. Please fix the errors listed above.\n` +
1115 `******************************\n`
1116
1117 rule.Command().
1118 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1119 Text(") || (").
1120 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1121 Text("; exit 38").
1122 Text(")")
1123
1124 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001125 }
1126}
1127
1128//
1129// Droidstubs
1130//
1131type Droidstubs struct {
1132 Javadoc
1133
Pete Gillin581d6082018-10-22 15:55:04 +01001134 properties DroidstubsProperties
1135 apiFile android.WritablePath
1136 apiXmlFile android.WritablePath
1137 lastReleasedApiXmlFile android.WritablePath
1138 dexApiFile android.WritablePath
1139 privateApiFile android.WritablePath
1140 privateDexApiFile android.WritablePath
1141 removedApiFile android.WritablePath
1142 removedDexApiFile android.WritablePath
1143 apiMappingFile android.WritablePath
1144 exactApiFile android.WritablePath
1145 proguardFile android.WritablePath
1146 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001147
1148 checkCurrentApiTimestamp android.WritablePath
1149 updateCurrentApiTimestamp android.WritablePath
1150 checkLastReleasedApiTimestamp android.WritablePath
1151
Pete Gillin581d6082018-10-22 15:55:04 +01001152 checkNullabilityWarningsTimestamp android.WritablePath
1153
Nan Zhang1598a9e2018-09-04 17:14:32 -07001154 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001155 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001156
1157 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001158
1159 jdiffDocZip android.WritablePath
1160 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001161}
1162
Colin Crossa3002fc2019-07-08 16:48:04 -07001163// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1164// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1165// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001166func DroidstubsFactory() android.Module {
1167 module := &Droidstubs{}
1168
1169 module.AddProperties(&module.properties,
1170 &module.Javadoc.properties)
1171
1172 InitDroiddocModule(module, android.HostAndDeviceSupported)
1173 return module
1174}
1175
Colin Crossa3002fc2019-07-08 16:48:04 -07001176// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1177// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1178// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1179// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001180func DroidstubsHostFactory() android.Module {
1181 module := &Droidstubs{}
1182
1183 module.AddProperties(&module.properties,
1184 &module.Javadoc.properties)
1185
1186 InitDroiddocModule(module, android.HostSupported)
1187 return module
1188}
1189
1190func (d *Droidstubs) ApiFilePath() android.Path {
1191 return d.apiFilePath
1192}
1193
1194func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1195 d.Javadoc.addDeps(ctx)
1196
Inseob Kim38449af2019-02-28 14:24:05 +09001197 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1198 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1199 }
1200
Nan Zhang1598a9e2018-09-04 17:14:32 -07001201 if len(d.properties.Merge_annotations_dirs) != 0 {
1202 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1203 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1204 }
1205 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001206
Pete Gillin77167902018-09-19 18:16:26 +01001207 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1208 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1209 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1210 }
1211 }
1212
Nan Zhang9c69a122018-08-22 10:22:08 -07001213 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1214 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1215 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1216 }
1217 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001218}
1219
Colin Cross33961b52019-07-11 11:01:22 -07001220func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001221 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1222 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001223 String(d.properties.Api_filename) != "" {
1224 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001225 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001226 d.apiFilePath = d.apiFile
1227 }
1228
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001229 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1230 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001231 String(d.properties.Removed_api_filename) != "" {
1232 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001233 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001234 }
1235
1236 if String(d.properties.Private_api_filename) != "" {
1237 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001238 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001239 }
1240
1241 if String(d.properties.Dex_api_filename) != "" {
1242 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001243 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001244 }
1245
1246 if String(d.properties.Private_dex_api_filename) != "" {
1247 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001248 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001249 }
1250
1251 if String(d.properties.Removed_dex_api_filename) != "" {
1252 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001253 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254 }
1255
1256 if String(d.properties.Exact_api_filename) != "" {
1257 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001258 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 }
1260
Nan Zhang9c69a122018-08-22 10:22:08 -07001261 if String(d.properties.Dex_mapping_filename) != "" {
1262 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001263 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001264 }
1265
Nan Zhang199645c2018-09-19 12:40:06 -07001266 if String(d.properties.Proguard_filename) != "" {
1267 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001268 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001269 }
1270
Nan Zhang9c69a122018-08-22 10:22:08 -07001271 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001272 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001273 }
1274
Nan Zhang1598a9e2018-09-04 17:14:32 -07001275 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001277 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001278 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001279 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001280}
1281
Colin Cross33961b52019-07-11 11:01:22 -07001282func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001283 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.Flag("--include-annotations")
1285
Pete Gillinc382a562018-11-14 18:45:46 +00001286 validatingNullability :=
1287 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1288 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001289 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001290
Pete Gillina262c052018-09-14 14:25:48 +01001291 if !(migratingNullability || validatingNullability) {
1292 ctx.PropertyErrorf("previous_api",
1293 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001294 }
Colin Cross33961b52019-07-11 11:01:22 -07001295
Pete Gillina262c052018-09-14 14:25:48 +01001296 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001297 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001298 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001299 }
Colin Cross33961b52019-07-11 11:01:22 -07001300
Pete Gillinc382a562018-11-14 18:45:46 +00001301 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001302 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001303 }
Colin Cross33961b52019-07-11 11:01:22 -07001304
Pete Gillina262c052018-09-14 14:25:48 +01001305 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001306 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001307 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001308 }
Nan Zhanga40da042018-08-01 12:48:00 -07001309
1310 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001311 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001312
Nan Zhang1598a9e2018-09-04 17:14:32 -07001313 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001314 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001315 "has to be non-empty if annotations was enabled!")
1316 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001317
Colin Cross33961b52019-07-11 11:01:22 -07001318 d.mergeAnnoDirFlags(ctx, cmd)
1319
1320 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1321 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1322 FlagWithArg("--hide ", "SuperfluousPrefix").
1323 FlagWithArg("--hide ", "AnnotationExtraction")
1324 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001325}
1326
Colin Cross33961b52019-07-11 11:01:22 -07001327func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1328 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1329 if t, ok := m.(*ExportedDroiddocDir); ok {
1330 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1331 } else {
1332 ctx.PropertyErrorf("merge_annotations_dirs",
1333 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1334 }
1335 })
1336}
1337
1338func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001339 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1340 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001341 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001342 } else {
1343 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1344 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1345 }
1346 })
Nan Zhanga40da042018-08-01 12:48:00 -07001347}
1348
Colin Cross33961b52019-07-11 11:01:22 -07001349func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001350 if Bool(d.properties.Api_levels_annotations_enabled) {
1351 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001352
1353 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1354 ctx.PropertyErrorf("api_levels_annotations_dirs",
1355 "has to be non-empty if api levels annotations was enabled!")
1356 }
1357
Colin Cross33961b52019-07-11 11:01:22 -07001358 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1359 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1360 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1361 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001362
1363 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1364 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001365 for _, dep := range t.deps {
1366 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001367 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001368 }
1369 }
Colin Cross33961b52019-07-11 11:01:22 -07001370 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001371 } else {
1372 ctx.PropertyErrorf("api_levels_annotations_dirs",
1373 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1374 }
1375 })
1376
1377 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001378}
1379
Colin Cross33961b52019-07-11 11:01:22 -07001380func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001381 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1382 if d.apiFile.String() == "" {
1383 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1384 }
1385
1386 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001387 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001388
1389 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1390 ctx.PropertyErrorf("check_api.last_released.api_file",
1391 "has to be non-empty if jdiff was enabled!")
1392 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001393
Colin Cross33961b52019-07-11 11:01:22 -07001394 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001395 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001396 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1397 }
1398}
Nan Zhang71bbe632018-09-17 14:32:21 -07001399
Colin Cross33961b52019-07-11 11:01:22 -07001400func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1401 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1402 cmd := rule.Command().BuiltTool(ctx, "metalava").
1403 Flag(config.JavacVmFlags).
1404 FlagWithArg("-encoding ", "UTF-8").
1405 FlagWithArg("-source ", javaVersion).
1406 FlagWithRspFileInputList("@", srcs).
1407 FlagWithInput("@", srcJarList)
1408
1409 if len(bootclasspath) > 0 {
1410 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001411 }
1412
Colin Cross33961b52019-07-11 11:01:22 -07001413 if len(classpath) > 0 {
1414 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1415 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001416
Colin Cross33961b52019-07-11 11:01:22 -07001417 if len(sourcepaths) > 0 {
1418 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1419 } else {
1420 cmd.FlagWithArg("-sourcepath ", `""`)
1421 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001422
Colin Cross33961b52019-07-11 11:01:22 -07001423 cmd.Flag("--no-banner").
1424 Flag("--color").
1425 Flag("--quiet").
1426 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001427
Colin Cross33961b52019-07-11 11:01:22 -07001428 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001429}
1430
Nan Zhang1598a9e2018-09-04 17:14:32 -07001431func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001432 deps := d.Javadoc.collectDeps(ctx)
1433
1434 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001435
Colin Cross33961b52019-07-11 11:01:22 -07001436 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001437
Colin Crossdaa4c672019-07-15 22:53:46 -07001438 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001439
Colin Cross33961b52019-07-11 11:01:22 -07001440 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1441 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001442
Colin Cross33961b52019-07-11 11:01:22 -07001443 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001444
Colin Cross33961b52019-07-11 11:01:22 -07001445 rule.Command().Text("rm -rf").Text(stubsDir.String())
1446 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001447
Colin Cross33961b52019-07-11 11:01:22 -07001448 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1449
1450 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1451 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1452
1453 d.stubsFlags(ctx, cmd, stubsDir)
1454
1455 d.annotationsFlags(ctx, cmd)
1456 d.inclusionAnnotationsFlags(ctx, cmd)
1457 d.apiLevelsAnnotationsFlags(ctx, cmd)
1458 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001459
Nan Zhang1598a9e2018-09-04 17:14:32 -07001460 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1461 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1462 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1463 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1464 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001465 }
Colin Cross33961b52019-07-11 11:01:22 -07001466
1467 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1468 for _, o := range d.Javadoc.properties.Out {
1469 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1470 }
1471
1472 rule.Command().
1473 BuiltTool(ctx, "soong_zip").
1474 Flag("-write_if_changed").
1475 Flag("-jar").
1476 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1477 FlagWithArg("-C ", stubsDir.String()).
1478 FlagWithArg("-D ", stubsDir.String())
1479 rule.Restat()
1480
1481 zipSyncCleanupCmd(rule, srcJarDir)
1482
1483 rule.Build(pctx, ctx, "metalava", "metalava")
1484
1485 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001486
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001487 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001488 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001489
1490 if len(d.Javadoc.properties.Out) > 0 {
1491 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1492 }
1493
1494 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1495 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001496 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1497 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001498
Nan Zhang2760dfc2018-08-24 17:32:54 +00001499 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001500
Colin Cross33961b52019-07-11 11:01:22 -07001501 rule := android.NewRuleBuilder()
1502
1503 rule.Command().Text("( true")
1504
1505 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1506 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1507
1508 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1509 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1510
1511 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1512 FlagWithInput("--check-compatibility:api:current ", apiFile).
1513 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1514
1515 d.inclusionAnnotationsFlags(ctx, cmd)
1516 d.mergeAnnoDirFlags(ctx, cmd)
1517
Adrian Roos14f75a92019-08-12 17:54:09 +02001518 if baselineFile.Valid() {
1519 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1520 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1521 }
1522
Colin Cross33961b52019-07-11 11:01:22 -07001523 zipSyncCleanupCmd(rule, srcJarDir)
1524
1525 msg := fmt.Sprintf(`\n******************************\n`+
1526 `You have tried to change the API from what has been previously approved.\n\n`+
1527 `To make these errors go away, you have two choices:\n`+
1528 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1529 ` errors above.\n\n`+
1530 ` 2. You can update current.txt by executing the following command:\n`+
1531 ` make %s-update-current-api\n\n`+
1532 ` To submit the revised current.txt to the main Android repository,\n`+
1533 ` you will need approval.\n`+
1534 `******************************\n`, ctx.ModuleName())
1535
1536 rule.Command().
1537 Text("touch").Output(d.checkCurrentApiTimestamp).
1538 Text(") || (").
1539 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1540 Text("; exit 38").
1541 Text(")")
1542
1543 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001544
1545 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001546
1547 // update API rule
1548 rule = android.NewRuleBuilder()
1549
1550 rule.Command().Text("( true")
1551
1552 rule.Command().
1553 Text("cp").Flag("-f").
1554 Input(d.apiFile).Flag(apiFile.String())
1555
1556 rule.Command().
1557 Text("cp").Flag("-f").
1558 Input(d.removedApiFile).Flag(removedApiFile.String())
1559
1560 msg = "failed to update public API"
1561
1562 rule.Command().
1563 Text("touch").Output(d.updateCurrentApiTimestamp).
1564 Text(") || (").
1565 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1566 Text("; exit 38").
1567 Text(")")
1568
1569 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001570 }
Nan Zhanga40da042018-08-01 12:48:00 -07001571
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001572 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001573 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001574
1575 if len(d.Javadoc.properties.Out) > 0 {
1576 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1577 }
1578
1579 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1580 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001581 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1582 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001583
Nan Zhang2760dfc2018-08-24 17:32:54 +00001584 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001585
Colin Cross33961b52019-07-11 11:01:22 -07001586 rule := android.NewRuleBuilder()
1587
1588 rule.Command().Text("( true")
1589
1590 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1591 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1592
1593 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1594 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1595
1596 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1597 FlagWithInput("--check-compatibility:api:released ", apiFile)
1598
1599 d.inclusionAnnotationsFlags(ctx, cmd)
1600
1601 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1602
1603 d.mergeAnnoDirFlags(ctx, cmd)
1604
Adrian Roos14f75a92019-08-12 17:54:09 +02001605 if baselineFile.Valid() {
1606 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1607 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1608 }
1609
Colin Cross33961b52019-07-11 11:01:22 -07001610 zipSyncCleanupCmd(rule, srcJarDir)
1611
1612 msg := `\n******************************\n` +
1613 `You have tried to change the API from what has been previously released in\n` +
1614 `an SDK. Please fix the errors listed above.\n` +
1615 `******************************\n`
1616 rule.Command().
1617 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1618 Text(") || (").
1619 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1620 Text("; exit 38").
1621 Text(")")
1622
1623 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001624 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001625
Pete Gillin581d6082018-10-22 15:55:04 +01001626 if String(d.properties.Check_nullability_warnings) != "" {
1627 if d.nullabilityWarningsFile == nil {
1628 ctx.PropertyErrorf("check_nullability_warnings",
1629 "Cannot specify check_nullability_warnings unless validating nullability")
1630 }
Colin Cross33961b52019-07-11 11:01:22 -07001631
1632 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1633
Pete Gillin581d6082018-10-22 15:55:04 +01001634 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001635
Pete Gillin581d6082018-10-22 15:55:04 +01001636 msg := fmt.Sprintf(`\n******************************\n`+
1637 `The warnings encountered during nullability annotation validation did\n`+
1638 `not match the checked in file of expected warnings. The diffs are shown\n`+
1639 `above. You have two options:\n`+
1640 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1641 ` 2. Update the file of expected warnings by running:\n`+
1642 ` cp %s %s\n`+
1643 ` and submitting the updated file as part of your change.`,
1644 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001645
1646 rule := android.NewRuleBuilder()
1647
1648 rule.Command().
1649 Text("(").
1650 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1651 Text("&&").
1652 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1653 Text(") || (").
1654 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1655 Text("; exit 38").
1656 Text(")")
1657
1658 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001659 }
1660
Nan Zhang71bbe632018-09-17 14:32:21 -07001661 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001662 if len(d.Javadoc.properties.Out) > 0 {
1663 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1664 }
1665
1666 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1667 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1668 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1669
1670 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001671
Nan Zhang86b06202018-09-21 17:09:21 -07001672 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1673 // since there's cron job downstream that fetch this .zip file periodically.
1674 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001675 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1676 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1677
Nan Zhang71bbe632018-09-17 14:32:21 -07001678 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001679
Colin Cross33961b52019-07-11 11:01:22 -07001680 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1681 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001682
Colin Cross33961b52019-07-11 11:01:22 -07001683 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1684
Colin Crossdaa4c672019-07-15 22:53:46 -07001685 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001686 deps.bootClasspath, deps.classpath, d.sourcepaths)
1687
1688 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001689 Flag("-XDignore.symbol.file").
1690 FlagWithArg("-doclet ", "jdiff.JDiff").
1691 FlagWithInput("-docletpath ", jdiff).
1692 Flag("-quiet").
1693 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1694 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1695 Implicit(d.apiXmlFile).
1696 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1697 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1698 Implicit(d.lastReleasedApiXmlFile)
1699
Colin Cross33961b52019-07-11 11:01:22 -07001700 rule.Command().
1701 BuiltTool(ctx, "soong_zip").
1702 Flag("-write_if_changed").
1703 Flag("-d").
1704 FlagWithOutput("-o ", d.jdiffDocZip).
1705 FlagWithArg("-C ", outDir.String()).
1706 FlagWithArg("-D ", outDir.String())
1707
1708 rule.Command().
1709 BuiltTool(ctx, "soong_zip").
1710 Flag("-write_if_changed").
1711 Flag("-jar").
1712 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1713 FlagWithArg("-C ", stubsDir.String()).
1714 FlagWithArg("-D ", stubsDir.String())
1715
1716 rule.Restat()
1717
1718 zipSyncCleanupCmd(rule, srcJarDir)
1719
1720 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001721 }
Nan Zhang581fd212018-01-10 16:06:12 -08001722}
Dan Willemsencc090972018-02-26 14:33:31 -08001723
Nan Zhanga40da042018-08-01 12:48:00 -07001724//
Nan Zhangf4936b02018-08-01 15:00:28 -07001725// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001726//
Dan Willemsencc090972018-02-26 14:33:31 -08001727var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001728var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001729var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001730var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001731
Nan Zhangf4936b02018-08-01 15:00:28 -07001732type ExportedDroiddocDirProperties struct {
1733 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001734 Path *string
1735}
1736
Nan Zhangf4936b02018-08-01 15:00:28 -07001737type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001738 android.ModuleBase
1739
Nan Zhangf4936b02018-08-01 15:00:28 -07001740 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001741
1742 deps android.Paths
1743 dir android.Path
1744}
1745
Colin Crossa3002fc2019-07-08 16:48:04 -07001746// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001747func ExportedDroiddocDirFactory() android.Module {
1748 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001749 module.AddProperties(&module.properties)
1750 android.InitAndroidModule(module)
1751 return module
1752}
1753
Nan Zhangf4936b02018-08-01 15:00:28 -07001754func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001755
Nan Zhangf4936b02018-08-01 15:00:28 -07001756func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001757 path := String(d.properties.Path)
1758 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001759 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001760}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001761
1762//
1763// Defaults
1764//
1765type DocDefaults struct {
1766 android.ModuleBase
1767 android.DefaultsModuleBase
1768}
1769
Nan Zhangb2b33de2018-02-23 11:18:47 -08001770func DocDefaultsFactory() android.Module {
1771 module := &DocDefaults{}
1772
1773 module.AddProperties(
1774 &JavadocProperties{},
1775 &DroiddocProperties{},
1776 )
1777
1778 android.InitDefaultsModule(module)
1779
1780 return module
1781}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001782
1783func StubsDefaultsFactory() android.Module {
1784 module := &DocDefaults{}
1785
1786 module.AddProperties(
1787 &JavadocProperties{},
1788 &DroidstubsProperties{},
1789 )
1790
1791 android.InitDefaultsModule(module)
1792
1793 return module
1794}
Colin Cross33961b52019-07-11 11:01:22 -07001795
1796func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1797 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1798
1799 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1800 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1801 srcJarList := srcJarDir.Join(ctx, "list")
1802
1803 rule.Temporary(srcJarList)
1804
1805 rule.Command().BuiltTool(ctx, "zipsync").
1806 FlagWithArg("-d ", srcJarDir.String()).
1807 FlagWithOutput("-l ", srcJarList).
1808 FlagWithArg("-f ", `"*.java"`).
1809 Inputs(srcJars)
1810
1811 return srcJarList
1812}
1813
1814func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1815 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1816}