blob: 4c5f66c186926996c69fd6a3230f3d81d10e77e3 [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"
Ramy Medhat427683c2020-04-30 03:08:37 -040027 "android/soong/remoteexec"
Nan Zhang581fd212018-01-10 16:06:12 -080028)
29
30func init() {
Paul Duffin884363e2019-12-19 10:21:09 +000031 RegisterDocsBuildComponents(android.InitRegistrationContext)
32 RegisterStubsBuildComponents(android.InitRegistrationContext)
Paul Duffin255f18e2019-12-13 11:22:16 +000033
34 // Register sdk member type.
35 android.RegisterSdkMemberType(&droidStubsSdkMemberType{
36 SdkMemberTypeBase: android.SdkMemberTypeBase{
37 PropertyName: "stubs_sources",
Paul Duffine6029182019-12-16 17:43:48 +000038 // stubs_sources can be used with sdk to provide the source stubs for APIs provided by
39 // the APEX.
40 SupportsSdk: true,
Paul Duffin255f18e2019-12-13 11:22:16 +000041 },
42 })
Nan Zhang581fd212018-01-10 16:06:12 -080043}
44
Paul Duffin884363e2019-12-19 10:21:09 +000045func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
46 ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
47
48 ctx.RegisterModuleType("droiddoc", DroiddocFactory)
49 ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
50 ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
51 ctx.RegisterModuleType("javadoc", JavadocFactory)
52 ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
53}
54
55func RegisterStubsBuildComponents(ctx android.RegistrationContext) {
56 ctx.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
57
58 ctx.RegisterModuleType("droidstubs", DroidstubsFactory)
59 ctx.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
60
61 ctx.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
62}
63
Colin Crossa1ce2a02018-06-20 15:19:39 -070064var (
65 srcsLibTag = dependencyTag{name: "sources from javalib"}
66)
67
Nan Zhang581fd212018-01-10 16:06:12 -080068type JavadocProperties struct {
69 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
70 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080071 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080072
Steve Kim3666c702020-09-01 17:58:01 +000073 // list of directories rooted at the Android.bp file that will
74 // be added to the search paths for finding source files when passing package names.
75 Local_sourcepaths []string
76
Nan Zhang581fd212018-01-10 16:06:12 -080077 // list of source files that should not be used to build the Java module.
78 // This is most useful in the arch/multilib variants to remove non-common files
79 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080080 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080081
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090082 // list of package names that should actually be used. If this property is left unspecified,
83 // all the sources from the srcs property is used.
84 Filter_packages []string
85
Nan Zhangb2b33de2018-02-23 11:18:47 -080086 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080087 Libs []string `android:"arch_variant"`
88
89 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080090 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080091
Paul Duffine25c6442019-10-11 13:50:28 +010092 // if not blank, set to the version of the sdk to compile against.
93 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080094 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090095
Paul Duffine25c6442019-10-11 13:50:28 +010096 // When targeting 1.9 and above, override the modules to use with --system,
97 // otherwise provides defaults libraries to add to the bootclasspath.
98 // Defaults to "none"
99 System_modules *string
100
Jiyong Park1e440682018-05-23 18:42:04 +0900101 Aidl struct {
102 // Top level directories to pass to aidl tool
103 Include_dirs []string
104
105 // Directories rooted at the Android.bp file to pass to aidl tool
106 Local_include_dirs []string
107 }
Nan Zhang357466b2018-04-17 17:38:36 -0700108
109 // If not blank, set the java version passed to javadoc as -source
110 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700111
112 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800113 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700114
Liz Kammer585cac22020-07-06 09:12:57 -0700115 // user customized droiddoc args. Deprecated, use flags instead.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700116 // Available variables for substitution:
117 //
118 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700119 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700120 Args *string
121
Liz Kammer585cac22020-07-06 09:12:57 -0700122 // user customized droiddoc args. Not compatible with property args.
123 // Available variables for substitution:
124 //
125 // $(location <label>): the path to the arg_files with name <label>
126 // $$: a literal $
127 Flags []string
128
Nan Zhang1598a9e2018-09-04 17:14:32 -0700129 // names of the output files used in args that will be generated
130 Out []string
Ramy Medhat2f99eec2020-06-13 17:38:27 -0400131
132 // If set, metalava is sandboxed to only read files explicitly specified on the command
133 // line. Defaults to false.
134 Sandbox *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800135}
136
Nan Zhang61819ce2018-05-04 18:49:16 -0700137type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900138 // path to the API txt file that the new API extracted from source code is checked
139 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800140 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700141
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900142 // path to the API txt file that the new @removed API extractd from source code is
143 // checked against. The path can be local to the module or from other module (via
144 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800145 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700146
Adrian Roos14f75a92019-08-12 17:54:09 +0200147 // If not blank, path to the baseline txt file for approved API check violations.
148 Baseline_file *string `android:"path"`
149
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900150 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700151 Args *string
152}
153
Nan Zhang581fd212018-01-10 16:06:12 -0800154type DroiddocProperties struct {
155 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800156 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800157
Nan Zhanga40da042018-08-01 12:48:00 -0700158 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800159 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800160
161 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800162 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800163
164 // proofread file contains all of the text content of the javadocs concatenated into one file,
165 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700166 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800167
168 // a todo file lists the program elements that are missing documentation.
169 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800170 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800171
172 // directory under current module source that provide additional resources (images).
173 Resourcesdir *string
174
175 // resources output directory under out/soong/.intermediates.
176 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800177
Steve Kim3666c702020-09-01 17:58:01 +0000178 // if set to true, collect the values used by the Dev tools and
179 // write them in files packaged with the SDK. Defaults to false.
180 Write_sdk_values *bool
181
Nan Zhange2ba5d42018-07-11 15:16:55 -0700182 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800183 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700184
185 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800186 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700187
Nan Zhang581fd212018-01-10 16:06:12 -0800188 // a list of files under current module source dir which contains known tags in Java sources.
189 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800190 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700191
Nan Zhang28c68b92018-03-13 16:17:01 -0700192 // the generated public API filename by Doclava.
193 Api_filename *string
194
Nan Zhang28c68b92018-03-13 16:17:01 -0700195 // the generated removed API filename by Doclava.
196 Removed_api_filename *string
197
Steve Kim3666c702020-09-01 17:58:01 +0000198 // the generated removed Dex API filename by Doclava.
199 Removed_dex_api_filename *string
200
201 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to false.
202 Create_stubs *bool
203
204 Check_api struct {
205 Last_released ApiToCheck
206
207 Current ApiToCheck
208
209 // do not perform API check against Last_released, in the case that both two specified API
210 // files by Last_released are modules which don't exist.
211 Ignore_missing_latest_api *bool `blueprint:"mutated"`
212 }
213
Nan Zhang1598a9e2018-09-04 17:14:32 -0700214 // if set to true, generate docs through Dokka instead of Doclava.
215 Dokka_enabled *bool
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000216
217 // Compat config XML. Generates compat change documentation if set.
218 Compat_config *string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700219}
220
221type DroidstubsProperties struct {
Nan Zhang199645c2018-09-19 12:40:06 -0700222 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700223 Api_filename *string
224
Nan Zhang199645c2018-09-19 12:40:06 -0700225 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700226 Removed_api_filename *string
227
Nan Zhang199645c2018-09-19 12:40:06 -0700228 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700229 Removed_dex_api_filename *string
230
Nan Zhang1598a9e2018-09-04 17:14:32 -0700231 Check_api struct {
232 Last_released ApiToCheck
233
234 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900235
Paul Duffin160fe412020-05-10 19:32:20 +0100236 // The java_sdk_library module generates references to modules (i.e. filegroups)
237 // from which information about the latest API version can be obtained. As those
238 // modules may not exist (e.g. because a previous version has not been released) it
239 // sets ignore_missing_latest_api=true on the droidstubs modules it creates so
240 // that droidstubs can ignore those references if the modules do not yet exist.
241 //
242 // If true then this will ignore module references for modules that do not exist
243 // in properties that supply the previous version of the API.
244 //
245 // There are two sets of those:
246 // * Api_file, Removed_api_file in check_api.last_released
247 // * New_since in check_api.api_lint.new_since
248 //
249 // The first two must be set as a pair, so either they should both exist or neither
250 // should exist - in which case when this property is true they are ignored. If one
251 // exists and the other does not then it is an error.
Inseob Kim38449af2019-02-28 14:24:05 +0900252 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Adrian Roos075eedc2019-10-10 12:07:03 +0200253
254 Api_lint struct {
255 Enabled *bool
256
257 // If set, performs api_lint on any new APIs not found in the given signature file
258 New_since *string `android:"path"`
259
260 // If not blank, path to the baseline txt file for approved API lint violations.
261 Baseline_file *string `android:"path"`
262 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 }
Nan Zhang79614d12018-04-19 18:03:39 -0700264
265 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800266 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700267
268 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700269 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700270
Pete Gillin77167902018-09-19 18:16:26 +0100271 // 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 -0700272 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700273
Pete Gillin77167902018-09-19 18:16:26 +0100274 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
275 Merge_inclusion_annotations_dirs []string
276
Pete Gillinc382a562018-11-14 18:45:46 +0000277 // a file containing a list of classes to do nullability validation for.
278 Validate_nullability_from_list *string
279
Pete Gillin581d6082018-10-22 15:55:04 +0100280 // a file containing expected warnings produced by validation of nullability annotations.
281 Check_nullability_warnings *string
282
Nan Zhang1598a9e2018-09-04 17:14:32 -0700283 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
284 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700285
Paul Duffin3ae29512020-04-08 18:18:03 +0100286 // if set to false then do not write out stubs. Defaults to true.
287 //
288 // TODO(b/146727827): Remove capability when we do not need to generate stubs and API separately.
289 Generate_stubs *bool
290
Nan Zhang9c69a122018-08-22 10:22:08 -0700291 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
292 Api_levels_annotations_enabled *bool
293
294 // the dirs which Metalava extracts API levels annotations from.
295 Api_levels_annotations_dirs []string
296
Liz Kammer3d894b72020-08-04 09:55:13 -0700297 // the filename which Metalava extracts API levels annotations from. Defaults to android.jar.
298 Api_levels_jar_filename *string
299
Nan Zhang9c69a122018-08-22 10:22:08 -0700300 // if set to true, collect the values used by the Dev tools and
301 // write them in files packaged with the SDK. Defaults to false.
302 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700303
304 // If set to true, .xml based public API file will be also generated, and
305 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
306 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800307}
308
Nan Zhanga40da042018-08-01 12:48:00 -0700309//
310// Common flags passed down to build rule
311//
312type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700313 bootClasspathArgs string
314 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700315 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700316 dokkaClasspathArgs string
317 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700318 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700319
Nan Zhanga40da042018-08-01 12:48:00 -0700320 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700321 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700322 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700323}
324
325func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
326 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
327 android.InitDefaultableModule(module)
328}
329
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200330func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
331 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
332 return false
333 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700334 return true
335 } else if String(apiToCheck.Api_file) != "" {
336 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
337 } else if String(apiToCheck.Removed_api_file) != "" {
338 panic("for " + apiVersionTag + " api_file has to be non-empty!")
339 }
340
341 return false
342}
343
Inseob Kim38449af2019-02-28 14:24:05 +0900344func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
345 api_file := String(apiToCheck.Api_file)
346 removed_api_file := String(apiToCheck.Removed_api_file)
347
348 api_module := android.SrcIsModule(api_file)
349 removed_api_module := android.SrcIsModule(removed_api_file)
350
351 if api_module == "" || removed_api_module == "" {
352 return
353 }
354
355 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
356 return
357 }
358
359 apiToCheck.Api_file = nil
360 apiToCheck.Removed_api_file = nil
361}
362
Paul Duffin3d1248c2020-04-09 00:10:17 +0100363// Used by xsd_config
Nan Zhang1598a9e2018-09-04 17:14:32 -0700364type ApiFilePath interface {
365 ApiFilePath() android.Path
366}
367
Paul Duffin0f8faff2020-05-20 16:18:00 +0100368type ApiStubsSrcProvider interface {
369 StubsSrcJar() android.Path
370}
371
Paul Duffin3d1248c2020-04-09 00:10:17 +0100372// Provider of information about API stubs, used by java_sdk_library.
373type ApiStubsProvider interface {
374 ApiFilePath
Paul Duffin1fd005d2020-04-09 01:08:11 +0100375 RemovedApiFilePath() android.Path
Paul Duffin0f8faff2020-05-20 16:18:00 +0100376
377 ApiStubsSrcProvider
Paul Duffin3d1248c2020-04-09 00:10:17 +0100378}
379
Nan Zhanga40da042018-08-01 12:48:00 -0700380//
381// Javadoc
382//
Nan Zhang581fd212018-01-10 16:06:12 -0800383type Javadoc struct {
384 android.ModuleBase
385 android.DefaultableModuleBase
386
387 properties JavadocProperties
388
389 srcJars android.Paths
390 srcFiles android.Paths
391 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700392 argFiles android.Paths
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400393 implicits android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700394
Liz Kammer585cac22020-07-06 09:12:57 -0700395 args []string
Nan Zhang581fd212018-01-10 16:06:12 -0800396
Nan Zhangccff0f72018-03-08 17:26:16 -0800397 docZip android.WritablePath
398 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800399}
400
Colin Cross41955e82019-05-29 14:40:35 -0700401func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
402 switch tag {
403 case "":
404 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700405 case ".docs.zip":
406 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700407 default:
408 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
409 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800410}
411
Colin Crossa3002fc2019-07-08 16:48:04 -0700412// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800413func JavadocFactory() android.Module {
414 module := &Javadoc{}
415
416 module.AddProperties(&module.properties)
417
418 InitDroiddocModule(module, android.HostAndDeviceSupported)
419 return module
420}
421
Colin Crossa3002fc2019-07-08 16:48:04 -0700422// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800423func JavadocHostFactory() android.Module {
424 module := &Javadoc{}
425
426 module.AddProperties(&module.properties)
427
428 InitDroiddocModule(module, android.HostSupported)
429 return module
430}
431
Colin Cross41955e82019-05-29 14:40:35 -0700432var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800433
Jiyong Park6a927c42020-01-21 02:03:43 +0900434func (j *Javadoc) sdkVersion() sdkSpec {
435 return sdkSpecFrom(String(j.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700436}
437
Paul Duffine25c6442019-10-11 13:50:28 +0100438func (j *Javadoc) systemModules() string {
439 return proptools.String(j.properties.System_modules)
440}
441
Jiyong Park6a927c42020-01-21 02:03:43 +0900442func (j *Javadoc) minSdkVersion() sdkSpec {
Colin Cross83bb3162018-06-25 15:48:06 -0700443 return j.sdkVersion()
444}
445
Jiyong Park6a927c42020-01-21 02:03:43 +0900446func (j *Javadoc) targetSdkVersion() sdkSpec {
Dan Willemsen419290a2018-10-31 15:28:47 -0700447 return j.sdkVersion()
448}
449
Nan Zhang581fd212018-01-10 16:06:12 -0800450func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
451 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100452 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Pete Gilline3d44b22020-06-29 11:28:51 +0100453 if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700454 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100455 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700456 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Pete Gilline3d44b22020-06-29 11:28:51 +0100457 ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800458 }
459 }
460
Colin Cross42d48b72018-08-29 14:10:52 -0700461 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800462}
463
Nan Zhanga40da042018-08-01 12:48:00 -0700464func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
465 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900466
Colin Cross3047fa22019-04-18 10:56:44 -0700467 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900468
469 return flags
470}
471
472func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700473 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900474
475 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
476 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
477
478 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700479 var deps android.Paths
480
Jiyong Park1e440682018-05-23 18:42:04 +0900481 if aidlPreprocess.Valid() {
482 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700483 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900484 } else {
485 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
486 }
487
488 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
489 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
490 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
491 flags = append(flags, "-I"+src.String())
492 }
493
Colin Cross3047fa22019-04-18 10:56:44 -0700494 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900495}
496
Jiyong Parkd90d7412019-08-20 22:49:19 +0900497// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900498func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700499 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900500
501 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700502 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900503
Jiyong Park1112c4c2019-08-16 21:12:10 +0900504 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
505
Jiyong Park1e440682018-05-23 18:42:04 +0900506 for _, srcFile := range srcFiles {
507 switch srcFile.Ext() {
508 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700509 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900510 case ".logtags":
511 javaFile := genLogtags(ctx, srcFile)
512 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900513 default:
514 outSrcFiles = append(outSrcFiles, srcFile)
515 }
516 }
517
Colin Crossc0806172019-06-14 18:51:47 -0700518 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
519 if len(aidlSrcs) > 0 {
520 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
521 outSrcFiles = append(outSrcFiles, srcJarFiles...)
522 }
523
Jiyong Park1e440682018-05-23 18:42:04 +0900524 return outSrcFiles
525}
526
Nan Zhang581fd212018-01-10 16:06:12 -0800527func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
528 var deps deps
529
Colin Cross83bb3162018-06-25 15:48:06 -0700530 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800531 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700532 ctx.AddMissingDependencies(sdkDep.bootclasspath)
533 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800534 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700535 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Anton Hansson26bf49b2020-02-08 20:26:29 +0000536 deps.aidlPreprocess = sdkDep.aidl
537 } else {
538 deps.aidlPreprocess = sdkDep.aidl
Nan Zhang581fd212018-01-10 16:06:12 -0800539 }
540
541 ctx.VisitDirectDeps(func(module android.Module) {
542 otherName := ctx.OtherModuleName(module)
543 tag := ctx.OtherModuleDependencyTag(module)
544
Colin Cross2d24c1b2018-05-23 10:59:18 -0700545 switch tag {
546 case bootClasspathTag:
547 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800548 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Paul Duffin83a2d962019-11-19 19:44:10 +0000549 } else if sm, ok := module.(SystemModulesProvider); ok {
Paul Duffine25c6442019-10-11 13:50:28 +0100550 // A system modules dependency has been added to the bootclasspath
551 // so add its libs to the bootclasspath.
Paul Duffin83a2d962019-11-19 19:44:10 +0000552 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700553 } else {
554 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
555 }
556 case libTag:
557 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800558 case SdkLibraryDependency:
Paul Duffin649dadf2020-05-26 11:42:13 +0100559 deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700560 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900561 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900562 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700563 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800564 checkProducesJars(ctx, dep)
565 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800566 default:
567 ctx.ModuleErrorf("depends on non-java module %q", otherName)
568 }
Colin Cross6cef4812019-10-17 14:23:50 -0700569 case java9LibTag:
570 switch dep := module.(type) {
571 case Dependency:
572 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...)
573 default:
574 ctx.ModuleErrorf("depends on non-java module %q", otherName)
575 }
Nan Zhang357466b2018-04-17 17:38:36 -0700576 case systemModulesTag:
577 if deps.systemModules != nil {
578 panic("Found two system module dependencies")
579 }
Paul Duffin83a2d962019-11-19 19:44:10 +0000580 sm := module.(SystemModulesProvider)
581 outputDir, outputDeps := sm.OutputDirAndDeps()
582 deps.systemModules = &systemModules{outputDir, outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800583 }
584 })
585 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
586 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800587 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400588 j.implicits = append(j.implicits, srcFiles...)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900589
590 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
591 if filterPackages == nil {
592 return srcs
593 }
594 filtered := []android.Path{}
595 for _, src := range srcs {
596 if src.Ext() != ".java" {
597 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
598 // but otherwise metalava emits stub sources having references to the generated AIDL classes
599 // in filtered-out pacages (e.g. com.android.internal.*).
600 // TODO(b/141149570) We need to fix this by introducing default private constructors or
601 // fixing metalava to not emit constructors having references to unknown classes.
602 filtered = append(filtered, src)
603 continue
604 }
605 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800606 if android.HasAnyPrefix(packageName, filterPackages) {
607 filtered = append(filtered, src)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900608 }
609 }
610 return filtered
611 }
612 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
613
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400614 // While metalava needs package html files, it does not need them to be explicit on the command
615 // line. More importantly, the metalava rsp file is also used by the subsequent jdiff action if
616 // jdiff_enabled=true. javadoc complains if it receives html files on the command line. The filter
617 // below excludes html files from the rsp file for both metalava and jdiff. Note that the html
618 // files are still included as implicit inputs for successful remote execution and correct
619 // incremental builds.
620 filterHtml := func(srcs []android.Path) []android.Path {
621 filtered := []android.Path{}
622 for _, src := range srcs {
623 if src.Ext() == ".html" {
624 continue
625 }
626 filtered = append(filtered, src)
627 }
628 return filtered
629 }
630 srcFiles = filterHtml(srcFiles)
631
Liz Kammer585cac22020-07-06 09:12:57 -0700632 aidlFlags := j.collectAidlFlags(ctx, deps)
633 srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
Nan Zhang581fd212018-01-10 16:06:12 -0800634
635 // srcs may depend on some genrule output.
636 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800637 j.srcJars = append(j.srcJars, deps.srcJars...)
638
Nan Zhang581fd212018-01-10 16:06:12 -0800639 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800640 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800641
Steve Kim3666c702020-09-01 17:58:01 +0000642 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
643 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
Nan Zhang581fd212018-01-10 16:06:12 -0800644 }
Steve Kim3666c702020-09-01 17:58:01 +0000645 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800646
Colin Cross8a497952019-03-05 22:25:09 -0800647 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000648 argFilesMap := map[string]string{}
649 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700650
Paul Duffin99e4a502019-02-11 15:38:42 +0000651 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800652 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000653 if _, exists := argFilesMap[label]; !exists {
654 argFilesMap[label] = strings.Join(paths.Strings(), " ")
655 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700656 } else {
657 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000658 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700659 }
660 }
661
Liz Kammer585cac22020-07-06 09:12:57 -0700662 var argsPropertyName string
663 flags := make([]string, 0)
664 if j.properties.Args != nil && j.properties.Flags != nil {
665 ctx.PropertyErrorf("args", "flags is set. Cannot set args")
666 } else if args := proptools.String(j.properties.Args); args != "" {
667 flags = append(flags, args)
668 argsPropertyName = "args"
669 } else {
670 flags = append(flags, j.properties.Flags...)
671 argsPropertyName = "flags"
672 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700673
Liz Kammer585cac22020-07-06 09:12:57 -0700674 for _, flag := range flags {
675 args, err := android.Expand(flag, func(name string) (string, error) {
676 if strings.HasPrefix(name, "location ") {
677 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
678 if paths, ok := argFilesMap[label]; ok {
679 return paths, nil
680 } else {
681 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
682 label, strings.Join(argFileLabels, ", "))
683 }
684 } else if name == "genDir" {
685 return android.PathForModuleGen(ctx).String(), nil
686 }
687 return "", fmt.Errorf("unknown variable '$(%s)'", name)
688 })
689
690 if err != nil {
691 ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
692 }
693 j.args = append(j.args, args)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700694 }
695
Nan Zhang581fd212018-01-10 16:06:12 -0800696 return deps
697}
698
699func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
700 j.addDeps(ctx)
701}
702
703func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
704 deps := j.collectDeps(ctx)
705
Colin Crossdaa4c672019-07-15 22:53:46 -0700706 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800707
Colin Crossdaa4c672019-07-15 22:53:46 -0700708 outDir := android.PathForModuleOut(ctx, "out")
709 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
710
711 j.stubsSrcJar = nil
712
713 rule := android.NewRuleBuilder()
714
715 rule.Command().Text("rm -rf").Text(outDir.String())
716 rule.Command().Text("mkdir -p").Text(outDir.String())
717
718 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700719
Colin Cross83bb3162018-06-25 15:48:06 -0700720 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800721
Colin Crossdaa4c672019-07-15 22:53:46 -0700722 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
723 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800724
Colin Cross1e743852019-10-28 11:37:20 -0700725 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700726 Flag("-J-Xmx1024m").
727 Flag("-XDignore.symbol.file").
728 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800729
Colin Crossdaa4c672019-07-15 22:53:46 -0700730 rule.Command().
731 BuiltTool(ctx, "soong_zip").
732 Flag("-write_if_changed").
733 Flag("-d").
734 FlagWithOutput("-o ", j.docZip).
735 FlagWithArg("-C ", outDir.String()).
736 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700737
Colin Crossdaa4c672019-07-15 22:53:46 -0700738 rule.Restat()
739
740 zipSyncCleanupCmd(rule, srcJarDir)
741
742 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800743}
744
Nan Zhanga40da042018-08-01 12:48:00 -0700745//
746// Droiddoc
747//
748type Droiddoc struct {
749 Javadoc
750
Steve Kim3666c702020-09-01 17:58:01 +0000751 properties DroiddocProperties
752 apiFile android.WritablePath
753 privateApiFile android.WritablePath
754 removedApiFile android.WritablePath
755 removedDexApiFile android.WritablePath
756
757 checkCurrentApiTimestamp android.WritablePath
758 updateCurrentApiTimestamp android.WritablePath
759 checkLastReleasedApiTimestamp android.WritablePath
760
761 apiFilePath android.Path
Nan Zhanga40da042018-08-01 12:48:00 -0700762}
763
Colin Crossa3002fc2019-07-08 16:48:04 -0700764// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700765func DroiddocFactory() android.Module {
766 module := &Droiddoc{}
767
768 module.AddProperties(&module.properties,
769 &module.Javadoc.properties)
770
771 InitDroiddocModule(module, android.HostAndDeviceSupported)
772 return module
773}
774
Colin Crossa3002fc2019-07-08 16:48:04 -0700775// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700776func DroiddocHostFactory() android.Module {
777 module := &Droiddoc{}
778
779 module.AddProperties(&module.properties,
780 &module.Javadoc.properties)
781
782 InitDroiddocModule(module, android.HostSupported)
783 return module
784}
785
Steve Kim3666c702020-09-01 17:58:01 +0000786func (d *Droiddoc) ApiFilePath() android.Path {
787 return d.apiFilePath
Nan Zhanga40da042018-08-01 12:48:00 -0700788}
789
Nan Zhang581fd212018-01-10 16:06:12 -0800790func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
791 d.Javadoc.addDeps(ctx)
792
Steve Kim3666c702020-09-01 17:58:01 +0000793 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
794 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
795 }
796
Nan Zhang79614d12018-04-19 18:03:39 -0700797 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800798 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
799 }
Nan Zhang581fd212018-01-10 16:06:12 -0800800}
801
Colin Crossab054432019-07-15 16:13:59 -0700802func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Colin Cross2a2e0db2020-02-21 16:55:46 -0800803 buildNumberFile := ctx.Config().BuildNumberFile(ctx)
Nan Zhang443fa522018-08-20 20:58:28 -0700804 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
805 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
806 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700807 cmd.FlagWithArg("-source ", "1.8").
808 Flag("-J-Xmx1600m").
809 Flag("-J-XX:-OmitStackTraceInFastThrow").
810 Flag("-XDignore.symbol.file").
811 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
812 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
Colin Cross2a2e0db2020-02-21 16:55:46 -0800813 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
Elliott Hughes26bce342019-09-12 15:05:13 -0700814 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 -0700815
Nan Zhanga40da042018-08-01 12:48:00 -0700816 if String(d.properties.Custom_template) == "" {
817 // TODO: This is almost always droiddoc-templates-sdk
818 ctx.PropertyErrorf("custom_template", "must specify a template")
819 }
820
821 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700822 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700823 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700824 } else {
Paul Duffin884363e2019-12-19 10:21:09 +0000825 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
Nan Zhanga40da042018-08-01 12:48:00 -0700826 }
827 })
828
829 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700830 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
831 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
832 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700833 }
834
835 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700836 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
837 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
838 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700839 }
840
841 if len(d.properties.Html_dirs) > 2 {
842 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
843 }
844
Colin Cross8a497952019-03-05 22:25:09 -0800845 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700846 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700847
Colin Crossab054432019-07-15 16:13:59 -0700848 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700849
850 if String(d.properties.Proofread_file) != "" {
851 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700852 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700853 }
854
855 if String(d.properties.Todo_file) != "" {
856 // tricky part:
857 // we should not compute full path for todo_file through PathForModuleOut().
858 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700859 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
860 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700861 }
862
863 if String(d.properties.Resourcesdir) != "" {
864 // TODO: should we add files under resourcesDir to the implicits? It seems that
865 // resourcesDir is one sub dir of htmlDir
866 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700867 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700868 }
869
870 if String(d.properties.Resourcesoutdir) != "" {
871 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700872 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700873 }
Nan Zhanga40da042018-08-01 12:48:00 -0700874}
875
Steve Kim3666c702020-09-01 17:58:01 +0000876func (d *Droiddoc) createStubs() bool {
877 return BoolDefault(d.properties.Create_stubs, false)
878}
879
880func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
881 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
882 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
883 String(d.properties.Api_filename) != "" {
884
885 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
886 cmd.FlagWithOutput("-api ", d.apiFile)
887 d.apiFilePath = d.apiFile
888 }
889
890 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
891 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
892 String(d.properties.Removed_api_filename) != "" {
893 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
894 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
895 }
896
897 if String(d.properties.Removed_dex_api_filename) != "" {
898 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
899 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
900 }
901
902 if d.createStubs() {
903 cmd.FlagWithArg("-stubs ", stubsDir.String())
904 }
905
906 if Bool(d.properties.Write_sdk_values) {
907 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
908 }
909}
910
Colin Crossab054432019-07-15 16:13:59 -0700911func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700912 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700913 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
914 rule.Command().Text("cp").
915 Input(staticDocIndexRedirect).
916 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700917 }
918
919 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700920 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
921 rule.Command().Text("cp").
922 Input(staticDocProperties).
923 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700924 }
Nan Zhanga40da042018-08-01 12:48:00 -0700925}
926
Colin Crossab054432019-07-15 16:13:59 -0700927func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700928 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700929
930 cmd := rule.Command().
931 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
932 Flag(config.JavacVmFlags).
933 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700934 FlagWithRspFileInputList("@", srcs).
935 FlagWithInput("@", srcJarList)
936
Colin Crossab054432019-07-15 16:13:59 -0700937 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
938 // based stubs generation.
939 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
940 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
941 // the correct package name base path.
942 if len(sourcepaths) > 0 {
943 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
944 } else {
945 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
946 }
947
948 cmd.FlagWithArg("-d ", outDir.String()).
949 Flag("-quiet")
950
951 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700952}
953
Colin Crossdaa4c672019-07-15 22:53:46 -0700954func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
955 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
956 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
957
958 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
959
960 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
961 cmd.Flag(flag).Implicits(deps)
962
963 cmd.FlagWithArg("--patch-module ", "java.base=.")
964
965 if len(classpath) > 0 {
966 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
967 }
968
969 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700970}
971
Colin Crossdaa4c672019-07-15 22:53:46 -0700972func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
973 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
974 sourcepaths android.Paths) *android.RuleBuilderCommand {
975
976 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
977
978 if len(bootclasspath) == 0 && ctx.Device() {
979 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
980 // ensure java does not fall back to the default bootclasspath.
981 cmd.FlagWithArg("-bootclasspath ", `""`)
982 } else if len(bootclasspath) > 0 {
983 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
984 }
985
986 if len(classpath) > 0 {
987 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
988 }
989
990 return cmd
991}
992
Colin Crossab054432019-07-15 16:13:59 -0700993func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
994 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995
Colin Crossab054432019-07-15 16:13:59 -0700996 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
997 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
998
999 return rule.Command().
1000 BuiltTool(ctx, "dokka").
1001 Flag(config.JavacVmFlags).
1002 Flag(srcJarDir.String()).
1003 FlagWithInputList("-classpath ", dokkaClasspath, ":").
1004 FlagWithArg("-format ", "dac").
1005 FlagWithArg("-dacRoot ", "/reference/kotlin").
1006 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001007}
1008
1009func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1010 deps := d.Javadoc.collectDeps(ctx)
1011
Colin Crossdaa4c672019-07-15 22:53:46 -07001012 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Steve Kim3666c702020-09-01 17:58:01 +00001013 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Colin Crossdaa4c672019-07-15 22:53:46 -07001014
Nan Zhang1598a9e2018-09-04 17:14:32 -07001015 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1016 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
Steve Kim3666c702020-09-01 17:58:01 +00001017 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1018 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001019
Colin Crossab054432019-07-15 16:13:59 -07001020 outDir := android.PathForModuleOut(ctx, "out")
1021 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
Steve Kim3666c702020-09-01 17:58:01 +00001022 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001023
Colin Crossab054432019-07-15 16:13:59 -07001024 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -07001025
Steve Kim3666c702020-09-01 17:58:01 +00001026 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1027 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
1028
Colin Crossab054432019-07-15 16:13:59 -07001029 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1030
1031 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -07001032 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -07001033 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001034 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -07001035 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001036 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001037 }
1038
Steve Kim3666c702020-09-01 17:58:01 +00001039 d.stubsFlags(ctx, cmd, stubsDir)
1040
Liz Kammer585cac22020-07-06 09:12:57 -07001041 cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
Colin Crossab054432019-07-15 16:13:59 -07001042
Mathew Inwoodabd49ab2019-12-19 14:27:08 +00001043 if d.properties.Compat_config != nil {
1044 compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
1045 cmd.FlagWithInput("-compatconfig ", compatConfig)
1046 }
1047
Colin Crossab054432019-07-15 16:13:59 -07001048 var desc string
1049 if Bool(d.properties.Dokka_enabled) {
1050 desc = "dokka"
1051 } else {
1052 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1053
1054 for _, o := range d.Javadoc.properties.Out {
1055 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1056 }
1057
1058 d.postDoclavaCmds(ctx, rule)
1059 desc = "doclava"
1060 }
1061
1062 rule.Command().
1063 BuiltTool(ctx, "soong_zip").
1064 Flag("-write_if_changed").
1065 Flag("-d").
1066 FlagWithOutput("-o ", d.docZip).
1067 FlagWithArg("-C ", outDir.String()).
1068 FlagWithArg("-D ", outDir.String())
1069
Steve Kim3666c702020-09-01 17:58:01 +00001070 rule.Command().
1071 BuiltTool(ctx, "soong_zip").
1072 Flag("-write_if_changed").
1073 Flag("-jar").
1074 FlagWithOutput("-o ", d.stubsSrcJar).
1075 FlagWithArg("-C ", stubsDir.String()).
1076 FlagWithArg("-D ", stubsDir.String())
1077
Colin Crossab054432019-07-15 16:13:59 -07001078 rule.Restat()
1079
1080 zipSyncCleanupCmd(rule, srcJarDir)
1081
1082 rule.Build(pctx, ctx, "javadoc", desc)
Steve Kim3666c702020-09-01 17:58:01 +00001083
1084 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
1085 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1086 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
1087
1088 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1089
1090 rule := android.NewRuleBuilder()
1091
1092 rule.Command().Text("( true")
1093
1094 rule.Command().
1095 BuiltTool(ctx, "apicheck").
1096 Flag("-JXmx1024m").
1097 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1098 OptionalFlag(d.properties.Check_api.Current.Args).
1099 Input(apiFile).
1100 Input(d.apiFile).
1101 Input(removedApiFile).
1102 Input(d.removedApiFile)
1103
1104 msg := fmt.Sprintf(`\n******************************\n`+
1105 `You have tried to change the API from what has been previously approved.\n\n`+
1106 `To make these errors go away, you have two choices:\n`+
1107 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1108 ` errors above.\n\n`+
1109 ` 2. You can update current.txt by executing the following command:\n`+
1110 ` make %s-update-current-api\n\n`+
1111 ` To submit the revised current.txt to the main Android repository,\n`+
1112 ` you will need approval.\n`+
1113 `******************************\n`, ctx.ModuleName())
1114
1115 rule.Command().
1116 Text("touch").Output(d.checkCurrentApiTimestamp).
1117 Text(") || (").
1118 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1119 Text("; exit 38").
1120 Text(")")
1121
1122 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
1123
1124 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1125
1126 // update API rule
1127 rule = android.NewRuleBuilder()
1128
1129 rule.Command().Text("( true")
1130
1131 rule.Command().
1132 Text("cp").Flag("-f").
1133 Input(d.apiFile).Flag(apiFile.String())
1134
1135 rule.Command().
1136 Text("cp").Flag("-f").
1137 Input(d.removedApiFile).Flag(removedApiFile.String())
1138
1139 msg = "failed to update public API"
1140
1141 rule.Command().
1142 Text("touch").Output(d.updateCurrentApiTimestamp).
1143 Text(") || (").
1144 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1145 Text("; exit 38").
1146 Text(")")
1147
1148 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
1149 }
1150
1151 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
1152 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1153 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
1154
1155 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1156
1157 rule := android.NewRuleBuilder()
1158
1159 rule.Command().
1160 Text("(").
1161 BuiltTool(ctx, "apicheck").
1162 Flag("-JXmx1024m").
1163 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1164 OptionalFlag(d.properties.Check_api.Last_released.Args).
1165 Input(apiFile).
1166 Input(d.apiFile).
1167 Input(removedApiFile).
1168 Input(d.removedApiFile)
1169
1170 msg := `\n******************************\n` +
1171 `You have tried to change the API from what has been previously released in\n` +
1172 `an SDK. Please fix the errors listed above.\n` +
1173 `******************************\n`
1174
1175 rule.Command().
1176 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1177 Text(") || (").
1178 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1179 Text("; exit 38").
1180 Text(")")
1181
1182 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
1183 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001184}
1185
1186//
1187// Droidstubs
1188//
1189type Droidstubs struct {
1190 Javadoc
Paul Duffin91547182019-11-12 19:39:36 +00001191 android.SdkBase
Nan Zhang1598a9e2018-09-04 17:14:32 -07001192
Pete Gillin581d6082018-10-22 15:55:04 +01001193 properties DroidstubsProperties
1194 apiFile android.WritablePath
1195 apiXmlFile android.WritablePath
1196 lastReleasedApiXmlFile android.WritablePath
Pete Gillin581d6082018-10-22 15:55:04 +01001197 privateApiFile android.WritablePath
Pete Gillin581d6082018-10-22 15:55:04 +01001198 removedApiFile android.WritablePath
1199 removedDexApiFile android.WritablePath
Pete Gillin581d6082018-10-22 15:55:04 +01001200 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001201
1202 checkCurrentApiTimestamp android.WritablePath
1203 updateCurrentApiTimestamp android.WritablePath
1204 checkLastReleasedApiTimestamp android.WritablePath
Adrian Roos075eedc2019-10-10 12:07:03 +02001205 apiLintTimestamp android.WritablePath
Adrian Roos3b8f1cd2019-11-01 13:42:39 +01001206 apiLintReport android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001207
Pete Gillin581d6082018-10-22 15:55:04 +01001208 checkNullabilityWarningsTimestamp android.WritablePath
1209
Nan Zhang1598a9e2018-09-04 17:14:32 -07001210 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001211 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001212
1213 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001214
1215 jdiffDocZip android.WritablePath
1216 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0f599032019-10-10 19:29:11 +01001217
1218 metadataZip android.WritablePath
1219 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001220}
1221
Colin Crossa3002fc2019-07-08 16:48:04 -07001222// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1223// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1224// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001225func DroidstubsFactory() android.Module {
1226 module := &Droidstubs{}
1227
1228 module.AddProperties(&module.properties,
1229 &module.Javadoc.properties)
1230
1231 InitDroiddocModule(module, android.HostAndDeviceSupported)
Paul Duffin91547182019-11-12 19:39:36 +00001232 android.InitSdkAwareModule(module)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001233 return module
1234}
1235
Colin Crossa3002fc2019-07-08 16:48:04 -07001236// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1237// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1238// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1239// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001240func DroidstubsHostFactory() android.Module {
1241 module := &Droidstubs{}
1242
1243 module.AddProperties(&module.properties,
1244 &module.Javadoc.properties)
1245
1246 InitDroiddocModule(module, android.HostSupported)
1247 return module
1248}
1249
Colin Cross014489c2020-06-02 20:09:13 -07001250func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
1251 switch tag {
1252 case "":
1253 return android.Paths{d.stubsSrcJar}, nil
1254 case ".docs.zip":
1255 return android.Paths{d.docZip}, nil
1256 case ".annotations.zip":
1257 return android.Paths{d.annotationsZip}, nil
1258 case ".api_versions.xml":
1259 return android.Paths{d.apiVersionsXml}, nil
1260 default:
1261 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
1262 }
1263}
1264
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265func (d *Droidstubs) ApiFilePath() android.Path {
1266 return d.apiFilePath
1267}
1268
Paul Duffin1fd005d2020-04-09 01:08:11 +01001269func (d *Droidstubs) RemovedApiFilePath() android.Path {
1270 return d.removedApiFile
1271}
1272
Paul Duffin3d1248c2020-04-09 00:10:17 +01001273func (d *Droidstubs) StubsSrcJar() android.Path {
1274 return d.stubsSrcJar
1275}
1276
Nan Zhang1598a9e2018-09-04 17:14:32 -07001277func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1278 d.Javadoc.addDeps(ctx)
1279
Paul Duffin160fe412020-05-10 19:32:20 +01001280 // If requested clear any properties that provide information about the latest version
1281 // of an API and which reference non-existent modules.
Inseob Kim38449af2019-02-28 14:24:05 +09001282 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1283 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
Paul Duffin160fe412020-05-10 19:32:20 +01001284
1285 // If the new_since references a module, e.g. :module-latest-api and the module
1286 // does not exist then clear it.
1287 newSinceSrc := d.properties.Check_api.Api_lint.New_since
1288 newSinceSrcModule := android.SrcIsModule(proptools.String(newSinceSrc))
1289 if newSinceSrcModule != "" && !ctx.OtherModuleExists(newSinceSrcModule) {
1290 d.properties.Check_api.Api_lint.New_since = nil
1291 }
Inseob Kim38449af2019-02-28 14:24:05 +09001292 }
1293
Nan Zhang1598a9e2018-09-04 17:14:32 -07001294 if len(d.properties.Merge_annotations_dirs) != 0 {
1295 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1296 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1297 }
1298 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001299
Pete Gillin77167902018-09-19 18:16:26 +01001300 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1301 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1302 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1303 }
1304 }
1305
Nan Zhang9c69a122018-08-22 10:22:08 -07001306 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1307 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1308 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1309 }
1310 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001311}
1312
Paul Duffin3ae29512020-04-08 18:18:03 +01001313func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001314 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1315 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001316 String(d.properties.Api_filename) != "" {
1317 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001318 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001319 d.apiFilePath = d.apiFile
1320 }
1321
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001322 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1323 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001324 String(d.properties.Removed_api_filename) != "" {
1325 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001326 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001327 }
1328
Nan Zhang1598a9e2018-09-04 17:14:32 -07001329 if String(d.properties.Removed_dex_api_filename) != "" {
1330 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001331 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001332 }
1333
Nan Zhang9c69a122018-08-22 10:22:08 -07001334 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0f599032019-10-10 19:29:11 +01001335 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1336 cmd.FlagWithArg("--sdk-values ", d.metadataDir.String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001337 }
1338
Paul Duffin3ae29512020-04-08 18:18:03 +01001339 if stubsDir.Valid() {
1340 if Bool(d.properties.Create_doc_stubs) {
1341 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
1342 } else {
1343 cmd.FlagWithArg("--stubs ", stubsDir.String())
1344 cmd.Flag("--exclude-documentation-from-stubs")
1345 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001346 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001347}
1348
Colin Cross33961b52019-07-11 11:01:22 -07001349func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001350 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001351 cmd.Flag("--include-annotations")
1352
Pete Gillinc382a562018-11-14 18:45:46 +00001353 validatingNullability :=
Liz Kammer585cac22020-07-06 09:12:57 -07001354 android.InList("--validate-nullability-from-merged-stubs", d.Javadoc.args) ||
Pete Gillinc382a562018-11-14 18:45:46 +00001355 String(d.properties.Validate_nullability_from_list) != ""
Paul Duffin13a9dd62019-11-04 10:26:47 +00001356
Pete Gillina262c052018-09-14 14:25:48 +01001357 migratingNullability := String(d.properties.Previous_api) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001358 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001359 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001360 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001361 }
Colin Cross33961b52019-07-11 11:01:22 -07001362
Pete Gillinc382a562018-11-14 18:45:46 +00001363 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001364 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001365 }
Colin Cross33961b52019-07-11 11:01:22 -07001366
Pete Gillina262c052018-09-14 14:25:48 +01001367 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001368 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001369 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001370 }
Nan Zhanga40da042018-08-01 12:48:00 -07001371
1372 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001373 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001374
Anton Hansson9d7c3fb2020-05-21 10:11:31 +01001375 if len(d.properties.Merge_annotations_dirs) != 0 {
1376 d.mergeAnnoDirFlags(ctx, cmd)
Nan Zhanga40da042018-08-01 12:48:00 -07001377 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001378
Colin Cross33961b52019-07-11 11:01:22 -07001379 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1380 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1381 FlagWithArg("--hide ", "SuperfluousPrefix").
1382 FlagWithArg("--hide ", "AnnotationExtraction")
1383 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001384}
1385
Colin Cross33961b52019-07-11 11:01:22 -07001386func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1387 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1388 if t, ok := m.(*ExportedDroiddocDir); ok {
1389 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1390 } else {
1391 ctx.PropertyErrorf("merge_annotations_dirs",
1392 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1393 }
1394 })
1395}
1396
1397func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001398 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1399 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001400 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001401 } else {
1402 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1403 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1404 }
1405 })
Nan Zhanga40da042018-08-01 12:48:00 -07001406}
1407
Colin Cross33961b52019-07-11 11:01:22 -07001408func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Liz Kammer3d894b72020-08-04 09:55:13 -07001409 if !Bool(d.properties.Api_levels_annotations_enabled) {
1410 return
Nan Zhang9c69a122018-08-22 10:22:08 -07001411 }
Liz Kammer3d894b72020-08-04 09:55:13 -07001412
1413 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1414
1415 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1416 ctx.PropertyErrorf("api_levels_annotations_dirs",
1417 "has to be non-empty if api levels annotations was enabled!")
1418 }
1419
1420 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1421 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1422 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1423 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
1424
1425 filename := proptools.StringDefault(d.properties.Api_levels_jar_filename, "android.jar")
1426
1427 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1428 if t, ok := m.(*ExportedDroiddocDir); ok {
1429 for _, dep := range t.deps {
1430 if strings.HasSuffix(dep.String(), filename) {
1431 cmd.Implicit(dep)
1432 }
1433 }
1434 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/"+filename)
1435 } else {
1436 ctx.PropertyErrorf("api_levels_annotations_dirs",
1437 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1438 }
1439 })
Nan Zhang9c69a122018-08-22 10:22:08 -07001440}
1441
Colin Cross33961b52019-07-11 11:01:22 -07001442func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Dan Willemsen9f435972020-05-28 15:28:00 -07001443 if Bool(d.properties.Jdiff_enabled) && d.apiFile != nil {
Nan Zhang71bbe632018-09-17 14:32:21 -07001444 if d.apiFile.String() == "" {
1445 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1446 }
1447
1448 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001449 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001450
1451 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1452 ctx.PropertyErrorf("check_api.last_released.api_file",
1453 "has to be non-empty if jdiff was enabled!")
1454 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001455
Colin Cross33961b52019-07-11 11:01:22 -07001456 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001457 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001458 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1459 }
1460}
Nan Zhang71bbe632018-09-17 14:32:21 -07001461
Colin Cross1e743852019-10-28 11:37:20 -07001462func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001463 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths, implicitsRsp android.WritablePath, sandbox bool) *android.RuleBuilderCommand {
Colin Cross8b8bec32019-11-15 13:18:43 -08001464 // Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
1465 rule.HighMem()
Ramy Medhat427683c2020-04-30 03:08:37 -04001466 cmd := rule.Command()
1467 if ctx.Config().IsEnvTrue("RBE_METALAVA") {
1468 rule.Remoteable(android.RemoteRuleSupports{RBE: true})
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001469 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "metalava")
1470 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
1471 labels := map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"}
1472 if !sandbox {
1473 execStrategy = remoteexec.LocalExecStrategy
1474 labels["shallow"] = "true"
Ramy Medhat427683c2020-04-30 03:08:37 -04001475 }
1476 inputs := []string{android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "metalava.jar").String()}
1477 if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" {
1478 inputs = append(inputs, strings.Split(v, ",")...)
1479 }
1480 cmd.Text((&remoteexec.REParams{
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001481 Labels: labels,
Ramy Medhat427683c2020-04-30 03:08:37 -04001482 ExecStrategy: execStrategy,
1483 Inputs: inputs,
Ramy Medhatc8d60bc2020-06-04 01:54:07 -04001484 RSPFile: implicitsRsp.String(),
Ramy Medhat427683c2020-04-30 03:08:37 -04001485 ToolchainInputs: []string{config.JavaCmd(ctx).String()},
1486 Platform: map[string]string{remoteexec.PoolKey: pool},
1487 }).NoVarTemplate(ctx.Config()))
1488 }
1489
1490 cmd.BuiltTool(ctx, "metalava").
Colin Cross33961b52019-07-11 11:01:22 -07001491 Flag(config.JavacVmFlags).
1492 FlagWithArg("-encoding ", "UTF-8").
Colin Cross1e743852019-10-28 11:37:20 -07001493 FlagWithArg("-source ", javaVersion.String()).
Colin Cross33961b52019-07-11 11:01:22 -07001494 FlagWithRspFileInputList("@", srcs).
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001495 FlagWithInput("@", srcJarList)
1496
1497 if javaHome := ctx.Config().Getenv("ANDROID_JAVA_HOME"); javaHome != "" {
1498 cmd.Implicit(android.PathForSource(ctx, javaHome))
1499 }
1500
1501 if sandbox {
1502 cmd.FlagWithOutput("--strict-input-files ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
1503 } else {
1504 cmd.FlagWithOutput("--strict-input-files:warn ", android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"violations.txt"))
1505 }
Ramy Medhatc8d60bc2020-06-04 01:54:07 -04001506
Colin Cross238c1f32020-06-07 16:58:18 -07001507 if implicitsRsp != nil {
Ramy Medhatc8d60bc2020-06-04 01:54:07 -04001508 cmd.FlagWithArg("--strict-input-files-exempt ", "@"+implicitsRsp.String())
1509 }
Colin Cross33961b52019-07-11 11:01:22 -07001510
1511 if len(bootclasspath) > 0 {
1512 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001513 }
1514
Colin Cross33961b52019-07-11 11:01:22 -07001515 if len(classpath) > 0 {
1516 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1517 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001518
Colin Cross33961b52019-07-11 11:01:22 -07001519 if len(sourcepaths) > 0 {
1520 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1521 } else {
1522 cmd.FlagWithArg("-sourcepath ", `""`)
1523 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001524
Colin Cross33961b52019-07-11 11:01:22 -07001525 cmd.Flag("--no-banner").
1526 Flag("--color").
1527 Flag("--quiet").
Makoto Onuki0df103a2020-07-17 15:11:24 -07001528 Flag("--format=v2").
1529 FlagWithArg("--repeat-errors-max ", "10").
1530 FlagWithArg("--hide ", "UnresolvedImport")
Nan Zhang86d2d552018-08-09 15:33:27 -07001531
Colin Cross33961b52019-07-11 11:01:22 -07001532 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001533}
1534
Nan Zhang1598a9e2018-09-04 17:14:32 -07001535func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001536 deps := d.Javadoc.collectDeps(ctx)
1537
1538 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001539
Colin Cross33961b52019-07-11 11:01:22 -07001540 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001541
Colin Cross33961b52019-07-11 11:01:22 -07001542 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
Nan Zhang71bbe632018-09-17 14:32:21 -07001543
Colin Cross33961b52019-07-11 11:01:22 -07001544 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001545
Paul Duffin3ae29512020-04-08 18:18:03 +01001546 generateStubs := BoolDefault(d.properties.Generate_stubs, true)
1547 var stubsDir android.OptionalPath
1548 if generateStubs {
1549 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
1550 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "stubsDir"))
1551 rule.Command().Text("rm -rf").Text(stubsDir.String())
1552 rule.Command().Text("mkdir -p").Text(stubsDir.String())
1553 }
Nan Zhanga40da042018-08-01 12:48:00 -07001554
Colin Cross33961b52019-07-11 11:01:22 -07001555 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1556
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001557 implicitsRsp := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"implicits.rsp")
1558
Colin Cross33961b52019-07-11 11:01:22 -07001559 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001560 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths, implicitsRsp,
1561 Bool(d.Javadoc.properties.Sandbox))
1562 cmd.Implicits(d.Javadoc.implicits)
Colin Cross33961b52019-07-11 11:01:22 -07001563
1564 d.stubsFlags(ctx, cmd, stubsDir)
1565
1566 d.annotationsFlags(ctx, cmd)
1567 d.inclusionAnnotationsFlags(ctx, cmd)
1568 d.apiLevelsAnnotationsFlags(ctx, cmd)
1569 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001570
Liz Kammer585cac22020-07-06 09:12:57 -07001571 if android.InList("--generate-documentation", d.Javadoc.args) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001572 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1573 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1574 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
Liz Kammer585cac22020-07-06 09:12:57 -07001575 d.Javadoc.args = append(d.Javadoc.args, "-nodocs")
Nan Zhang79614d12018-04-19 18:03:39 -07001576 }
Colin Cross33961b52019-07-11 11:01:22 -07001577
Liz Kammer585cac22020-07-06 09:12:57 -07001578 cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
Colin Cross33961b52019-07-11 11:01:22 -07001579 for _, o := range d.Javadoc.properties.Out {
1580 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1581 }
1582
Makoto Onuki88b99052020-04-27 17:22:16 -07001583 // Add options for the other optional tasks: API-lint and check-released.
1584 // We generate separate timestamp files for them.
1585
1586 doApiLint := false
1587 doCheckReleased := false
1588
1589 // Add API lint options.
1590
Dan Willemsen9f435972020-05-28 15:28:00 -07001591 if BoolDefault(d.properties.Check_api.Api_lint.Enabled, false) {
Makoto Onuki88b99052020-04-27 17:22:16 -07001592 doApiLint = true
1593
1594 newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
1595 if newSince.Valid() {
1596 cmd.FlagWithInput("--api-lint ", newSince.Path())
1597 } else {
1598 cmd.Flag("--api-lint")
1599 }
1600 d.apiLintReport = android.PathForModuleOut(ctx, "api_lint_report.txt")
1601 cmd.FlagWithOutput("--report-even-if-suppressed ", d.apiLintReport) // TODO: Change to ":api-lint"
1602
1603 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.Baseline_file)
1604 updatedBaselineOutput := android.PathForModuleOut(ctx, "api_lint_baseline.txt")
1605 d.apiLintTimestamp = android.PathForModuleOut(ctx, "api_lint.timestamp")
1606
1607 // Note this string includes a special shell quote $' ... ', which decodes the "\n"s.
1608 // However, because $' ... ' doesn't expand environmental variables, we can't just embed
1609 // $PWD, so we have to terminate $'...', use "$PWD", then start $' ... ' again,
1610 // which is why we have '"$PWD"$' in it.
1611 //
1612 // TODO: metalava also has a slightly different message hardcoded. Should we unify this
1613 // message and metalava's one?
1614 msg := `$'` + // Enclose with $' ... '
1615 `************************************************************\n` +
1616 `Your API changes are triggering API Lint warnings or errors.\n` +
1617 `To make these errors go away, fix the code according to the\n` +
1618 `error and/or warning messages above.\n` +
1619 `\n` +
1620 `If it is not possible to do so, there are workarounds:\n` +
1621 `\n` +
1622 `1. You can suppress the errors with @SuppressLint("<id>")\n`
1623
1624 if baselineFile.Valid() {
1625 cmd.FlagWithInput("--baseline:api-lint ", baselineFile.Path())
1626 cmd.FlagWithOutput("--update-baseline:api-lint ", updatedBaselineOutput)
1627
1628 msg += fmt.Sprintf(``+
1629 `2. You can update the baseline by executing the following\n`+
1630 ` command:\n`+
Anton Hansson3361a292020-05-11 15:38:31 +01001631 ` cp \\\n`+
1632 ` "'"$PWD"$'/%s" \\\n`+
1633 ` "'"$PWD"$'/%s"\n`+
Makoto Onuki88b99052020-04-27 17:22:16 -07001634 ` To submit the revised baseline.txt to the main Android\n`+
1635 ` repository, you will need approval.\n`, updatedBaselineOutput, baselineFile.Path())
1636 } else {
1637 msg += fmt.Sprintf(``+
1638 `2. You can add a baseline file of existing lint failures\n`+
1639 ` to the build rule of %s.\n`, d.Name())
1640 }
1641 // Note the message ends with a ' (single quote), to close the $' ... ' .
1642 msg += `************************************************************\n'`
1643
1644 cmd.FlagWithArg("--error-message:api-lint ", msg)
1645 }
1646
1647 // Add "check released" options. (Detect incompatible API changes from the last public release)
1648
Dan Willemsen9f435972020-05-28 15:28:00 -07001649 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") {
Makoto Onuki88b99052020-04-27 17:22:16 -07001650 doCheckReleased = true
1651
1652 if len(d.Javadoc.properties.Out) > 0 {
1653 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1654 }
1655
1656 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1657 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
1658 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1659 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
1660
1661 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1662
1663 cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
1664 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1665
1666 if baselineFile.Valid() {
1667 cmd.FlagWithInput("--baseline:compatibility:released ", baselineFile.Path())
1668 cmd.FlagWithOutput("--update-baseline:compatibility:released ", updatedBaselineOutput)
1669 }
1670
1671 // Note this string includes quote ($' ... '), which decodes the "\n"s.
1672 msg := `$'\n******************************\n` +
1673 `You have tried to change the API from what has been previously released in\n` +
1674 `an SDK. Please fix the errors listed above.\n` +
1675 `******************************\n'`
1676
1677 cmd.FlagWithArg("--error-message:compatibility:released ", msg)
1678 }
1679
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001680 impRule := android.NewRuleBuilder()
1681 impCmd := impRule.Command()
Liz Kammer20ebfb42020-07-28 11:32:07 -07001682 // An action that copies the ninja generated rsp file to a new location. This allows us to
Ramy Medhat2f99eec2020-06-13 17:38:27 -04001683 // add a large number of inputs to a file without exceeding bash command length limits (which
1684 // would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
1685 // rsp file to be ${output}.rsp.
1686 impCmd.Text("cp").FlagWithRspFileInputList("", cmd.GetImplicits()).Output(implicitsRsp)
1687 impRule.Build(pctx, ctx, "implicitsGen", "implicits generation")
1688 cmd.Implicit(implicitsRsp)
1689
Paul Duffin3ae29512020-04-08 18:18:03 +01001690 if generateStubs {
1691 rule.Command().
1692 BuiltTool(ctx, "soong_zip").
1693 Flag("-write_if_changed").
1694 Flag("-jar").
1695 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1696 FlagWithArg("-C ", stubsDir.String()).
1697 FlagWithArg("-D ", stubsDir.String())
1698 }
Jerome Gaillard0f599032019-10-10 19:29:11 +01001699
1700 if Bool(d.properties.Write_sdk_values) {
1701 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1702 rule.Command().
1703 BuiltTool(ctx, "soong_zip").
1704 Flag("-write_if_changed").
1705 Flag("-d").
1706 FlagWithOutput("-o ", d.metadataZip).
1707 FlagWithArg("-C ", d.metadataDir.String()).
1708 FlagWithArg("-D ", d.metadataDir.String())
1709 }
1710
Makoto Onuki88b99052020-04-27 17:22:16 -07001711 // TODO: We don't really need two separate API files, but this is a reminiscence of how
1712 // we used to run metalava separately for API lint and the "last_released" check. Unify them.
1713 if doApiLint {
1714 rule.Command().Text("touch").Output(d.apiLintTimestamp)
1715 }
1716 if doCheckReleased {
1717 rule.Command().Text("touch").Output(d.checkLastReleasedApiTimestamp)
1718 }
1719
Colin Cross33961b52019-07-11 11:01:22 -07001720 rule.Restat()
1721
1722 zipSyncCleanupCmd(rule, srcJarDir)
1723
Makoto Onuki88b99052020-04-27 17:22:16 -07001724 rule.Build(pctx, ctx, "metalava", "metalava merged")
Adrian Roos075eedc2019-10-10 12:07:03 +02001725
Dan Willemsen9f435972020-05-28 15:28:00 -07001726 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") {
Colin Cross33961b52019-07-11 11:01:22 -07001727
1728 if len(d.Javadoc.properties.Out) > 0 {
1729 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1730 }
1731
1732 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1733 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001734 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
Makoto Onuki5405a732020-04-16 17:02:40 -07001735
1736 if baselineFile.Valid() {
Makoto Onuki88b99052020-04-27 17:22:16 -07001737 ctx.PropertyErrorf("baseline_file", "current API check can't have a baseline file. (module %s)", ctx.ModuleName())
Makoto Onuki5405a732020-04-16 17:02:40 -07001738 }
Nan Zhang61819ce2018-05-04 18:49:16 -07001739
Nan Zhang2760dfc2018-08-24 17:32:54 +00001740 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001741
Colin Cross33961b52019-07-11 11:01:22 -07001742 rule := android.NewRuleBuilder()
1743
Makoto Onuki5405a732020-04-16 17:02:40 -07001744 // Diff command line.
Makoto Onuki88b99052020-04-27 17:22:16 -07001745 // -F matches the closest "opening" line, such as "package android {"
1746 // and " public class Intent {".
Makoto Onuki5405a732020-04-16 17:02:40 -07001747 diff := `diff -u -F '{ *$'`
1748
Colin Cross33961b52019-07-11 11:01:22 -07001749 rule.Command().Text("( true")
Makoto Onuki5405a732020-04-16 17:02:40 -07001750 rule.Command().
1751 Text(diff).
1752 Input(apiFile).Input(d.apiFile)
Colin Cross33961b52019-07-11 11:01:22 -07001753
Makoto Onuki5405a732020-04-16 17:02:40 -07001754 rule.Command().
1755 Text(diff).
1756 Input(removedApiFile).Input(d.removedApiFile)
Colin Cross33961b52019-07-11 11:01:22 -07001757
1758 msg := fmt.Sprintf(`\n******************************\n`+
1759 `You have tried to change the API from what has been previously approved.\n\n`+
1760 `To make these errors go away, you have two choices:\n`+
Makoto Onuki5405a732020-04-16 17:02:40 -07001761 ` 1. You can add '@hide' javadoc comments (and remove @SystemApi/@TestApi/etc)\n`+
1762 ` to the new methods, etc. shown in the above diff.\n\n`+
1763 ` 2. You can update current.txt and/or removed.txt by executing the following command:\n`+
Colin Cross33961b52019-07-11 11:01:22 -07001764 ` make %s-update-current-api\n\n`+
1765 ` To submit the revised current.txt to the main Android repository,\n`+
1766 ` you will need approval.\n`+
1767 `******************************\n`, ctx.ModuleName())
1768
1769 rule.Command().
1770 Text("touch").Output(d.checkCurrentApiTimestamp).
1771 Text(") || (").
1772 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1773 Text("; exit 38").
1774 Text(")")
1775
Makoto Onuki5405a732020-04-16 17:02:40 -07001776 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001777
1778 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001779
1780 // update API rule
1781 rule = android.NewRuleBuilder()
1782
1783 rule.Command().Text("( true")
1784
1785 rule.Command().
1786 Text("cp").Flag("-f").
1787 Input(d.apiFile).Flag(apiFile.String())
1788
1789 rule.Command().
1790 Text("cp").Flag("-f").
1791 Input(d.removedApiFile).Flag(removedApiFile.String())
1792
1793 msg = "failed to update public API"
1794
1795 rule.Command().
1796 Text("touch").Output(d.updateCurrentApiTimestamp).
1797 Text(") || (").
1798 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1799 Text("; exit 38").
1800 Text(")")
1801
1802 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001803 }
Nan Zhanga40da042018-08-01 12:48:00 -07001804
Pete Gillin581d6082018-10-22 15:55:04 +01001805 if String(d.properties.Check_nullability_warnings) != "" {
1806 if d.nullabilityWarningsFile == nil {
1807 ctx.PropertyErrorf("check_nullability_warnings",
1808 "Cannot specify check_nullability_warnings unless validating nullability")
1809 }
Colin Cross33961b52019-07-11 11:01:22 -07001810
1811 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1812
Pete Gillin581d6082018-10-22 15:55:04 +01001813 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001814
Pete Gillin581d6082018-10-22 15:55:04 +01001815 msg := fmt.Sprintf(`\n******************************\n`+
1816 `The warnings encountered during nullability annotation validation did\n`+
1817 `not match the checked in file of expected warnings. The diffs are shown\n`+
1818 `above. You have two options:\n`+
1819 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1820 ` 2. Update the file of expected warnings by running:\n`+
1821 ` cp %s %s\n`+
1822 ` and submitting the updated file as part of your change.`,
1823 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001824
1825 rule := android.NewRuleBuilder()
1826
1827 rule.Command().
1828 Text("(").
1829 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1830 Text("&&").
1831 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1832 Text(") || (").
1833 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1834 Text("; exit 38").
1835 Text(")")
1836
1837 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001838 }
1839
Dan Willemsen9f435972020-05-28 15:28:00 -07001840 if Bool(d.properties.Jdiff_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001841 if len(d.Javadoc.properties.Out) > 0 {
1842 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1843 }
1844
1845 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1846 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1847 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1848
1849 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001850
Nan Zhang86b06202018-09-21 17:09:21 -07001851 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1852 // since there's cron job downstream that fetch this .zip file periodically.
1853 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001854 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1855 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1856
Nan Zhang71bbe632018-09-17 14:32:21 -07001857 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001858
Colin Cross33961b52019-07-11 11:01:22 -07001859 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1860 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001861
Colin Cross33961b52019-07-11 11:01:22 -07001862 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1863
Colin Crossdaa4c672019-07-15 22:53:46 -07001864 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001865 deps.bootClasspath, deps.classpath, d.sourcepaths)
1866
1867 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001868 Flag("-XDignore.symbol.file").
1869 FlagWithArg("-doclet ", "jdiff.JDiff").
1870 FlagWithInput("-docletpath ", jdiff).
Paul Duffin10269f12020-06-19 18:39:55 +01001871 Flag("-quiet")
1872
1873 if d.apiXmlFile != nil {
1874 cmd.FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1875 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1876 Implicit(d.apiXmlFile)
1877 }
1878
1879 if d.lastReleasedApiXmlFile != nil {
1880 cmd.FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1881 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1882 Implicit(d.lastReleasedApiXmlFile)
1883 }
Colin Cross33961b52019-07-11 11:01:22 -07001884
Colin Cross33961b52019-07-11 11:01:22 -07001885 rule.Command().
1886 BuiltTool(ctx, "soong_zip").
1887 Flag("-write_if_changed").
1888 Flag("-d").
1889 FlagWithOutput("-o ", d.jdiffDocZip).
1890 FlagWithArg("-C ", outDir.String()).
1891 FlagWithArg("-D ", outDir.String())
1892
1893 rule.Command().
1894 BuiltTool(ctx, "soong_zip").
1895 Flag("-write_if_changed").
1896 Flag("-jar").
1897 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1898 FlagWithArg("-C ", stubsDir.String()).
1899 FlagWithArg("-D ", stubsDir.String())
1900
1901 rule.Restat()
1902
1903 zipSyncCleanupCmd(rule, srcJarDir)
1904
1905 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001906 }
Nan Zhang581fd212018-01-10 16:06:12 -08001907}
Dan Willemsencc090972018-02-26 14:33:31 -08001908
Nan Zhanga40da042018-08-01 12:48:00 -07001909//
Nan Zhangf4936b02018-08-01 15:00:28 -07001910// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001911//
Dan Willemsencc090972018-02-26 14:33:31 -08001912var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001913var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001914var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001915var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001916
Nan Zhangf4936b02018-08-01 15:00:28 -07001917type ExportedDroiddocDirProperties struct {
1918 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001919 Path *string
1920}
1921
Nan Zhangf4936b02018-08-01 15:00:28 -07001922type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001923 android.ModuleBase
1924
Nan Zhangf4936b02018-08-01 15:00:28 -07001925 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001926
1927 deps android.Paths
1928 dir android.Path
1929}
1930
Colin Crossa3002fc2019-07-08 16:48:04 -07001931// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001932func ExportedDroiddocDirFactory() android.Module {
1933 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001934 module.AddProperties(&module.properties)
1935 android.InitAndroidModule(module)
1936 return module
1937}
1938
Nan Zhangf4936b02018-08-01 15:00:28 -07001939func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001940
Nan Zhangf4936b02018-08-01 15:00:28 -07001941func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001942 path := String(d.properties.Path)
1943 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001944 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001945}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001946
1947//
1948// Defaults
1949//
1950type DocDefaults struct {
1951 android.ModuleBase
1952 android.DefaultsModuleBase
1953}
1954
Nan Zhangb2b33de2018-02-23 11:18:47 -08001955func DocDefaultsFactory() android.Module {
1956 module := &DocDefaults{}
1957
1958 module.AddProperties(
1959 &JavadocProperties{},
1960 &DroiddocProperties{},
1961 )
1962
1963 android.InitDefaultsModule(module)
1964
1965 return module
1966}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001967
1968func StubsDefaultsFactory() android.Module {
1969 module := &DocDefaults{}
1970
1971 module.AddProperties(
1972 &JavadocProperties{},
1973 &DroidstubsProperties{},
1974 )
1975
1976 android.InitDefaultsModule(module)
1977
1978 return module
1979}
Colin Cross33961b52019-07-11 11:01:22 -07001980
1981func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1982 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1983
1984 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1985 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1986 srcJarList := srcJarDir.Join(ctx, "list")
1987
1988 rule.Temporary(srcJarList)
1989
1990 rule.Command().BuiltTool(ctx, "zipsync").
1991 FlagWithArg("-d ", srcJarDir.String()).
1992 FlagWithOutput("-l ", srcJarList).
1993 FlagWithArg("-f ", `"*.java"`).
1994 Inputs(srcJars)
1995
1996 return srcJarList
1997}
1998
1999func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
2000 rule.Command().Text("rm -rf").Text(srcJarDir.String())
2001}
Paul Duffin91547182019-11-12 19:39:36 +00002002
2003var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
2004
2005type PrebuiltStubsSourcesProperties struct {
2006 Srcs []string `android:"path"`
2007}
2008
2009type PrebuiltStubsSources struct {
2010 android.ModuleBase
2011 android.DefaultableModuleBase
2012 prebuilt android.Prebuilt
2013 android.SdkBase
2014
2015 properties PrebuiltStubsSourcesProperties
2016
Paul Duffin9b478b02019-12-10 13:41:51 +00002017 // The source directories containing stubs source files.
2018 srcDirs android.Paths
Paul Duffin91547182019-11-12 19:39:36 +00002019 stubsSrcJar android.ModuleOutPath
2020}
2021
Paul Duffin9b478b02019-12-10 13:41:51 +00002022func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
2023 switch tag {
2024 case "":
2025 return android.Paths{p.stubsSrcJar}, nil
2026 default:
2027 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
2028 }
2029}
2030
Paul Duffin0f8faff2020-05-20 16:18:00 +01002031func (d *PrebuiltStubsSources) StubsSrcJar() android.Path {
2032 return d.stubsSrcJar
2033}
2034
Paul Duffin91547182019-11-12 19:39:36 +00002035func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffin9b478b02019-12-10 13:41:51 +00002036 p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
2037
2038 p.srcDirs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
2039
2040 rule := android.NewRuleBuilder()
2041 command := rule.Command().
2042 BuiltTool(ctx, "soong_zip").
2043 Flag("-write_if_changed").
2044 Flag("-jar").
2045 FlagWithOutput("-o ", p.stubsSrcJar)
2046
2047 for _, d := range p.srcDirs {
2048 dir := d.String()
2049 command.
2050 FlagWithArg("-C ", dir).
2051 FlagWithInput("-D ", d)
2052 }
2053
2054 rule.Restat()
2055
2056 rule.Build(pctx, ctx, "zip src", "Create srcjar from prebuilt source")
Paul Duffin91547182019-11-12 19:39:36 +00002057}
2058
2059func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
2060 return &p.prebuilt
2061}
2062
2063func (p *PrebuiltStubsSources) Name() string {
2064 return p.prebuilt.Name(p.ModuleBase.Name())
2065}
2066
Paul Duffin91547182019-11-12 19:39:36 +00002067// prebuilt_stubs_sources imports a set of java source files as if they were
2068// generated by droidstubs.
2069//
2070// By default, a prebuilt_stubs_sources has a single variant that expects a
2071// set of `.java` files generated by droidstubs.
2072//
2073// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
2074// for host modules.
2075//
2076// Intended only for use by sdk snapshots.
2077func PrebuiltStubsSourcesFactory() android.Module {
2078 module := &PrebuiltStubsSources{}
2079
2080 module.AddProperties(&module.properties)
2081
2082 android.InitPrebuiltModule(module, &module.properties.Srcs)
2083 android.InitSdkAwareModule(module)
2084 InitDroiddocModule(module, android.HostAndDeviceSupported)
2085 return module
2086}
2087
Paul Duffin13879572019-11-28 14:31:38 +00002088type droidStubsSdkMemberType struct {
Paul Duffin255f18e2019-12-13 11:22:16 +00002089 android.SdkMemberTypeBase
Paul Duffin13879572019-11-28 14:31:38 +00002090}
2091
2092func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
2093 mctx.AddVariationDependencies(nil, dependencyTag, names...)
2094}
2095
2096func (mt *droidStubsSdkMemberType) IsInstance(module android.Module) bool {
2097 _, ok := module.(*Droidstubs)
2098 return ok
2099}
2100
Paul Duffin495ffb92020-03-20 13:35:40 +00002101func (mt *droidStubsSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
2102 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "prebuilt_stubs_sources")
2103}
2104
2105func (mt *droidStubsSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
2106 return &droidStubsInfoProperties{}
2107}
2108
2109type droidStubsInfoProperties struct {
2110 android.SdkMemberPropertiesBase
2111
2112 StubsSrcJar android.Path
2113}
2114
2115func (p *droidStubsInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
2116 droidstubs := variant.(*Droidstubs)
2117 p.StubsSrcJar = droidstubs.stubsSrcJar
2118}
2119
2120func (p *droidStubsInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
2121 if p.StubsSrcJar != nil {
2122 builder := ctx.SnapshotBuilder()
2123
2124 snapshotRelativeDir := filepath.Join("java", ctx.Name()+"_stubs_sources")
2125
2126 builder.UnzipToSnapshot(p.StubsSrcJar, snapshotRelativeDir)
2127
2128 propertySet.AddProperty("srcs", []string{snapshotRelativeDir})
Paul Duffin13879572019-11-28 14:31:38 +00002129 }
Paul Duffin91547182019-11-12 19:39:36 +00002130}