blob: 8e7797aa4fe3a1d93fb48bed0659083dddaf902b [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
Paul Duffin3ae29512020-04-08 18:18:03 +0100304 // if set to false then do not write out stubs. Defaults to true.
305 //
306 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
307 Generate_stubs *bool
308
Nan Zhang9c69a122018-08-22 10:22:08 -0700309 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
310 Api_levels_annotations_enabled *bool
311
312 // the dirs which Metalava extracts API levels annotations from.
313 Api_levels_annotations_dirs []string
314
315 // if set to true, collect the values used by the Dev tools and
316 // write them in files packaged with the SDK. Defaults to false.
317 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700318
319 // If set to true, .xml based public API file will be also generated, and
320 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
321 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800322}
323
Nan Zhanga40da042018-08-01 12:48:00 -0700324//
325// Common flags passed down to build rule
326//
327type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700328 bootClasspathArgs string
329 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700330 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700331 dokkaClasspathArgs string
332 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700333 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700334
Nan Zhanga40da042018-08-01 12:48:00 -0700335 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700336 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700337 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700338}
339
340func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
341 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
342 android.InitDefaultableModule(module)
343}
344
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200345func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
346 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
347 return false
348 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700349 return true
350 } else if String(apiToCheck.Api_file) != "" {
351 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
352 } else if String(apiToCheck.Removed_api_file) != "" {
353 panic("for " + apiVersionTag + " api_file has to be non-empty!")
354 }
355
356 return false
357}
358
Inseob Kim38449af2019-02-28 14:24:05 +0900359func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
360 api_file := String(apiToCheck.Api_file)
361 removed_api_file := String(apiToCheck.Removed_api_file)
362
363 api_module := android.SrcIsModule(api_file)
364 removed_api_module := android.SrcIsModule(removed_api_file)
365
366 if api_module == "" || removed_api_module == "" {
367 return
368 }
369
370 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
371 return
372 }
373
374 apiToCheck.Api_file = nil
375 apiToCheck.Removed_api_file = nil
376}
377
Paul Duffin3d1248c2020-04-09 00:10:17 +0100378// Used by xsd_config
Nan Zhang1598a9e2018-09-04 17:14:32 -0700379type ApiFilePath interface {
380 ApiFilePath() android.Path
381}
382
Paul Duffin3d1248c2020-04-09 00:10:17 +0100383// Provider of information about API stubs, used by java_sdk_library.
384type ApiStubsProvider interface {
385 ApiFilePath
Paul Duffin1fd005d2020-04-09 01:08:11 +0100386 RemovedApiFilePath() android.Path
Paul Duffin3d1248c2020-04-09 00:10:17 +0100387 StubsSrcJar() android.Path
388}
389
Nan Zhanga40da042018-08-01 12:48:00 -0700390//
391// Javadoc
392//
Nan Zhang581fd212018-01-10 16:06:12 -0800393type Javadoc struct {
394 android.ModuleBase
395 android.DefaultableModuleBase
396
397 properties JavadocProperties
398
399 srcJars android.Paths
400 srcFiles android.Paths
401 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700402 argFiles android.Paths
403
404 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800405
Nan Zhangccff0f72018-03-08 17:26:16 -0800406 docZip android.WritablePath
407 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800408}
409
Colin Cross41955e82019-05-29 14:40:35 -0700410func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
411 switch tag {
412 case "":
413 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700414 case ".docs.zip":
415 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700416 default:
417 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
418 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800419}
420
Colin Crossa3002fc2019-07-08 16:48:04 -0700421// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800422func JavadocFactory() android.Module {
423 module := &Javadoc{}
424
425 module.AddProperties(&module.properties)
426
427 InitDroiddocModule(module, android.HostAndDeviceSupported)
428 return module
429}
430
Colin Crossa3002fc2019-07-08 16:48:04 -0700431// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800432func JavadocHostFactory() android.Module {
433 module := &Javadoc{}
434
435 module.AddProperties(&module.properties)
436
437 InitDroiddocModule(module, android.HostSupported)
438 return module
439}
440
Colin Cross41955e82019-05-29 14:40:35 -0700441var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800442
Jiyong Park6a927c42020-01-21 02:03:43 +0900443func (j *Javadoc) sdkVersion() sdkSpec {
444 return sdkSpecFrom(String(j.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700445}
446
Paul Duffine25c6442019-10-11 13:50:28 +0100447func (j *Javadoc) systemModules() string {
448 return proptools.String(j.properties.System_modules)
449}
450
Jiyong Park6a927c42020-01-21 02:03:43 +0900451func (j *Javadoc) minSdkVersion() sdkSpec {
Colin Cross83bb3162018-06-25 15:48:06 -0700452 return j.sdkVersion()
453}
454
Jiyong Park6a927c42020-01-21 02:03:43 +0900455func (j *Javadoc) targetSdkVersion() sdkSpec {
Dan Willemsen419290a2018-10-31 15:28:47 -0700456 return j.sdkVersion()
457}
458
Nan Zhang581fd212018-01-10 16:06:12 -0800459func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
460 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100461 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Colin Cross6d8d8c62019-10-28 15:10:03 -0700462 if sdkDep.useDefaultLibs {
463 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
464 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
465 if sdkDep.hasFrameworkLibs() {
466 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700467 }
Colin Cross6d8d8c62019-10-28 15:10:03 -0700468 } else if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700469 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100470 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700471 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800472 }
473 }
474
Colin Cross42d48b72018-08-29 14:10:52 -0700475 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800476}
477
Nan Zhanga40da042018-08-01 12:48:00 -0700478func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
479 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900480
Colin Cross3047fa22019-04-18 10:56:44 -0700481 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900482
483 return flags
484}
485
486func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700487 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900488
489 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
490 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
491
492 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700493 var deps android.Paths
494
Jiyong Park1e440682018-05-23 18:42:04 +0900495 if aidlPreprocess.Valid() {
496 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700497 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900498 } else {
499 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
500 }
501
502 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
503 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
504 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
505 flags = append(flags, "-I"+src.String())
506 }
507
Colin Cross3047fa22019-04-18 10:56:44 -0700508 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900509}
510
Jiyong Parkd90d7412019-08-20 22:49:19 +0900511// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900512func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700513 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900514
515 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700516 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900517
Jiyong Park1112c4c2019-08-16 21:12:10 +0900518 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
519
Jiyong Park1e440682018-05-23 18:42:04 +0900520 for _, srcFile := range srcFiles {
521 switch srcFile.Ext() {
522 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700523 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900524 case ".logtags":
525 javaFile := genLogtags(ctx, srcFile)
526 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900527 default:
528 outSrcFiles = append(outSrcFiles, srcFile)
529 }
530 }
531
Colin Crossc0806172019-06-14 18:51:47 -0700532 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
533 if len(aidlSrcs) > 0 {
534 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
535 outSrcFiles = append(outSrcFiles, srcJarFiles...)
536 }
537
Jiyong Park1e440682018-05-23 18:42:04 +0900538 return outSrcFiles
539}
540
Nan Zhang581fd212018-01-10 16:06:12 -0800541func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
542 var deps deps
543
Colin Cross83bb3162018-06-25 15:48:06 -0700544 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800545 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700546 ctx.AddMissingDependencies(sdkDep.bootclasspath)
547 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800548 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700549 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Anton Hansson26bf49b2020-02-08 20:26:29 +0000550 deps.aidlPreprocess = sdkDep.aidl
551 } else {
552 deps.aidlPreprocess = sdkDep.aidl
Nan Zhang581fd212018-01-10 16:06:12 -0800553 }
554
555 ctx.VisitDirectDeps(func(module android.Module) {
556 otherName := ctx.OtherModuleName(module)
557 tag := ctx.OtherModuleDependencyTag(module)
558
Colin Cross2d24c1b2018-05-23 10:59:18 -0700559 switch tag {
560 case bootClasspathTag:
561 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800562 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffin83a2d962019-11-19 19:44:10 +0000563 } else if sm, ok := module.(SystemModulesProvider); ok {
Paul Duffine25c6442019-10-11 13:50:28 +0100564 // A system modules dependency has been added to the bootclasspath
565 // so add its libs to the bootclasspath.
Paul Duffin83a2d962019-11-19 19:44:10 +0000566 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700567 } else {
568 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
569 }
570 case libTag:
571 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800572 case SdkLibraryDependency:
573 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700574 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900575 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900576 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700577 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800578 checkProducesJars(ctx, dep)
579 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800580 default:
581 ctx.ModuleErrorf("depends on non-java module %q", otherName)
582 }
Colin Cross6cef4812019-10-17 14:23:50 -0700583 case java9LibTag:
584 switch dep := module.(type) {
585 case Dependency:
586 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
587 default:
588 ctx.ModuleErrorf("depends on non-java module %q", otherName)
589 }
Nan Zhang357466b2018-04-17 17:38:36 -0700590 case systemModulesTag:
591 if deps.systemModules != nil {
592 panic("Found two system module dependencies")
593 }
Paul Duffin83a2d962019-11-19 19:44:10 +0000594 sm := module.(SystemModulesProvider)
595 outputDir, outputDeps := sm.OutputDirAndDeps()
596 deps.systemModules = &systemModules{outputDir, outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800597 }
598 })
599 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
600 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800601 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900602
603 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
604 if filterPackages == nil {
605 return srcs
606 }
607 filtered := []android.Path{}
608 for _, src := range srcs {
609 if src.Ext() != ".java" {
610 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
611 // but otherwise metalava emits stub sources having references to the generated AIDL classes
612 // in filtered-out pacages (e.g. com.android.internal.*).
613 // TODO(b/141149570) We need to fix this by introducing default private constructors or
614 // fixing metalava to not emit constructors having references to unknown classes.
615 filtered = append(filtered, src)
616 continue
617 }
618 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800619 if android.HasAnyPrefix(packageName, filterPackages) {
620 filtered = append(filtered, src)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900621 }
622 }
623 return filtered
624 }
625 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
626
Nan Zhanga40da042018-08-01 12:48:00 -0700627 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900628 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800629
630 // srcs may depend on some genrule output.
631 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800632 j.srcJars = append(j.srcJars, deps.srcJars...)
633
Nan Zhang581fd212018-01-10 16:06:12 -0800634 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800635 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800636
Nan Zhang9c69a122018-08-22 10:22:08 -0700637 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800638 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
639 }
640 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800641
Colin Cross8a497952019-03-05 22:25:09 -0800642 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000643 argFilesMap := map[string]string{}
644 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700645
Paul Duffin99e4a502019-02-11 15:38:42 +0000646 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800647 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000648 if _, exists := argFilesMap[label]; !exists {
649 argFilesMap[label] = strings.Join(paths.Strings(), " ")
650 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700651 } else {
652 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000653 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700654 }
655 }
656
657 var err error
Colin Cross15638152019-07-11 11:11:35 -0700658 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700659 if strings.HasPrefix(name, "location ") {
660 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000661 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700662 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700663 } else {
Colin Cross15638152019-07-11 11:11:35 -0700664 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000665 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700666 }
667 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700668 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700669 }
Colin Cross15638152019-07-11 11:11:35 -0700670 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700671 })
672
673 if err != nil {
674 ctx.PropertyErrorf("args", "%s", err.Error())
675 }
676
Nan Zhang581fd212018-01-10 16:06:12 -0800677 return deps
678}
679
680func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
681 j.addDeps(ctx)
682}
683
684func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
685 deps := j.collectDeps(ctx)
686
Colin Crossdaa4c672019-07-15 22:53:46 -0700687 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800688
Colin Crossdaa4c672019-07-15 22:53:46 -0700689 outDir := android.PathForModuleOut(ctx, "out")
690 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
691
692 j.stubsSrcJar = nil
693
694 rule := android.NewRuleBuilder()
695
696 rule.Command().Text("rm -rf").Text(outDir.String())
697 rule.Command().Text("mkdir -p").Text(outDir.String())
698
699 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700700
Colin Cross83bb3162018-06-25 15:48:06 -0700701 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800702
Colin Crossdaa4c672019-07-15 22:53:46 -0700703 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
704 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800705
Colin Cross1e743852019-10-28 11:37:20 -0700706 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700707 Flag("-J-Xmx1024m").
708 Flag("-XDignore.symbol.file").
709 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800710
Colin Crossdaa4c672019-07-15 22:53:46 -0700711 rule.Command().
712 BuiltTool(ctx, "soong_zip").
713 Flag("-write_if_changed").
714 Flag("-d").
715 FlagWithOutput("-o ", j.docZip).
716 FlagWithArg("-C ", outDir.String()).
717 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700718
Colin Crossdaa4c672019-07-15 22:53:46 -0700719 rule.Restat()
720
721 zipSyncCleanupCmd(rule, srcJarDir)
722
723 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800724}
725
Nan Zhanga40da042018-08-01 12:48:00 -0700726//
727// Droiddoc
728//
729type Droiddoc struct {
730 Javadoc
731
732 properties DroiddocProperties
733 apiFile android.WritablePath
734 dexApiFile android.WritablePath
735 privateApiFile android.WritablePath
736 privateDexApiFile android.WritablePath
737 removedApiFile android.WritablePath
738 removedDexApiFile android.WritablePath
739 exactApiFile android.WritablePath
740 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700741 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700742
743 checkCurrentApiTimestamp android.WritablePath
744 updateCurrentApiTimestamp android.WritablePath
745 checkLastReleasedApiTimestamp android.WritablePath
746
Nan Zhanga40da042018-08-01 12:48:00 -0700747 apiFilePath android.Path
748}
749
Colin Crossa3002fc2019-07-08 16:48:04 -0700750// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700751func DroiddocFactory() android.Module {
752 module := &Droiddoc{}
753
754 module.AddProperties(&module.properties,
755 &module.Javadoc.properties)
756
757 InitDroiddocModule(module, android.HostAndDeviceSupported)
758 return module
759}
760
Colin Crossa3002fc2019-07-08 16:48:04 -0700761// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700762func DroiddocHostFactory() android.Module {
763 module := &Droiddoc{}
764
765 module.AddProperties(&module.properties,
766 &module.Javadoc.properties)
767
768 InitDroiddocModule(module, android.HostSupported)
769 return module
770}
771
772func (d *Droiddoc) ApiFilePath() android.Path {
773 return d.apiFilePath
774}
775
Nan Zhang581fd212018-01-10 16:06:12 -0800776func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
777 d.Javadoc.addDeps(ctx)
778
Inseob Kim38449af2019-02-28 14:24:05 +0900779 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
780 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
781 }
782
Nan Zhang79614d12018-04-19 18:03:39 -0700783 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800784 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
785 }
Nan Zhang581fd212018-01-10 16:06:12 -0800786}
787
Colin Crossab054432019-07-15 16:13:59 -0700788func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Colin Cross2a2e0db2020-02-21 16:55:46 -0800789 buildNumberFile := ctx.Config().BuildNumberFile(ctx)
Nan Zhang443fa522018-08-20 20:58:28 -0700790 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
791 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
792 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700793 cmd.FlagWithArg("-source ", "1.8").
794 Flag("-J-Xmx1600m").
795 Flag("-J-XX:-OmitStackTraceInFastThrow").
796 Flag("-XDignore.symbol.file").
797 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
798 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
Colin Cross2a2e0db2020-02-21 16:55:46 -0800799 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
Elliott Hughes26bce342019-09-12 15:05:13 -0700800 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 -0700801
Nan Zhanga40da042018-08-01 12:48:00 -0700802 if String(d.properties.Custom_template) == "" {
803 // TODO: This is almost always droiddoc-templates-sdk
804 ctx.PropertyErrorf("custom_template", "must specify a template")
805 }
806
807 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700808 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700809 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700810 } else {
Paul Duffin884363e2019-12-19 10:21:09 +0000811 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
Nan Zhanga40da042018-08-01 12:48:00 -0700812 }
813 })
814
815 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700816 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
817 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
818 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700819 }
820
821 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700822 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
823 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
824 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700825 }
826
827 if len(d.properties.Html_dirs) > 2 {
828 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
829 }
830
Colin Cross8a497952019-03-05 22:25:09 -0800831 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700833
Colin Crossab054432019-07-15 16:13:59 -0700834 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700835
836 if String(d.properties.Proofread_file) != "" {
837 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700838 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
841 if String(d.properties.Todo_file) != "" {
842 // tricky part:
843 // we should not compute full path for todo_file through PathForModuleOut().
844 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700845 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
846 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700847 }
848
849 if String(d.properties.Resourcesdir) != "" {
850 // TODO: should we add files under resourcesDir to the implicits? It seems that
851 // resourcesDir is one sub dir of htmlDir
852 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700853 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700854 }
855
856 if String(d.properties.Resourcesoutdir) != "" {
857 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700858 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700859 }
Nan Zhanga40da042018-08-01 12:48:00 -0700860}
861
Colin Crossab054432019-07-15 16:13:59 -0700862func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200863 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
864 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700865 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700866
Nan Zhanga40da042018-08-01 12:48:00 -0700867 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700868 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700869 d.apiFilePath = d.apiFile
870 }
871
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200872 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
873 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700874 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700875 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700876 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700877 }
878
879 if String(d.properties.Private_api_filename) != "" {
880 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700881 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700882 }
883
884 if String(d.properties.Dex_api_filename) != "" {
885 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700886 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700887 }
888
889 if String(d.properties.Private_dex_api_filename) != "" {
890 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700891 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700892 }
893
894 if String(d.properties.Removed_dex_api_filename) != "" {
895 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700896 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700897 }
898
899 if String(d.properties.Exact_api_filename) != "" {
900 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700901 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700902 }
903
904 if String(d.properties.Dex_mapping_filename) != "" {
905 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700906 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700907 }
908
Nan Zhang66dc2362018-08-14 20:41:04 -0700909 if String(d.properties.Proguard_filename) != "" {
910 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700911 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700912 }
913
Nan Zhanga40da042018-08-01 12:48:00 -0700914 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700915 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700916 }
917
918 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700919 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700920 }
Nan Zhanga40da042018-08-01 12:48:00 -0700921}
922
Colin Crossab054432019-07-15 16:13:59 -0700923func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700924 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700925 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
926 rule.Command().Text("cp").
927 Input(staticDocIndexRedirect).
928 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700929 }
930
931 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700932 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
933 rule.Command().Text("cp").
934 Input(staticDocProperties).
935 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700936 }
Nan Zhanga40da042018-08-01 12:48:00 -0700937}
938
Colin Crossab054432019-07-15 16:13:59 -0700939func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700940 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700941
942 cmd := rule.Command().
943 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
944 Flag(config.JavacVmFlags).
945 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700946 FlagWithRspFileInputList("@", srcs).
947 FlagWithInput("@", srcJarList)
948
Colin Crossab054432019-07-15 16:13:59 -0700949 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
950 // based stubs generation.
951 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
952 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
953 // the correct package name base path.
954 if len(sourcepaths) > 0 {
955 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
956 } else {
957 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
958 }
959
960 cmd.FlagWithArg("-d ", outDir.String()).
961 Flag("-quiet")
962
963 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700964}
965
Colin Crossdaa4c672019-07-15 22:53:46 -0700966func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
967 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
968 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
969
970 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
971
972 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
973 cmd.Flag(flag).Implicits(deps)
974
975 cmd.FlagWithArg("--patch-module ", "java.base=.")
976
977 if len(classpath) > 0 {
978 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
979 }
980
981 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700982}
983
Colin Crossdaa4c672019-07-15 22:53:46 -0700984func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
985 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
986 sourcepaths android.Paths) *android.RuleBuilderCommand {
987
988 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
989
990 if len(bootclasspath) == 0 && ctx.Device() {
991 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
992 // ensure java does not fall back to the default bootclasspath.
993 cmd.FlagWithArg("-bootclasspath ", `""`)
994 } else if len(bootclasspath) > 0 {
995 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
996 }
997
998 if len(classpath) > 0 {
999 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1000 }
1001
1002 return cmd
1003}
1004
Colin Crossab054432019-07-15 16:13:59 -07001005func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1006 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001007
Colin Crossab054432019-07-15 16:13:59 -07001008 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
1009 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
1010
1011 return rule.Command().
1012 BuiltTool(ctx, "dokka").
1013 Flag(config.JavacVmFlags).
1014 Flag(srcJarDir.String()).
1015 FlagWithInputList("-classpath ", dokkaClasspath, ":").
1016 FlagWithArg("-format ", "dac").
1017 FlagWithArg("-dacRoot ", "/reference/kotlin").
1018 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001019}
1020
1021func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1022 deps := d.Javadoc.collectDeps(ctx)
1023
Colin Crossdaa4c672019-07-15 22:53:46 -07001024 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
1025 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1026
Nan Zhang1598a9e2018-09-04 17:14:32 -07001027 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1028 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1029 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1030 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1031
Colin Crossab054432019-07-15 16:13:59 -07001032 outDir := android.PathForModuleOut(ctx, "out")
1033 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1034 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001035
Colin Crossab054432019-07-15 16:13:59 -07001036 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -07001037
Colin Crossab054432019-07-15 16:13:59 -07001038 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1039 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001040
Colin Crossab054432019-07-15 16:13:59 -07001041 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1042
1043 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001044 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001045 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001046 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001047 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001048 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001049 }
1050
Colin Crossab054432019-07-15 16:13:59 -07001051 d.stubsFlags(ctx, cmd, stubsDir)
1052
1053 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1054
Mathew Inwoodabd49ab2019-12-19 14:27:08 +00001055 if d.properties.Compat_config != nil {
1056 compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
1057 cmd.FlagWithInput("-compatconfig ", compatConfig)
1058 }
1059
Colin Crossab054432019-07-15 16:13:59 -07001060 var desc string
1061 if Bool(d.properties.Dokka_enabled) {
1062 desc = "dokka"
1063 } else {
1064 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1065
1066 for _, o := range d.Javadoc.properties.Out {
1067 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1068 }
1069
1070 d.postDoclavaCmds(ctx, rule)
1071 desc = "doclava"
1072 }
1073
1074 rule.Command().
1075 BuiltTool(ctx, "soong_zip").
1076 Flag("-write_if_changed").
1077 Flag("-d").
1078 FlagWithOutput("-o ", d.docZip).
1079 FlagWithArg("-C ", outDir.String()).
1080 FlagWithArg("-D ", outDir.String())
1081
1082 rule.Command().
1083 BuiltTool(ctx, "soong_zip").
1084 Flag("-write_if_changed").
1085 Flag("-jar").
1086 FlagWithOutput("-o ", d.stubsSrcJar).
1087 FlagWithArg("-C ", stubsDir.String()).
1088 FlagWithArg("-D ", stubsDir.String())
1089
1090 rule.Restat()
1091
1092 zipSyncCleanupCmd(rule, srcJarDir)
1093
1094 rule.Build(pctx, ctx, "javadoc", desc)
1095
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001096 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001097 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001098
1099 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1100 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001101
1102 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001103
1104 rule := android.NewRuleBuilder()
1105
1106 rule.Command().Text("( true")
1107
1108 rule.Command().
1109 BuiltTool(ctx, "apicheck").
1110 Flag("-JXmx1024m").
1111 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1112 OptionalFlag(d.properties.Check_api.Current.Args).
1113 Input(apiFile).
1114 Input(d.apiFile).
1115 Input(removedApiFile).
1116 Input(d.removedApiFile)
1117
1118 msg := fmt.Sprintf(`\n******************************\n`+
1119 `You have tried to change the API from what has been previously approved.\n\n`+
1120 `To make these errors go away, you have two choices:\n`+
1121 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1122 ` errors above.\n\n`+
1123 ` 2. You can update current.txt by executing the following command:\n`+
1124 ` make %s-update-current-api\n\n`+
1125 ` To submit the revised current.txt to the main Android repository,\n`+
1126 ` you will need approval.\n`+
1127 `******************************\n`, ctx.ModuleName())
1128
1129 rule.Command().
1130 Text("touch").Output(d.checkCurrentApiTimestamp).
1131 Text(") || (").
1132 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1133 Text("; exit 38").
1134 Text(")")
1135
1136 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001137
1138 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001139
1140 // update API rule
1141 rule = android.NewRuleBuilder()
1142
1143 rule.Command().Text("( true")
1144
1145 rule.Command().
1146 Text("cp").Flag("-f").
1147 Input(d.apiFile).Flag(apiFile.String())
1148
1149 rule.Command().
1150 Text("cp").Flag("-f").
1151 Input(d.removedApiFile).Flag(removedApiFile.String())
1152
1153 msg = "failed to update public API"
1154
1155 rule.Command().
1156 Text("touch").Output(d.updateCurrentApiTimestamp).
1157 Text(") || (").
1158 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1159 Text("; exit 38").
1160 Text(")")
1161
1162 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001163 }
1164
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001165 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001166 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001167
1168 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1169 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001170
1171 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001172
1173 rule := android.NewRuleBuilder()
1174
1175 rule.Command().
1176 Text("(").
1177 BuiltTool(ctx, "apicheck").
1178 Flag("-JXmx1024m").
1179 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1180 OptionalFlag(d.properties.Check_api.Last_released.Args).
1181 Input(apiFile).
1182 Input(d.apiFile).
1183 Input(removedApiFile).
1184 Input(d.removedApiFile)
1185
1186 msg := `\n******************************\n` +
1187 `You have tried to change the API from what has been previously released in\n` +
1188 `an SDK. Please fix the errors listed above.\n` +
1189 `******************************\n`
1190
1191 rule.Command().
1192 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1193 Text(") || (").
1194 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1195 Text("; exit 38").
1196 Text(")")
1197
1198 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001199 }
1200}
1201
1202//
1203// Droidstubs
1204//
1205type Droidstubs struct {
1206 Javadoc
Paul Duffin91547182019-11-12 19:39:36 +00001207 android.SdkBase
Nan Zhang1598a9e2018-09-04 17:14:32 -07001208
Pete Gillin581d6082018-10-22 15:55:04 +01001209 properties DroidstubsProperties
1210 apiFile android.WritablePath
1211 apiXmlFile android.WritablePath
1212 lastReleasedApiXmlFile android.WritablePath
1213 dexApiFile android.WritablePath
1214 privateApiFile android.WritablePath
1215 privateDexApiFile android.WritablePath
1216 removedApiFile android.WritablePath
1217 removedDexApiFile android.WritablePath
1218 apiMappingFile android.WritablePath
1219 exactApiFile android.WritablePath
1220 proguardFile android.WritablePath
1221 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001222
1223 checkCurrentApiTimestamp android.WritablePath
1224 updateCurrentApiTimestamp android.WritablePath
1225 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001226 apiLintTimestamp android.WritablePath
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001227 apiLintReport android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001228
Pete Gillin581d6082018-10-22 15:55:04 +01001229 checkNullabilityWarningsTimestamp android.WritablePath
1230
Nan Zhang1598a9e2018-09-04 17:14:32 -07001231 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001232 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001233
1234 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001235
1236 jdiffDocZip android.WritablePath
1237 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001238
1239 metadataZip android.WritablePath
1240 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001241}
1242
Colin Crossa3002fc2019-07-08 16:48:04 -07001243// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1244// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1245// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001246func DroidstubsFactory() android.Module {
1247 module := &Droidstubs{}
1248
1249 module.AddProperties(&module.properties,
1250 &module.Javadoc.properties)
1251
1252 InitDroiddocModule(module, android.HostAndDeviceSupported)
Paul Duffin91547182019-11-12 19:39:36 +00001253 android.InitSdkAwareModule(module)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254 return module
1255}
1256
Colin Crossa3002fc2019-07-08 16:48:04 -07001257// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1258// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1259// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1260// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001261func DroidstubsHostFactory() android.Module {
1262 module := &Droidstubs{}
1263
1264 module.AddProperties(&module.properties,
1265 &module.Javadoc.properties)
1266
1267 InitDroiddocModule(module, android.HostSupported)
1268 return module
1269}
1270
1271func (d *Droidstubs) ApiFilePath() android.Path {
1272 return d.apiFilePath
1273}
1274
Paul Duffin1fd005d2020-04-09 01:08:11 +01001275func (d *Droidstubs) RemovedApiFilePath() android.Path {
1276 return d.removedApiFile
1277}
1278
Paul Duffin3d1248c2020-04-09 00:10:17 +01001279func (d *Droidstubs) StubsSrcJar() android.Path {
1280 return d.stubsSrcJar
1281}
1282
Nan Zhang1598a9e2018-09-04 17:14:32 -07001283func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1284 d.Javadoc.addDeps(ctx)
1285
Inseob Kim38449af2019-02-28 14:24:05 +09001286 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1287 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1288 }
1289
Nan Zhang1598a9e2018-09-04 17:14:32 -07001290 if len(d.properties.Merge_annotations_dirs) != 0 {
1291 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1292 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1293 }
1294 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001295
Pete Gillin77167902018-09-19 18:16:26 +01001296 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1297 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1298 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1299 }
1300 }
1301
Nan Zhang9c69a122018-08-22 10:22:08 -07001302 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1303 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1304 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1305 }
1306 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001307}
1308
Paul Duffin3ae29512020-04-08 18:18:03 +01001309func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001310 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1311 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001312 String(d.properties.Api_filename) != "" {
1313 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001314 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001315 d.apiFilePath = d.apiFile
1316 }
1317
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001318 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1319 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001320 String(d.properties.Removed_api_filename) != "" {
1321 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001322 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001323 }
1324
1325 if String(d.properties.Private_api_filename) != "" {
1326 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001328 }
1329
1330 if String(d.properties.Dex_api_filename) != "" {
1331 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001332 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001333 }
1334
1335 if String(d.properties.Private_dex_api_filename) != "" {
1336 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001337 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001338 }
1339
1340 if String(d.properties.Removed_dex_api_filename) != "" {
1341 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001342 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001343 }
1344
1345 if String(d.properties.Exact_api_filename) != "" {
1346 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001347 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001348 }
1349
Nan Zhang9c69a122018-08-22 10:22:08 -07001350 if String(d.properties.Dex_mapping_filename) != "" {
1351 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001352 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001353 }
1354
Nan Zhang199645c2018-09-19 12:40:06 -07001355 if String(d.properties.Proguard_filename) != "" {
1356 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001357 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001358 }
1359
Nan Zhang9c69a122018-08-22 10:22:08 -07001360 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001361 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1362 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001363 }
1364
Paul Duffin3ae29512020-04-08 18:18:03 +01001365 if stubsDir.Valid() {
1366 if Bool(d.properties.Create_doc_stubs) {
1367 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
1368 } else {
1369 cmd.FlagWithArg("--stubs ", stubsDir.String())
1370 cmd.Flag("--exclude-documentation-from-stubs")
1371 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001372 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001373}
1374
Colin Cross33961b52019-07-11 11:01:22 -07001375func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001376 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001377 cmd.Flag("--include-annotations")
1378
Pete Gillinc382a562018-11-14 18:45:46 +00001379 validatingNullability :=
1380 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1381 String(d.properties.Validate_nullability_from_list) != ""
Paul Duffin13a9dd62019-11-04 10:26:47 +00001382
Pete Gillina262c052018-09-14 14:25:48 +01001383 migratingNullability := String(d.properties.Previous_api) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001384 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001385 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001386 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001387 }
Colin Cross33961b52019-07-11 11:01:22 -07001388
Pete Gillinc382a562018-11-14 18:45:46 +00001389 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001390 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001391 }
Colin Cross33961b52019-07-11 11:01:22 -07001392
Pete Gillina262c052018-09-14 14:25:48 +01001393 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001394 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001395 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001396 }
Nan Zhanga40da042018-08-01 12:48:00 -07001397
1398 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001399 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001400
Nan Zhang1598a9e2018-09-04 17:14:32 -07001401 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001402 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001403 "has to be non-empty if annotations was enabled!")
1404 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001405
Colin Cross33961b52019-07-11 11:01:22 -07001406 d.mergeAnnoDirFlags(ctx, cmd)
1407
1408 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1409 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1410 FlagWithArg("--hide ", "SuperfluousPrefix").
1411 FlagWithArg("--hide ", "AnnotationExtraction")
1412 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001413}
1414
Colin Cross33961b52019-07-11 11:01:22 -07001415func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1416 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1417 if t, ok := m.(*ExportedDroiddocDir); ok {
1418 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1419 } else {
1420 ctx.PropertyErrorf("merge_annotations_dirs",
1421 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1422 }
1423 })
1424}
1425
1426func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001427 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1428 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001429 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001430 } else {
1431 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1432 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1433 }
1434 })
Nan Zhanga40da042018-08-01 12:48:00 -07001435}
1436
Colin Cross33961b52019-07-11 11:01:22 -07001437func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001438 if Bool(d.properties.Api_levels_annotations_enabled) {
1439 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001440
1441 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1442 ctx.PropertyErrorf("api_levels_annotations_dirs",
1443 "has to be non-empty if api levels annotations was enabled!")
1444 }
1445
Colin Cross33961b52019-07-11 11:01:22 -07001446 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1447 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1448 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1449 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001450
1451 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1452 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001453 for _, dep := range t.deps {
1454 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001455 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001456 }
1457 }
Colin Cross33961b52019-07-11 11:01:22 -07001458 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001459 } else {
1460 ctx.PropertyErrorf("api_levels_annotations_dirs",
1461 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1462 }
1463 })
1464
1465 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001466}
1467
Colin Cross33961b52019-07-11 11:01:22 -07001468func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001469 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1470 if d.apiFile.String() == "" {
1471 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1472 }
1473
1474 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001475 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001476
1477 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1478 ctx.PropertyErrorf("check_api.last_released.api_file",
1479 "has to be non-empty if jdiff was enabled!")
1480 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001481
Colin Cross33961b52019-07-11 11:01:22 -07001482 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001483 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001484 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1485 }
1486}
Nan Zhang71bbe632018-09-17 14:32:21 -07001487
Colin Cross1e743852019-10-28 11:37:20 -07001488func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Colin Cross33961b52019-07-11 11:01:22 -07001489 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Cross8b8bec32019-11-15 13:18:43 -08001490 // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
1491 rule.HighMem()
Colin Cross33961b52019-07-11 11:01:22 -07001492 cmd := rule.Command().BuiltTool(ctx, "metalava").
1493 Flag(config.JavacVmFlags).
1494 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001495 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001496 FlagWithRspFileInputList("@", srcs).
1497 FlagWithInput("@", srcJarList)
1498
1499 if len(bootclasspath) > 0 {
1500 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001501 }
1502
Colin Cross33961b52019-07-11 11:01:22 -07001503 if len(classpath) > 0 {
1504 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1505 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001506
Colin Cross33961b52019-07-11 11:01:22 -07001507 if len(sourcepaths) > 0 {
1508 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1509 } else {
1510 cmd.FlagWithArg("-sourcepath ", `""`)
1511 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001512
Colin Cross33961b52019-07-11 11:01:22 -07001513 cmd.Flag("--no-banner").
1514 Flag("--color").
1515 Flag("--quiet").
1516 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001517
Colin Cross33961b52019-07-11 11:01:22 -07001518 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001519}
1520
Nan Zhang1598a9e2018-09-04 17:14:32 -07001521func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001522 deps := d.Javadoc.collectDeps(ctx)
1523
1524 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001525
Colin Cross33961b52019-07-11 11:01:22 -07001526 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001527
Colin Cross33961b52019-07-11 11:01:22 -07001528 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
Nan Zhang71bbe632018-09-17 14:32:21 -07001529
Colin Cross33961b52019-07-11 11:01:22 -07001530 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001531
Paul Duffin3ae29512020-04-08 18:18:03 +01001532 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1533 var stubsDir android.OptionalPath
1534 if generateStubs {
1535 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1536 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "stubsDir"))
1537 rule.Command().Text("rm -rf").Text(stubsDir.String())
1538 rule.Command().Text("mkdir -p").Text(stubsDir.String())
1539 }
Nan Zhanga40da042018-08-01 12:48:00 -07001540
Colin Cross33961b52019-07-11 11:01:22 -07001541 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1542
1543 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1544 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1545
1546 d.stubsFlags(ctx, cmd, stubsDir)
1547
1548 d.annotationsFlags(ctx, cmd)
1549 d.inclusionAnnotationsFlags(ctx, cmd)
1550 d.apiLevelsAnnotationsFlags(ctx, cmd)
1551 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001552
Nan Zhang1598a9e2018-09-04 17:14:32 -07001553 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1554 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1555 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1556 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1557 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001558 }
Colin Cross33961b52019-07-11 11:01:22 -07001559
1560 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1561 for _, o := range d.Javadoc.properties.Out {
1562 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1563 }
1564
Paul Duffin3ae29512020-04-08 18:18:03 +01001565 if generateStubs {
1566 rule.Command().
1567 BuiltTool(ctx, "soong_zip").
1568 Flag("-write_if_changed").
1569 Flag("-jar").
1570 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1571 FlagWithArg("-C ", stubsDir.String()).
1572 FlagWithArg("-D ", stubsDir.String())
1573 }
Jerome Gaillard0f599032019-10-10 19:29:11 +01001574
1575 if Bool(d.properties.Write_sdk_values) {
1576 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1577 rule.Command().
1578 BuiltTool(ctx, "soong_zip").
1579 Flag("-write_if_changed").
1580 Flag("-d").
1581 FlagWithOutput("-o ", d.metadataZip).
1582 FlagWithArg("-C ", d.metadataDir.String()).
1583 FlagWithArg("-D ", d.metadataDir.String())
1584 }
1585
Colin Cross33961b52019-07-11 11:01:22 -07001586 rule.Restat()
1587
1588 zipSyncCleanupCmd(rule, srcJarDir)
1589
1590 rule.Build(pctx, ctx, "metalava", "metalava")
1591
1592 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001593
Adrian Roos075eedc2019-10-10 12:07:03 +02001594 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) && !ctx.Config().IsPdkBuild() {
1595 rule := android.NewRuleBuilder()
1596 rule.Command().Text("( true")
1597
1598 srcJarDir := android.PathForModuleOut(ctx, "api_lint", "srcjars")
1599 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1600
1601 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1602 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1603
Adrian Rooscab4a2c2019-10-14 16:32:41 +02001604 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1605
Adrian Roos075eedc2019-10-10 12:07:03 +02001606 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1607 if newSince.Valid() {
1608 cmd.FlagWithInput("--api-lint ", newSince.Path())
1609 } else {
1610 cmd.Flag("--api-lint")
1611 }
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001612 d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
1613 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport)
Adrian Roos075eedc2019-10-10 12:07:03 +02001614
1615 d.inclusionAnnotationsFlags(ctx, cmd)
1616 d.mergeAnnoDirFlags(ctx, cmd)
1617
1618 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1619 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1620 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1621
1622 if baselineFile.Valid() {
1623 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1624 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1625 }
1626
1627 zipSyncCleanupCmd(rule, srcJarDir)
1628
1629 msg := fmt.Sprintf(`\n******************************\n`+
1630 `Your API changes are triggering API Lint warnings or errors.\n\n`+
1631 `To make these errors go away, you have two choices:\n`+
1632 ` 1. You can suppress the errors with @SuppressLint(\"<id>\").\n\n`+
1633 ` 2. You can update the baseline by executing the following command:\n`+
1634 ` cp \"$PWD/%s\" \"$PWD/%s\"\n\n`+
1635 `******************************\n`, updatedBaselineOutput, baselineFile.Path())
1636 rule.Command().
1637 Text("touch").Output(d.apiLintTimestamp).
1638 Text(") || (").
1639 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1640 Text("; exit 38").
1641 Text(")")
1642
1643 rule.Build(pctx, ctx, "metalavaApiLint", "metalava API lint")
1644
1645 }
1646
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001647 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001648 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001649
1650 if len(d.Javadoc.properties.Out) > 0 {
1651 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1652 }
1653
1654 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1655 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001656 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
Makoto Onuki5405a732020-04-16 17:02:40 -07001657
1658 if baselineFile.Valid() {
1659 ctx.PropertyErrorf("current API check can't have a baseline file. (module %s)", ctx.ModuleName())
1660 }
Nan Zhang61819ce2018-05-04 18:49:16 -07001661
Nan Zhang2760dfc2018-08-24 17:32:54 +00001662 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001663
Colin Cross33961b52019-07-11 11:01:22 -07001664 rule := android.NewRuleBuilder()
1665
Makoto Onuki5405a732020-04-16 17:02:40 -07001666 // Diff command line.
1667 // -F matches the closest "opening" line, such as "package xxx{"
1668 // and " public class Yyy {".
1669 diff := `diff -u -F '{ *$'`
1670
Colin Cross33961b52019-07-11 11:01:22 -07001671 rule.Command().Text("( true")
Makoto Onuki5405a732020-04-16 17:02:40 -07001672 rule.Command().
1673 Text(diff).
1674 Input(apiFile).Input(d.apiFile)
Colin Cross33961b52019-07-11 11:01:22 -07001675
Makoto Onuki5405a732020-04-16 17:02:40 -07001676 rule.Command().
1677 Text(diff).
1678 Input(removedApiFile).Input(d.removedApiFile)
Colin Cross33961b52019-07-11 11:01:22 -07001679
1680 msg := fmt.Sprintf(`\n******************************\n`+
1681 `You have tried to change the API from what has been previously approved.\n\n`+
1682 `To make these errors go away, you have two choices:\n`+
Makoto Onuki5405a732020-04-16 17:02:40 -07001683 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1684 ` to the new methods, etc. shown in the above diff.\n\n`+
1685 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
Colin Cross33961b52019-07-11 11:01:22 -07001686 ` make %s-update-current-api\n\n`+
1687 ` To submit the revised current.txt to the main Android repository,\n`+
1688 ` you will need approval.\n`+
1689 `******************************\n`, ctx.ModuleName())
1690
1691 rule.Command().
1692 Text("touch").Output(d.checkCurrentApiTimestamp).
1693 Text(") || (").
1694 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1695 Text("; exit 38").
1696 Text(")")
1697
Makoto Onuki5405a732020-04-16 17:02:40 -07001698 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001699
1700 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001701
1702 // update API rule
1703 rule = android.NewRuleBuilder()
1704
1705 rule.Command().Text("( true")
1706
1707 rule.Command().
1708 Text("cp").Flag("-f").
1709 Input(d.apiFile).Flag(apiFile.String())
1710
1711 rule.Command().
1712 Text("cp").Flag("-f").
1713 Input(d.removedApiFile).Flag(removedApiFile.String())
1714
1715 msg = "failed to update public API"
1716
1717 rule.Command().
1718 Text("touch").Output(d.updateCurrentApiTimestamp).
1719 Text(") || (").
1720 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1721 Text("; exit 38").
1722 Text(")")
1723
1724 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001725 }
Nan Zhanga40da042018-08-01 12:48:00 -07001726
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001727 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001728 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001729
1730 if len(d.Javadoc.properties.Out) > 0 {
1731 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1732 }
1733
1734 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1735 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001736 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1737 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001738
Nan Zhang2760dfc2018-08-24 17:32:54 +00001739 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001740
Colin Cross33961b52019-07-11 11:01:22 -07001741 rule := android.NewRuleBuilder()
1742
1743 rule.Command().Text("( true")
1744
1745 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1746 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1747
1748 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1749 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1750
1751 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1752 FlagWithInput("--check-compatibility:api:released ", apiFile)
1753
1754 d.inclusionAnnotationsFlags(ctx, cmd)
1755
1756 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1757
1758 d.mergeAnnoDirFlags(ctx, cmd)
1759
Adrian Roos14f75a92019-08-12 17:54:09 +02001760 if baselineFile.Valid() {
1761 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1762 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1763 }
1764
Colin Cross33961b52019-07-11 11:01:22 -07001765 zipSyncCleanupCmd(rule, srcJarDir)
1766
1767 msg := `\n******************************\n` +
1768 `You have tried to change the API from what has been previously released in\n` +
1769 `an SDK. Please fix the errors listed above.\n` +
1770 `******************************\n`
1771 rule.Command().
1772 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1773 Text(") || (").
1774 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1775 Text("; exit 38").
1776 Text(")")
1777
1778 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001779 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001780
Pete Gillin581d6082018-10-22 15:55:04 +01001781 if String(d.properties.Check_nullability_warnings) != "" {
1782 if d.nullabilityWarningsFile == nil {
1783 ctx.PropertyErrorf("check_nullability_warnings",
1784 "Cannot specify check_nullability_warnings unless validating nullability")
1785 }
Colin Cross33961b52019-07-11 11:01:22 -07001786
1787 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1788
Pete Gillin581d6082018-10-22 15:55:04 +01001789 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001790
Pete Gillin581d6082018-10-22 15:55:04 +01001791 msg := fmt.Sprintf(`\n******************************\n`+
1792 `The warnings encountered during nullability annotation validation did\n`+
1793 `not match the checked in file of expected warnings. The diffs are shown\n`+
1794 `above. You have two options:\n`+
1795 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1796 ` 2. Update the file of expected warnings by running:\n`+
1797 ` cp %s %s\n`+
1798 ` and submitting the updated file as part of your change.`,
1799 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001800
1801 rule := android.NewRuleBuilder()
1802
1803 rule.Command().
1804 Text("(").
1805 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1806 Text("&&").
1807 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1808 Text(") || (").
1809 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1810 Text("; exit 38").
1811 Text(")")
1812
1813 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001814 }
1815
Nan Zhang71bbe632018-09-17 14:32:21 -07001816 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001817 if len(d.Javadoc.properties.Out) > 0 {
1818 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1819 }
1820
1821 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1822 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1823 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1824
1825 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001826
Nan Zhang86b06202018-09-21 17:09:21 -07001827 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1828 // since there's cron job downstream that fetch this .zip file periodically.
1829 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001830 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1831 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1832
Nan Zhang71bbe632018-09-17 14:32:21 -07001833 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001834
Colin Cross33961b52019-07-11 11:01:22 -07001835 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1836 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001837
Colin Cross33961b52019-07-11 11:01:22 -07001838 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1839
Colin Crossdaa4c672019-07-15 22:53:46 -07001840 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001841 deps.bootClasspath, deps.classpath, d.sourcepaths)
1842
1843 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001844 Flag("-XDignore.symbol.file").
1845 FlagWithArg("-doclet ", "jdiff.JDiff").
1846 FlagWithInput("-docletpath ", jdiff).
1847 Flag("-quiet").
1848 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1849 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1850 Implicit(d.apiXmlFile).
1851 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1852 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1853 Implicit(d.lastReleasedApiXmlFile)
1854
Colin Cross33961b52019-07-11 11:01:22 -07001855 rule.Command().
1856 BuiltTool(ctx, "soong_zip").
1857 Flag("-write_if_changed").
1858 Flag("-d").
1859 FlagWithOutput("-o ", d.jdiffDocZip).
1860 FlagWithArg("-C ", outDir.String()).
1861 FlagWithArg("-D ", outDir.String())
1862
1863 rule.Command().
1864 BuiltTool(ctx, "soong_zip").
1865 Flag("-write_if_changed").
1866 Flag("-jar").
1867 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1868 FlagWithArg("-C ", stubsDir.String()).
1869 FlagWithArg("-D ", stubsDir.String())
1870
1871 rule.Restat()
1872
1873 zipSyncCleanupCmd(rule, srcJarDir)
1874
1875 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001876 }
Nan Zhang581fd212018-01-10 16:06:12 -08001877}
Dan Willemsencc090972018-02-26 14:33:31 -08001878
Nan Zhanga40da042018-08-01 12:48:00 -07001879//
Nan Zhangf4936b02018-08-01 15:00:28 -07001880// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001881//
Dan Willemsencc090972018-02-26 14:33:31 -08001882var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001883var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001884var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001885var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001886
Nan Zhangf4936b02018-08-01 15:00:28 -07001887type ExportedDroiddocDirProperties struct {
1888 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001889 Path *string
1890}
1891
Nan Zhangf4936b02018-08-01 15:00:28 -07001892type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001893 android.ModuleBase
1894
Nan Zhangf4936b02018-08-01 15:00:28 -07001895 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001896
1897 deps android.Paths
1898 dir android.Path
1899}
1900
Colin Crossa3002fc2019-07-08 16:48:04 -07001901// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001902func ExportedDroiddocDirFactory() android.Module {
1903 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001904 module.AddProperties(&module.properties)
1905 android.InitAndroidModule(module)
1906 return module
1907}
1908
Nan Zhangf4936b02018-08-01 15:00:28 -07001909func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001910
Nan Zhangf4936b02018-08-01 15:00:28 -07001911func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001912 path := String(d.properties.Path)
1913 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001914 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001915}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001916
1917//
1918// Defaults
1919//
1920type DocDefaults struct {
1921 android.ModuleBase
1922 android.DefaultsModuleBase
1923}
1924
Nan Zhangb2b33de2018-02-23 11:18:47 -08001925func DocDefaultsFactory() android.Module {
1926 module := &DocDefaults{}
1927
1928 module.AddProperties(
1929 &JavadocProperties{},
1930 &DroiddocProperties{},
1931 )
1932
1933 android.InitDefaultsModule(module)
1934
1935 return module
1936}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001937
1938func StubsDefaultsFactory() android.Module {
1939 module := &DocDefaults{}
1940
1941 module.AddProperties(
1942 &JavadocProperties{},
1943 &DroidstubsProperties{},
1944 )
1945
1946 android.InitDefaultsModule(module)
1947
1948 return module
1949}
Colin Cross33961b52019-07-11 11:01:22 -07001950
1951func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1952 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1953
1954 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1955 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1956 srcJarList := srcJarDir.Join(ctx, "list")
1957
1958 rule.Temporary(srcJarList)
1959
1960 rule.Command().BuiltTool(ctx, "zipsync").
1961 FlagWithArg("-d ", srcJarDir.String()).
1962 FlagWithOutput("-l ", srcJarList).
1963 FlagWithArg("-f ", `"*.java"`).
1964 Inputs(srcJars)
1965
1966 return srcJarList
1967}
1968
1969func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1970 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1971}
Paul Duffin91547182019-11-12 19:39:36 +00001972
1973var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
1974
1975type PrebuiltStubsSourcesProperties struct {
1976 Srcs []string `android:"path"`
1977}
1978
1979type PrebuiltStubsSources struct {
1980 android.ModuleBase
1981 android.DefaultableModuleBase
1982 prebuilt android.Prebuilt
1983 android.SdkBase
1984
1985 properties PrebuiltStubsSourcesProperties
1986
Paul Duffin9b478b02019-12-10 13:41:51 +00001987 // The source directories containing stubs source files.
1988 srcDirs android.Paths
Paul Duffin91547182019-11-12 19:39:36 +00001989 stubsSrcJar android.ModuleOutPath
1990}
1991
Paul Duffin9b478b02019-12-10 13:41:51 +00001992func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
1993 switch tag {
1994 case "":
1995 return android.Paths{p.stubsSrcJar}, nil
1996 default:
1997 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1998 }
1999}
2000
Paul Duffin91547182019-11-12 19:39:36 +00002001func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffin9b478b02019-12-10 13:41:51 +00002002 p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
2003
2004 p.srcDirs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
2005
2006 rule := android.NewRuleBuilder()
2007 command := rule.Command().
2008 BuiltTool(ctx, "soong_zip").
2009 Flag("-write_if_changed").
2010 Flag("-jar").
2011 FlagWithOutput("-o ", p.stubsSrcJar)
2012
2013 for _, d := range p.srcDirs {
2014 dir := d.String()
2015 command.
2016 FlagWithArg("-C ", dir).
2017 FlagWithInput("-D ", d)
2018 }
2019
2020 rule.Restat()
2021
2022 rule.Build(pctx, ctx, "zip src", "Create srcjar from prebuilt source")
Paul Duffin91547182019-11-12 19:39:36 +00002023}
2024
2025func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
2026 return &p.prebuilt
2027}
2028
2029func (p *PrebuiltStubsSources) Name() string {
2030 return p.prebuilt.Name(p.ModuleBase.Name())
2031}
2032
Paul Duffin91547182019-11-12 19:39:36 +00002033// prebuilt_stubs_sources imports a set of java source files as if they were
2034// generated by droidstubs.
2035//
2036// By default, a prebuilt_stubs_sources has a single variant that expects a
2037// set of `.java` files generated by droidstubs.
2038//
2039// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
2040// for host modules.
2041//
2042// Intended only for use by sdk snapshots.
2043func PrebuiltStubsSourcesFactory() android.Module {
2044 module := &PrebuiltStubsSources{}
2045
2046 module.AddProperties(&module.properties)
2047
2048 android.InitPrebuiltModule(module, &module.properties.Srcs)
2049 android.InitSdkAwareModule(module)
2050 InitDroiddocModule(module, android.HostAndDeviceSupported)
2051 return module
2052}
2053
Paul Duffin13879572019-11-28 14:31:38 +00002054type droidStubsSdkMemberType struct {
Paul Duffin255f18e2019-12-13 11:22:16 +00002055 android.SdkMemberTypeBase
Paul Duffin13879572019-11-28 14:31:38 +00002056}
2057
2058func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
2059 mctx.AddVariationDependencies(nil, dependencyTag, names...)
2060}
2061
2062func (mt *droidStubsSdkMemberType) IsInstance(module android.Module) bool {
2063 _, ok := module.(*Droidstubs)
2064 return ok
2065}
2066
Paul Duffin495ffb92020-03-20 13:35:40 +00002067func (mt *droidStubsSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
2068 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_stubs_sources")
2069}
2070
2071func (mt *droidStubsSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
2072 return &droidStubsInfoProperties{}
2073}
2074
2075type droidStubsInfoProperties struct {
2076 android.SdkMemberPropertiesBase
2077
2078 StubsSrcJar android.Path
2079}
2080
2081func (p *droidStubsInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
2082 droidstubs := variant.(*Droidstubs)
2083 p.StubsSrcJar = droidstubs.stubsSrcJar
2084}
2085
2086func (p *droidStubsInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
2087 if p.StubsSrcJar != nil {
2088 builder := ctx.SnapshotBuilder()
2089
2090 snapshotRelativeDir := filepath.Join("java", ctx.Name()+"_stubs_sources")
2091
2092 builder.UnzipToSnapshot(p.StubsSrcJar, snapshotRelativeDir)
2093
2094 propertySet.AddProperty("srcs", []string{snapshotRelativeDir})
Paul Duffin13879572019-11-28 14:31:38 +00002095 }
Paul Duffin91547182019-11-12 19:39:36 +00002096}