blob: 63da6d2758ef663460d090f49e4b2fbf4cb2925e [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070020 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080021 "strings"
22
Jeongik Cha6bd33c12019-06-25 16:26:18 +090023 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080024
Colin Crossab054432019-07-15 16:13:59 -070025 "android/soong/android"
26 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080030 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070031 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080032
Nan Zhang581fd212018-01-10 16:06:12 -080033 android.RegisterModuleType("droiddoc", DroiddocFactory)
34 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070035 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080036 android.RegisterModuleType("javadoc", JavadocFactory)
37 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070038
39 android.RegisterModuleType("droidstubs", DroidstubsFactory)
40 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080041}
42
Colin Crossa1ce2a02018-06-20 15:19:39 -070043var (
44 srcsLibTag = dependencyTag{name: "sources from javalib"}
45)
46
Nan Zhang581fd212018-01-10 16:06:12 -080047type JavadocProperties struct {
48 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
49 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080051
52 // list of directories rooted at the Android.bp file that will
53 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080054 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080055
56 // list of source files that should not be used to build the Java module.
57 // This is most useful in the arch/multilib variants to remove non-common files
58 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080059 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080060
Nan Zhangb2b33de2018-02-23 11:18:47 -080061 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080062 Libs []string `android:"arch_variant"`
63
64 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080065 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080066
67 // if not blank, set to the version of the sdk to compile against
68 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090069
70 Aidl struct {
71 // Top level directories to pass to aidl tool
72 Include_dirs []string
73
74 // Directories rooted at the Android.bp file to pass to aidl tool
75 Local_include_dirs []string
76 }
Nan Zhang357466b2018-04-17 17:38:36 -070077
78 // If not blank, set the java version passed to javadoc as -source
79 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070080
81 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080082 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070083
84 // user customized droiddoc args.
85 // Available variables for substitution:
86 //
87 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070088 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070089 Args *string
90
91 // names of the output files used in args that will be generated
92 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080093}
94
Nan Zhang61819ce2018-05-04 18:49:16 -070095type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +090096 // path to the API txt file that the new API extracted from source code is checked
97 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -080098 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -070099
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900100 // path to the API txt file that the new @removed API extractd from source code is
101 // checked against. The path can be local to the module or from other module (via
102 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800103 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700104
Adrian Roos14f75a92019-08-12 17:54:09 +0200105 // If not blank, path to the baseline txt file for approved API check violations.
106 Baseline_file *string `android:"path"`
107
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900108 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700109 Args *string
110}
111
Nan Zhang581fd212018-01-10 16:06:12 -0800112type DroiddocProperties struct {
113 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800114 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800115
Nan Zhanga40da042018-08-01 12:48:00 -0700116 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800117 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800118
119 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800121
122 // proofread file contains all of the text content of the javadocs concatenated into one file,
123 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700124 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800125
126 // a todo file lists the program elements that are missing documentation.
127 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800128 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129
130 // directory under current module source that provide additional resources (images).
131 Resourcesdir *string
132
133 // resources output directory under out/soong/.intermediates.
134 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800135
Nan Zhange2ba5d42018-07-11 15:16:55 -0700136 // if set to true, collect the values used by the Dev tools and
137 // write them in files packaged with the SDK. Defaults to false.
138 Write_sdk_values *bool
139
140 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800141 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700142
143 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800144 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145
Nan Zhang581fd212018-01-10 16:06:12 -0800146 // a list of files under current module source dir which contains known tags in Java sources.
147 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800148 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700149
150 // the tag name used to distinguish if the API files belong to public/system/test.
151 Api_tag_name *string
152
153 // the generated public API filename by Doclava.
154 Api_filename *string
155
David Brazdilfbe4cc32018-05-31 13:56:46 +0100156 // the generated public Dex API filename by Doclava.
157 Dex_api_filename *string
158
Nan Zhang28c68b92018-03-13 16:17:01 -0700159 // the generated private API filename by Doclava.
160 Private_api_filename *string
161
162 // the generated private Dex API filename by Doclava.
163 Private_dex_api_filename *string
164
165 // the generated removed API filename by Doclava.
166 Removed_api_filename *string
167
David Brazdilaac0c3c2018-04-24 16:23:29 +0100168 // the generated removed Dex API filename by Doclava.
169 Removed_dex_api_filename *string
170
Mathew Inwood76c3de12018-06-22 15:28:11 +0100171 // mapping of dex signatures to source file and line number. This is a temporary property and
172 // will be deleted; you probably shouldn't be using it.
173 Dex_mapping_filename *string
174
Nan Zhang28c68b92018-03-13 16:17:01 -0700175 // the generated exact API filename by Doclava.
176 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700177
Nan Zhang66dc2362018-08-14 20:41:04 -0700178 // the generated proguard filename by Doclava.
179 Proguard_filename *string
180
Nan Zhang853f4202018-04-12 16:55:56 -0700181 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
182 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700183
184 Check_api struct {
185 Last_released ApiToCheck
186
187 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900188
189 // do not perform API check against Last_released, in the case that both two specified API
190 // files by Last_released are modules which don't exist.
191 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700192 }
Nan Zhang79614d12018-04-19 18:03:39 -0700193
Nan Zhang1598a9e2018-09-04 17:14:32 -0700194 // if set to true, generate docs through Dokka instead of Doclava.
195 Dokka_enabled *bool
196}
197
198type DroidstubsProperties struct {
199 // the tag name used to distinguish if the API files belong to public/system/test.
200 Api_tag_name *string
201
Nan Zhang199645c2018-09-19 12:40:06 -0700202 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203 Api_filename *string
204
Nan Zhang199645c2018-09-19 12:40:06 -0700205 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206 Dex_api_filename *string
207
Nan Zhang199645c2018-09-19 12:40:06 -0700208 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Private_api_filename *string
210
Nan Zhang199645c2018-09-19 12:40:06 -0700211 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700212 Private_dex_api_filename *string
213
Nan Zhang199645c2018-09-19 12:40:06 -0700214 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Removed_api_filename *string
216
Nan Zhang199645c2018-09-19 12:40:06 -0700217 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700218 Removed_dex_api_filename *string
219
Nan Zhang9c69a122018-08-22 10:22:08 -0700220 // mapping of dex signatures to source file and line number. This is a temporary property and
221 // will be deleted; you probably shouldn't be using it.
222 Dex_mapping_filename *string
223
Nan Zhang199645c2018-09-19 12:40:06 -0700224 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700225 Exact_api_filename *string
226
Nan Zhang199645c2018-09-19 12:40:06 -0700227 // the generated proguard filename by Metalava.
228 Proguard_filename *string
229
Nan Zhang1598a9e2018-09-04 17:14:32 -0700230 Check_api struct {
231 Last_released ApiToCheck
232
233 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900234
235 // do not perform API check against Last_released, in the case that both two specified API
236 // files by Last_released are modules which don't exist.
237 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700238 }
Nan Zhang79614d12018-04-19 18:03:39 -0700239
240 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800241 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700242
243 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700244 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700245
Pete Gillin77167902018-09-19 18:16:26 +0100246 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700247 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700248
Pete Gillin77167902018-09-19 18:16:26 +0100249 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
250 Merge_inclusion_annotations_dirs []string
251
Pete Gillinc382a562018-11-14 18:45:46 +0000252 // a file containing a list of classes to do nullability validation for.
253 Validate_nullability_from_list *string
254
Pete Gillin581d6082018-10-22 15:55:04 +0100255 // a file containing expected warnings produced by validation of nullability annotations.
256 Check_nullability_warnings *string
257
Nan Zhang1598a9e2018-09-04 17:14:32 -0700258 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
259 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700260
261 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
262 Api_levels_annotations_enabled *bool
263
264 // the dirs which Metalava extracts API levels annotations from.
265 Api_levels_annotations_dirs []string
266
267 // if set to true, collect the values used by the Dev tools and
268 // write them in files packaged with the SDK. Defaults to false.
269 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700270
271 // If set to true, .xml based public API file will be also generated, and
272 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
273 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800274}
275
Nan Zhanga40da042018-08-01 12:48:00 -0700276//
277// Common flags passed down to build rule
278//
279type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700280 bootClasspathArgs string
281 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700282 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700283 dokkaClasspathArgs string
284 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700285 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700286
Nan Zhanga40da042018-08-01 12:48:00 -0700287 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700288 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700289 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700290}
291
292func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
293 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
294 android.InitDefaultableModule(module)
295}
296
Nan Zhang1598a9e2018-09-04 17:14:32 -0700297func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
298 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
299 return true
300 } else if String(apiToCheck.Api_file) != "" {
301 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
302 } else if String(apiToCheck.Removed_api_file) != "" {
303 panic("for " + apiVersionTag + " api_file has to be non-empty!")
304 }
305
306 return false
307}
308
Inseob Kim38449af2019-02-28 14:24:05 +0900309func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
310 api_file := String(apiToCheck.Api_file)
311 removed_api_file := String(apiToCheck.Removed_api_file)
312
313 api_module := android.SrcIsModule(api_file)
314 removed_api_module := android.SrcIsModule(removed_api_file)
315
316 if api_module == "" || removed_api_module == "" {
317 return
318 }
319
320 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
321 return
322 }
323
324 apiToCheck.Api_file = nil
325 apiToCheck.Removed_api_file = nil
326}
327
Nan Zhang1598a9e2018-09-04 17:14:32 -0700328type ApiFilePath interface {
329 ApiFilePath() android.Path
330}
331
Nan Zhanga40da042018-08-01 12:48:00 -0700332//
333// Javadoc
334//
Nan Zhang581fd212018-01-10 16:06:12 -0800335type Javadoc struct {
336 android.ModuleBase
337 android.DefaultableModuleBase
338
339 properties JavadocProperties
340
341 srcJars android.Paths
342 srcFiles android.Paths
343 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700344 argFiles android.Paths
345
346 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800347
Nan Zhangccff0f72018-03-08 17:26:16 -0800348 docZip android.WritablePath
349 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800350}
351
Colin Cross41955e82019-05-29 14:40:35 -0700352func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
353 switch tag {
354 case "":
355 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700356 case ".docs.zip":
357 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700358 default:
359 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
360 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800361}
362
Colin Crossa3002fc2019-07-08 16:48:04 -0700363// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800364func JavadocFactory() android.Module {
365 module := &Javadoc{}
366
367 module.AddProperties(&module.properties)
368
369 InitDroiddocModule(module, android.HostAndDeviceSupported)
370 return module
371}
372
Colin Crossa3002fc2019-07-08 16:48:04 -0700373// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800374func JavadocHostFactory() android.Module {
375 module := &Javadoc{}
376
377 module.AddProperties(&module.properties)
378
379 InitDroiddocModule(module, android.HostSupported)
380 return module
381}
382
Colin Cross41955e82019-05-29 14:40:35 -0700383var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800384
Colin Cross83bb3162018-06-25 15:48:06 -0700385func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900386 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700387}
388
389func (j *Javadoc) minSdkVersion() string {
390 return j.sdkVersion()
391}
392
Dan Willemsen419290a2018-10-31 15:28:47 -0700393func (j *Javadoc) targetSdkVersion() string {
394 return j.sdkVersion()
395}
396
Nan Zhang581fd212018-01-10 16:06:12 -0800397func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
398 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100399 sdkDep := decodeSdkDep(ctx, sdkContext(j))
400 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700401 if sdkDep.useDefaultLibs {
402 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
403 if ctx.Config().TargetOpenJDK9() {
404 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
405 }
Paul Duffin250e6192019-06-07 10:44:37 +0100406 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700407 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
408 }
409 } else if sdkDep.useModule {
410 if ctx.Config().TargetOpenJDK9() {
411 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
412 }
413 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700414 }
Nan Zhang581fd212018-01-10 16:06:12 -0800415 }
416 }
417
Colin Cross42d48b72018-08-29 14:10:52 -0700418 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800419}
420
Nan Zhanga40da042018-08-01 12:48:00 -0700421func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
422 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900423
Colin Cross3047fa22019-04-18 10:56:44 -0700424 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900425
426 return flags
427}
428
429func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700430 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900431
432 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
433 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
434
435 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700436 var deps android.Paths
437
Jiyong Park1e440682018-05-23 18:42:04 +0900438 if aidlPreprocess.Valid() {
439 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700440 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900441 } else {
442 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
443 }
444
445 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
446 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
447 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
448 flags = append(flags, "-I"+src.String())
449 }
450
Colin Cross3047fa22019-04-18 10:56:44 -0700451 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900452}
453
Jiyong Parkd90d7412019-08-20 22:49:19 +0900454// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900455func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700456 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900457
458 outSrcFiles := make(android.Paths, 0, len(srcFiles))
459
Jiyong Park1112c4c2019-08-16 21:12:10 +0900460 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
461
Jiyong Park1e440682018-05-23 18:42:04 +0900462 for _, srcFile := range srcFiles {
463 switch srcFile.Ext() {
464 case ".aidl":
Jiyong Park1112c4c2019-08-16 21:12:10 +0900465 javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900466 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900467 case ".logtags":
468 javaFile := genLogtags(ctx, srcFile)
469 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900470 default:
471 outSrcFiles = append(outSrcFiles, srcFile)
472 }
473 }
474
475 return outSrcFiles
476}
477
Nan Zhang581fd212018-01-10 16:06:12 -0800478func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
479 var deps deps
480
Colin Cross83bb3162018-06-25 15:48:06 -0700481 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800482 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700483 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800484 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700485 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800486 }
487
488 ctx.VisitDirectDeps(func(module android.Module) {
489 otherName := ctx.OtherModuleName(module)
490 tag := ctx.OtherModuleDependencyTag(module)
491
Colin Cross2d24c1b2018-05-23 10:59:18 -0700492 switch tag {
493 case bootClasspathTag:
494 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800495 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700496 } else {
497 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
498 }
499 case libTag:
500 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800501 case SdkLibraryDependency:
502 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700503 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900504 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900505 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700506 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800507 checkProducesJars(ctx, dep)
508 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800509 default:
510 ctx.ModuleErrorf("depends on non-java module %q", otherName)
511 }
Nan Zhang357466b2018-04-17 17:38:36 -0700512 case systemModulesTag:
513 if deps.systemModules != nil {
514 panic("Found two system module dependencies")
515 }
516 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000517 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700518 panic("Missing directory for system module dependency")
519 }
Colin Crossb77043e2019-07-16 13:57:13 -0700520 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800521 }
522 })
523 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
524 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800525 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700526 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900527 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800528
529 // srcs may depend on some genrule output.
530 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800531 j.srcJars = append(j.srcJars, deps.srcJars...)
532
Nan Zhang581fd212018-01-10 16:06:12 -0800533 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800534 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800535
Nan Zhang9c69a122018-08-22 10:22:08 -0700536 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800537 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
538 }
539 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800540
Colin Cross8a497952019-03-05 22:25:09 -0800541 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000542 argFilesMap := map[string]string{}
543 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700544
Paul Duffin99e4a502019-02-11 15:38:42 +0000545 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800546 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000547 if _, exists := argFilesMap[label]; !exists {
548 argFilesMap[label] = strings.Join(paths.Strings(), " ")
549 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700550 } else {
551 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000552 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700553 }
554 }
555
556 var err error
Colin Cross15638152019-07-11 11:11:35 -0700557 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700558 if strings.HasPrefix(name, "location ") {
559 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000560 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700561 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700562 } else {
Colin Cross15638152019-07-11 11:11:35 -0700563 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000564 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700565 }
566 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700567 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700568 }
Colin Cross15638152019-07-11 11:11:35 -0700569 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700570 })
571
572 if err != nil {
573 ctx.PropertyErrorf("args", "%s", err.Error())
574 }
575
Nan Zhang581fd212018-01-10 16:06:12 -0800576 return deps
577}
578
579func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
580 j.addDeps(ctx)
581}
582
583func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
584 deps := j.collectDeps(ctx)
585
Colin Crossdaa4c672019-07-15 22:53:46 -0700586 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800587
Colin Crossdaa4c672019-07-15 22:53:46 -0700588 outDir := android.PathForModuleOut(ctx, "out")
589 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
590
591 j.stubsSrcJar = nil
592
593 rule := android.NewRuleBuilder()
594
595 rule.Command().Text("rm -rf").Text(outDir.String())
596 rule.Command().Text("mkdir -p").Text(outDir.String())
597
598 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700599
Colin Cross83bb3162018-06-25 15:48:06 -0700600 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800601
Colin Crossdaa4c672019-07-15 22:53:46 -0700602 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
603 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800604
Colin Crossdaa4c672019-07-15 22:53:46 -0700605 cmd.FlagWithArg("-source ", javaVersion).
606 Flag("-J-Xmx1024m").
607 Flag("-XDignore.symbol.file").
608 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800609
Colin Crossdaa4c672019-07-15 22:53:46 -0700610 rule.Command().
611 BuiltTool(ctx, "soong_zip").
612 Flag("-write_if_changed").
613 Flag("-d").
614 FlagWithOutput("-o ", j.docZip).
615 FlagWithArg("-C ", outDir.String()).
616 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700617
Colin Crossdaa4c672019-07-15 22:53:46 -0700618 rule.Restat()
619
620 zipSyncCleanupCmd(rule, srcJarDir)
621
622 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800623}
624
Nan Zhanga40da042018-08-01 12:48:00 -0700625//
626// Droiddoc
627//
628type Droiddoc struct {
629 Javadoc
630
631 properties DroiddocProperties
632 apiFile android.WritablePath
633 dexApiFile android.WritablePath
634 privateApiFile android.WritablePath
635 privateDexApiFile android.WritablePath
636 removedApiFile android.WritablePath
637 removedDexApiFile android.WritablePath
638 exactApiFile android.WritablePath
639 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700640 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700641
642 checkCurrentApiTimestamp android.WritablePath
643 updateCurrentApiTimestamp android.WritablePath
644 checkLastReleasedApiTimestamp android.WritablePath
645
Nan Zhanga40da042018-08-01 12:48:00 -0700646 apiFilePath android.Path
647}
648
Colin Crossa3002fc2019-07-08 16:48:04 -0700649// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700650func DroiddocFactory() android.Module {
651 module := &Droiddoc{}
652
653 module.AddProperties(&module.properties,
654 &module.Javadoc.properties)
655
656 InitDroiddocModule(module, android.HostAndDeviceSupported)
657 return module
658}
659
Colin Crossa3002fc2019-07-08 16:48:04 -0700660// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700661func DroiddocHostFactory() android.Module {
662 module := &Droiddoc{}
663
664 module.AddProperties(&module.properties,
665 &module.Javadoc.properties)
666
667 InitDroiddocModule(module, android.HostSupported)
668 return module
669}
670
671func (d *Droiddoc) ApiFilePath() android.Path {
672 return d.apiFilePath
673}
674
Nan Zhang581fd212018-01-10 16:06:12 -0800675func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
676 d.Javadoc.addDeps(ctx)
677
Inseob Kim38449af2019-02-28 14:24:05 +0900678 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
679 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
680 }
681
Nan Zhang79614d12018-04-19 18:03:39 -0700682 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800683 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
684 }
Nan Zhang581fd212018-01-10 16:06:12 -0800685}
686
Colin Crossab054432019-07-15 16:13:59 -0700687func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700688 var date string
689 if runtime.GOOS == "darwin" {
690 date = `date -r`
691 } else {
Colin Crossd64b3252019-07-18 11:19:33 -0700692 date = `date -d @`
Nan Zhang46130972018-06-04 11:28:01 -0700693 }
694
Nan Zhang443fa522018-08-20 20:58:28 -0700695 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
696 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
697 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700698 cmd.FlagWithArg("-source ", "1.8").
699 Flag("-J-Xmx1600m").
700 Flag("-J-XX:-OmitStackTraceInFastThrow").
701 Flag("-XDignore.symbol.file").
702 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
703 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
704 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Colin Crossd64b3252019-07-18 11:19:33 -0700705 FlagWithArg("-hdf page.now ", `"$(`+date+`$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700706
Nan Zhanga40da042018-08-01 12:48:00 -0700707 if String(d.properties.Custom_template) == "" {
708 // TODO: This is almost always droiddoc-templates-sdk
709 ctx.PropertyErrorf("custom_template", "must specify a template")
710 }
711
712 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700713 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700714 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700715 } else {
716 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
717 }
718 })
719
720 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700721 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
722 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
723 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700724 }
725
726 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700727 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
728 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
729 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700730 }
731
732 if len(d.properties.Html_dirs) > 2 {
733 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
734 }
735
Colin Cross8a497952019-03-05 22:25:09 -0800736 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700737 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700738
Colin Crossab054432019-07-15 16:13:59 -0700739 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700740
741 if String(d.properties.Proofread_file) != "" {
742 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700743 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700744 }
745
746 if String(d.properties.Todo_file) != "" {
747 // tricky part:
748 // we should not compute full path for todo_file through PathForModuleOut().
749 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700750 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
751 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700752 }
753
754 if String(d.properties.Resourcesdir) != "" {
755 // TODO: should we add files under resourcesDir to the implicits? It seems that
756 // resourcesDir is one sub dir of htmlDir
757 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700758 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700759 }
760
761 if String(d.properties.Resourcesoutdir) != "" {
762 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700763 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700764 }
Nan Zhanga40da042018-08-01 12:48:00 -0700765}
766
Colin Crossab054432019-07-15 16:13:59 -0700767func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700768 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
769 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
770 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700771
Nan Zhanga40da042018-08-01 12:48:00 -0700772 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700773 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700774 d.apiFilePath = d.apiFile
775 }
776
Nan Zhang1598a9e2018-09-04 17:14:32 -0700777 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
778 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
779 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700780 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700781 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700782 }
783
784 if String(d.properties.Private_api_filename) != "" {
785 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700786 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700787 }
788
789 if String(d.properties.Dex_api_filename) != "" {
790 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700791 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700792 }
793
794 if String(d.properties.Private_dex_api_filename) != "" {
795 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700796 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700797 }
798
799 if String(d.properties.Removed_dex_api_filename) != "" {
800 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700801 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700802 }
803
804 if String(d.properties.Exact_api_filename) != "" {
805 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700806 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700807 }
808
809 if String(d.properties.Dex_mapping_filename) != "" {
810 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700811 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700812 }
813
Nan Zhang66dc2362018-08-14 20:41:04 -0700814 if String(d.properties.Proguard_filename) != "" {
815 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700816 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700817 }
818
Nan Zhanga40da042018-08-01 12:48:00 -0700819 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700820 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700821 }
822
823 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700824 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700825 }
Nan Zhanga40da042018-08-01 12:48:00 -0700826}
827
Colin Crossab054432019-07-15 16:13:59 -0700828func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700829 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700830 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
831 rule.Command().Text("cp").
832 Input(staticDocIndexRedirect).
833 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700834 }
835
836 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700837 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
838 rule.Command().Text("cp").
839 Input(staticDocProperties).
840 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700841 }
Nan Zhanga40da042018-08-01 12:48:00 -0700842}
843
Colin Crossab054432019-07-15 16:13:59 -0700844func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700845 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700846
847 cmd := rule.Command().
848 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
849 Flag(config.JavacVmFlags).
850 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700851 FlagWithRspFileInputList("@", srcs).
852 FlagWithInput("@", srcJarList)
853
Colin Crossab054432019-07-15 16:13:59 -0700854 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
855 // based stubs generation.
856 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
857 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
858 // the correct package name base path.
859 if len(sourcepaths) > 0 {
860 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
861 } else {
862 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
863 }
864
865 cmd.FlagWithArg("-d ", outDir.String()).
866 Flag("-quiet")
867
868 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700869}
870
Colin Crossdaa4c672019-07-15 22:53:46 -0700871func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
872 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
873 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
874
875 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
876
877 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
878 cmd.Flag(flag).Implicits(deps)
879
880 cmd.FlagWithArg("--patch-module ", "java.base=.")
881
882 if len(classpath) > 0 {
883 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
884 }
885
886 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700887}
888
Colin Crossdaa4c672019-07-15 22:53:46 -0700889func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
890 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
891 sourcepaths android.Paths) *android.RuleBuilderCommand {
892
893 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
894
895 if len(bootclasspath) == 0 && ctx.Device() {
896 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
897 // ensure java does not fall back to the default bootclasspath.
898 cmd.FlagWithArg("-bootclasspath ", `""`)
899 } else if len(bootclasspath) > 0 {
900 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
901 }
902
903 if len(classpath) > 0 {
904 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
905 }
906
907 return cmd
908}
909
Colin Crossab054432019-07-15 16:13:59 -0700910func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
911 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700912
Colin Crossab054432019-07-15 16:13:59 -0700913 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
914 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
915
916 return rule.Command().
917 BuiltTool(ctx, "dokka").
918 Flag(config.JavacVmFlags).
919 Flag(srcJarDir.String()).
920 FlagWithInputList("-classpath ", dokkaClasspath, ":").
921 FlagWithArg("-format ", "dac").
922 FlagWithArg("-dacRoot ", "/reference/kotlin").
923 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700924}
925
926func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
927 deps := d.Javadoc.collectDeps(ctx)
928
Colin Crossdaa4c672019-07-15 22:53:46 -0700929 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
930 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
931
Nan Zhang1598a9e2018-09-04 17:14:32 -0700932 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
933 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
934 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
935 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
936
Colin Crossab054432019-07-15 16:13:59 -0700937 outDir := android.PathForModuleOut(ctx, "out")
938 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
939 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700940
Colin Crossab054432019-07-15 16:13:59 -0700941 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700942
Colin Crossab054432019-07-15 16:13:59 -0700943 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
944 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700945
Colin Crossab054432019-07-15 16:13:59 -0700946 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
947
948 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700949 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700950 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700951 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700952 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700953 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700954 }
955
Colin Crossab054432019-07-15 16:13:59 -0700956 d.stubsFlags(ctx, cmd, stubsDir)
957
958 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
959
960 var desc string
961 if Bool(d.properties.Dokka_enabled) {
962 desc = "dokka"
963 } else {
964 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
965
966 for _, o := range d.Javadoc.properties.Out {
967 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
968 }
969
970 d.postDoclavaCmds(ctx, rule)
971 desc = "doclava"
972 }
973
974 rule.Command().
975 BuiltTool(ctx, "soong_zip").
976 Flag("-write_if_changed").
977 Flag("-d").
978 FlagWithOutput("-o ", d.docZip).
979 FlagWithArg("-C ", outDir.String()).
980 FlagWithArg("-D ", outDir.String())
981
982 rule.Command().
983 BuiltTool(ctx, "soong_zip").
984 Flag("-write_if_changed").
985 Flag("-jar").
986 FlagWithOutput("-o ", d.stubsSrcJar).
987 FlagWithArg("-C ", stubsDir.String()).
988 FlagWithArg("-D ", stubsDir.String())
989
990 rule.Restat()
991
992 zipSyncCleanupCmd(rule, srcJarDir)
993
994 rule.Build(pctx, ctx, "javadoc", desc)
995
Nan Zhang1598a9e2018-09-04 17:14:32 -0700996 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
997 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -0700998
999 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1000 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001001
1002 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001003
1004 rule := android.NewRuleBuilder()
1005
1006 rule.Command().Text("( true")
1007
1008 rule.Command().
1009 BuiltTool(ctx, "apicheck").
1010 Flag("-JXmx1024m").
1011 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1012 OptionalFlag(d.properties.Check_api.Current.Args).
1013 Input(apiFile).
1014 Input(d.apiFile).
1015 Input(removedApiFile).
1016 Input(d.removedApiFile)
1017
1018 msg := fmt.Sprintf(`\n******************************\n`+
1019 `You have tried to change the API from what has been previously approved.\n\n`+
1020 `To make these errors go away, you have two choices:\n`+
1021 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1022 ` errors above.\n\n`+
1023 ` 2. You can update current.txt by executing the following command:\n`+
1024 ` make %s-update-current-api\n\n`+
1025 ` To submit the revised current.txt to the main Android repository,\n`+
1026 ` you will need approval.\n`+
1027 `******************************\n`, ctx.ModuleName())
1028
1029 rule.Command().
1030 Text("touch").Output(d.checkCurrentApiTimestamp).
1031 Text(") || (").
1032 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1033 Text("; exit 38").
1034 Text(")")
1035
1036 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001037
1038 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001039
1040 // update API rule
1041 rule = android.NewRuleBuilder()
1042
1043 rule.Command().Text("( true")
1044
1045 rule.Command().
1046 Text("cp").Flag("-f").
1047 Input(d.apiFile).Flag(apiFile.String())
1048
1049 rule.Command().
1050 Text("cp").Flag("-f").
1051 Input(d.removedApiFile).Flag(removedApiFile.String())
1052
1053 msg = "failed to update public API"
1054
1055 rule.Command().
1056 Text("touch").Output(d.updateCurrentApiTimestamp).
1057 Text(") || (").
1058 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1059 Text("; exit 38").
1060 Text(")")
1061
1062 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001063 }
1064
1065 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1066 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001067
1068 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1069 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001070
1071 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001072
1073 rule := android.NewRuleBuilder()
1074
1075 rule.Command().
1076 Text("(").
1077 BuiltTool(ctx, "apicheck").
1078 Flag("-JXmx1024m").
1079 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1080 OptionalFlag(d.properties.Check_api.Last_released.Args).
1081 Input(apiFile).
1082 Input(d.apiFile).
1083 Input(removedApiFile).
1084 Input(d.removedApiFile)
1085
1086 msg := `\n******************************\n` +
1087 `You have tried to change the API from what has been previously released in\n` +
1088 `an SDK. Please fix the errors listed above.\n` +
1089 `******************************\n`
1090
1091 rule.Command().
1092 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1093 Text(") || (").
1094 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1095 Text("; exit 38").
1096 Text(")")
1097
1098 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001099 }
1100}
1101
1102//
1103// Droidstubs
1104//
1105type Droidstubs struct {
1106 Javadoc
1107
Pete Gillin581d6082018-10-22 15:55:04 +01001108 properties DroidstubsProperties
1109 apiFile android.WritablePath
1110 apiXmlFile android.WritablePath
1111 lastReleasedApiXmlFile android.WritablePath
1112 dexApiFile android.WritablePath
1113 privateApiFile android.WritablePath
1114 privateDexApiFile android.WritablePath
1115 removedApiFile android.WritablePath
1116 removedDexApiFile android.WritablePath
1117 apiMappingFile android.WritablePath
1118 exactApiFile android.WritablePath
1119 proguardFile android.WritablePath
1120 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001121
1122 checkCurrentApiTimestamp android.WritablePath
1123 updateCurrentApiTimestamp android.WritablePath
1124 checkLastReleasedApiTimestamp android.WritablePath
1125
Pete Gillin581d6082018-10-22 15:55:04 +01001126 checkNullabilityWarningsTimestamp android.WritablePath
1127
Nan Zhang1598a9e2018-09-04 17:14:32 -07001128 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001129 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001130
1131 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001132
1133 jdiffDocZip android.WritablePath
1134 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001135}
1136
Colin Crossa3002fc2019-07-08 16:48:04 -07001137// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1138// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1139// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001140func DroidstubsFactory() android.Module {
1141 module := &Droidstubs{}
1142
1143 module.AddProperties(&module.properties,
1144 &module.Javadoc.properties)
1145
1146 InitDroiddocModule(module, android.HostAndDeviceSupported)
1147 return module
1148}
1149
Colin Crossa3002fc2019-07-08 16:48:04 -07001150// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1151// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1152// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1153// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001154func DroidstubsHostFactory() android.Module {
1155 module := &Droidstubs{}
1156
1157 module.AddProperties(&module.properties,
1158 &module.Javadoc.properties)
1159
1160 InitDroiddocModule(module, android.HostSupported)
1161 return module
1162}
1163
1164func (d *Droidstubs) ApiFilePath() android.Path {
1165 return d.apiFilePath
1166}
1167
1168func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1169 d.Javadoc.addDeps(ctx)
1170
Inseob Kim38449af2019-02-28 14:24:05 +09001171 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1172 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1173 }
1174
Nan Zhang1598a9e2018-09-04 17:14:32 -07001175 if len(d.properties.Merge_annotations_dirs) != 0 {
1176 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1177 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1178 }
1179 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001180
Pete Gillin77167902018-09-19 18:16:26 +01001181 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1182 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1183 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1184 }
1185 }
1186
Nan Zhang9c69a122018-08-22 10:22:08 -07001187 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1188 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1189 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1190 }
1191 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001192}
1193
Colin Cross33961b52019-07-11 11:01:22 -07001194func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001195 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1196 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1197 String(d.properties.Api_filename) != "" {
1198 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001199 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001200 d.apiFilePath = d.apiFile
1201 }
1202
1203 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1204 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1205 String(d.properties.Removed_api_filename) != "" {
1206 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001207 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001208 }
1209
1210 if String(d.properties.Private_api_filename) != "" {
1211 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001212 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001213 }
1214
1215 if String(d.properties.Dex_api_filename) != "" {
1216 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001217 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001218 }
1219
1220 if String(d.properties.Private_dex_api_filename) != "" {
1221 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001222 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001223 }
1224
1225 if String(d.properties.Removed_dex_api_filename) != "" {
1226 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001227 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001228 }
1229
1230 if String(d.properties.Exact_api_filename) != "" {
1231 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001232 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001233 }
1234
Nan Zhang9c69a122018-08-22 10:22:08 -07001235 if String(d.properties.Dex_mapping_filename) != "" {
1236 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001237 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001238 }
1239
Nan Zhang199645c2018-09-19 12:40:06 -07001240 if String(d.properties.Proguard_filename) != "" {
1241 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001242 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001243 }
1244
Nan Zhang9c69a122018-08-22 10:22:08 -07001245 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001246 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001247 }
1248
Nan Zhang1598a9e2018-09-04 17:14:32 -07001249 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001250 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001252 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001253 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254}
1255
Colin Cross33961b52019-07-11 11:01:22 -07001256func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001258 cmd.Flag("--include-annotations")
1259
Pete Gillinc382a562018-11-14 18:45:46 +00001260 validatingNullability :=
1261 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1262 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001263 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001264
Pete Gillina262c052018-09-14 14:25:48 +01001265 if !(migratingNullability || validatingNullability) {
1266 ctx.PropertyErrorf("previous_api",
1267 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001268 }
Colin Cross33961b52019-07-11 11:01:22 -07001269
Pete Gillina262c052018-09-14 14:25:48 +01001270 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001271 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001272 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001273 }
Colin Cross33961b52019-07-11 11:01:22 -07001274
Pete Gillinc382a562018-11-14 18:45:46 +00001275 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001276 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001277 }
Colin Cross33961b52019-07-11 11:01:22 -07001278
Pete Gillina262c052018-09-14 14:25:48 +01001279 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001280 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001281 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001282 }
Nan Zhanga40da042018-08-01 12:48:00 -07001283
1284 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001285 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001286
Nan Zhang1598a9e2018-09-04 17:14:32 -07001287 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001288 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001289 "has to be non-empty if annotations was enabled!")
1290 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001291
Colin Cross33961b52019-07-11 11:01:22 -07001292 d.mergeAnnoDirFlags(ctx, cmd)
1293
1294 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1295 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1296 FlagWithArg("--hide ", "SuperfluousPrefix").
1297 FlagWithArg("--hide ", "AnnotationExtraction")
1298 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001299}
1300
Colin Cross33961b52019-07-11 11:01:22 -07001301func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1302 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1303 if t, ok := m.(*ExportedDroiddocDir); ok {
1304 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1305 } else {
1306 ctx.PropertyErrorf("merge_annotations_dirs",
1307 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1308 }
1309 })
1310}
1311
1312func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001313 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1314 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001315 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001316 } else {
1317 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1318 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1319 }
1320 })
Nan Zhanga40da042018-08-01 12:48:00 -07001321}
1322
Colin Cross33961b52019-07-11 11:01:22 -07001323func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001324 if Bool(d.properties.Api_levels_annotations_enabled) {
1325 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001326
1327 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1328 ctx.PropertyErrorf("api_levels_annotations_dirs",
1329 "has to be non-empty if api levels annotations was enabled!")
1330 }
1331
Colin Cross33961b52019-07-11 11:01:22 -07001332 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1333 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1334 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1335 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001336
1337 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1338 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001339 for _, dep := range t.deps {
1340 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001341 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001342 }
1343 }
Colin Cross33961b52019-07-11 11:01:22 -07001344 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001345 } else {
1346 ctx.PropertyErrorf("api_levels_annotations_dirs",
1347 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1348 }
1349 })
1350
1351 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001352}
1353
Colin Cross33961b52019-07-11 11:01:22 -07001354func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001355 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1356 if d.apiFile.String() == "" {
1357 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1358 }
1359
1360 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001361 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001362
1363 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1364 ctx.PropertyErrorf("check_api.last_released.api_file",
1365 "has to be non-empty if jdiff was enabled!")
1366 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001367
Colin Cross33961b52019-07-11 11:01:22 -07001368 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001369 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001370 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1371 }
1372}
Nan Zhang71bbe632018-09-17 14:32:21 -07001373
Colin Cross33961b52019-07-11 11:01:22 -07001374func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1375 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1376 cmd := rule.Command().BuiltTool(ctx, "metalava").
1377 Flag(config.JavacVmFlags).
1378 FlagWithArg("-encoding ", "UTF-8").
1379 FlagWithArg("-source ", javaVersion).
1380 FlagWithRspFileInputList("@", srcs).
1381 FlagWithInput("@", srcJarList)
1382
1383 if len(bootclasspath) > 0 {
1384 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001385 }
1386
Colin Cross33961b52019-07-11 11:01:22 -07001387 if len(classpath) > 0 {
1388 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1389 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001390
Colin Cross33961b52019-07-11 11:01:22 -07001391 if len(sourcepaths) > 0 {
1392 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1393 } else {
1394 cmd.FlagWithArg("-sourcepath ", `""`)
1395 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001396
Colin Cross33961b52019-07-11 11:01:22 -07001397 cmd.Flag("--no-banner").
1398 Flag("--color").
1399 Flag("--quiet").
1400 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001401
Colin Cross33961b52019-07-11 11:01:22 -07001402 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001403}
1404
Nan Zhang1598a9e2018-09-04 17:14:32 -07001405func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001406 deps := d.Javadoc.collectDeps(ctx)
1407
1408 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001409
Colin Cross33961b52019-07-11 11:01:22 -07001410 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001411
Colin Crossdaa4c672019-07-15 22:53:46 -07001412 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001413
Colin Cross33961b52019-07-11 11:01:22 -07001414 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1415 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001416
Colin Cross33961b52019-07-11 11:01:22 -07001417 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001418
Colin Cross33961b52019-07-11 11:01:22 -07001419 rule.Command().Text("rm -rf").Text(stubsDir.String())
1420 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001421
Colin Cross33961b52019-07-11 11:01:22 -07001422 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1423
1424 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1425 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1426
1427 d.stubsFlags(ctx, cmd, stubsDir)
1428
1429 d.annotationsFlags(ctx, cmd)
1430 d.inclusionAnnotationsFlags(ctx, cmd)
1431 d.apiLevelsAnnotationsFlags(ctx, cmd)
1432 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001433
Nan Zhang1598a9e2018-09-04 17:14:32 -07001434 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1435 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1436 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1437 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1438 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001439 }
Colin Cross33961b52019-07-11 11:01:22 -07001440
1441 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1442 for _, o := range d.Javadoc.properties.Out {
1443 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1444 }
1445
1446 rule.Command().
1447 BuiltTool(ctx, "soong_zip").
1448 Flag("-write_if_changed").
1449 Flag("-jar").
1450 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1451 FlagWithArg("-C ", stubsDir.String()).
1452 FlagWithArg("-D ", stubsDir.String())
1453 rule.Restat()
1454
1455 zipSyncCleanupCmd(rule, srcJarDir)
1456
1457 rule.Build(pctx, ctx, "metalava", "metalava")
1458
1459 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001460
Nan Zhang1598a9e2018-09-04 17:14:32 -07001461 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1462 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001463
1464 if len(d.Javadoc.properties.Out) > 0 {
1465 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1466 }
1467
1468 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1469 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001470 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1471 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001472
Nan Zhang2760dfc2018-08-24 17:32:54 +00001473 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001474
Colin Cross33961b52019-07-11 11:01:22 -07001475 rule := android.NewRuleBuilder()
1476
1477 rule.Command().Text("( true")
1478
1479 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1480 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1481
1482 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1483 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1484
1485 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1486 FlagWithInput("--check-compatibility:api:current ", apiFile).
1487 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1488
1489 d.inclusionAnnotationsFlags(ctx, cmd)
1490 d.mergeAnnoDirFlags(ctx, cmd)
1491
Adrian Roos14f75a92019-08-12 17:54:09 +02001492 if baselineFile.Valid() {
1493 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1494 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1495 }
1496
Colin Cross33961b52019-07-11 11:01:22 -07001497 zipSyncCleanupCmd(rule, srcJarDir)
1498
1499 msg := fmt.Sprintf(`\n******************************\n`+
1500 `You have tried to change the API from what has been previously approved.\n\n`+
1501 `To make these errors go away, you have two choices:\n`+
1502 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1503 ` errors above.\n\n`+
1504 ` 2. You can update current.txt by executing the following command:\n`+
1505 ` make %s-update-current-api\n\n`+
1506 ` To submit the revised current.txt to the main Android repository,\n`+
1507 ` you will need approval.\n`+
1508 `******************************\n`, ctx.ModuleName())
1509
1510 rule.Command().
1511 Text("touch").Output(d.checkCurrentApiTimestamp).
1512 Text(") || (").
1513 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1514 Text("; exit 38").
1515 Text(")")
1516
1517 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001518
1519 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001520
1521 // update API rule
1522 rule = android.NewRuleBuilder()
1523
1524 rule.Command().Text("( true")
1525
1526 rule.Command().
1527 Text("cp").Flag("-f").
1528 Input(d.apiFile).Flag(apiFile.String())
1529
1530 rule.Command().
1531 Text("cp").Flag("-f").
1532 Input(d.removedApiFile).Flag(removedApiFile.String())
1533
1534 msg = "failed to update public API"
1535
1536 rule.Command().
1537 Text("touch").Output(d.updateCurrentApiTimestamp).
1538 Text(") || (").
1539 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1540 Text("; exit 38").
1541 Text(")")
1542
1543 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001544 }
Nan Zhanga40da042018-08-01 12:48:00 -07001545
Nan Zhang1598a9e2018-09-04 17:14:32 -07001546 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1547 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001548
1549 if len(d.Javadoc.properties.Out) > 0 {
1550 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1551 }
1552
1553 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1554 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001555 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1556 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001557
Nan Zhang2760dfc2018-08-24 17:32:54 +00001558 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001559
Colin Cross33961b52019-07-11 11:01:22 -07001560 rule := android.NewRuleBuilder()
1561
1562 rule.Command().Text("( true")
1563
1564 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1565 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1566
1567 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1568 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1569
1570 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1571 FlagWithInput("--check-compatibility:api:released ", apiFile)
1572
1573 d.inclusionAnnotationsFlags(ctx, cmd)
1574
1575 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1576
1577 d.mergeAnnoDirFlags(ctx, cmd)
1578
Adrian Roos14f75a92019-08-12 17:54:09 +02001579 if baselineFile.Valid() {
1580 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1581 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1582 }
1583
Colin Cross33961b52019-07-11 11:01:22 -07001584 zipSyncCleanupCmd(rule, srcJarDir)
1585
1586 msg := `\n******************************\n` +
1587 `You have tried to change the API from what has been previously released in\n` +
1588 `an SDK. Please fix the errors listed above.\n` +
1589 `******************************\n`
1590 rule.Command().
1591 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1592 Text(") || (").
1593 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1594 Text("; exit 38").
1595 Text(")")
1596
1597 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001598 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001599
Pete Gillin581d6082018-10-22 15:55:04 +01001600 if String(d.properties.Check_nullability_warnings) != "" {
1601 if d.nullabilityWarningsFile == nil {
1602 ctx.PropertyErrorf("check_nullability_warnings",
1603 "Cannot specify check_nullability_warnings unless validating nullability")
1604 }
Colin Cross33961b52019-07-11 11:01:22 -07001605
1606 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1607
Pete Gillin581d6082018-10-22 15:55:04 +01001608 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001609
Pete Gillin581d6082018-10-22 15:55:04 +01001610 msg := fmt.Sprintf(`\n******************************\n`+
1611 `The warnings encountered during nullability annotation validation did\n`+
1612 `not match the checked in file of expected warnings. The diffs are shown\n`+
1613 `above. You have two options:\n`+
1614 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1615 ` 2. Update the file of expected warnings by running:\n`+
1616 ` cp %s %s\n`+
1617 ` and submitting the updated file as part of your change.`,
1618 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001619
1620 rule := android.NewRuleBuilder()
1621
1622 rule.Command().
1623 Text("(").
1624 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1625 Text("&&").
1626 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1627 Text(") || (").
1628 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1629 Text("; exit 38").
1630 Text(")")
1631
1632 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001633 }
1634
Nan Zhang71bbe632018-09-17 14:32:21 -07001635 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001636 if len(d.Javadoc.properties.Out) > 0 {
1637 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1638 }
1639
1640 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1641 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1642 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1643
1644 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001645
Nan Zhang86b06202018-09-21 17:09:21 -07001646 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1647 // since there's cron job downstream that fetch this .zip file periodically.
1648 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001649 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1650 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1651
Nan Zhang71bbe632018-09-17 14:32:21 -07001652 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001653
Colin Cross33961b52019-07-11 11:01:22 -07001654 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1655 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001656
Colin Cross33961b52019-07-11 11:01:22 -07001657 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1658
Colin Crossdaa4c672019-07-15 22:53:46 -07001659 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001660 deps.bootClasspath, deps.classpath, d.sourcepaths)
1661
1662 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001663 Flag("-XDignore.symbol.file").
1664 FlagWithArg("-doclet ", "jdiff.JDiff").
1665 FlagWithInput("-docletpath ", jdiff).
1666 Flag("-quiet").
1667 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1668 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1669 Implicit(d.apiXmlFile).
1670 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1671 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1672 Implicit(d.lastReleasedApiXmlFile)
1673
Colin Cross33961b52019-07-11 11:01:22 -07001674 rule.Command().
1675 BuiltTool(ctx, "soong_zip").
1676 Flag("-write_if_changed").
1677 Flag("-d").
1678 FlagWithOutput("-o ", d.jdiffDocZip).
1679 FlagWithArg("-C ", outDir.String()).
1680 FlagWithArg("-D ", outDir.String())
1681
1682 rule.Command().
1683 BuiltTool(ctx, "soong_zip").
1684 Flag("-write_if_changed").
1685 Flag("-jar").
1686 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1687 FlagWithArg("-C ", stubsDir.String()).
1688 FlagWithArg("-D ", stubsDir.String())
1689
1690 rule.Restat()
1691
1692 zipSyncCleanupCmd(rule, srcJarDir)
1693
1694 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001695 }
Nan Zhang581fd212018-01-10 16:06:12 -08001696}
Dan Willemsencc090972018-02-26 14:33:31 -08001697
Nan Zhanga40da042018-08-01 12:48:00 -07001698//
Nan Zhangf4936b02018-08-01 15:00:28 -07001699// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001700//
Dan Willemsencc090972018-02-26 14:33:31 -08001701var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001702var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001703var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001704var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001705
Nan Zhangf4936b02018-08-01 15:00:28 -07001706type ExportedDroiddocDirProperties struct {
1707 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001708 Path *string
1709}
1710
Nan Zhangf4936b02018-08-01 15:00:28 -07001711type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001712 android.ModuleBase
1713
Nan Zhangf4936b02018-08-01 15:00:28 -07001714 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001715
1716 deps android.Paths
1717 dir android.Path
1718}
1719
Colin Crossa3002fc2019-07-08 16:48:04 -07001720// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001721func ExportedDroiddocDirFactory() android.Module {
1722 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001723 module.AddProperties(&module.properties)
1724 android.InitAndroidModule(module)
1725 return module
1726}
1727
Nan Zhangf4936b02018-08-01 15:00:28 -07001728func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001729
Nan Zhangf4936b02018-08-01 15:00:28 -07001730func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001731 path := String(d.properties.Path)
1732 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001733 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001734}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001735
1736//
1737// Defaults
1738//
1739type DocDefaults struct {
1740 android.ModuleBase
1741 android.DefaultsModuleBase
1742}
1743
Nan Zhangb2b33de2018-02-23 11:18:47 -08001744func DocDefaultsFactory() android.Module {
1745 module := &DocDefaults{}
1746
1747 module.AddProperties(
1748 &JavadocProperties{},
1749 &DroiddocProperties{},
1750 )
1751
1752 android.InitDefaultsModule(module)
1753
1754 return module
1755}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001756
1757func StubsDefaultsFactory() android.Module {
1758 module := &DocDefaults{}
1759
1760 module.AddProperties(
1761 &JavadocProperties{},
1762 &DroidstubsProperties{},
1763 )
1764
1765 android.InitDefaultsModule(module)
1766
1767 return module
1768}
Colin Cross33961b52019-07-11 11:01:22 -07001769
1770func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1771 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1772
1773 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1774 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1775 srcJarList := srcJarDir.Join(ctx, "list")
1776
1777 rule.Temporary(srcJarList)
1778
1779 rule.Command().BuiltTool(ctx, "zipsync").
1780 FlagWithArg("-d ", srcJarDir.String()).
1781 FlagWithOutput("-l ", srcJarList).
1782 FlagWithArg("-f ", `"*.java"`).
1783 Inputs(srcJars)
1784
1785 return srcJarList
1786}
1787
1788func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1789 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1790}