blob: 9eaa1b67354b28a84810ee5b0c7fa60a19f6a786 [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070020 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080021 "strings"
22
Jeongik Cha6bd33c12019-06-25 16:26:18 +090023 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080024
Colin Crossab054432019-07-15 16:13:59 -070025 "android/soong/android"
26 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080030 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070031 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080032
Nan Zhang581fd212018-01-10 16:06:12 -080033 android.RegisterModuleType("droiddoc", DroiddocFactory)
34 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070035 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080036 android.RegisterModuleType("javadoc", JavadocFactory)
37 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070038
39 android.RegisterModuleType("droidstubs", DroidstubsFactory)
40 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080041}
42
Colin Crossa1ce2a02018-06-20 15:19:39 -070043var (
44 srcsLibTag = dependencyTag{name: "sources from javalib"}
45)
46
Nan Zhang581fd212018-01-10 16:06:12 -080047type JavadocProperties struct {
48 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
49 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080051
52 // list of directories rooted at the Android.bp file that will
53 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080054 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080055
56 // list of source files that should not be used to build the Java module.
57 // This is most useful in the arch/multilib variants to remove non-common files
58 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080059 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080060
Nan Zhangb2b33de2018-02-23 11:18:47 -080061 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080062 Libs []string `android:"arch_variant"`
63
64 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080065 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080066
67 // if not blank, set to the version of the sdk to compile against
68 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090069
70 Aidl struct {
71 // Top level directories to pass to aidl tool
72 Include_dirs []string
73
74 // Directories rooted at the Android.bp file to pass to aidl tool
75 Local_include_dirs []string
76 }
Nan Zhang357466b2018-04-17 17:38:36 -070077
78 // If not blank, set the java version passed to javadoc as -source
79 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070080
81 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080082 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070083
84 // user customized droiddoc args.
85 // Available variables for substitution:
86 //
87 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070088 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070089 Args *string
90
91 // names of the output files used in args that will be generated
92 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080093}
94
Nan Zhang61819ce2018-05-04 18:49:16 -070095type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +090096 // path to the API txt file that the new API extracted from source code is checked
97 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -080098 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -070099
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900100 // path to the API txt file that the new @removed API extractd from source code is
101 // checked against. The path can be local to the module or from other module (via
102 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800103 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700104
Adrian Roos14f75a92019-08-12 17:54:09 +0200105 // If not blank, path to the baseline txt file for approved API check violations.
106 Baseline_file *string `android:"path"`
107
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900108 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700109 Args *string
110}
111
Nan Zhang581fd212018-01-10 16:06:12 -0800112type DroiddocProperties struct {
113 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800114 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800115
Nan Zhanga40da042018-08-01 12:48:00 -0700116 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800117 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800118
119 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800121
122 // proofread file contains all of the text content of the javadocs concatenated into one file,
123 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700124 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800125
126 // a todo file lists the program elements that are missing documentation.
127 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800128 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129
130 // directory under current module source that provide additional resources (images).
131 Resourcesdir *string
132
133 // resources output directory under out/soong/.intermediates.
134 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800135
Nan Zhange2ba5d42018-07-11 15:16:55 -0700136 // if set to true, collect the values used by the Dev tools and
137 // write them in files packaged with the SDK. Defaults to false.
138 Write_sdk_values *bool
139
140 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800141 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700142
143 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800144 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145
Nan Zhang581fd212018-01-10 16:06:12 -0800146 // a list of files under current module source dir which contains known tags in Java sources.
147 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800148 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700149
150 // the tag name used to distinguish if the API files belong to public/system/test.
151 Api_tag_name *string
152
153 // the generated public API filename by Doclava.
154 Api_filename *string
155
David Brazdilfbe4cc32018-05-31 13:56:46 +0100156 // the generated public Dex API filename by Doclava.
157 Dex_api_filename *string
158
Nan Zhang28c68b92018-03-13 16:17:01 -0700159 // the generated private API filename by Doclava.
160 Private_api_filename *string
161
162 // the generated private Dex API filename by Doclava.
163 Private_dex_api_filename *string
164
165 // the generated removed API filename by Doclava.
166 Removed_api_filename *string
167
David Brazdilaac0c3c2018-04-24 16:23:29 +0100168 // the generated removed Dex API filename by Doclava.
169 Removed_dex_api_filename *string
170
Mathew Inwood76c3de12018-06-22 15:28:11 +0100171 // mapping of dex signatures to source file and line number. This is a temporary property and
172 // will be deleted; you probably shouldn't be using it.
173 Dex_mapping_filename *string
174
Nan Zhang28c68b92018-03-13 16:17:01 -0700175 // the generated exact API filename by Doclava.
176 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700177
Nan Zhang66dc2362018-08-14 20:41:04 -0700178 // the generated proguard filename by Doclava.
179 Proguard_filename *string
180
Nan Zhang853f4202018-04-12 16:55:56 -0700181 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
182 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700183
184 Check_api struct {
185 Last_released ApiToCheck
186
187 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900188
189 // do not perform API check against Last_released, in the case that both two specified API
190 // files by Last_released are modules which don't exist.
191 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700192 }
Nan Zhang79614d12018-04-19 18:03:39 -0700193
Nan Zhang1598a9e2018-09-04 17:14:32 -0700194 // if set to true, generate docs through Dokka instead of Doclava.
195 Dokka_enabled *bool
196}
197
198type DroidstubsProperties struct {
199 // the tag name used to distinguish if the API files belong to public/system/test.
200 Api_tag_name *string
201
Nan Zhang199645c2018-09-19 12:40:06 -0700202 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 Api_filename *string
204
Nan Zhang199645c2018-09-19 12:40:06 -0700205 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206 Dex_api_filename *string
207
Nan Zhang199645c2018-09-19 12:40:06 -0700208 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Private_api_filename *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Private_dex_api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Removed_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Removed_dex_api_filename *string
219
Nan Zhang9c69a122018-08-22 10:22:08 -0700220 // mapping of dex signatures to source file and line number. This is a temporary property and
221 // will be deleted; you probably shouldn't be using it.
222 Dex_mapping_filename *string
223
Nan Zhang199645c2018-09-19 12:40:06 -0700224 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700225 Exact_api_filename *string
226
Nan Zhang199645c2018-09-19 12:40:06 -0700227 // the generated proguard filename by Metalava.
228 Proguard_filename *string
229
Nan Zhang1598a9e2018-09-04 17:14:32 -0700230 Check_api struct {
231 Last_released ApiToCheck
232
233 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900234
235 // do not perform API check against Last_released, in the case that both two specified API
236 // files by Last_released are modules which don't exist.
237 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700238 }
Nan Zhang79614d12018-04-19 18:03:39 -0700239
240 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800241 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700242
243 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700244 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700245
Pete Gillin77167902018-09-19 18:16:26 +0100246 // 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 -0700247 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700248
Pete Gillin77167902018-09-19 18:16:26 +0100249 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
250 Merge_inclusion_annotations_dirs []string
251
Pete Gillinc382a562018-11-14 18:45:46 +0000252 // a file containing a list of classes to do nullability validation for.
253 Validate_nullability_from_list *string
254
Pete Gillin581d6082018-10-22 15:55:04 +0100255 // a file containing expected warnings produced by validation of nullability annotations.
256 Check_nullability_warnings *string
257
Nan Zhang1598a9e2018-09-04 17:14:32 -0700258 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
259 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700260
261 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
262 Api_levels_annotations_enabled *bool
263
264 // the dirs which Metalava extracts API levels annotations from.
265 Api_levels_annotations_dirs []string
266
267 // if set to true, collect the values used by the Dev tools and
268 // write them in files packaged with the SDK. Defaults to false.
269 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700270
271 // If set to true, .xml based public API file will be also generated, and
272 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
273 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800274}
275
Nan Zhanga40da042018-08-01 12:48:00 -0700276//
277// Common flags passed down to build rule
278//
279type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700280 bootClasspathArgs string
281 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700282 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700283 dokkaClasspathArgs string
284 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700285 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700286
Nan Zhanga40da042018-08-01 12:48:00 -0700287 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700288 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700289 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700290}
291
292func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
293 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
294 android.InitDefaultableModule(module)
295}
296
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200297func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
298 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
299 return false
300 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700301 return true
302 } else if String(apiToCheck.Api_file) != "" {
303 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
304 } else if String(apiToCheck.Removed_api_file) != "" {
305 panic("for " + apiVersionTag + " api_file has to be non-empty!")
306 }
307
308 return false
309}
310
Inseob Kim38449af2019-02-28 14:24:05 +0900311func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
312 api_file := String(apiToCheck.Api_file)
313 removed_api_file := String(apiToCheck.Removed_api_file)
314
315 api_module := android.SrcIsModule(api_file)
316 removed_api_module := android.SrcIsModule(removed_api_file)
317
318 if api_module == "" || removed_api_module == "" {
319 return
320 }
321
322 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
323 return
324 }
325
326 apiToCheck.Api_file = nil
327 apiToCheck.Removed_api_file = nil
328}
329
Nan Zhang1598a9e2018-09-04 17:14:32 -0700330type ApiFilePath interface {
331 ApiFilePath() android.Path
332}
333
Nan Zhanga40da042018-08-01 12:48:00 -0700334//
335// Javadoc
336//
Nan Zhang581fd212018-01-10 16:06:12 -0800337type Javadoc struct {
338 android.ModuleBase
339 android.DefaultableModuleBase
340
341 properties JavadocProperties
342
343 srcJars android.Paths
344 srcFiles android.Paths
345 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700346 argFiles android.Paths
347
348 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800349
Nan Zhangccff0f72018-03-08 17:26:16 -0800350 docZip android.WritablePath
351 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800352}
353
Colin Cross41955e82019-05-29 14:40:35 -0700354func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
355 switch tag {
356 case "":
357 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700358 case ".docs.zip":
359 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700360 default:
361 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
362 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800363}
364
Colin Crossa3002fc2019-07-08 16:48:04 -0700365// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800366func JavadocFactory() android.Module {
367 module := &Javadoc{}
368
369 module.AddProperties(&module.properties)
370
371 InitDroiddocModule(module, android.HostAndDeviceSupported)
372 return module
373}
374
Colin Crossa3002fc2019-07-08 16:48:04 -0700375// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800376func JavadocHostFactory() android.Module {
377 module := &Javadoc{}
378
379 module.AddProperties(&module.properties)
380
381 InitDroiddocModule(module, android.HostSupported)
382 return module
383}
384
Colin Cross41955e82019-05-29 14:40:35 -0700385var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800386
Colin Cross83bb3162018-06-25 15:48:06 -0700387func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900388 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700389}
390
391func (j *Javadoc) minSdkVersion() string {
392 return j.sdkVersion()
393}
394
Dan Willemsen419290a2018-10-31 15:28:47 -0700395func (j *Javadoc) targetSdkVersion() string {
396 return j.sdkVersion()
397}
398
Nan Zhang581fd212018-01-10 16:06:12 -0800399func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
400 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100401 sdkDep := decodeSdkDep(ctx, sdkContext(j))
402 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700403 if sdkDep.useDefaultLibs {
404 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
405 if ctx.Config().TargetOpenJDK9() {
406 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
407 }
Paul Duffin250e6192019-06-07 10:44:37 +0100408 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700409 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
410 }
411 } else if sdkDep.useModule {
412 if ctx.Config().TargetOpenJDK9() {
413 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
414 }
415 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700416 }
Nan Zhang581fd212018-01-10 16:06:12 -0800417 }
418 }
419
Colin Cross42d48b72018-08-29 14:10:52 -0700420 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800421}
422
Nan Zhanga40da042018-08-01 12:48:00 -0700423func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
424 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900425
Colin Cross3047fa22019-04-18 10:56:44 -0700426 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900427
428 return flags
429}
430
431func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700432 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900433
434 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
435 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
436
437 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700438 var deps android.Paths
439
Jiyong Park1e440682018-05-23 18:42:04 +0900440 if aidlPreprocess.Valid() {
441 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700442 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900443 } else {
444 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
445 }
446
447 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
448 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
449 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
450 flags = append(flags, "-I"+src.String())
451 }
452
Colin Cross3047fa22019-04-18 10:56:44 -0700453 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900454}
455
Jiyong Parkd90d7412019-08-20 22:49:19 +0900456// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900457func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700458 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900459
460 outSrcFiles := make(android.Paths, 0, len(srcFiles))
461
Jiyong Park1112c4c2019-08-16 21:12:10 +0900462 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
463
Jiyong Park1e440682018-05-23 18:42:04 +0900464 for _, srcFile := range srcFiles {
465 switch srcFile.Ext() {
466 case ".aidl":
Jiyong Park1112c4c2019-08-16 21:12:10 +0900467 javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900468 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900469 case ".logtags":
470 javaFile := genLogtags(ctx, srcFile)
471 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900472 default:
473 outSrcFiles = append(outSrcFiles, srcFile)
474 }
475 }
476
477 return outSrcFiles
478}
479
Nan Zhang581fd212018-01-10 16:06:12 -0800480func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
481 var deps deps
482
Colin Cross83bb3162018-06-25 15:48:06 -0700483 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800484 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700485 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800486 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700487 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800488 }
489
490 ctx.VisitDirectDeps(func(module android.Module) {
491 otherName := ctx.OtherModuleName(module)
492 tag := ctx.OtherModuleDependencyTag(module)
493
Colin Cross2d24c1b2018-05-23 10:59:18 -0700494 switch tag {
495 case bootClasspathTag:
496 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800497 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700498 } else {
499 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
500 }
501 case libTag:
502 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800503 case SdkLibraryDependency:
504 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700505 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900506 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900507 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700508 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800509 checkProducesJars(ctx, dep)
510 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800511 default:
512 ctx.ModuleErrorf("depends on non-java module %q", otherName)
513 }
Nan Zhang357466b2018-04-17 17:38:36 -0700514 case systemModulesTag:
515 if deps.systemModules != nil {
516 panic("Found two system module dependencies")
517 }
518 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000519 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700520 panic("Missing directory for system module dependency")
521 }
Colin Crossb77043e2019-07-16 13:57:13 -0700522 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800523 }
524 })
525 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
526 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800527 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700528 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900529 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800530
531 // srcs may depend on some genrule output.
532 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800533 j.srcJars = append(j.srcJars, deps.srcJars...)
534
Nan Zhang581fd212018-01-10 16:06:12 -0800535 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800536 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800537
Nan Zhang9c69a122018-08-22 10:22:08 -0700538 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800539 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
540 }
541 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800542
Colin Cross8a497952019-03-05 22:25:09 -0800543 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000544 argFilesMap := map[string]string{}
545 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700546
Paul Duffin99e4a502019-02-11 15:38:42 +0000547 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800548 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000549 if _, exists := argFilesMap[label]; !exists {
550 argFilesMap[label] = strings.Join(paths.Strings(), " ")
551 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700552 } else {
553 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000554 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700555 }
556 }
557
558 var err error
Colin Cross15638152019-07-11 11:11:35 -0700559 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700560 if strings.HasPrefix(name, "location ") {
561 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000562 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700563 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700564 } else {
Colin Cross15638152019-07-11 11:11:35 -0700565 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000566 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700567 }
568 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700569 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700570 }
Colin Cross15638152019-07-11 11:11:35 -0700571 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700572 })
573
574 if err != nil {
575 ctx.PropertyErrorf("args", "%s", err.Error())
576 }
577
Nan Zhang581fd212018-01-10 16:06:12 -0800578 return deps
579}
580
581func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
582 j.addDeps(ctx)
583}
584
585func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
586 deps := j.collectDeps(ctx)
587
Colin Crossdaa4c672019-07-15 22:53:46 -0700588 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800589
Colin Crossdaa4c672019-07-15 22:53:46 -0700590 outDir := android.PathForModuleOut(ctx, "out")
591 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
592
593 j.stubsSrcJar = nil
594
595 rule := android.NewRuleBuilder()
596
597 rule.Command().Text("rm -rf").Text(outDir.String())
598 rule.Command().Text("mkdir -p").Text(outDir.String())
599
600 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700601
Colin Cross83bb3162018-06-25 15:48:06 -0700602 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800603
Colin Crossdaa4c672019-07-15 22:53:46 -0700604 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
605 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800606
Colin Crossdaa4c672019-07-15 22:53:46 -0700607 cmd.FlagWithArg("-source ", javaVersion).
608 Flag("-J-Xmx1024m").
609 Flag("-XDignore.symbol.file").
610 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800611
Colin Crossdaa4c672019-07-15 22:53:46 -0700612 rule.Command().
613 BuiltTool(ctx, "soong_zip").
614 Flag("-write_if_changed").
615 Flag("-d").
616 FlagWithOutput("-o ", j.docZip).
617 FlagWithArg("-C ", outDir.String()).
618 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700619
Colin Crossdaa4c672019-07-15 22:53:46 -0700620 rule.Restat()
621
622 zipSyncCleanupCmd(rule, srcJarDir)
623
624 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800625}
626
Nan Zhanga40da042018-08-01 12:48:00 -0700627//
628// Droiddoc
629//
630type Droiddoc struct {
631 Javadoc
632
633 properties DroiddocProperties
634 apiFile android.WritablePath
635 dexApiFile android.WritablePath
636 privateApiFile android.WritablePath
637 privateDexApiFile android.WritablePath
638 removedApiFile android.WritablePath
639 removedDexApiFile android.WritablePath
640 exactApiFile android.WritablePath
641 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700642 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700643
644 checkCurrentApiTimestamp android.WritablePath
645 updateCurrentApiTimestamp android.WritablePath
646 checkLastReleasedApiTimestamp android.WritablePath
647
Nan Zhanga40da042018-08-01 12:48:00 -0700648 apiFilePath android.Path
649}
650
Colin Crossa3002fc2019-07-08 16:48:04 -0700651// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700652func DroiddocFactory() android.Module {
653 module := &Droiddoc{}
654
655 module.AddProperties(&module.properties,
656 &module.Javadoc.properties)
657
658 InitDroiddocModule(module, android.HostAndDeviceSupported)
659 return module
660}
661
Colin Crossa3002fc2019-07-08 16:48:04 -0700662// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700663func DroiddocHostFactory() android.Module {
664 module := &Droiddoc{}
665
666 module.AddProperties(&module.properties,
667 &module.Javadoc.properties)
668
669 InitDroiddocModule(module, android.HostSupported)
670 return module
671}
672
673func (d *Droiddoc) ApiFilePath() android.Path {
674 return d.apiFilePath
675}
676
Nan Zhang581fd212018-01-10 16:06:12 -0800677func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
678 d.Javadoc.addDeps(ctx)
679
Inseob Kim38449af2019-02-28 14:24:05 +0900680 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
681 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
682 }
683
Nan Zhang79614d12018-04-19 18:03:39 -0700684 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800685 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
686 }
Nan Zhang581fd212018-01-10 16:06:12 -0800687}
688
Colin Crossab054432019-07-15 16:13:59 -0700689func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700690 var date string
691 if runtime.GOOS == "darwin" {
692 date = `date -r`
693 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700694 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700695 }
696
Nan Zhang443fa522018-08-20 20:58:28 -0700697 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
698 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
699 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700700 cmd.FlagWithArg("-source ", "1.8").
701 Flag("-J-Xmx1600m").
702 Flag("-J-XX:-OmitStackTraceInFastThrow").
703 Flag("-XDignore.symbol.file").
704 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
705 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
706 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700707 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700708
Nan Zhanga40da042018-08-01 12:48:00 -0700709 if String(d.properties.Custom_template) == "" {
710 // TODO: This is almost always droiddoc-templates-sdk
711 ctx.PropertyErrorf("custom_template", "must specify a template")
712 }
713
714 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700715 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700716 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700717 } else {
718 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
719 }
720 })
721
722 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700723 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
724 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
725 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700726 }
727
728 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700729 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
730 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
731 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700732 }
733
734 if len(d.properties.Html_dirs) > 2 {
735 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
736 }
737
Colin Cross8a497952019-03-05 22:25:09 -0800738 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700739 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700740
Colin Crossab054432019-07-15 16:13:59 -0700741 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700742
743 if String(d.properties.Proofread_file) != "" {
744 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700745 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700746 }
747
748 if String(d.properties.Todo_file) != "" {
749 // tricky part:
750 // we should not compute full path for todo_file through PathForModuleOut().
751 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700752 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
753 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700754 }
755
756 if String(d.properties.Resourcesdir) != "" {
757 // TODO: should we add files under resourcesDir to the implicits? It seems that
758 // resourcesDir is one sub dir of htmlDir
759 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700760 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700761 }
762
763 if String(d.properties.Resourcesoutdir) != "" {
764 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700765 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700766 }
Nan Zhanga40da042018-08-01 12:48:00 -0700767}
768
Colin Crossab054432019-07-15 16:13:59 -0700769func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200770 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
771 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700772 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700773
Nan Zhanga40da042018-08-01 12:48:00 -0700774 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700775 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700776 d.apiFilePath = d.apiFile
777 }
778
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200779 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
780 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700781 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700782 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700783 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700784 }
785
786 if String(d.properties.Private_api_filename) != "" {
787 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700788 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700789 }
790
791 if String(d.properties.Dex_api_filename) != "" {
792 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700793 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700794 }
795
796 if String(d.properties.Private_dex_api_filename) != "" {
797 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700798 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700799 }
800
801 if String(d.properties.Removed_dex_api_filename) != "" {
802 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700803 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700804 }
805
806 if String(d.properties.Exact_api_filename) != "" {
807 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700808 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700809 }
810
811 if String(d.properties.Dex_mapping_filename) != "" {
812 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700813 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700814 }
815
Nan Zhang66dc2362018-08-14 20:41:04 -0700816 if String(d.properties.Proguard_filename) != "" {
817 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700818 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700819 }
820
Nan Zhanga40da042018-08-01 12:48:00 -0700821 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700822 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700823 }
824
825 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700826 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700827 }
Nan Zhanga40da042018-08-01 12:48:00 -0700828}
829
Colin Crossab054432019-07-15 16:13:59 -0700830func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700831 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700832 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
833 rule.Command().Text("cp").
834 Input(staticDocIndexRedirect).
835 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700836 }
837
838 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700839 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
840 rule.Command().Text("cp").
841 Input(staticDocProperties).
842 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700843 }
Nan Zhanga40da042018-08-01 12:48:00 -0700844}
845
Colin Crossab054432019-07-15 16:13:59 -0700846func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700847 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700848
849 cmd := rule.Command().
850 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
851 Flag(config.JavacVmFlags).
852 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700853 FlagWithRspFileInputList("@", srcs).
854 FlagWithInput("@", srcJarList)
855
Colin Crossab054432019-07-15 16:13:59 -0700856 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
857 // based stubs generation.
858 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
859 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
860 // the correct package name base path.
861 if len(sourcepaths) > 0 {
862 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
863 } else {
864 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
865 }
866
867 cmd.FlagWithArg("-d ", outDir.String()).
868 Flag("-quiet")
869
870 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700871}
872
Colin Crossdaa4c672019-07-15 22:53:46 -0700873func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
874 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
875 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
876
877 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
878
879 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
880 cmd.Flag(flag).Implicits(deps)
881
882 cmd.FlagWithArg("--patch-module ", "java.base=.")
883
884 if len(classpath) > 0 {
885 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
886 }
887
888 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700889}
890
Colin Crossdaa4c672019-07-15 22:53:46 -0700891func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
892 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
893 sourcepaths android.Paths) *android.RuleBuilderCommand {
894
895 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
896
897 if len(bootclasspath) == 0 && ctx.Device() {
898 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
899 // ensure java does not fall back to the default bootclasspath.
900 cmd.FlagWithArg("-bootclasspath ", `""`)
901 } else if len(bootclasspath) > 0 {
902 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
903 }
904
905 if len(classpath) > 0 {
906 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
907 }
908
909 return cmd
910}
911
Colin Crossab054432019-07-15 16:13:59 -0700912func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
913 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700914
Colin Crossab054432019-07-15 16:13:59 -0700915 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
916 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
917
918 return rule.Command().
919 BuiltTool(ctx, "dokka").
920 Flag(config.JavacVmFlags).
921 Flag(srcJarDir.String()).
922 FlagWithInputList("-classpath ", dokkaClasspath, ":").
923 FlagWithArg("-format ", "dac").
924 FlagWithArg("-dacRoot ", "/reference/kotlin").
925 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700926}
927
928func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
929 deps := d.Javadoc.collectDeps(ctx)
930
Colin Crossdaa4c672019-07-15 22:53:46 -0700931 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
932 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
933
Nan Zhang1598a9e2018-09-04 17:14:32 -0700934 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
935 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
936 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
937 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
938
Colin Crossab054432019-07-15 16:13:59 -0700939 outDir := android.PathForModuleOut(ctx, "out")
940 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
941 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700942
Colin Crossab054432019-07-15 16:13:59 -0700943 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700944
Colin Crossab054432019-07-15 16:13:59 -0700945 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
946 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700947
Colin Crossab054432019-07-15 16:13:59 -0700948 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
949
950 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700951 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700952 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700953 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700954 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700955 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700956 }
957
Colin Crossab054432019-07-15 16:13:59 -0700958 d.stubsFlags(ctx, cmd, stubsDir)
959
960 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
961
962 var desc string
963 if Bool(d.properties.Dokka_enabled) {
964 desc = "dokka"
965 } else {
966 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
967
968 for _, o := range d.Javadoc.properties.Out {
969 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
970 }
971
972 d.postDoclavaCmds(ctx, rule)
973 desc = "doclava"
974 }
975
976 rule.Command().
977 BuiltTool(ctx, "soong_zip").
978 Flag("-write_if_changed").
979 Flag("-d").
980 FlagWithOutput("-o ", d.docZip).
981 FlagWithArg("-C ", outDir.String()).
982 FlagWithArg("-D ", outDir.String())
983
984 rule.Command().
985 BuiltTool(ctx, "soong_zip").
986 Flag("-write_if_changed").
987 Flag("-jar").
988 FlagWithOutput("-o ", d.stubsSrcJar).
989 FlagWithArg("-C ", stubsDir.String()).
990 FlagWithArg("-D ", stubsDir.String())
991
992 rule.Restat()
993
994 zipSyncCleanupCmd(rule, srcJarDir)
995
996 rule.Build(pctx, ctx, "javadoc", desc)
997
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200998 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -0700999 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001000
1001 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1002 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001003
1004 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001005
1006 rule := android.NewRuleBuilder()
1007
1008 rule.Command().Text("( true")
1009
1010 rule.Command().
1011 BuiltTool(ctx, "apicheck").
1012 Flag("-JXmx1024m").
1013 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1014 OptionalFlag(d.properties.Check_api.Current.Args).
1015 Input(apiFile).
1016 Input(d.apiFile).
1017 Input(removedApiFile).
1018 Input(d.removedApiFile)
1019
1020 msg := fmt.Sprintf(`\n******************************\n`+
1021 `You have tried to change the API from what has been previously approved.\n\n`+
1022 `To make these errors go away, you have two choices:\n`+
1023 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1024 ` errors above.\n\n`+
1025 ` 2. You can update current.txt by executing the following command:\n`+
1026 ` make %s-update-current-api\n\n`+
1027 ` To submit the revised current.txt to the main Android repository,\n`+
1028 ` you will need approval.\n`+
1029 `******************************\n`, ctx.ModuleName())
1030
1031 rule.Command().
1032 Text("touch").Output(d.checkCurrentApiTimestamp).
1033 Text(") || (").
1034 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1035 Text("; exit 38").
1036 Text(")")
1037
1038 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001039
1040 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001041
1042 // update API rule
1043 rule = android.NewRuleBuilder()
1044
1045 rule.Command().Text("( true")
1046
1047 rule.Command().
1048 Text("cp").Flag("-f").
1049 Input(d.apiFile).Flag(apiFile.String())
1050
1051 rule.Command().
1052 Text("cp").Flag("-f").
1053 Input(d.removedApiFile).Flag(removedApiFile.String())
1054
1055 msg = "failed to update public API"
1056
1057 rule.Command().
1058 Text("touch").Output(d.updateCurrentApiTimestamp).
1059 Text(") || (").
1060 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1061 Text("; exit 38").
1062 Text(")")
1063
1064 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001065 }
1066
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001067 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001068 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001069
1070 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1071 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001072
1073 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001074
1075 rule := android.NewRuleBuilder()
1076
1077 rule.Command().
1078 Text("(").
1079 BuiltTool(ctx, "apicheck").
1080 Flag("-JXmx1024m").
1081 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1082 OptionalFlag(d.properties.Check_api.Last_released.Args).
1083 Input(apiFile).
1084 Input(d.apiFile).
1085 Input(removedApiFile).
1086 Input(d.removedApiFile)
1087
1088 msg := `\n******************************\n` +
1089 `You have tried to change the API from what has been previously released in\n` +
1090 `an SDK. Please fix the errors listed above.\n` +
1091 `******************************\n`
1092
1093 rule.Command().
1094 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1095 Text(") || (").
1096 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1097 Text("; exit 38").
1098 Text(")")
1099
1100 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001101 }
1102}
1103
1104//
1105// Droidstubs
1106//
1107type Droidstubs struct {
1108 Javadoc
1109
Pete Gillin581d6082018-10-22 15:55:04 +01001110 properties DroidstubsProperties
1111 apiFile android.WritablePath
1112 apiXmlFile android.WritablePath
1113 lastReleasedApiXmlFile android.WritablePath
1114 dexApiFile android.WritablePath
1115 privateApiFile android.WritablePath
1116 privateDexApiFile android.WritablePath
1117 removedApiFile android.WritablePath
1118 removedDexApiFile android.WritablePath
1119 apiMappingFile android.WritablePath
1120 exactApiFile android.WritablePath
1121 proguardFile android.WritablePath
1122 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001123
1124 checkCurrentApiTimestamp android.WritablePath
1125 updateCurrentApiTimestamp android.WritablePath
1126 checkLastReleasedApiTimestamp android.WritablePath
1127
Pete Gillin581d6082018-10-22 15:55:04 +01001128 checkNullabilityWarningsTimestamp android.WritablePath
1129
Nan Zhang1598a9e2018-09-04 17:14:32 -07001130 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001131 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001132
1133 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001134
1135 jdiffDocZip android.WritablePath
1136 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001137}
1138
Colin Crossa3002fc2019-07-08 16:48:04 -07001139// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1140// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1141// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001142func DroidstubsFactory() android.Module {
1143 module := &Droidstubs{}
1144
1145 module.AddProperties(&module.properties,
1146 &module.Javadoc.properties)
1147
1148 InitDroiddocModule(module, android.HostAndDeviceSupported)
1149 return module
1150}
1151
Colin Crossa3002fc2019-07-08 16:48:04 -07001152// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1153// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1154// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1155// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001156func DroidstubsHostFactory() android.Module {
1157 module := &Droidstubs{}
1158
1159 module.AddProperties(&module.properties,
1160 &module.Javadoc.properties)
1161
1162 InitDroiddocModule(module, android.HostSupported)
1163 return module
1164}
1165
1166func (d *Droidstubs) ApiFilePath() android.Path {
1167 return d.apiFilePath
1168}
1169
1170func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1171 d.Javadoc.addDeps(ctx)
1172
Inseob Kim38449af2019-02-28 14:24:05 +09001173 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1174 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1175 }
1176
Nan Zhang1598a9e2018-09-04 17:14:32 -07001177 if len(d.properties.Merge_annotations_dirs) != 0 {
1178 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1179 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1180 }
1181 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001182
Pete Gillin77167902018-09-19 18:16:26 +01001183 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1184 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1185 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1186 }
1187 }
1188
Nan Zhang9c69a122018-08-22 10:22:08 -07001189 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1190 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1191 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1192 }
1193 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001194}
1195
Colin Cross33961b52019-07-11 11:01:22 -07001196func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001197 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1198 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001199 String(d.properties.Api_filename) != "" {
1200 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001201 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001202 d.apiFilePath = d.apiFile
1203 }
1204
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001205 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1206 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001207 String(d.properties.Removed_api_filename) != "" {
1208 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001209 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001210 }
1211
1212 if String(d.properties.Private_api_filename) != "" {
1213 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001214 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001215 }
1216
1217 if String(d.properties.Dex_api_filename) != "" {
1218 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001219 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001220 }
1221
1222 if String(d.properties.Private_dex_api_filename) != "" {
1223 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001224 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001225 }
1226
1227 if String(d.properties.Removed_dex_api_filename) != "" {
1228 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001229 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001230 }
1231
1232 if String(d.properties.Exact_api_filename) != "" {
1233 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001234 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001235 }
1236
Nan Zhang9c69a122018-08-22 10:22:08 -07001237 if String(d.properties.Dex_mapping_filename) != "" {
1238 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001239 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001240 }
1241
Nan Zhang199645c2018-09-19 12:40:06 -07001242 if String(d.properties.Proguard_filename) != "" {
1243 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001244 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001245 }
1246
Nan Zhang9c69a122018-08-22 10:22:08 -07001247 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001248 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001249 }
1250
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001252 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001253 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001254 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256}
1257
Colin Cross33961b52019-07-11 11:01:22 -07001258func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001260 cmd.Flag("--include-annotations")
1261
Pete Gillinc382a562018-11-14 18:45:46 +00001262 validatingNullability :=
1263 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1264 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001265 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001266
Pete Gillina262c052018-09-14 14:25:48 +01001267 if !(migratingNullability || validatingNullability) {
1268 ctx.PropertyErrorf("previous_api",
1269 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001270 }
Colin Cross33961b52019-07-11 11:01:22 -07001271
Pete Gillina262c052018-09-14 14:25:48 +01001272 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001273 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001274 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001275 }
Colin Cross33961b52019-07-11 11:01:22 -07001276
Pete Gillinc382a562018-11-14 18:45:46 +00001277 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001278 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001279 }
Colin Cross33961b52019-07-11 11:01:22 -07001280
Pete Gillina262c052018-09-14 14:25:48 +01001281 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001282 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001283 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001284 }
Nan Zhanga40da042018-08-01 12:48:00 -07001285
1286 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001287 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001288
Nan Zhang1598a9e2018-09-04 17:14:32 -07001289 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001290 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001291 "has to be non-empty if annotations was enabled!")
1292 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001293
Colin Cross33961b52019-07-11 11:01:22 -07001294 d.mergeAnnoDirFlags(ctx, cmd)
1295
1296 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1297 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1298 FlagWithArg("--hide ", "SuperfluousPrefix").
1299 FlagWithArg("--hide ", "AnnotationExtraction")
1300 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001301}
1302
Colin Cross33961b52019-07-11 11:01:22 -07001303func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1304 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1305 if t, ok := m.(*ExportedDroiddocDir); ok {
1306 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1307 } else {
1308 ctx.PropertyErrorf("merge_annotations_dirs",
1309 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1310 }
1311 })
1312}
1313
1314func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001315 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1316 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001317 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001318 } else {
1319 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1320 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1321 }
1322 })
Nan Zhanga40da042018-08-01 12:48:00 -07001323}
1324
Colin Cross33961b52019-07-11 11:01:22 -07001325func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001326 if Bool(d.properties.Api_levels_annotations_enabled) {
1327 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001328
1329 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1330 ctx.PropertyErrorf("api_levels_annotations_dirs",
1331 "has to be non-empty if api levels annotations was enabled!")
1332 }
1333
Colin Cross33961b52019-07-11 11:01:22 -07001334 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1335 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1336 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1337 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001338
1339 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1340 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001341 for _, dep := range t.deps {
1342 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001343 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001344 }
1345 }
Colin Cross33961b52019-07-11 11:01:22 -07001346 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001347 } else {
1348 ctx.PropertyErrorf("api_levels_annotations_dirs",
1349 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1350 }
1351 })
1352
1353 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001354}
1355
Colin Cross33961b52019-07-11 11:01:22 -07001356func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001357 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1358 if d.apiFile.String() == "" {
1359 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1360 }
1361
1362 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001363 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001364
1365 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1366 ctx.PropertyErrorf("check_api.last_released.api_file",
1367 "has to be non-empty if jdiff was enabled!")
1368 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001369
Colin Cross33961b52019-07-11 11:01:22 -07001370 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001371 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001372 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1373 }
1374}
Nan Zhang71bbe632018-09-17 14:32:21 -07001375
Colin Cross33961b52019-07-11 11:01:22 -07001376func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1377 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1378 cmd := rule.Command().BuiltTool(ctx, "metalava").
1379 Flag(config.JavacVmFlags).
1380 FlagWithArg("-encoding ", "UTF-8").
1381 FlagWithArg("-source ", javaVersion).
1382 FlagWithRspFileInputList("@", srcs).
1383 FlagWithInput("@", srcJarList)
1384
1385 if len(bootclasspath) > 0 {
1386 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001387 }
1388
Colin Cross33961b52019-07-11 11:01:22 -07001389 if len(classpath) > 0 {
1390 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1391 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001392
Colin Cross33961b52019-07-11 11:01:22 -07001393 if len(sourcepaths) > 0 {
1394 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1395 } else {
1396 cmd.FlagWithArg("-sourcepath ", `""`)
1397 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001398
Colin Cross33961b52019-07-11 11:01:22 -07001399 cmd.Flag("--no-banner").
1400 Flag("--color").
1401 Flag("--quiet").
1402 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001403
Colin Cross33961b52019-07-11 11:01:22 -07001404 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001405}
1406
Nan Zhang1598a9e2018-09-04 17:14:32 -07001407func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001408 deps := d.Javadoc.collectDeps(ctx)
1409
1410 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001411
Colin Cross33961b52019-07-11 11:01:22 -07001412 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001413
Colin Crossdaa4c672019-07-15 22:53:46 -07001414 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001415
Colin Cross33961b52019-07-11 11:01:22 -07001416 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1417 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001418
Colin Cross33961b52019-07-11 11:01:22 -07001419 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001420
Colin Cross33961b52019-07-11 11:01:22 -07001421 rule.Command().Text("rm -rf").Text(stubsDir.String())
1422 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001423
Colin Cross33961b52019-07-11 11:01:22 -07001424 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1425
1426 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1427 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1428
1429 d.stubsFlags(ctx, cmd, stubsDir)
1430
1431 d.annotationsFlags(ctx, cmd)
1432 d.inclusionAnnotationsFlags(ctx, cmd)
1433 d.apiLevelsAnnotationsFlags(ctx, cmd)
1434 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001435
Nan Zhang1598a9e2018-09-04 17:14:32 -07001436 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1437 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1438 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1439 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1440 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001441 }
Colin Cross33961b52019-07-11 11:01:22 -07001442
1443 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1444 for _, o := range d.Javadoc.properties.Out {
1445 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1446 }
1447
1448 rule.Command().
1449 BuiltTool(ctx, "soong_zip").
1450 Flag("-write_if_changed").
1451 Flag("-jar").
1452 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1453 FlagWithArg("-C ", stubsDir.String()).
1454 FlagWithArg("-D ", stubsDir.String())
1455 rule.Restat()
1456
1457 zipSyncCleanupCmd(rule, srcJarDir)
1458
1459 rule.Build(pctx, ctx, "metalava", "metalava")
1460
1461 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001462
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001463 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001464 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001465
1466 if len(d.Javadoc.properties.Out) > 0 {
1467 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1468 }
1469
1470 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1471 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001472 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1473 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001474
Nan Zhang2760dfc2018-08-24 17:32:54 +00001475 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001476
Colin Cross33961b52019-07-11 11:01:22 -07001477 rule := android.NewRuleBuilder()
1478
1479 rule.Command().Text("( true")
1480
1481 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1482 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1483
1484 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1485 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1486
1487 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1488 FlagWithInput("--check-compatibility:api:current ", apiFile).
1489 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1490
1491 d.inclusionAnnotationsFlags(ctx, cmd)
1492 d.mergeAnnoDirFlags(ctx, cmd)
1493
Adrian Roos14f75a92019-08-12 17:54:09 +02001494 if baselineFile.Valid() {
1495 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1496 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1497 }
1498
Colin Cross33961b52019-07-11 11:01:22 -07001499 zipSyncCleanupCmd(rule, srcJarDir)
1500
1501 msg := fmt.Sprintf(`\n******************************\n`+
1502 `You have tried to change the API from what has been previously approved.\n\n`+
1503 `To make these errors go away, you have two choices:\n`+
1504 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1505 ` errors above.\n\n`+
1506 ` 2. You can update current.txt by executing the following command:\n`+
1507 ` make %s-update-current-api\n\n`+
1508 ` To submit the revised current.txt to the main Android repository,\n`+
1509 ` you will need approval.\n`+
1510 `******************************\n`, ctx.ModuleName())
1511
1512 rule.Command().
1513 Text("touch").Output(d.checkCurrentApiTimestamp).
1514 Text(") || (").
1515 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1516 Text("; exit 38").
1517 Text(")")
1518
1519 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001520
1521 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001522
1523 // update API rule
1524 rule = android.NewRuleBuilder()
1525
1526 rule.Command().Text("( true")
1527
1528 rule.Command().
1529 Text("cp").Flag("-f").
1530 Input(d.apiFile).Flag(apiFile.String())
1531
1532 rule.Command().
1533 Text("cp").Flag("-f").
1534 Input(d.removedApiFile).Flag(removedApiFile.String())
1535
1536 msg = "failed to update public API"
1537
1538 rule.Command().
1539 Text("touch").Output(d.updateCurrentApiTimestamp).
1540 Text(") || (").
1541 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1542 Text("; exit 38").
1543 Text(")")
1544
1545 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001546 }
Nan Zhanga40da042018-08-01 12:48:00 -07001547
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001548 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001549 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001550
1551 if len(d.Javadoc.properties.Out) > 0 {
1552 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1553 }
1554
1555 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1556 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001557 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1558 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001559
Nan Zhang2760dfc2018-08-24 17:32:54 +00001560 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001561
Colin Cross33961b52019-07-11 11:01:22 -07001562 rule := android.NewRuleBuilder()
1563
1564 rule.Command().Text("( true")
1565
1566 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1567 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1568
1569 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1570 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1571
1572 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1573 FlagWithInput("--check-compatibility:api:released ", apiFile)
1574
1575 d.inclusionAnnotationsFlags(ctx, cmd)
1576
1577 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1578
1579 d.mergeAnnoDirFlags(ctx, cmd)
1580
Adrian Roos14f75a92019-08-12 17:54:09 +02001581 if baselineFile.Valid() {
1582 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1583 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1584 }
1585
Colin Cross33961b52019-07-11 11:01:22 -07001586 zipSyncCleanupCmd(rule, srcJarDir)
1587
1588 msg := `\n******************************\n` +
1589 `You have tried to change the API from what has been previously released in\n` +
1590 `an SDK. Please fix the errors listed above.\n` +
1591 `******************************\n`
1592 rule.Command().
1593 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1594 Text(") || (").
1595 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1596 Text("; exit 38").
1597 Text(")")
1598
1599 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001600 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001601
Pete Gillin581d6082018-10-22 15:55:04 +01001602 if String(d.properties.Check_nullability_warnings) != "" {
1603 if d.nullabilityWarningsFile == nil {
1604 ctx.PropertyErrorf("check_nullability_warnings",
1605 "Cannot specify check_nullability_warnings unless validating nullability")
1606 }
Colin Cross33961b52019-07-11 11:01:22 -07001607
1608 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1609
Pete Gillin581d6082018-10-22 15:55:04 +01001610 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001611
Pete Gillin581d6082018-10-22 15:55:04 +01001612 msg := fmt.Sprintf(`\n******************************\n`+
1613 `The warnings encountered during nullability annotation validation did\n`+
1614 `not match the checked in file of expected warnings. The diffs are shown\n`+
1615 `above. You have two options:\n`+
1616 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1617 ` 2. Update the file of expected warnings by running:\n`+
1618 ` cp %s %s\n`+
1619 ` and submitting the updated file as part of your change.`,
1620 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001621
1622 rule := android.NewRuleBuilder()
1623
1624 rule.Command().
1625 Text("(").
1626 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1627 Text("&&").
1628 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1629 Text(") || (").
1630 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1631 Text("; exit 38").
1632 Text(")")
1633
1634 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001635 }
1636
Nan Zhang71bbe632018-09-17 14:32:21 -07001637 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001638 if len(d.Javadoc.properties.Out) > 0 {
1639 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1640 }
1641
1642 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1643 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1644 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1645
1646 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001647
Nan Zhang86b06202018-09-21 17:09:21 -07001648 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1649 // since there's cron job downstream that fetch this .zip file periodically.
1650 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001651 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1652 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1653
Nan Zhang71bbe632018-09-17 14:32:21 -07001654 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001655
Colin Cross33961b52019-07-11 11:01:22 -07001656 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1657 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001658
Colin Cross33961b52019-07-11 11:01:22 -07001659 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1660
Colin Crossdaa4c672019-07-15 22:53:46 -07001661 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001662 deps.bootClasspath, deps.classpath, d.sourcepaths)
1663
1664 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001665 Flag("-XDignore.symbol.file").
1666 FlagWithArg("-doclet ", "jdiff.JDiff").
1667 FlagWithInput("-docletpath ", jdiff).
1668 Flag("-quiet").
1669 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1670 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1671 Implicit(d.apiXmlFile).
1672 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1673 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1674 Implicit(d.lastReleasedApiXmlFile)
1675
Colin Cross33961b52019-07-11 11:01:22 -07001676 rule.Command().
1677 BuiltTool(ctx, "soong_zip").
1678 Flag("-write_if_changed").
1679 Flag("-d").
1680 FlagWithOutput("-o ", d.jdiffDocZip).
1681 FlagWithArg("-C ", outDir.String()).
1682 FlagWithArg("-D ", outDir.String())
1683
1684 rule.Command().
1685 BuiltTool(ctx, "soong_zip").
1686 Flag("-write_if_changed").
1687 Flag("-jar").
1688 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1689 FlagWithArg("-C ", stubsDir.String()).
1690 FlagWithArg("-D ", stubsDir.String())
1691
1692 rule.Restat()
1693
1694 zipSyncCleanupCmd(rule, srcJarDir)
1695
1696 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001697 }
Nan Zhang581fd212018-01-10 16:06:12 -08001698}
Dan Willemsencc090972018-02-26 14:33:31 -08001699
Nan Zhanga40da042018-08-01 12:48:00 -07001700//
Nan Zhangf4936b02018-08-01 15:00:28 -07001701// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001702//
Dan Willemsencc090972018-02-26 14:33:31 -08001703var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001704var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001705var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001706var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001707
Nan Zhangf4936b02018-08-01 15:00:28 -07001708type ExportedDroiddocDirProperties struct {
1709 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001710 Path *string
1711}
1712
Nan Zhangf4936b02018-08-01 15:00:28 -07001713type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001714 android.ModuleBase
1715
Nan Zhangf4936b02018-08-01 15:00:28 -07001716 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001717
1718 deps android.Paths
1719 dir android.Path
1720}
1721
Colin Crossa3002fc2019-07-08 16:48:04 -07001722// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001723func ExportedDroiddocDirFactory() android.Module {
1724 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001725 module.AddProperties(&module.properties)
1726 android.InitAndroidModule(module)
1727 return module
1728}
1729
Nan Zhangf4936b02018-08-01 15:00:28 -07001730func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001731
Nan Zhangf4936b02018-08-01 15:00:28 -07001732func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001733 path := String(d.properties.Path)
1734 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001735 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001736}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001737
1738//
1739// Defaults
1740//
1741type DocDefaults struct {
1742 android.ModuleBase
1743 android.DefaultsModuleBase
1744}
1745
Nan Zhangb2b33de2018-02-23 11:18:47 -08001746func DocDefaultsFactory() android.Module {
1747 module := &DocDefaults{}
1748
1749 module.AddProperties(
1750 &JavadocProperties{},
1751 &DroiddocProperties{},
1752 )
1753
1754 android.InitDefaultsModule(module)
1755
1756 return module
1757}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001758
1759func StubsDefaultsFactory() android.Module {
1760 module := &DocDefaults{}
1761
1762 module.AddProperties(
1763 &JavadocProperties{},
1764 &DroidstubsProperties{},
1765 )
1766
1767 android.InitDefaultsModule(module)
1768
1769 return module
1770}
Colin Cross33961b52019-07-11 11:01:22 -07001771
1772func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1773 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1774
1775 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1776 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1777 srcJarList := srcJarDir.Join(ctx, "list")
1778
1779 rule.Temporary(srcJarList)
1780
1781 rule.Command().BuiltTool(ctx, "zipsync").
1782 FlagWithArg("-d ", srcJarDir.String()).
1783 FlagWithOutput("-l ", srcJarList).
1784 FlagWithArg("-f ", `"*.java"`).
1785 Inputs(srcJars)
1786
1787 return srcJarList
1788}
1789
1790func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1791 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1792}