blob: 098400bff33a695463f8cf2fa8c377e5fa801143 [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
Paul Duffin13879572019-11-28 14:31:38 +000022 "github.com/google/blueprint"
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() {
Paul Duffin884363e2019-12-19 10:21:09 +000030 RegisterDocsBuildComponents(android.InitRegistrationContext)
31 RegisterStubsBuildComponents(android.InitRegistrationContext)
Paul Duffin255f18e2019-12-13 11:22:16 +000032
33 // Register sdk member type.
34 android.RegisterSdkMemberType(&droidStubsSdkMemberType{
35 SdkMemberTypeBase: android.SdkMemberTypeBase{
36 PropertyName: "stubs_sources",
Paul Duffine6029182019-12-16 17:43:48 +000037 // stubs_sources can be used with sdk to provide the source stubs for APIs provided by
38 // the APEX.
39 SupportsSdk: true,
Paul Duffin255f18e2019-12-13 11:22:16 +000040 },
41 })
Nan Zhang581fd212018-01-10 16:06:12 -080042}
43
Paul Duffin884363e2019-12-19 10:21:09 +000044func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
45 ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
46
47 ctx.RegisterModuleType("droiddoc", DroiddocFactory)
48 ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
49 ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
50 ctx.RegisterModuleType("javadoc", JavadocFactory)
51 ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
52}
53
54func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
55 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
56
57 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
58 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
59
60 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
61}
62
Colin Crossa1ce2a02018-06-20 15:19:39 -070063var (
64 srcsLibTag = dependencyTag{name: "sources from javalib"}
65)
66
Nan Zhang581fd212018-01-10 16:06:12 -080067type JavadocProperties struct {
68 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
69 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080070 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080071
72 // list of directories rooted at the Android.bp file that will
73 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080074 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080075
76 // list of source files that should not be used to build the Java module.
77 // This is most useful in the arch/multilib variants to remove non-common files
78 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080079 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080080
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090081 // list of package names that should actually be used. If this property is left unspecified,
82 // all the sources from the srcs property is used.
83 Filter_packages []string
84
Nan Zhangb2b33de2018-02-23 11:18:47 -080085 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080086 Libs []string `android:"arch_variant"`
87
88 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080089 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080090
Paul Duffine25c6442019-10-11 13:50:28 +010091 // if not blank, set to the version of the sdk to compile against.
92 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080093 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090094
Paul Duffine25c6442019-10-11 13:50:28 +010095 // When targeting 1.9 and above, override the modules to use with --system,
96 // otherwise provides defaults libraries to add to the bootclasspath.
97 // Defaults to "none"
98 System_modules *string
99
Jiyong Park1e440682018-05-23 18:42:04 +0900100 Aidl struct {
101 // Top level directories to pass to aidl tool
102 Include_dirs []string
103
104 // Directories rooted at the Android.bp file to pass to aidl tool
105 Local_include_dirs []string
106 }
Nan Zhang357466b2018-04-17 17:38:36 -0700107
108 // If not blank, set the java version passed to javadoc as -source
109 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700110
111 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700113
114 // user customized droiddoc args.
115 // Available variables for substitution:
116 //
117 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700118 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700119 Args *string
120
121 // names of the output files used in args that will be generated
122 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800123}
124
Nan Zhang61819ce2018-05-04 18:49:16 -0700125type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900126 // path to the API txt file that the new API extracted from source code is checked
127 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800128 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700129
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900130 // path to the API txt file that the new @removed API extractd from source code is
131 // checked against. The path can be local to the module or from other module (via
132 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800133 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700134
Adrian Roos14f75a92019-08-12 17:54:09 +0200135 // If not blank, path to the baseline txt file for approved API check violations.
136 Baseline_file *string `android:"path"`
137
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900138 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700139 Args *string
140}
141
Nan Zhang581fd212018-01-10 16:06:12 -0800142type DroiddocProperties struct {
143 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800144 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800145
Nan Zhanga40da042018-08-01 12:48:00 -0700146 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800147 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800148
149 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800150 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800151
152 // proofread file contains all of the text content of the javadocs concatenated into one file,
153 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700154 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800155
156 // a todo file lists the program elements that are missing documentation.
157 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800158 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800159
160 // directory under current module source that provide additional resources (images).
161 Resourcesdir *string
162
163 // resources output directory under out/soong/.intermediates.
164 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800165
Nan Zhange2ba5d42018-07-11 15:16:55 -0700166 // if set to true, collect the values used by the Dev tools and
167 // write them in files packaged with the SDK. Defaults to false.
168 Write_sdk_values *bool
169
170 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800171 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700172
173 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800174 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700175
Nan Zhang581fd212018-01-10 16:06:12 -0800176 // a list of files under current module source dir which contains known tags in Java sources.
177 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800178 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700179
180 // the tag name used to distinguish if the API files belong to public/system/test.
181 Api_tag_name *string
182
183 // the generated public API filename by Doclava.
184 Api_filename *string
185
David Brazdilfbe4cc32018-05-31 13:56:46 +0100186 // the generated public Dex API filename by Doclava.
187 Dex_api_filename *string
188
Nan Zhang28c68b92018-03-13 16:17:01 -0700189 // the generated private API filename by Doclava.
190 Private_api_filename *string
191
192 // the generated private Dex API filename by Doclava.
193 Private_dex_api_filename *string
194
195 // the generated removed API filename by Doclava.
196 Removed_api_filename *string
197
David Brazdilaac0c3c2018-04-24 16:23:29 +0100198 // the generated removed Dex API filename by Doclava.
199 Removed_dex_api_filename *string
200
Mathew Inwood76c3de12018-06-22 15:28:11 +0100201 // mapping of dex signatures to source file and line number. This is a temporary property and
202 // will be deleted; you probably shouldn't be using it.
203 Dex_mapping_filename *string
204
Nan Zhang28c68b92018-03-13 16:17:01 -0700205 // the generated exact API filename by Doclava.
206 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700207
Nan Zhang66dc2362018-08-14 20:41:04 -0700208 // the generated proguard filename by Doclava.
209 Proguard_filename *string
210
Nan Zhang853f4202018-04-12 16:55:56 -0700211 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
212 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700213
214 Check_api struct {
215 Last_released ApiToCheck
216
217 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900218
219 // do not perform API check against Last_released, in the case that both two specified API
220 // files by Last_released are modules which don't exist.
221 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700222 }
Nan Zhang79614d12018-04-19 18:03:39 -0700223
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 // if set to true, generate docs through Dokka instead of Doclava.
225 Dokka_enabled *bool
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000226
227 // Compat config XML. Generates compat change documentation if set.
228 Compat_config *string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700229}
230
231type DroidstubsProperties struct {
232 // the tag name used to distinguish if the API files belong to public/system/test.
233 Api_tag_name *string
234
Nan Zhang199645c2018-09-19 12:40:06 -0700235 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700236 Api_filename *string
237
Nan Zhang199645c2018-09-19 12:40:06 -0700238 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Dex_api_filename *string
240
Nan Zhang199645c2018-09-19 12:40:06 -0700241 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700242 Private_api_filename *string
243
Nan Zhang199645c2018-09-19 12:40:06 -0700244 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700245 Private_dex_api_filename *string
246
Nan Zhang199645c2018-09-19 12:40:06 -0700247 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700248 Removed_api_filename *string
249
Nan Zhang199645c2018-09-19 12:40:06 -0700250 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700251 Removed_dex_api_filename *string
252
Nan Zhang9c69a122018-08-22 10:22:08 -0700253 // mapping of dex signatures to source file and line number. This is a temporary property and
254 // will be deleted; you probably shouldn't be using it.
255 Dex_mapping_filename *string
256
Nan Zhang199645c2018-09-19 12:40:06 -0700257 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700258 Exact_api_filename *string
259
Nan Zhang199645c2018-09-19 12:40:06 -0700260 // the generated proguard filename by Metalava.
261 Proguard_filename *string
262
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 Check_api struct {
264 Last_released ApiToCheck
265
266 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900267
268 // do not perform API check against Last_released, in the case that both two specified API
269 // files by Last_released are modules which don't exist.
270 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200271
272 Api_lint struct {
273 Enabled *bool
274
275 // If set, performs api_lint on any new APIs not found in the given signature file
276 New_since *string `android:"path"`
277
278 // If not blank, path to the baseline txt file for approved API lint violations.
279 Baseline_file *string `android:"path"`
280 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700281 }
Nan Zhang79614d12018-04-19 18:03:39 -0700282
283 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800284 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700285
286 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700287 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700288
Pete Gillin77167902018-09-19 18:16:26 +0100289 // 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 -0700290 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700291
Pete Gillin77167902018-09-19 18:16:26 +0100292 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
293 Merge_inclusion_annotations_dirs []string
294
Pete Gillinc382a562018-11-14 18:45:46 +0000295 // a file containing a list of classes to do nullability validation for.
296 Validate_nullability_from_list *string
297
Pete Gillin581d6082018-10-22 15:55:04 +0100298 // a file containing expected warnings produced by validation of nullability annotations.
299 Check_nullability_warnings *string
300
Nan Zhang1598a9e2018-09-04 17:14:32 -0700301 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
302 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700303
304 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
305 Api_levels_annotations_enabled *bool
306
307 // the dirs which Metalava extracts API levels annotations from.
308 Api_levels_annotations_dirs []string
309
310 // if set to true, collect the values used by the Dev tools and
311 // write them in files packaged with the SDK. Defaults to false.
312 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700313
314 // If set to true, .xml based public API file will be also generated, and
315 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
316 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800317}
318
Nan Zhanga40da042018-08-01 12:48:00 -0700319//
320// Common flags passed down to build rule
321//
322type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700323 bootClasspathArgs string
324 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700325 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700326 dokkaClasspathArgs string
327 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700328 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700329
Nan Zhanga40da042018-08-01 12:48:00 -0700330 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700331 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700332 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700333}
334
335func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
336 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
337 android.InitDefaultableModule(module)
338}
339
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200340func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
341 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
342 return false
343 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700344 return true
345 } else if String(apiToCheck.Api_file) != "" {
346 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
347 } else if String(apiToCheck.Removed_api_file) != "" {
348 panic("for " + apiVersionTag + " api_file has to be non-empty!")
349 }
350
351 return false
352}
353
Inseob Kim38449af2019-02-28 14:24:05 +0900354func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
355 api_file := String(apiToCheck.Api_file)
356 removed_api_file := String(apiToCheck.Removed_api_file)
357
358 api_module := android.SrcIsModule(api_file)
359 removed_api_module := android.SrcIsModule(removed_api_file)
360
361 if api_module == "" || removed_api_module == "" {
362 return
363 }
364
365 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
366 return
367 }
368
369 apiToCheck.Api_file = nil
370 apiToCheck.Removed_api_file = nil
371}
372
Nan Zhang1598a9e2018-09-04 17:14:32 -0700373type ApiFilePath interface {
374 ApiFilePath() android.Path
375}
376
Nan Zhanga40da042018-08-01 12:48:00 -0700377//
378// Javadoc
379//
Nan Zhang581fd212018-01-10 16:06:12 -0800380type Javadoc struct {
381 android.ModuleBase
382 android.DefaultableModuleBase
383
384 properties JavadocProperties
385
386 srcJars android.Paths
387 srcFiles android.Paths
388 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700389 argFiles android.Paths
390
391 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800392
Nan Zhangccff0f72018-03-08 17:26:16 -0800393 docZip android.WritablePath
394 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800395}
396
Colin Cross41955e82019-05-29 14:40:35 -0700397func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
398 switch tag {
399 case "":
400 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700401 case ".docs.zip":
402 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700403 default:
404 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
405 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800406}
407
Colin Crossa3002fc2019-07-08 16:48:04 -0700408// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800409func JavadocFactory() android.Module {
410 module := &Javadoc{}
411
412 module.AddProperties(&module.properties)
413
414 InitDroiddocModule(module, android.HostAndDeviceSupported)
415 return module
416}
417
Colin Crossa3002fc2019-07-08 16:48:04 -0700418// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800419func JavadocHostFactory() android.Module {
420 module := &Javadoc{}
421
422 module.AddProperties(&module.properties)
423
424 InitDroiddocModule(module, android.HostSupported)
425 return module
426}
427
Colin Cross41955e82019-05-29 14:40:35 -0700428var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800429
Jiyong Park6a927c42020-01-21 02:03:43 +0900430func (j *Javadoc) sdkVersion() sdkSpec {
431 return sdkSpecFrom(String(j.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700432}
433
Paul Duffine25c6442019-10-11 13:50:28 +0100434func (j *Javadoc) systemModules() string {
435 return proptools.String(j.properties.System_modules)
436}
437
Jiyong Park6a927c42020-01-21 02:03:43 +0900438func (j *Javadoc) minSdkVersion() sdkSpec {
Colin Cross83bb3162018-06-25 15:48:06 -0700439 return j.sdkVersion()
440}
441
Jiyong Park6a927c42020-01-21 02:03:43 +0900442func (j *Javadoc) targetSdkVersion() sdkSpec {
Dan Willemsen419290a2018-10-31 15:28:47 -0700443 return j.sdkVersion()
444}
445
Nan Zhang581fd212018-01-10 16:06:12 -0800446func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
447 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100448 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Colin Cross6d8d8c62019-10-28 15:10:03 -0700449 if sdkDep.useDefaultLibs {
450 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
451 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
452 if sdkDep.hasFrameworkLibs() {
453 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700454 }
Colin Cross6d8d8c62019-10-28 15:10:03 -0700455 } else if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700456 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100457 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700458 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800459 }
460 }
461
Colin Cross42d48b72018-08-29 14:10:52 -0700462 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800463}
464
Nan Zhanga40da042018-08-01 12:48:00 -0700465func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
466 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900467
Colin Cross3047fa22019-04-18 10:56:44 -0700468 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900469
470 return flags
471}
472
473func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700474 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900475
476 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
477 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
478
479 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700480 var deps android.Paths
481
Jiyong Park1e440682018-05-23 18:42:04 +0900482 if aidlPreprocess.Valid() {
483 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700484 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900485 } else {
486 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
487 }
488
489 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
490 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
491 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
492 flags = append(flags, "-I"+src.String())
493 }
494
Colin Cross3047fa22019-04-18 10:56:44 -0700495 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900496}
497
Jiyong Parkd90d7412019-08-20 22:49:19 +0900498// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900499func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700500 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900501
502 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700503 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900504
Jiyong Park1112c4c2019-08-16 21:12:10 +0900505 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
506
Jiyong Park1e440682018-05-23 18:42:04 +0900507 for _, srcFile := range srcFiles {
508 switch srcFile.Ext() {
509 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700510 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900511 case ".logtags":
512 javaFile := genLogtags(ctx, srcFile)
513 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900514 default:
515 outSrcFiles = append(outSrcFiles, srcFile)
516 }
517 }
518
Colin Crossc0806172019-06-14 18:51:47 -0700519 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
520 if len(aidlSrcs) > 0 {
521 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
522 outSrcFiles = append(outSrcFiles, srcJarFiles...)
523 }
524
Jiyong Park1e440682018-05-23 18:42:04 +0900525 return outSrcFiles
526}
527
Nan Zhang581fd212018-01-10 16:06:12 -0800528func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
529 var deps deps
530
Colin Cross83bb3162018-06-25 15:48:06 -0700531 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800532 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700533 ctx.AddMissingDependencies(sdkDep.bootclasspath)
534 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800535 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700536 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800537 }
538
539 ctx.VisitDirectDeps(func(module android.Module) {
540 otherName := ctx.OtherModuleName(module)
541 tag := ctx.OtherModuleDependencyTag(module)
542
Colin Cross2d24c1b2018-05-23 10:59:18 -0700543 switch tag {
544 case bootClasspathTag:
545 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800546 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffine25c6442019-10-11 13:50:28 +0100547 } else if sm, ok := module.(*SystemModules); ok {
548 // A system modules dependency has been added to the bootclasspath
549 // so add its libs to the bootclasspath.
550 deps.bootClasspath = append(deps.bootClasspath, sm.headerJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700551 } else {
552 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
553 }
554 case libTag:
555 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800556 case SdkLibraryDependency:
557 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700558 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900559 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900560 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700561 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800562 checkProducesJars(ctx, dep)
563 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800564 default:
565 ctx.ModuleErrorf("depends on non-java module %q", otherName)
566 }
Colin Cross6cef4812019-10-17 14:23:50 -0700567 case java9LibTag:
568 switch dep := module.(type) {
569 case Dependency:
570 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
571 default:
572 ctx.ModuleErrorf("depends on non-java module %q", otherName)
573 }
Nan Zhang357466b2018-04-17 17:38:36 -0700574 case systemModulesTag:
575 if deps.systemModules != nil {
576 panic("Found two system module dependencies")
577 }
578 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000579 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700580 panic("Missing directory for system module dependency")
581 }
Colin Crossb77043e2019-07-16 13:57:13 -0700582 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800583 }
584 })
585 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
586 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800587 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900588
589 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
590 if filterPackages == nil {
591 return srcs
592 }
593 filtered := []android.Path{}
594 for _, src := range srcs {
595 if src.Ext() != ".java" {
596 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
597 // but otherwise metalava emits stub sources having references to the generated AIDL classes
598 // in filtered-out pacages (e.g. com.android.internal.*).
599 // TODO(b/141149570) We need to fix this by introducing default private constructors or
600 // fixing metalava to not emit constructors having references to unknown classes.
601 filtered = append(filtered, src)
602 continue
603 }
604 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
605 for _, pkg := range filterPackages {
606 if strings.HasPrefix(packageName, pkg) {
607 filtered = append(filtered, src)
608 break
609 }
610 }
611 }
612 return filtered
613 }
614 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
615
Nan Zhanga40da042018-08-01 12:48:00 -0700616 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900617 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800618
619 // srcs may depend on some genrule output.
620 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800621 j.srcJars = append(j.srcJars, deps.srcJars...)
622
Nan Zhang581fd212018-01-10 16:06:12 -0800623 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800624 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800625
Nan Zhang9c69a122018-08-22 10:22:08 -0700626 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800627 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
628 }
629 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800630
Colin Cross8a497952019-03-05 22:25:09 -0800631 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000632 argFilesMap := map[string]string{}
633 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700634
Paul Duffin99e4a502019-02-11 15:38:42 +0000635 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800636 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000637 if _, exists := argFilesMap[label]; !exists {
638 argFilesMap[label] = strings.Join(paths.Strings(), " ")
639 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700640 } else {
641 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000642 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700643 }
644 }
645
646 var err error
Colin Cross15638152019-07-11 11:11:35 -0700647 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700648 if strings.HasPrefix(name, "location ") {
649 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000650 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700651 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700652 } else {
Colin Cross15638152019-07-11 11:11:35 -0700653 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000654 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700655 }
656 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700657 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700658 }
Colin Cross15638152019-07-11 11:11:35 -0700659 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700660 })
661
662 if err != nil {
663 ctx.PropertyErrorf("args", "%s", err.Error())
664 }
665
Nan Zhang581fd212018-01-10 16:06:12 -0800666 return deps
667}
668
669func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
670 j.addDeps(ctx)
671}
672
673func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
674 deps := j.collectDeps(ctx)
675
Colin Crossdaa4c672019-07-15 22:53:46 -0700676 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800677
Colin Crossdaa4c672019-07-15 22:53:46 -0700678 outDir := android.PathForModuleOut(ctx, "out")
679 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
680
681 j.stubsSrcJar = nil
682
683 rule := android.NewRuleBuilder()
684
685 rule.Command().Text("rm -rf").Text(outDir.String())
686 rule.Command().Text("mkdir -p").Text(outDir.String())
687
688 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700689
Colin Cross83bb3162018-06-25 15:48:06 -0700690 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800691
Colin Crossdaa4c672019-07-15 22:53:46 -0700692 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
693 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800694
Colin Cross1e743852019-10-28 11:37:20 -0700695 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700696 Flag("-J-Xmx1024m").
697 Flag("-XDignore.symbol.file").
698 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800699
Colin Crossdaa4c672019-07-15 22:53:46 -0700700 rule.Command().
701 BuiltTool(ctx, "soong_zip").
702 Flag("-write_if_changed").
703 Flag("-d").
704 FlagWithOutput("-o ", j.docZip).
705 FlagWithArg("-C ", outDir.String()).
706 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700707
Colin Crossdaa4c672019-07-15 22:53:46 -0700708 rule.Restat()
709
710 zipSyncCleanupCmd(rule, srcJarDir)
711
712 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800713}
714
Nan Zhanga40da042018-08-01 12:48:00 -0700715//
716// Droiddoc
717//
718type Droiddoc struct {
719 Javadoc
720
721 properties DroiddocProperties
722 apiFile android.WritablePath
723 dexApiFile android.WritablePath
724 privateApiFile android.WritablePath
725 privateDexApiFile android.WritablePath
726 removedApiFile android.WritablePath
727 removedDexApiFile android.WritablePath
728 exactApiFile android.WritablePath
729 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700730 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700731
732 checkCurrentApiTimestamp android.WritablePath
733 updateCurrentApiTimestamp android.WritablePath
734 checkLastReleasedApiTimestamp android.WritablePath
735
Nan Zhanga40da042018-08-01 12:48:00 -0700736 apiFilePath android.Path
737}
738
Colin Crossa3002fc2019-07-08 16:48:04 -0700739// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700740func DroiddocFactory() android.Module {
741 module := &Droiddoc{}
742
743 module.AddProperties(&module.properties,
744 &module.Javadoc.properties)
745
746 InitDroiddocModule(module, android.HostAndDeviceSupported)
747 return module
748}
749
Colin Crossa3002fc2019-07-08 16:48:04 -0700750// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700751func DroiddocHostFactory() android.Module {
752 module := &Droiddoc{}
753
754 module.AddProperties(&module.properties,
755 &module.Javadoc.properties)
756
757 InitDroiddocModule(module, android.HostSupported)
758 return module
759}
760
761func (d *Droiddoc) ApiFilePath() android.Path {
762 return d.apiFilePath
763}
764
Nan Zhang581fd212018-01-10 16:06:12 -0800765func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
766 d.Javadoc.addDeps(ctx)
767
Inseob Kim38449af2019-02-28 14:24:05 +0900768 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
769 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
770 }
771
Nan Zhang79614d12018-04-19 18:03:39 -0700772 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800773 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
774 }
Nan Zhang581fd212018-01-10 16:06:12 -0800775}
776
Colin Crossab054432019-07-15 16:13:59 -0700777func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700778 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
779 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
780 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700781 cmd.FlagWithArg("-source ", "1.8").
782 Flag("-J-Xmx1600m").
783 Flag("-J-XX:-OmitStackTraceInFastThrow").
784 Flag("-XDignore.symbol.file").
785 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
786 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
787 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700788 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 -0700789
Nan Zhanga40da042018-08-01 12:48:00 -0700790 if String(d.properties.Custom_template) == "" {
791 // TODO: This is almost always droiddoc-templates-sdk
792 ctx.PropertyErrorf("custom_template", "must specify a template")
793 }
794
795 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700796 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700797 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700798 } else {
Paul Duffin884363e2019-12-19 10:21:09 +0000799 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
Nan Zhanga40da042018-08-01 12:48:00 -0700800 }
801 })
802
803 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700804 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
805 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
806 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700807 }
808
809 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700810 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
811 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
812 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700813 }
814
815 if len(d.properties.Html_dirs) > 2 {
816 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
817 }
818
Colin Cross8a497952019-03-05 22:25:09 -0800819 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700820 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700821
Colin Crossab054432019-07-15 16:13:59 -0700822 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700823
824 if String(d.properties.Proofread_file) != "" {
825 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700826 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700827 }
828
829 if String(d.properties.Todo_file) != "" {
830 // tricky part:
831 // we should not compute full path for todo_file through PathForModuleOut().
832 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700833 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
834 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700835 }
836
837 if String(d.properties.Resourcesdir) != "" {
838 // TODO: should we add files under resourcesDir to the implicits? It seems that
839 // resourcesDir is one sub dir of htmlDir
840 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700841 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700842 }
843
844 if String(d.properties.Resourcesoutdir) != "" {
845 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700846 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700847 }
Nan Zhanga40da042018-08-01 12:48:00 -0700848}
849
Colin Crossab054432019-07-15 16:13:59 -0700850func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200851 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
852 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700853 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700854
Nan Zhanga40da042018-08-01 12:48:00 -0700855 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700856 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700857 d.apiFilePath = d.apiFile
858 }
859
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200860 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
861 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700862 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700863 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700864 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700865 }
866
867 if String(d.properties.Private_api_filename) != "" {
868 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700869 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700870 }
871
872 if String(d.properties.Dex_api_filename) != "" {
873 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700874 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700875 }
876
877 if String(d.properties.Private_dex_api_filename) != "" {
878 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700879 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700880 }
881
882 if String(d.properties.Removed_dex_api_filename) != "" {
883 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700884 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700885 }
886
887 if String(d.properties.Exact_api_filename) != "" {
888 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700889 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700890 }
891
892 if String(d.properties.Dex_mapping_filename) != "" {
893 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700894 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700895 }
896
Nan Zhang66dc2362018-08-14 20:41:04 -0700897 if String(d.properties.Proguard_filename) != "" {
898 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700899 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700900 }
901
Nan Zhanga40da042018-08-01 12:48:00 -0700902 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700903 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700904 }
905
906 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700907 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700908 }
Nan Zhanga40da042018-08-01 12:48:00 -0700909}
910
Colin Crossab054432019-07-15 16:13:59 -0700911func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700912 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700913 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
914 rule.Command().Text("cp").
915 Input(staticDocIndexRedirect).
916 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700917 }
918
919 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700920 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
921 rule.Command().Text("cp").
922 Input(staticDocProperties).
923 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700924 }
Nan Zhanga40da042018-08-01 12:48:00 -0700925}
926
Colin Crossab054432019-07-15 16:13:59 -0700927func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700928 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700929
930 cmd := rule.Command().
931 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
932 Flag(config.JavacVmFlags).
933 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700934 FlagWithRspFileInputList("@", srcs).
935 FlagWithInput("@", srcJarList)
936
Colin Crossab054432019-07-15 16:13:59 -0700937 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
938 // based stubs generation.
939 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
940 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
941 // the correct package name base path.
942 if len(sourcepaths) > 0 {
943 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
944 } else {
945 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
946 }
947
948 cmd.FlagWithArg("-d ", outDir.String()).
949 Flag("-quiet")
950
951 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700952}
953
Colin Crossdaa4c672019-07-15 22:53:46 -0700954func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
955 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
956 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
957
958 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
959
960 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
961 cmd.Flag(flag).Implicits(deps)
962
963 cmd.FlagWithArg("--patch-module ", "java.base=.")
964
965 if len(classpath) > 0 {
966 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
967 }
968
969 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700970}
971
Colin Crossdaa4c672019-07-15 22:53:46 -0700972func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
973 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
974 sourcepaths android.Paths) *android.RuleBuilderCommand {
975
976 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
977
978 if len(bootclasspath) == 0 && ctx.Device() {
979 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
980 // ensure java does not fall back to the default bootclasspath.
981 cmd.FlagWithArg("-bootclasspath ", `""`)
982 } else if len(bootclasspath) > 0 {
983 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
984 }
985
986 if len(classpath) > 0 {
987 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
988 }
989
990 return cmd
991}
992
Colin Crossab054432019-07-15 16:13:59 -0700993func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
994 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995
Colin Crossab054432019-07-15 16:13:59 -0700996 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
997 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
998
999 return rule.Command().
1000 BuiltTool(ctx, "dokka").
1001 Flag(config.JavacVmFlags).
1002 Flag(srcJarDir.String()).
1003 FlagWithInputList("-classpath ", dokkaClasspath, ":").
1004 FlagWithArg("-format ", "dac").
1005 FlagWithArg("-dacRoot ", "/reference/kotlin").
1006 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001007}
1008
1009func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1010 deps := d.Javadoc.collectDeps(ctx)
1011
Colin Crossdaa4c672019-07-15 22:53:46 -07001012 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
1013 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1014
Nan Zhang1598a9e2018-09-04 17:14:32 -07001015 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1016 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1017 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1018 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1019
Colin Crossab054432019-07-15 16:13:59 -07001020 outDir := android.PathForModuleOut(ctx, "out")
1021 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1022 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001023
Colin Crossab054432019-07-15 16:13:59 -07001024 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -07001025
Colin Crossab054432019-07-15 16:13:59 -07001026 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1027 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001028
Colin Crossab054432019-07-15 16:13:59 -07001029 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1030
1031 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001032 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001033 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001034 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001035 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001036 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001037 }
1038
Colin Crossab054432019-07-15 16:13:59 -07001039 d.stubsFlags(ctx, cmd, stubsDir)
1040
1041 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1042
Mathew Inwoodabd49ab2019-12-19 14:27:08 +00001043 if d.properties.Compat_config != nil {
1044 compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
1045 cmd.FlagWithInput("-compatconfig ", compatConfig)
1046 }
1047
Colin Crossab054432019-07-15 16:13:59 -07001048 var desc string
1049 if Bool(d.properties.Dokka_enabled) {
1050 desc = "dokka"
1051 } else {
1052 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1053
1054 for _, o := range d.Javadoc.properties.Out {
1055 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1056 }
1057
1058 d.postDoclavaCmds(ctx, rule)
1059 desc = "doclava"
1060 }
1061
1062 rule.Command().
1063 BuiltTool(ctx, "soong_zip").
1064 Flag("-write_if_changed").
1065 Flag("-d").
1066 FlagWithOutput("-o ", d.docZip).
1067 FlagWithArg("-C ", outDir.String()).
1068 FlagWithArg("-D ", outDir.String())
1069
1070 rule.Command().
1071 BuiltTool(ctx, "soong_zip").
1072 Flag("-write_if_changed").
1073 Flag("-jar").
1074 FlagWithOutput("-o ", d.stubsSrcJar).
1075 FlagWithArg("-C ", stubsDir.String()).
1076 FlagWithArg("-D ", stubsDir.String())
1077
1078 rule.Restat()
1079
1080 zipSyncCleanupCmd(rule, srcJarDir)
1081
1082 rule.Build(pctx, ctx, "javadoc", desc)
1083
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001084 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001085 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001086
1087 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1088 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001089
1090 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001091
1092 rule := android.NewRuleBuilder()
1093
1094 rule.Command().Text("( true")
1095
1096 rule.Command().
1097 BuiltTool(ctx, "apicheck").
1098 Flag("-JXmx1024m").
1099 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1100 OptionalFlag(d.properties.Check_api.Current.Args).
1101 Input(apiFile).
1102 Input(d.apiFile).
1103 Input(removedApiFile).
1104 Input(d.removedApiFile)
1105
1106 msg := fmt.Sprintf(`\n******************************\n`+
1107 `You have tried to change the API from what has been previously approved.\n\n`+
1108 `To make these errors go away, you have two choices:\n`+
1109 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1110 ` errors above.\n\n`+
1111 ` 2. You can update current.txt by executing the following command:\n`+
1112 ` make %s-update-current-api\n\n`+
1113 ` To submit the revised current.txt to the main Android repository,\n`+
1114 ` you will need approval.\n`+
1115 `******************************\n`, ctx.ModuleName())
1116
1117 rule.Command().
1118 Text("touch").Output(d.checkCurrentApiTimestamp).
1119 Text(") || (").
1120 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1121 Text("; exit 38").
1122 Text(")")
1123
1124 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001125
1126 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001127
1128 // update API rule
1129 rule = android.NewRuleBuilder()
1130
1131 rule.Command().Text("( true")
1132
1133 rule.Command().
1134 Text("cp").Flag("-f").
1135 Input(d.apiFile).Flag(apiFile.String())
1136
1137 rule.Command().
1138 Text("cp").Flag("-f").
1139 Input(d.removedApiFile).Flag(removedApiFile.String())
1140
1141 msg = "failed to update public API"
1142
1143 rule.Command().
1144 Text("touch").Output(d.updateCurrentApiTimestamp).
1145 Text(") || (").
1146 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1147 Text("; exit 38").
1148 Text(")")
1149
1150 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001151 }
1152
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001153 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001154 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001155
1156 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1157 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001158
1159 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001160
1161 rule := android.NewRuleBuilder()
1162
1163 rule.Command().
1164 Text("(").
1165 BuiltTool(ctx, "apicheck").
1166 Flag("-JXmx1024m").
1167 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1168 OptionalFlag(d.properties.Check_api.Last_released.Args).
1169 Input(apiFile).
1170 Input(d.apiFile).
1171 Input(removedApiFile).
1172 Input(d.removedApiFile)
1173
1174 msg := `\n******************************\n` +
1175 `You have tried to change the API from what has been previously released in\n` +
1176 `an SDK. Please fix the errors listed above.\n` +
1177 `******************************\n`
1178
1179 rule.Command().
1180 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1181 Text(") || (").
1182 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1183 Text("; exit 38").
1184 Text(")")
1185
1186 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001187 }
1188}
1189
1190//
1191// Droidstubs
1192//
1193type Droidstubs struct {
1194 Javadoc
Paul Duffin91547182019-11-12 19:39:36 +00001195 android.SdkBase
Nan Zhang1598a9e2018-09-04 17:14:32 -07001196
Pete Gillin581d6082018-10-22 15:55:04 +01001197 properties DroidstubsProperties
1198 apiFile android.WritablePath
1199 apiXmlFile android.WritablePath
1200 lastReleasedApiXmlFile android.WritablePath
1201 dexApiFile android.WritablePath
1202 privateApiFile android.WritablePath
1203 privateDexApiFile android.WritablePath
1204 removedApiFile android.WritablePath
1205 removedDexApiFile android.WritablePath
1206 apiMappingFile android.WritablePath
1207 exactApiFile android.WritablePath
1208 proguardFile android.WritablePath
1209 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001210
1211 checkCurrentApiTimestamp android.WritablePath
1212 updateCurrentApiTimestamp android.WritablePath
1213 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001214 apiLintTimestamp android.WritablePath
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001215 apiLintReport android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001216
Pete Gillin581d6082018-10-22 15:55:04 +01001217 checkNullabilityWarningsTimestamp android.WritablePath
1218
Nan Zhang1598a9e2018-09-04 17:14:32 -07001219 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001220 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001221
1222 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001223
1224 jdiffDocZip android.WritablePath
1225 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001226
1227 metadataZip android.WritablePath
1228 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001229}
1230
Colin Crossa3002fc2019-07-08 16:48:04 -07001231// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1232// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1233// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001234func DroidstubsFactory() android.Module {
1235 module := &Droidstubs{}
1236
1237 module.AddProperties(&module.properties,
1238 &module.Javadoc.properties)
1239
1240 InitDroiddocModule(module, android.HostAndDeviceSupported)
Paul Duffin91547182019-11-12 19:39:36 +00001241 android.InitSdkAwareModule(module)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001242 return module
1243}
1244
Colin Crossa3002fc2019-07-08 16:48:04 -07001245// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1246// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1247// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1248// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001249func DroidstubsHostFactory() android.Module {
1250 module := &Droidstubs{}
1251
1252 module.AddProperties(&module.properties,
1253 &module.Javadoc.properties)
1254
1255 InitDroiddocModule(module, android.HostSupported)
1256 return module
1257}
1258
1259func (d *Droidstubs) ApiFilePath() android.Path {
1260 return d.apiFilePath
1261}
1262
1263func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1264 d.Javadoc.addDeps(ctx)
1265
Inseob Kim38449af2019-02-28 14:24:05 +09001266 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1267 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1268 }
1269
Nan Zhang1598a9e2018-09-04 17:14:32 -07001270 if len(d.properties.Merge_annotations_dirs) != 0 {
1271 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1272 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1273 }
1274 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001275
Pete Gillin77167902018-09-19 18:16:26 +01001276 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1277 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1278 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1279 }
1280 }
1281
Nan Zhang9c69a122018-08-22 10:22:08 -07001282 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1283 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1284 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1285 }
1286 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287}
1288
Colin Cross33961b52019-07-11 11:01:22 -07001289func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001290 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1291 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 String(d.properties.Api_filename) != "" {
1293 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001294 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 d.apiFilePath = d.apiFile
1296 }
1297
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001298 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1299 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001300 String(d.properties.Removed_api_filename) != "" {
1301 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001302 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001303 }
1304
1305 if String(d.properties.Private_api_filename) != "" {
1306 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001307 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001308 }
1309
1310 if String(d.properties.Dex_api_filename) != "" {
1311 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001312 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001313 }
1314
1315 if String(d.properties.Private_dex_api_filename) != "" {
1316 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001317 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001318 }
1319
1320 if String(d.properties.Removed_dex_api_filename) != "" {
1321 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001322 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001323 }
1324
1325 if String(d.properties.Exact_api_filename) != "" {
1326 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001328 }
1329
Nan Zhang9c69a122018-08-22 10:22:08 -07001330 if String(d.properties.Dex_mapping_filename) != "" {
1331 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001332 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001333 }
1334
Nan Zhang199645c2018-09-19 12:40:06 -07001335 if String(d.properties.Proguard_filename) != "" {
1336 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001337 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001338 }
1339
Nan Zhang9c69a122018-08-22 10:22:08 -07001340 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001341 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1342 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001343 }
1344
Nan Zhang1598a9e2018-09-04 17:14:32 -07001345 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001346 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001347 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001348 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001349 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001350}
1351
Colin Cross33961b52019-07-11 11:01:22 -07001352func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001353 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001354 cmd.Flag("--include-annotations")
1355
Pete Gillinc382a562018-11-14 18:45:46 +00001356 validatingNullability :=
1357 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1358 String(d.properties.Validate_nullability_from_list) != ""
Paul Duffin13a9dd62019-11-04 10:26:47 +00001359
Pete Gillina262c052018-09-14 14:25:48 +01001360 migratingNullability := String(d.properties.Previous_api) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001361 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001362 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001363 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001364 }
Colin Cross33961b52019-07-11 11:01:22 -07001365
Pete Gillinc382a562018-11-14 18:45:46 +00001366 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001367 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001368 }
Colin Cross33961b52019-07-11 11:01:22 -07001369
Pete Gillina262c052018-09-14 14:25:48 +01001370 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001371 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001372 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001373 }
Nan Zhanga40da042018-08-01 12:48:00 -07001374
1375 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001376 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001377
Nan Zhang1598a9e2018-09-04 17:14:32 -07001378 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001379 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001380 "has to be non-empty if annotations was enabled!")
1381 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001382
Colin Cross33961b52019-07-11 11:01:22 -07001383 d.mergeAnnoDirFlags(ctx, cmd)
1384
1385 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1386 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1387 FlagWithArg("--hide ", "SuperfluousPrefix").
1388 FlagWithArg("--hide ", "AnnotationExtraction")
1389 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001390}
1391
Colin Cross33961b52019-07-11 11:01:22 -07001392func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1393 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1394 if t, ok := m.(*ExportedDroiddocDir); ok {
1395 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1396 } else {
1397 ctx.PropertyErrorf("merge_annotations_dirs",
1398 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1399 }
1400 })
1401}
1402
1403func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001404 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1405 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001406 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001407 } else {
1408 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1409 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1410 }
1411 })
Nan Zhanga40da042018-08-01 12:48:00 -07001412}
1413
Colin Cross33961b52019-07-11 11:01:22 -07001414func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001415 if Bool(d.properties.Api_levels_annotations_enabled) {
1416 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001417
1418 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1419 ctx.PropertyErrorf("api_levels_annotations_dirs",
1420 "has to be non-empty if api levels annotations was enabled!")
1421 }
1422
Colin Cross33961b52019-07-11 11:01:22 -07001423 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1424 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1425 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1426 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001427
1428 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1429 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001430 for _, dep := range t.deps {
1431 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001432 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001433 }
1434 }
Colin Cross33961b52019-07-11 11:01:22 -07001435 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001436 } else {
1437 ctx.PropertyErrorf("api_levels_annotations_dirs",
1438 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1439 }
1440 })
1441
1442 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001443}
1444
Colin Cross33961b52019-07-11 11:01:22 -07001445func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001446 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1447 if d.apiFile.String() == "" {
1448 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1449 }
1450
1451 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001452 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001453
1454 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1455 ctx.PropertyErrorf("check_api.last_released.api_file",
1456 "has to be non-empty if jdiff was enabled!")
1457 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001458
Colin Cross33961b52019-07-11 11:01:22 -07001459 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001460 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001461 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1462 }
1463}
Nan Zhang71bbe632018-09-17 14:32:21 -07001464
Colin Cross1e743852019-10-28 11:37:20 -07001465func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Colin Cross33961b52019-07-11 11:01:22 -07001466 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Cross8b8bec32019-11-15 13:18:43 -08001467 // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
1468 rule.HighMem()
Colin Cross33961b52019-07-11 11:01:22 -07001469 cmd := rule.Command().BuiltTool(ctx, "metalava").
1470 Flag(config.JavacVmFlags).
1471 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001472 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001473 FlagWithRspFileInputList("@", srcs).
1474 FlagWithInput("@", srcJarList)
1475
1476 if len(bootclasspath) > 0 {
1477 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001478 }
1479
Colin Cross33961b52019-07-11 11:01:22 -07001480 if len(classpath) > 0 {
1481 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1482 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001483
Colin Cross33961b52019-07-11 11:01:22 -07001484 if len(sourcepaths) > 0 {
1485 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1486 } else {
1487 cmd.FlagWithArg("-sourcepath ", `""`)
1488 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001489
Colin Cross33961b52019-07-11 11:01:22 -07001490 cmd.Flag("--no-banner").
1491 Flag("--color").
1492 Flag("--quiet").
1493 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001494
Colin Cross33961b52019-07-11 11:01:22 -07001495 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001496}
1497
Nan Zhang1598a9e2018-09-04 17:14:32 -07001498func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001499 deps := d.Javadoc.collectDeps(ctx)
1500
1501 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001502
Colin Cross33961b52019-07-11 11:01:22 -07001503 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001504
Colin Crossdaa4c672019-07-15 22:53:46 -07001505 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001506
Colin Cross33961b52019-07-11 11:01:22 -07001507 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1508 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001509
Colin Cross33961b52019-07-11 11:01:22 -07001510 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001511
Colin Cross33961b52019-07-11 11:01:22 -07001512 rule.Command().Text("rm -rf").Text(stubsDir.String())
1513 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001514
Colin Cross33961b52019-07-11 11:01:22 -07001515 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1516
1517 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1518 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1519
1520 d.stubsFlags(ctx, cmd, stubsDir)
1521
1522 d.annotationsFlags(ctx, cmd)
1523 d.inclusionAnnotationsFlags(ctx, cmd)
1524 d.apiLevelsAnnotationsFlags(ctx, cmd)
1525 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001526
Nan Zhang1598a9e2018-09-04 17:14:32 -07001527 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1528 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1529 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1530 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1531 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001532 }
Colin Cross33961b52019-07-11 11:01:22 -07001533
1534 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1535 for _, o := range d.Javadoc.properties.Out {
1536 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1537 }
1538
1539 rule.Command().
1540 BuiltTool(ctx, "soong_zip").
1541 Flag("-write_if_changed").
1542 Flag("-jar").
1543 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1544 FlagWithArg("-C ", stubsDir.String()).
1545 FlagWithArg("-D ", stubsDir.String())
Jerome Gaillard0f599032019-10-10 19:29:11 +01001546
1547 if Bool(d.properties.Write_sdk_values) {
1548 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1549 rule.Command().
1550 BuiltTool(ctx, "soong_zip").
1551 Flag("-write_if_changed").
1552 Flag("-d").
1553 FlagWithOutput("-o ", d.metadataZip).
1554 FlagWithArg("-C ", d.metadataDir.String()).
1555 FlagWithArg("-D ", d.metadataDir.String())
1556 }
1557
Colin Cross33961b52019-07-11 11:01:22 -07001558 rule.Restat()
1559
1560 zipSyncCleanupCmd(rule, srcJarDir)
1561
1562 rule.Build(pctx, ctx, "metalava", "metalava")
1563
1564 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001565
Adrian Roos075eedc2019-10-10 12:07:03 +02001566 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1567 rule := android.NewRuleBuilder()
1568 rule.Command().Text("( true")
1569
1570 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1571 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1572
1573 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1574 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1575
Adrian Rooscab4a2c2019-10-14 16:32:41 +02001576 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1577
Adrian Roos075eedc2019-10-10 12:07:03 +02001578 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1579 if newSince.Valid() {
1580 cmd.FlagWithInput("--api-lint ", newSince.Path())
1581 } else {
1582 cmd.Flag("--api-lint")
1583 }
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001584 d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
1585 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)
Adrian Roos075eedc2019-10-10 12:07:03 +02001586
1587 d.inclusionAnnotationsFlags(ctx, cmd)
1588 d.mergeAnnoDirFlags(ctx, cmd)
1589
1590 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1591 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1592 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1593
1594 if baselineFile.Valid() {
1595 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1596 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1597 }
1598
1599 zipSyncCleanupCmd(rule, srcJarDir)
1600
1601 msg := fmt.Sprintf(`\n******************************\n`+
1602 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1603 `To make these errors go away, you have two choices:\n`+
1604 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1605 ` 2. You can update the baseline by executing the following command:\n`+
1606 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1607 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1608 rule.Command().
1609 Text("touch").Output(d.apiLintTimestamp).
1610 Text(") || (").
1611 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1612 Text("; exit 38").
1613 Text(")")
1614
1615 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1616
1617 }
1618
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001619 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001620 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001621
1622 if len(d.Javadoc.properties.Out) > 0 {
1623 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1624 }
1625
1626 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1627 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001628 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1629 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001630
Nan Zhang2760dfc2018-08-24 17:32:54 +00001631 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001632
Colin Cross33961b52019-07-11 11:01:22 -07001633 rule := android.NewRuleBuilder()
1634
1635 rule.Command().Text("( true")
1636
1637 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1638 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1639
1640 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1641 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1642
1643 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1644 FlagWithInput("--check-compatibility:api:current ", apiFile).
1645 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1646
1647 d.inclusionAnnotationsFlags(ctx, cmd)
1648 d.mergeAnnoDirFlags(ctx, cmd)
1649
Adrian Roos14f75a92019-08-12 17:54:09 +02001650 if baselineFile.Valid() {
1651 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1652 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1653 }
1654
Colin Cross33961b52019-07-11 11:01:22 -07001655 zipSyncCleanupCmd(rule, srcJarDir)
1656
1657 msg := fmt.Sprintf(`\n******************************\n`+
1658 `You have tried to change the API from what has been previously approved.\n\n`+
1659 `To make these errors go away, you have two choices:\n`+
1660 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1661 ` errors above.\n\n`+
1662 ` 2. You can update current.txt by executing the following command:\n`+
1663 ` make %s-update-current-api\n\n`+
1664 ` To submit the revised current.txt to the main Android repository,\n`+
1665 ` you will need approval.\n`+
1666 `******************************\n`, ctx.ModuleName())
1667
1668 rule.Command().
1669 Text("touch").Output(d.checkCurrentApiTimestamp).
1670 Text(") || (").
1671 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1672 Text("; exit 38").
1673 Text(")")
1674
1675 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001676
1677 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001678
1679 // update API rule
1680 rule = android.NewRuleBuilder()
1681
1682 rule.Command().Text("( true")
1683
1684 rule.Command().
1685 Text("cp").Flag("-f").
1686 Input(d.apiFile).Flag(apiFile.String())
1687
1688 rule.Command().
1689 Text("cp").Flag("-f").
1690 Input(d.removedApiFile).Flag(removedApiFile.String())
1691
1692 msg = "failed to update public API"
1693
1694 rule.Command().
1695 Text("touch").Output(d.updateCurrentApiTimestamp).
1696 Text(") || (").
1697 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1698 Text("; exit 38").
1699 Text(")")
1700
1701 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001702 }
Nan Zhanga40da042018-08-01 12:48:00 -07001703
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001704 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001705 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001706
1707 if len(d.Javadoc.properties.Out) > 0 {
1708 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1709 }
1710
1711 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1712 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001713 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1714 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001715
Nan Zhang2760dfc2018-08-24 17:32:54 +00001716 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001717
Colin Cross33961b52019-07-11 11:01:22 -07001718 rule := android.NewRuleBuilder()
1719
1720 rule.Command().Text("( true")
1721
1722 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1723 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1724
1725 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1726 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1727
1728 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1729 FlagWithInput("--check-compatibility:api:released ", apiFile)
1730
1731 d.inclusionAnnotationsFlags(ctx, cmd)
1732
1733 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1734
1735 d.mergeAnnoDirFlags(ctx, cmd)
1736
Adrian Roos14f75a92019-08-12 17:54:09 +02001737 if baselineFile.Valid() {
1738 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1739 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1740 }
1741
Colin Cross33961b52019-07-11 11:01:22 -07001742 zipSyncCleanupCmd(rule, srcJarDir)
1743
1744 msg := `\n******************************\n` +
1745 `You have tried to change the API from what has been previously released in\n` +
1746 `an SDK. Please fix the errors listed above.\n` +
1747 `******************************\n`
1748 rule.Command().
1749 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1750 Text(") || (").
1751 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1752 Text("; exit 38").
1753 Text(")")
1754
1755 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001756 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001757
Pete Gillin581d6082018-10-22 15:55:04 +01001758 if String(d.properties.Check_nullability_warnings) != "" {
1759 if d.nullabilityWarningsFile == nil {
1760 ctx.PropertyErrorf("check_nullability_warnings",
1761 "Cannot specify check_nullability_warnings unless validating nullability")
1762 }
Colin Cross33961b52019-07-11 11:01:22 -07001763
1764 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1765
Pete Gillin581d6082018-10-22 15:55:04 +01001766 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001767
Pete Gillin581d6082018-10-22 15:55:04 +01001768 msg := fmt.Sprintf(`\n******************************\n`+
1769 `The warnings encountered during nullability annotation validation did\n`+
1770 `not match the checked in file of expected warnings. The diffs are shown\n`+
1771 `above. You have two options:\n`+
1772 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1773 ` 2. Update the file of expected warnings by running:\n`+
1774 ` cp %s %s\n`+
1775 ` and submitting the updated file as part of your change.`,
1776 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001777
1778 rule := android.NewRuleBuilder()
1779
1780 rule.Command().
1781 Text("(").
1782 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1783 Text("&&").
1784 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1785 Text(") || (").
1786 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1787 Text("; exit 38").
1788 Text(")")
1789
1790 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001791 }
1792
Nan Zhang71bbe632018-09-17 14:32:21 -07001793 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001794 if len(d.Javadoc.properties.Out) > 0 {
1795 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1796 }
1797
1798 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1799 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1800 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1801
1802 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001803
Nan Zhang86b06202018-09-21 17:09:21 -07001804 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1805 // since there's cron job downstream that fetch this .zip file periodically.
1806 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001807 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1808 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1809
Nan Zhang71bbe632018-09-17 14:32:21 -07001810 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001811
Colin Cross33961b52019-07-11 11:01:22 -07001812 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1813 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001814
Colin Cross33961b52019-07-11 11:01:22 -07001815 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1816
Colin Crossdaa4c672019-07-15 22:53:46 -07001817 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001818 deps.bootClasspath, deps.classpath, d.sourcepaths)
1819
1820 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001821 Flag("-XDignore.symbol.file").
1822 FlagWithArg("-doclet ", "jdiff.JDiff").
1823 FlagWithInput("-docletpath ", jdiff).
1824 Flag("-quiet").
1825 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1826 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1827 Implicit(d.apiXmlFile).
1828 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1829 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1830 Implicit(d.lastReleasedApiXmlFile)
1831
Colin Cross33961b52019-07-11 11:01:22 -07001832 rule.Command().
1833 BuiltTool(ctx, "soong_zip").
1834 Flag("-write_if_changed").
1835 Flag("-d").
1836 FlagWithOutput("-o ", d.jdiffDocZip).
1837 FlagWithArg("-C ", outDir.String()).
1838 FlagWithArg("-D ", outDir.String())
1839
1840 rule.Command().
1841 BuiltTool(ctx, "soong_zip").
1842 Flag("-write_if_changed").
1843 Flag("-jar").
1844 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1845 FlagWithArg("-C ", stubsDir.String()).
1846 FlagWithArg("-D ", stubsDir.String())
1847
1848 rule.Restat()
1849
1850 zipSyncCleanupCmd(rule, srcJarDir)
1851
1852 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001853 }
Nan Zhang581fd212018-01-10 16:06:12 -08001854}
Dan Willemsencc090972018-02-26 14:33:31 -08001855
Nan Zhanga40da042018-08-01 12:48:00 -07001856//
Nan Zhangf4936b02018-08-01 15:00:28 -07001857// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001858//
Dan Willemsencc090972018-02-26 14:33:31 -08001859var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001860var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001861var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001862var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001863
Nan Zhangf4936b02018-08-01 15:00:28 -07001864type ExportedDroiddocDirProperties struct {
1865 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001866 Path *string
1867}
1868
Nan Zhangf4936b02018-08-01 15:00:28 -07001869type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001870 android.ModuleBase
1871
Nan Zhangf4936b02018-08-01 15:00:28 -07001872 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001873
1874 deps android.Paths
1875 dir android.Path
1876}
1877
Colin Crossa3002fc2019-07-08 16:48:04 -07001878// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001879func ExportedDroiddocDirFactory() android.Module {
1880 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001881 module.AddProperties(&module.properties)
1882 android.InitAndroidModule(module)
1883 return module
1884}
1885
Nan Zhangf4936b02018-08-01 15:00:28 -07001886func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001887
Nan Zhangf4936b02018-08-01 15:00:28 -07001888func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001889 path := String(d.properties.Path)
1890 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001891 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001892}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001893
1894//
1895// Defaults
1896//
1897type DocDefaults struct {
1898 android.ModuleBase
1899 android.DefaultsModuleBase
1900}
1901
Nan Zhangb2b33de2018-02-23 11:18:47 -08001902func DocDefaultsFactory() android.Module {
1903 module := &DocDefaults{}
1904
1905 module.AddProperties(
1906 &JavadocProperties{},
1907 &DroiddocProperties{},
1908 )
1909
1910 android.InitDefaultsModule(module)
1911
1912 return module
1913}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001914
1915func StubsDefaultsFactory() android.Module {
1916 module := &DocDefaults{}
1917
1918 module.AddProperties(
1919 &JavadocProperties{},
1920 &DroidstubsProperties{},
1921 )
1922
1923 android.InitDefaultsModule(module)
1924
1925 return module
1926}
Colin Cross33961b52019-07-11 11:01:22 -07001927
1928func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1929 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1930
1931 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1932 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1933 srcJarList := srcJarDir.Join(ctx, "list")
1934
1935 rule.Temporary(srcJarList)
1936
1937 rule.Command().BuiltTool(ctx, "zipsync").
1938 FlagWithArg("-d ", srcJarDir.String()).
1939 FlagWithOutput("-l ", srcJarList).
1940 FlagWithArg("-f ", `"*.java"`).
1941 Inputs(srcJars)
1942
1943 return srcJarList
1944}
1945
1946func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1947 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1948}
Paul Duffin91547182019-11-12 19:39:36 +00001949
1950var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1951
1952type PrebuiltStubsSourcesProperties struct {
1953 Srcs []string `android:"path"`
1954}
1955
1956type PrebuiltStubsSources struct {
1957 android.ModuleBase
1958 android.DefaultableModuleBase
1959 prebuilt android.Prebuilt
1960 android.SdkBase
1961
1962 properties PrebuiltStubsSourcesProperties
1963
Paul Duffin9b478b02019-12-10 13:41:51 +00001964 // The source directories containing stubs source files.
1965 srcDirs android.Paths
Paul Duffin91547182019-11-12 19:39:36 +00001966 stubsSrcJar android.ModuleOutPath
1967}
1968
Paul Duffin9b478b02019-12-10 13:41:51 +00001969func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1970 switch tag {
1971 case "":
1972 return android.Paths{p.stubsSrcJar}, nil
1973 default:
1974 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1975 }
1976}
1977
Paul Duffin91547182019-11-12 19:39:36 +00001978func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffin9b478b02019-12-10 13:41:51 +00001979 p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1980
1981 p.srcDirs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
1982
1983 rule := android.NewRuleBuilder()
1984 command := rule.Command().
1985 BuiltTool(ctx, "soong_zip").
1986 Flag("-write_if_changed").
1987 Flag("-jar").
1988 FlagWithOutput("-o ", p.stubsSrcJar)
1989
1990 for _, d := range p.srcDirs {
1991 dir := d.String()
1992 command.
1993 FlagWithArg("-C ", dir).
1994 FlagWithInput("-D ", d)
1995 }
1996
1997 rule.Restat()
1998
1999 rule.Build(pctx, ctx, "zip src", "Create srcjar from prebuilt source")
Paul Duffin91547182019-11-12 19:39:36 +00002000}
2001
2002func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
2003 return &p.prebuilt
2004}
2005
2006func (p *PrebuiltStubsSources) Name() string {
2007 return p.prebuilt.Name(p.ModuleBase.Name())
2008}
2009
Paul Duffin91547182019-11-12 19:39:36 +00002010// prebuilt_stubs_sources imports a set of java source files as if they were
2011// generated by droidstubs.
2012//
2013// By default, a prebuilt_stubs_sources has a single variant that expects a
2014// set of `.java` files generated by droidstubs.
2015//
2016// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
2017// for host modules.
2018//
2019// Intended only for use by sdk snapshots.
2020func PrebuiltStubsSourcesFactory() android.Module {
2021 module := &PrebuiltStubsSources{}
2022
2023 module.AddProperties(&module.properties)
2024
2025 android.InitPrebuiltModule(module, &module.properties.Srcs)
2026 android.InitSdkAwareModule(module)
2027 InitDroiddocModule(module, android.HostAndDeviceSupported)
2028 return module
2029}
2030
Paul Duffin13879572019-11-28 14:31:38 +00002031type droidStubsSdkMemberType struct {
Paul Duffin255f18e2019-12-13 11:22:16 +00002032 android.SdkMemberTypeBase
Paul Duffin13879572019-11-28 14:31:38 +00002033}
2034
2035func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
2036 mctx.AddVariationDependencies(nil, dependencyTag, names...)
2037}
2038
2039func (mt *droidStubsSdkMemberType) IsInstance(module android.Module) bool {
2040 _, ok := module.(*Droidstubs)
2041 return ok
2042}
2043
2044func (mt *droidStubsSdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
2045 variants := member.Variants()
2046 if len(variants) != 1 {
2047 sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name())
2048 }
2049 variant := variants[0]
2050 d, _ := variant.(*Droidstubs)
Paul Duffin91547182019-11-12 19:39:36 +00002051 stubsSrcJar := d.stubsSrcJar
2052
2053 snapshotRelativeDir := filepath.Join("java", d.Name()+"_stubs_sources")
2054 builder.UnzipToSnapshot(stubsSrcJar, snapshotRelativeDir)
2055
Paul Duffin9d8d6092019-12-05 18:19:29 +00002056 pbm := builder.AddPrebuiltModule(member, "prebuilt_stubs_sources")
Paul Duffinb645ec82019-11-27 17:43:54 +00002057 pbm.AddProperty("srcs", []string{snapshotRelativeDir})
Paul Duffin91547182019-11-12 19:39:36 +00002058}