blob: 5deac5ea951daaa478cc738e53baaff100c71376 [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
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080029 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070030 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080031
Nan Zhang581fd212018-01-10 16:06:12 -080032 android.RegisterModuleType("droiddoc", DroiddocFactory)
33 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070034 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080035 android.RegisterModuleType("javadoc", JavadocFactory)
36 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070037
38 android.RegisterModuleType("droidstubs", DroidstubsFactory)
39 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080040}
41
Colin Crossa1ce2a02018-06-20 15:19:39 -070042var (
43 srcsLibTag = dependencyTag{name: "sources from javalib"}
44)
45
Nan Zhang581fd212018-01-10 16:06:12 -080046type JavadocProperties struct {
47 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
48 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080049 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080050
51 // list of directories rooted at the Android.bp file that will
52 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080053 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080054
55 // list of source files that should not be used to build the Java module.
56 // This is most useful in the arch/multilib variants to remove non-common files
57 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080058 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080059
Nan Zhangb2b33de2018-02-23 11:18:47 -080060 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080061 Libs []string `android:"arch_variant"`
62
63 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080064 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080065
66 // if not blank, set to the version of the sdk to compile against
67 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090068
69 Aidl struct {
70 // Top level directories to pass to aidl tool
71 Include_dirs []string
72
73 // Directories rooted at the Android.bp file to pass to aidl tool
74 Local_include_dirs []string
75 }
Nan Zhang357466b2018-04-17 17:38:36 -070076
77 // If not blank, set the java version passed to javadoc as -source
78 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070079
80 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080081 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070082
83 // user customized droiddoc args.
84 // Available variables for substitution:
85 //
86 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070087 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070088 Args *string
89
90 // names of the output files used in args that will be generated
91 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -080092}
93
Nan Zhang61819ce2018-05-04 18:49:16 -070094type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +090095 // path to the API txt file that the new API extracted from source code is checked
96 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -080097 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -070098
Jiyong Parkeeb8a642018-05-12 22:21:20 +090099 // path to the API txt file that the new @removed API extractd from source code is
100 // checked against. The path can be local to the module or from other module (via
101 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800102 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700103
Adrian Roos14f75a92019-08-12 17:54:09 +0200104 // If not blank, path to the baseline txt file for approved API check violations.
105 Baseline_file *string `android:"path"`
106
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900107 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700108 Args *string
109}
110
Nan Zhang581fd212018-01-10 16:06:12 -0800111type DroiddocProperties struct {
112 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800113 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800114
Nan Zhanga40da042018-08-01 12:48:00 -0700115 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800116 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800117
118 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800119 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800120
121 // proofread file contains all of the text content of the javadocs concatenated into one file,
122 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700123 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
125 // a todo file lists the program elements that are missing documentation.
126 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800127 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800128
129 // directory under current module source that provide additional resources (images).
130 Resourcesdir *string
131
132 // resources output directory under out/soong/.intermediates.
133 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
Nan Zhange2ba5d42018-07-11 15:16:55 -0700135 // if set to true, collect the values used by the Dev tools and
136 // write them in files packaged with the SDK. Defaults to false.
137 Write_sdk_values *bool
138
139 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800140 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700141
142 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800143 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700144
Nan Zhang581fd212018-01-10 16:06:12 -0800145 // a list of files under current module source dir which contains known tags in Java sources.
146 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800147 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700148
149 // the tag name used to distinguish if the API files belong to public/system/test.
150 Api_tag_name *string
151
152 // the generated public API filename by Doclava.
153 Api_filename *string
154
David Brazdilfbe4cc32018-05-31 13:56:46 +0100155 // the generated public Dex API filename by Doclava.
156 Dex_api_filename *string
157
Nan Zhang28c68b92018-03-13 16:17:01 -0700158 // the generated private API filename by Doclava.
159 Private_api_filename *string
160
161 // the generated private Dex API filename by Doclava.
162 Private_dex_api_filename *string
163
164 // the generated removed API filename by Doclava.
165 Removed_api_filename *string
166
David Brazdilaac0c3c2018-04-24 16:23:29 +0100167 // the generated removed Dex API filename by Doclava.
168 Removed_dex_api_filename *string
169
Mathew Inwood76c3de12018-06-22 15:28:11 +0100170 // mapping of dex signatures to source file and line number. This is a temporary property and
171 // will be deleted; you probably shouldn't be using it.
172 Dex_mapping_filename *string
173
Nan Zhang28c68b92018-03-13 16:17:01 -0700174 // the generated exact API filename by Doclava.
175 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700176
Nan Zhang66dc2362018-08-14 20:41:04 -0700177 // the generated proguard filename by Doclava.
178 Proguard_filename *string
179
Nan Zhang853f4202018-04-12 16:55:56 -0700180 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
181 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700182
183 Check_api struct {
184 Last_released ApiToCheck
185
186 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900187
188 // do not perform API check against Last_released, in the case that both two specified API
189 // files by Last_released are modules which don't exist.
190 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700191 }
Nan Zhang79614d12018-04-19 18:03:39 -0700192
Nan Zhang1598a9e2018-09-04 17:14:32 -0700193 // if set to true, generate docs through Dokka instead of Doclava.
194 Dokka_enabled *bool
195}
196
197type DroidstubsProperties struct {
198 // the tag name used to distinguish if the API files belong to public/system/test.
199 Api_tag_name *string
200
Nan Zhang199645c2018-09-19 12:40:06 -0700201 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700202 Api_filename *string
203
Nan Zhang199645c2018-09-19 12:40:06 -0700204 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700205 Dex_api_filename *string
206
Nan Zhang199645c2018-09-19 12:40:06 -0700207 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700208 Private_api_filename *string
209
Nan Zhang199645c2018-09-19 12:40:06 -0700210 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700211 Private_dex_api_filename *string
212
Nan Zhang199645c2018-09-19 12:40:06 -0700213 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700214 Removed_api_filename *string
215
Nan Zhang199645c2018-09-19 12:40:06 -0700216 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700217 Removed_dex_api_filename *string
218
Nan Zhang9c69a122018-08-22 10:22:08 -0700219 // mapping of dex signatures to source file and line number. This is a temporary property and
220 // will be deleted; you probably shouldn't be using it.
221 Dex_mapping_filename *string
222
Nan Zhang199645c2018-09-19 12:40:06 -0700223 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700224 Exact_api_filename *string
225
Nan Zhang199645c2018-09-19 12:40:06 -0700226 // the generated proguard filename by Metalava.
227 Proguard_filename *string
228
Nan Zhang1598a9e2018-09-04 17:14:32 -0700229 Check_api struct {
230 Last_released ApiToCheck
231
232 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900233
234 // do not perform API check against Last_released, in the case that both two specified API
235 // files by Last_released are modules which don't exist.
236 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700237 }
Nan Zhang79614d12018-04-19 18:03:39 -0700238
239 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800240 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700241
242 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700243 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700244
Pete Gillin77167902018-09-19 18:16:26 +0100245 // 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 -0700246 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700247
Pete Gillin77167902018-09-19 18:16:26 +0100248 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
249 Merge_inclusion_annotations_dirs []string
250
Pete Gillinc382a562018-11-14 18:45:46 +0000251 // a file containing a list of classes to do nullability validation for.
252 Validate_nullability_from_list *string
253
Pete Gillin581d6082018-10-22 15:55:04 +0100254 // a file containing expected warnings produced by validation of nullability annotations.
255 Check_nullability_warnings *string
256
Nan Zhang1598a9e2018-09-04 17:14:32 -0700257 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
258 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700259
260 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
261 Api_levels_annotations_enabled *bool
262
263 // the dirs which Metalava extracts API levels annotations from.
264 Api_levels_annotations_dirs []string
265
266 // if set to true, collect the values used by the Dev tools and
267 // write them in files packaged with the SDK. Defaults to false.
268 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700269
270 // If set to true, .xml based public API file will be also generated, and
271 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
272 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800273}
274
Nan Zhanga40da042018-08-01 12:48:00 -0700275//
276// Common flags passed down to build rule
277//
278type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700279 bootClasspathArgs string
280 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700281 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700282 dokkaClasspathArgs string
283 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700284 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700285
Nan Zhanga40da042018-08-01 12:48:00 -0700286 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700287 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700288 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700289}
290
291func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
292 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
293 android.InitDefaultableModule(module)
294}
295
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200296func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
297 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
298 return false
299 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700300 return true
301 } else if String(apiToCheck.Api_file) != "" {
302 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
303 } else if String(apiToCheck.Removed_api_file) != "" {
304 panic("for " + apiVersionTag + " api_file has to be non-empty!")
305 }
306
307 return false
308}
309
Inseob Kim38449af2019-02-28 14:24:05 +0900310func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
311 api_file := String(apiToCheck.Api_file)
312 removed_api_file := String(apiToCheck.Removed_api_file)
313
314 api_module := android.SrcIsModule(api_file)
315 removed_api_module := android.SrcIsModule(removed_api_file)
316
317 if api_module == "" || removed_api_module == "" {
318 return
319 }
320
321 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
322 return
323 }
324
325 apiToCheck.Api_file = nil
326 apiToCheck.Removed_api_file = nil
327}
328
Nan Zhang1598a9e2018-09-04 17:14:32 -0700329type ApiFilePath interface {
330 ApiFilePath() android.Path
331}
332
Nan Zhanga40da042018-08-01 12:48:00 -0700333//
334// Javadoc
335//
Nan Zhang581fd212018-01-10 16:06:12 -0800336type Javadoc struct {
337 android.ModuleBase
338 android.DefaultableModuleBase
339
340 properties JavadocProperties
341
342 srcJars android.Paths
343 srcFiles android.Paths
344 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700345 argFiles android.Paths
346
347 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800348
Nan Zhangccff0f72018-03-08 17:26:16 -0800349 docZip android.WritablePath
350 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800351}
352
Colin Cross41955e82019-05-29 14:40:35 -0700353func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
354 switch tag {
355 case "":
356 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700357 case ".docs.zip":
358 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700359 default:
360 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
361 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800362}
363
Colin Crossa3002fc2019-07-08 16:48:04 -0700364// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800365func JavadocFactory() android.Module {
366 module := &Javadoc{}
367
368 module.AddProperties(&module.properties)
369
370 InitDroiddocModule(module, android.HostAndDeviceSupported)
371 return module
372}
373
Colin Crossa3002fc2019-07-08 16:48:04 -0700374// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800375func JavadocHostFactory() android.Module {
376 module := &Javadoc{}
377
378 module.AddProperties(&module.properties)
379
380 InitDroiddocModule(module, android.HostSupported)
381 return module
382}
383
Colin Cross41955e82019-05-29 14:40:35 -0700384var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800385
Colin Cross83bb3162018-06-25 15:48:06 -0700386func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900387 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700388}
389
390func (j *Javadoc) minSdkVersion() string {
391 return j.sdkVersion()
392}
393
Dan Willemsen419290a2018-10-31 15:28:47 -0700394func (j *Javadoc) targetSdkVersion() string {
395 return j.sdkVersion()
396}
397
Nan Zhang581fd212018-01-10 16:06:12 -0800398func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
399 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100400 sdkDep := decodeSdkDep(ctx, sdkContext(j))
401 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700402 if sdkDep.useDefaultLibs {
403 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
404 if ctx.Config().TargetOpenJDK9() {
405 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
406 }
Paul Duffin250e6192019-06-07 10:44:37 +0100407 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700408 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
409 }
410 } else if sdkDep.useModule {
411 if ctx.Config().TargetOpenJDK9() {
412 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
413 }
414 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700415 }
Nan Zhang581fd212018-01-10 16:06:12 -0800416 }
417 }
418
Colin Cross42d48b72018-08-29 14:10:52 -0700419 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800420}
421
Nan Zhanga40da042018-08-01 12:48:00 -0700422func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
423 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900424
Colin Cross3047fa22019-04-18 10:56:44 -0700425 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900426
427 return flags
428}
429
430func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700431 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900432
433 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
434 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
435
436 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700437 var deps android.Paths
438
Jiyong Park1e440682018-05-23 18:42:04 +0900439 if aidlPreprocess.Valid() {
440 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700441 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900442 } else {
443 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
444 }
445
446 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
447 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
448 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
449 flags = append(flags, "-I"+src.String())
450 }
451
Colin Cross3047fa22019-04-18 10:56:44 -0700452 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900453}
454
Jiyong Parkd90d7412019-08-20 22:49:19 +0900455// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900456func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700457 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900458
459 outSrcFiles := make(android.Paths, 0, len(srcFiles))
460
Jiyong Park1112c4c2019-08-16 21:12:10 +0900461 aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
462
Jiyong Park1e440682018-05-23 18:42:04 +0900463 for _, srcFile := range srcFiles {
464 switch srcFile.Ext() {
465 case ".aidl":
Jiyong Park1112c4c2019-08-16 21:12:10 +0900466 javaFile := genAidl(ctx, srcFile, flags.aidlFlags+aidlIncludeFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900467 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900468 case ".logtags":
469 javaFile := genLogtags(ctx, srcFile)
470 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900471 default:
472 outSrcFiles = append(outSrcFiles, srcFile)
473 }
474 }
475
476 return outSrcFiles
477}
478
Nan Zhang581fd212018-01-10 16:06:12 -0800479func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
480 var deps deps
481
Colin Cross83bb3162018-06-25 15:48:06 -0700482 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800483 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700484 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800485 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700486 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800487 }
488
489 ctx.VisitDirectDeps(func(module android.Module) {
490 otherName := ctx.OtherModuleName(module)
491 tag := ctx.OtherModuleDependencyTag(module)
492
Colin Cross2d24c1b2018-05-23 10:59:18 -0700493 switch tag {
494 case bootClasspathTag:
495 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800496 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700497 } else {
498 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
499 }
500 case libTag:
501 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800502 case SdkLibraryDependency:
503 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700504 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900505 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Jiyong Park19a7f252019-07-10 16:59:31 +0900506 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700507 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800508 checkProducesJars(ctx, dep)
509 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800510 default:
511 ctx.ModuleErrorf("depends on non-java module %q", otherName)
512 }
Nan Zhang357466b2018-04-17 17:38:36 -0700513 case systemModulesTag:
514 if deps.systemModules != nil {
515 panic("Found two system module dependencies")
516 }
517 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000518 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700519 panic("Missing directory for system module dependency")
520 }
Colin Crossb77043e2019-07-16 13:57:13 -0700521 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800522 }
523 })
524 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
525 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800526 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700527 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900528 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800529
530 // srcs may depend on some genrule output.
531 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800532 j.srcJars = append(j.srcJars, deps.srcJars...)
533
Nan Zhang581fd212018-01-10 16:06:12 -0800534 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800535 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800536
Nan Zhang9c69a122018-08-22 10:22:08 -0700537 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800538 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
539 }
540 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800541
Colin Cross8a497952019-03-05 22:25:09 -0800542 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000543 argFilesMap := map[string]string{}
544 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700545
Paul Duffin99e4a502019-02-11 15:38:42 +0000546 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800547 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000548 if _, exists := argFilesMap[label]; !exists {
549 argFilesMap[label] = strings.Join(paths.Strings(), " ")
550 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700551 } else {
552 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000553 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700554 }
555 }
556
557 var err error
Colin Cross15638152019-07-11 11:11:35 -0700558 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700559 if strings.HasPrefix(name, "location ") {
560 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000561 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700562 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700563 } else {
Colin Cross15638152019-07-11 11:11:35 -0700564 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000565 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700566 }
567 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700568 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700569 }
Colin Cross15638152019-07-11 11:11:35 -0700570 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700571 })
572
573 if err != nil {
574 ctx.PropertyErrorf("args", "%s", err.Error())
575 }
576
Nan Zhang581fd212018-01-10 16:06:12 -0800577 return deps
578}
579
580func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
581 j.addDeps(ctx)
582}
583
584func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
585 deps := j.collectDeps(ctx)
586
Colin Crossdaa4c672019-07-15 22:53:46 -0700587 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800588
Colin Crossdaa4c672019-07-15 22:53:46 -0700589 outDir := android.PathForModuleOut(ctx, "out")
590 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
591
592 j.stubsSrcJar = nil
593
594 rule := android.NewRuleBuilder()
595
596 rule.Command().Text("rm -rf").Text(outDir.String())
597 rule.Command().Text("mkdir -p").Text(outDir.String())
598
599 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700600
Colin Cross83bb3162018-06-25 15:48:06 -0700601 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800602
Colin Crossdaa4c672019-07-15 22:53:46 -0700603 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
604 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800605
Colin Crossdaa4c672019-07-15 22:53:46 -0700606 cmd.FlagWithArg("-source ", javaVersion).
607 Flag("-J-Xmx1024m").
608 Flag("-XDignore.symbol.file").
609 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800610
Colin Crossdaa4c672019-07-15 22:53:46 -0700611 rule.Command().
612 BuiltTool(ctx, "soong_zip").
613 Flag("-write_if_changed").
614 Flag("-d").
615 FlagWithOutput("-o ", j.docZip).
616 FlagWithArg("-C ", outDir.String()).
617 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700618
Colin Crossdaa4c672019-07-15 22:53:46 -0700619 rule.Restat()
620
621 zipSyncCleanupCmd(rule, srcJarDir)
622
623 rule.Build(pctx, ctx, "javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800624}
625
Nan Zhanga40da042018-08-01 12:48:00 -0700626//
627// Droiddoc
628//
629type Droiddoc struct {
630 Javadoc
631
632 properties DroiddocProperties
633 apiFile android.WritablePath
634 dexApiFile android.WritablePath
635 privateApiFile android.WritablePath
636 privateDexApiFile android.WritablePath
637 removedApiFile android.WritablePath
638 removedDexApiFile android.WritablePath
639 exactApiFile android.WritablePath
640 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700641 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700642
643 checkCurrentApiTimestamp android.WritablePath
644 updateCurrentApiTimestamp android.WritablePath
645 checkLastReleasedApiTimestamp android.WritablePath
646
Nan Zhanga40da042018-08-01 12:48:00 -0700647 apiFilePath android.Path
648}
649
Colin Crossa3002fc2019-07-08 16:48:04 -0700650// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700651func DroiddocFactory() android.Module {
652 module := &Droiddoc{}
653
654 module.AddProperties(&module.properties,
655 &module.Javadoc.properties)
656
657 InitDroiddocModule(module, android.HostAndDeviceSupported)
658 return module
659}
660
Colin Crossa3002fc2019-07-08 16:48:04 -0700661// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700662func DroiddocHostFactory() android.Module {
663 module := &Droiddoc{}
664
665 module.AddProperties(&module.properties,
666 &module.Javadoc.properties)
667
668 InitDroiddocModule(module, android.HostSupported)
669 return module
670}
671
672func (d *Droiddoc) ApiFilePath() android.Path {
673 return d.apiFilePath
674}
675
Nan Zhang581fd212018-01-10 16:06:12 -0800676func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
677 d.Javadoc.addDeps(ctx)
678
Inseob Kim38449af2019-02-28 14:24:05 +0900679 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
680 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
681 }
682
Nan Zhang79614d12018-04-19 18:03:39 -0700683 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800684 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
685 }
Nan Zhang581fd212018-01-10 16:06:12 -0800686}
687
Colin Crossab054432019-07-15 16:13:59 -0700688func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang443fa522018-08-20 20:58:28 -0700689 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
690 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
691 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700692 cmd.FlagWithArg("-source ", "1.8").
693 Flag("-J-Xmx1600m").
694 Flag("-J-XX:-OmitStackTraceInFastThrow").
695 Flag("-XDignore.symbol.file").
696 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
697 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
698 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
Elliott Hughes26bce342019-09-12 15:05:13 -0700699 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 -0700700
Nan Zhanga40da042018-08-01 12:48:00 -0700701 if String(d.properties.Custom_template) == "" {
702 // TODO: This is almost always droiddoc-templates-sdk
703 ctx.PropertyErrorf("custom_template", "must specify a template")
704 }
705
706 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700707 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700708 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700709 } else {
710 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
711 }
712 })
713
714 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700715 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
716 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
717 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700718 }
719
720 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700721 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
722 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
723 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700724 }
725
726 if len(d.properties.Html_dirs) > 2 {
727 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
728 }
729
Colin Cross8a497952019-03-05 22:25:09 -0800730 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700731 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700732
Colin Crossab054432019-07-15 16:13:59 -0700733 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700734
735 if String(d.properties.Proofread_file) != "" {
736 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700737 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700738 }
739
740 if String(d.properties.Todo_file) != "" {
741 // tricky part:
742 // we should not compute full path for todo_file through PathForModuleOut().
743 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700744 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
745 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700746 }
747
748 if String(d.properties.Resourcesdir) != "" {
749 // TODO: should we add files under resourcesDir to the implicits? It seems that
750 // resourcesDir is one sub dir of htmlDir
751 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700752 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700753 }
754
755 if String(d.properties.Resourcesoutdir) != "" {
756 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700757 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700758 }
Nan Zhanga40da042018-08-01 12:48:00 -0700759}
760
Colin Crossab054432019-07-15 16:13:59 -0700761func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200762 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
763 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700764 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700765
Nan Zhanga40da042018-08-01 12:48:00 -0700766 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700767 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700768 d.apiFilePath = d.apiFile
769 }
770
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200771 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
772 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -0700773 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700774 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700775 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700776 }
777
778 if String(d.properties.Private_api_filename) != "" {
779 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700780 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700781 }
782
783 if String(d.properties.Dex_api_filename) != "" {
784 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700785 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700786 }
787
788 if String(d.properties.Private_dex_api_filename) != "" {
789 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700790 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700791 }
792
793 if String(d.properties.Removed_dex_api_filename) != "" {
794 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700795 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700796 }
797
798 if String(d.properties.Exact_api_filename) != "" {
799 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700800 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700801 }
802
803 if String(d.properties.Dex_mapping_filename) != "" {
804 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700805 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700806 }
807
Nan Zhang66dc2362018-08-14 20:41:04 -0700808 if String(d.properties.Proguard_filename) != "" {
809 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700810 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700811 }
812
Nan Zhanga40da042018-08-01 12:48:00 -0700813 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700814 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700815 }
816
817 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700818 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700819 }
Nan Zhanga40da042018-08-01 12:48:00 -0700820}
821
Colin Crossab054432019-07-15 16:13:59 -0700822func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700823 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700824 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
825 rule.Command().Text("cp").
826 Input(staticDocIndexRedirect).
827 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700828 }
829
830 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700831 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
832 rule.Command().Text("cp").
833 Input(staticDocProperties).
834 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700835 }
Nan Zhanga40da042018-08-01 12:48:00 -0700836}
837
Colin Crossab054432019-07-15 16:13:59 -0700838func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700839 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700840
841 cmd := rule.Command().
842 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
843 Flag(config.JavacVmFlags).
844 FlagWithArg("-encoding ", "UTF-8").
Colin Crossab054432019-07-15 16:13:59 -0700845 FlagWithRspFileInputList("@", srcs).
846 FlagWithInput("@", srcJarList)
847
Colin Crossab054432019-07-15 16:13:59 -0700848 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
849 // based stubs generation.
850 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
851 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
852 // the correct package name base path.
853 if len(sourcepaths) > 0 {
854 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
855 } else {
856 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
857 }
858
859 cmd.FlagWithArg("-d ", outDir.String()).
860 Flag("-quiet")
861
862 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700863}
864
Colin Crossdaa4c672019-07-15 22:53:46 -0700865func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
866 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
867 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
868
869 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
870
871 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
872 cmd.Flag(flag).Implicits(deps)
873
874 cmd.FlagWithArg("--patch-module ", "java.base=.")
875
876 if len(classpath) > 0 {
877 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
878 }
879
880 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700881}
882
Colin Crossdaa4c672019-07-15 22:53:46 -0700883func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
884 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
885 sourcepaths android.Paths) *android.RuleBuilderCommand {
886
887 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
888
889 if len(bootclasspath) == 0 && ctx.Device() {
890 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
891 // ensure java does not fall back to the default bootclasspath.
892 cmd.FlagWithArg("-bootclasspath ", `""`)
893 } else if len(bootclasspath) > 0 {
894 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
895 }
896
897 if len(classpath) > 0 {
898 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
899 }
900
901 return cmd
902}
903
Colin Crossab054432019-07-15 16:13:59 -0700904func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
905 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700906
Colin Crossab054432019-07-15 16:13:59 -0700907 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
908 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
909
910 return rule.Command().
911 BuiltTool(ctx, "dokka").
912 Flag(config.JavacVmFlags).
913 Flag(srcJarDir.String()).
914 FlagWithInputList("-classpath ", dokkaClasspath, ":").
915 FlagWithArg("-format ", "dac").
916 FlagWithArg("-dacRoot ", "/reference/kotlin").
917 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700918}
919
920func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
921 deps := d.Javadoc.collectDeps(ctx)
922
Colin Crossdaa4c672019-07-15 22:53:46 -0700923 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
924 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
925
Nan Zhang1598a9e2018-09-04 17:14:32 -0700926 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
927 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
928 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
929 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
930
Colin Crossab054432019-07-15 16:13:59 -0700931 outDir := android.PathForModuleOut(ctx, "out")
932 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
933 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700934
Colin Crossab054432019-07-15 16:13:59 -0700935 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700936
Colin Crossab054432019-07-15 16:13:59 -0700937 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
938 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700939
Colin Crossab054432019-07-15 16:13:59 -0700940 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
941
942 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700943 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700944 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700945 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700946 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700947 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700948 }
949
Colin Crossab054432019-07-15 16:13:59 -0700950 d.stubsFlags(ctx, cmd, stubsDir)
951
952 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
953
954 var desc string
955 if Bool(d.properties.Dokka_enabled) {
956 desc = "dokka"
957 } else {
958 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
959
960 for _, o := range d.Javadoc.properties.Out {
961 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
962 }
963
964 d.postDoclavaCmds(ctx, rule)
965 desc = "doclava"
966 }
967
968 rule.Command().
969 BuiltTool(ctx, "soong_zip").
970 Flag("-write_if_changed").
971 Flag("-d").
972 FlagWithOutput("-o ", d.docZip).
973 FlagWithArg("-C ", outDir.String()).
974 FlagWithArg("-D ", outDir.String())
975
976 rule.Command().
977 BuiltTool(ctx, "soong_zip").
978 Flag("-write_if_changed").
979 Flag("-jar").
980 FlagWithOutput("-o ", d.stubsSrcJar).
981 FlagWithArg("-C ", stubsDir.String()).
982 FlagWithArg("-D ", stubsDir.String())
983
984 rule.Restat()
985
986 zipSyncCleanupCmd(rule, srcJarDir)
987
988 rule.Build(pctx, ctx, "javadoc", desc)
989
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200990 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -0700992
993 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
994 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995
996 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -0700997
998 rule := android.NewRuleBuilder()
999
1000 rule.Command().Text("( true")
1001
1002 rule.Command().
1003 BuiltTool(ctx, "apicheck").
1004 Flag("-JXmx1024m").
1005 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1006 OptionalFlag(d.properties.Check_api.Current.Args).
1007 Input(apiFile).
1008 Input(d.apiFile).
1009 Input(removedApiFile).
1010 Input(d.removedApiFile)
1011
1012 msg := fmt.Sprintf(`\n******************************\n`+
1013 `You have tried to change the API from what has been previously approved.\n\n`+
1014 `To make these errors go away, you have two choices:\n`+
1015 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1016 ` errors above.\n\n`+
1017 ` 2. You can update current.txt by executing the following command:\n`+
1018 ` make %s-update-current-api\n\n`+
1019 ` To submit the revised current.txt to the main Android repository,\n`+
1020 ` you will need approval.\n`+
1021 `******************************\n`, ctx.ModuleName())
1022
1023 rule.Command().
1024 Text("touch").Output(d.checkCurrentApiTimestamp).
1025 Text(") || (").
1026 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1027 Text("; exit 38").
1028 Text(")")
1029
1030 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001031
1032 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001033
1034 // update API rule
1035 rule = android.NewRuleBuilder()
1036
1037 rule.Command().Text("( true")
1038
1039 rule.Command().
1040 Text("cp").Flag("-f").
1041 Input(d.apiFile).Flag(apiFile.String())
1042
1043 rule.Command().
1044 Text("cp").Flag("-f").
1045 Input(d.removedApiFile).Flag(removedApiFile.String())
1046
1047 msg = "failed to update public API"
1048
1049 rule.Command().
1050 Text("touch").Output(d.updateCurrentApiTimestamp).
1051 Text(") || (").
1052 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1053 Text("; exit 38").
1054 Text(")")
1055
1056 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001057 }
1058
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001059 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001060 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001061
1062 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1063 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001064
1065 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001066
1067 rule := android.NewRuleBuilder()
1068
1069 rule.Command().
1070 Text("(").
1071 BuiltTool(ctx, "apicheck").
1072 Flag("-JXmx1024m").
1073 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1074 OptionalFlag(d.properties.Check_api.Last_released.Args).
1075 Input(apiFile).
1076 Input(d.apiFile).
1077 Input(removedApiFile).
1078 Input(d.removedApiFile)
1079
1080 msg := `\n******************************\n` +
1081 `You have tried to change the API from what has been previously released in\n` +
1082 `an SDK. Please fix the errors listed above.\n` +
1083 `******************************\n`
1084
1085 rule.Command().
1086 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1087 Text(") || (").
1088 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1089 Text("; exit 38").
1090 Text(")")
1091
1092 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001093 }
1094}
1095
1096//
1097// Droidstubs
1098//
1099type Droidstubs struct {
1100 Javadoc
1101
Pete Gillin581d6082018-10-22 15:55:04 +01001102 properties DroidstubsProperties
1103 apiFile android.WritablePath
1104 apiXmlFile android.WritablePath
1105 lastReleasedApiXmlFile android.WritablePath
1106 dexApiFile android.WritablePath
1107 privateApiFile android.WritablePath
1108 privateDexApiFile android.WritablePath
1109 removedApiFile android.WritablePath
1110 removedDexApiFile android.WritablePath
1111 apiMappingFile android.WritablePath
1112 exactApiFile android.WritablePath
1113 proguardFile android.WritablePath
1114 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001115
1116 checkCurrentApiTimestamp android.WritablePath
1117 updateCurrentApiTimestamp android.WritablePath
1118 checkLastReleasedApiTimestamp android.WritablePath
1119
Pete Gillin581d6082018-10-22 15:55:04 +01001120 checkNullabilityWarningsTimestamp android.WritablePath
1121
Nan Zhang1598a9e2018-09-04 17:14:32 -07001122 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001123 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001124
1125 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001126
1127 jdiffDocZip android.WritablePath
1128 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001129}
1130
Colin Crossa3002fc2019-07-08 16:48:04 -07001131// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1132// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1133// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001134func DroidstubsFactory() android.Module {
1135 module := &Droidstubs{}
1136
1137 module.AddProperties(&module.properties,
1138 &module.Javadoc.properties)
1139
1140 InitDroiddocModule(module, android.HostAndDeviceSupported)
1141 return module
1142}
1143
Colin Crossa3002fc2019-07-08 16:48:04 -07001144// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1145// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1146// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1147// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001148func DroidstubsHostFactory() android.Module {
1149 module := &Droidstubs{}
1150
1151 module.AddProperties(&module.properties,
1152 &module.Javadoc.properties)
1153
1154 InitDroiddocModule(module, android.HostSupported)
1155 return module
1156}
1157
1158func (d *Droidstubs) ApiFilePath() android.Path {
1159 return d.apiFilePath
1160}
1161
1162func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1163 d.Javadoc.addDeps(ctx)
1164
Inseob Kim38449af2019-02-28 14:24:05 +09001165 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1166 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1167 }
1168
Nan Zhang1598a9e2018-09-04 17:14:32 -07001169 if len(d.properties.Merge_annotations_dirs) != 0 {
1170 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1171 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1172 }
1173 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001174
Pete Gillin77167902018-09-19 18:16:26 +01001175 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1176 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1177 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1178 }
1179 }
1180
Nan Zhang9c69a122018-08-22 10:22:08 -07001181 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1182 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1183 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1184 }
1185 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001186}
1187
Colin Cross33961b52019-07-11 11:01:22 -07001188func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001189 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1190 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001191 String(d.properties.Api_filename) != "" {
1192 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001193 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001194 d.apiFilePath = d.apiFile
1195 }
1196
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001197 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1198 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001199 String(d.properties.Removed_api_filename) != "" {
1200 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001201 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001202 }
1203
1204 if String(d.properties.Private_api_filename) != "" {
1205 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001206 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001207 }
1208
1209 if String(d.properties.Dex_api_filename) != "" {
1210 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001211 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001212 }
1213
1214 if String(d.properties.Private_dex_api_filename) != "" {
1215 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001216 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001217 }
1218
1219 if String(d.properties.Removed_dex_api_filename) != "" {
1220 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001221 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001222 }
1223
1224 if String(d.properties.Exact_api_filename) != "" {
1225 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001226 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001227 }
1228
Nan Zhang9c69a122018-08-22 10:22:08 -07001229 if String(d.properties.Dex_mapping_filename) != "" {
1230 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001231 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001232 }
1233
Nan Zhang199645c2018-09-19 12:40:06 -07001234 if String(d.properties.Proguard_filename) != "" {
1235 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001236 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001237 }
1238
Nan Zhang9c69a122018-08-22 10:22:08 -07001239 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001240 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001241 }
1242
Nan Zhang1598a9e2018-09-04 17:14:32 -07001243 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001244 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001245 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001246 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001247 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001248}
1249
Colin Cross33961b52019-07-11 11:01:22 -07001250func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001251 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001252 cmd.Flag("--include-annotations")
1253
Pete Gillinc382a562018-11-14 18:45:46 +00001254 validatingNullability :=
1255 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1256 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001257 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001258
Pete Gillina262c052018-09-14 14:25:48 +01001259 if !(migratingNullability || validatingNullability) {
1260 ctx.PropertyErrorf("previous_api",
1261 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001262 }
Colin Cross33961b52019-07-11 11:01:22 -07001263
Pete Gillina262c052018-09-14 14:25:48 +01001264 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001265 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001266 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001267 }
Colin Cross33961b52019-07-11 11:01:22 -07001268
Pete Gillinc382a562018-11-14 18:45:46 +00001269 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001270 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001271 }
Colin Cross33961b52019-07-11 11:01:22 -07001272
Pete Gillina262c052018-09-14 14:25:48 +01001273 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001274 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001275 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001276 }
Nan Zhanga40da042018-08-01 12:48:00 -07001277
1278 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001279 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001280
Nan Zhang1598a9e2018-09-04 17:14:32 -07001281 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001282 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001283 "has to be non-empty if annotations was enabled!")
1284 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001285
Colin Cross33961b52019-07-11 11:01:22 -07001286 d.mergeAnnoDirFlags(ctx, cmd)
1287
1288 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1289 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1290 FlagWithArg("--hide ", "SuperfluousPrefix").
1291 FlagWithArg("--hide ", "AnnotationExtraction")
1292 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001293}
1294
Colin Cross33961b52019-07-11 11:01:22 -07001295func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1296 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1297 if t, ok := m.(*ExportedDroiddocDir); ok {
1298 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1299 } else {
1300 ctx.PropertyErrorf("merge_annotations_dirs",
1301 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1302 }
1303 })
1304}
1305
1306func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001307 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1308 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001309 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001310 } else {
1311 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1312 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1313 }
1314 })
Nan Zhanga40da042018-08-01 12:48:00 -07001315}
1316
Colin Cross33961b52019-07-11 11:01:22 -07001317func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001318 if Bool(d.properties.Api_levels_annotations_enabled) {
1319 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001320
1321 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1322 ctx.PropertyErrorf("api_levels_annotations_dirs",
1323 "has to be non-empty if api levels annotations was enabled!")
1324 }
1325
Colin Cross33961b52019-07-11 11:01:22 -07001326 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1327 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1328 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1329 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001330
1331 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1332 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001333 for _, dep := range t.deps {
1334 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001335 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001336 }
1337 }
Colin Cross33961b52019-07-11 11:01:22 -07001338 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001339 } else {
1340 ctx.PropertyErrorf("api_levels_annotations_dirs",
1341 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1342 }
1343 })
1344
1345 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001346}
1347
Colin Cross33961b52019-07-11 11:01:22 -07001348func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001349 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1350 if d.apiFile.String() == "" {
1351 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1352 }
1353
1354 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001355 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001356
1357 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1358 ctx.PropertyErrorf("check_api.last_released.api_file",
1359 "has to be non-empty if jdiff was enabled!")
1360 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001361
Colin Cross33961b52019-07-11 11:01:22 -07001362 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001363 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001364 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1365 }
1366}
Nan Zhang71bbe632018-09-17 14:32:21 -07001367
Colin Cross33961b52019-07-11 11:01:22 -07001368func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1369 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1370 cmd := rule.Command().BuiltTool(ctx, "metalava").
1371 Flag(config.JavacVmFlags).
1372 FlagWithArg("-encoding ", "UTF-8").
1373 FlagWithArg("-source ", javaVersion).
1374 FlagWithRspFileInputList("@", srcs).
1375 FlagWithInput("@", srcJarList)
1376
1377 if len(bootclasspath) > 0 {
1378 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001379 }
1380
Colin Cross33961b52019-07-11 11:01:22 -07001381 if len(classpath) > 0 {
1382 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1383 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001384
Colin Cross33961b52019-07-11 11:01:22 -07001385 if len(sourcepaths) > 0 {
1386 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1387 } else {
1388 cmd.FlagWithArg("-sourcepath ", `""`)
1389 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001390
Colin Cross33961b52019-07-11 11:01:22 -07001391 cmd.Flag("--no-banner").
1392 Flag("--color").
1393 Flag("--quiet").
1394 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001395
Colin Cross33961b52019-07-11 11:01:22 -07001396 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001397}
1398
Nan Zhang1598a9e2018-09-04 17:14:32 -07001399func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001400 deps := d.Javadoc.collectDeps(ctx)
1401
1402 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001403
Colin Cross33961b52019-07-11 11:01:22 -07001404 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001405
Colin Crossdaa4c672019-07-15 22:53:46 -07001406 d.Javadoc.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhanga40da042018-08-01 12:48:00 -07001407
Colin Cross33961b52019-07-11 11:01:22 -07001408 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1409 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang71bbe632018-09-17 14:32:21 -07001410
Colin Cross33961b52019-07-11 11:01:22 -07001411 rule := android.NewRuleBuilder()
Nan Zhanga40da042018-08-01 12:48:00 -07001412
Colin Cross33961b52019-07-11 11:01:22 -07001413 rule.Command().Text("rm -rf").Text(stubsDir.String())
1414 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001415
Colin Cross33961b52019-07-11 11:01:22 -07001416 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1417
1418 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1419 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1420
1421 d.stubsFlags(ctx, cmd, stubsDir)
1422
1423 d.annotationsFlags(ctx, cmd)
1424 d.inclusionAnnotationsFlags(ctx, cmd)
1425 d.apiLevelsAnnotationsFlags(ctx, cmd)
1426 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001427
Nan Zhang1598a9e2018-09-04 17:14:32 -07001428 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1429 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1430 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1431 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1432 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001433 }
Colin Cross33961b52019-07-11 11:01:22 -07001434
1435 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1436 for _, o := range d.Javadoc.properties.Out {
1437 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1438 }
1439
1440 rule.Command().
1441 BuiltTool(ctx, "soong_zip").
1442 Flag("-write_if_changed").
1443 Flag("-jar").
1444 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1445 FlagWithArg("-C ", stubsDir.String()).
1446 FlagWithArg("-D ", stubsDir.String())
1447 rule.Restat()
1448
1449 zipSyncCleanupCmd(rule, srcJarDir)
1450
1451 rule.Build(pctx, ctx, "metalava", "metalava")
1452
1453 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001454
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001455 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001456 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001457
1458 if len(d.Javadoc.properties.Out) > 0 {
1459 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1460 }
1461
1462 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1463 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001464 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
1465 updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001466
Nan Zhang2760dfc2018-08-24 17:32:54 +00001467 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001468
Colin Cross33961b52019-07-11 11:01:22 -07001469 rule := android.NewRuleBuilder()
1470
1471 rule.Command().Text("( true")
1472
1473 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1474 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1475
1476 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1477 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1478
1479 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1480 FlagWithInput("--check-compatibility:api:current ", apiFile).
1481 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1482
1483 d.inclusionAnnotationsFlags(ctx, cmd)
1484 d.mergeAnnoDirFlags(ctx, cmd)
1485
Adrian Roos14f75a92019-08-12 17:54:09 +02001486 if baselineFile.Valid() {
1487 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1488 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1489 }
1490
Colin Cross33961b52019-07-11 11:01:22 -07001491 zipSyncCleanupCmd(rule, srcJarDir)
1492
1493 msg := fmt.Sprintf(`\n******************************\n`+
1494 `You have tried to change the API from what has been previously approved.\n\n`+
1495 `To make these errors go away, you have two choices:\n`+
1496 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1497 ` errors above.\n\n`+
1498 ` 2. You can update current.txt by executing the following command:\n`+
1499 ` make %s-update-current-api\n\n`+
1500 ` To submit the revised current.txt to the main Android repository,\n`+
1501 ` you will need approval.\n`+
1502 `******************************\n`, ctx.ModuleName())
1503
1504 rule.Command().
1505 Text("touch").Output(d.checkCurrentApiTimestamp).
1506 Text(") || (").
1507 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1508 Text("; exit 38").
1509 Text(")")
1510
1511 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001512
1513 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001514
1515 // update API rule
1516 rule = android.NewRuleBuilder()
1517
1518 rule.Command().Text("( true")
1519
1520 rule.Command().
1521 Text("cp").Flag("-f").
1522 Input(d.apiFile).Flag(apiFile.String())
1523
1524 rule.Command().
1525 Text("cp").Flag("-f").
1526 Input(d.removedApiFile).Flag(removedApiFile.String())
1527
1528 msg = "failed to update public API"
1529
1530 rule.Command().
1531 Text("touch").Output(d.updateCurrentApiTimestamp).
1532 Text(") || (").
1533 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1534 Text("; exit 38").
1535 Text(")")
1536
1537 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001538 }
Nan Zhanga40da042018-08-01 12:48:00 -07001539
Luca Stefanid63ea0a2019-09-01 21:49:45 +02001540 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001541 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001542
1543 if len(d.Javadoc.properties.Out) > 0 {
1544 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1545 }
1546
1547 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1548 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Adrian Roos14f75a92019-08-12 17:54:09 +02001549 baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
1550 updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
Nan Zhang61819ce2018-05-04 18:49:16 -07001551
Nan Zhang2760dfc2018-08-24 17:32:54 +00001552 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001553
Colin Cross33961b52019-07-11 11:01:22 -07001554 rule := android.NewRuleBuilder()
1555
1556 rule.Command().Text("( true")
1557
1558 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1559 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1560
1561 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1562 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1563
1564 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1565 FlagWithInput("--check-compatibility:api:released ", apiFile)
1566
1567 d.inclusionAnnotationsFlags(ctx, cmd)
1568
1569 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1570
1571 d.mergeAnnoDirFlags(ctx, cmd)
1572
Adrian Roos14f75a92019-08-12 17:54:09 +02001573 if baselineFile.Valid() {
1574 cmd.FlagWithInput("--baseline ", baselineFile.Path())
1575 cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
1576 }
1577
Colin Cross33961b52019-07-11 11:01:22 -07001578 zipSyncCleanupCmd(rule, srcJarDir)
1579
1580 msg := `\n******************************\n` +
1581 `You have tried to change the API from what has been previously released in\n` +
1582 `an SDK. Please fix the errors listed above.\n` +
1583 `******************************\n`
1584 rule.Command().
1585 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1586 Text(") || (").
1587 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1588 Text("; exit 38").
1589 Text(")")
1590
1591 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001592 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001593
Pete Gillin581d6082018-10-22 15:55:04 +01001594 if String(d.properties.Check_nullability_warnings) != "" {
1595 if d.nullabilityWarningsFile == nil {
1596 ctx.PropertyErrorf("check_nullability_warnings",
1597 "Cannot specify check_nullability_warnings unless validating nullability")
1598 }
Colin Cross33961b52019-07-11 11:01:22 -07001599
1600 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1601
Pete Gillin581d6082018-10-22 15:55:04 +01001602 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001603
Pete Gillin581d6082018-10-22 15:55:04 +01001604 msg := fmt.Sprintf(`\n******************************\n`+
1605 `The warnings encountered during nullability annotation validation did\n`+
1606 `not match the checked in file of expected warnings. The diffs are shown\n`+
1607 `above. You have two options:\n`+
1608 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1609 ` 2. Update the file of expected warnings by running:\n`+
1610 ` cp %s %s\n`+
1611 ` and submitting the updated file as part of your change.`,
1612 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001613
1614 rule := android.NewRuleBuilder()
1615
1616 rule.Command().
1617 Text("(").
1618 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1619 Text("&&").
1620 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1621 Text(") || (").
1622 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1623 Text("; exit 38").
1624 Text(")")
1625
1626 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001627 }
1628
Nan Zhang71bbe632018-09-17 14:32:21 -07001629 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001630 if len(d.Javadoc.properties.Out) > 0 {
1631 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1632 }
1633
1634 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1635 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1636 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1637
1638 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001639
Nan Zhang86b06202018-09-21 17:09:21 -07001640 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1641 // since there's cron job downstream that fetch this .zip file periodically.
1642 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001643 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1644 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1645
Nan Zhang71bbe632018-09-17 14:32:21 -07001646 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001647
Colin Cross33961b52019-07-11 11:01:22 -07001648 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1649 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001650
Colin Cross33961b52019-07-11 11:01:22 -07001651 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1652
Colin Crossdaa4c672019-07-15 22:53:46 -07001653 cmd := javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -07001654 deps.bootClasspath, deps.classpath, d.sourcepaths)
1655
1656 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001657 Flag("-XDignore.symbol.file").
1658 FlagWithArg("-doclet ", "jdiff.JDiff").
1659 FlagWithInput("-docletpath ", jdiff).
1660 Flag("-quiet").
1661 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1662 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1663 Implicit(d.apiXmlFile).
1664 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1665 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1666 Implicit(d.lastReleasedApiXmlFile)
1667
Colin Cross33961b52019-07-11 11:01:22 -07001668 rule.Command().
1669 BuiltTool(ctx, "soong_zip").
1670 Flag("-write_if_changed").
1671 Flag("-d").
1672 FlagWithOutput("-o ", d.jdiffDocZip).
1673 FlagWithArg("-C ", outDir.String()).
1674 FlagWithArg("-D ", outDir.String())
1675
1676 rule.Command().
1677 BuiltTool(ctx, "soong_zip").
1678 Flag("-write_if_changed").
1679 Flag("-jar").
1680 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1681 FlagWithArg("-C ", stubsDir.String()).
1682 FlagWithArg("-D ", stubsDir.String())
1683
1684 rule.Restat()
1685
1686 zipSyncCleanupCmd(rule, srcJarDir)
1687
1688 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001689 }
Nan Zhang581fd212018-01-10 16:06:12 -08001690}
Dan Willemsencc090972018-02-26 14:33:31 -08001691
Nan Zhanga40da042018-08-01 12:48:00 -07001692//
Nan Zhangf4936b02018-08-01 15:00:28 -07001693// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001694//
Dan Willemsencc090972018-02-26 14:33:31 -08001695var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001696var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001697var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001698var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001699
Nan Zhangf4936b02018-08-01 15:00:28 -07001700type ExportedDroiddocDirProperties struct {
1701 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001702 Path *string
1703}
1704
Nan Zhangf4936b02018-08-01 15:00:28 -07001705type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001706 android.ModuleBase
1707
Nan Zhangf4936b02018-08-01 15:00:28 -07001708 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001709
1710 deps android.Paths
1711 dir android.Path
1712}
1713
Colin Crossa3002fc2019-07-08 16:48:04 -07001714// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001715func ExportedDroiddocDirFactory() android.Module {
1716 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001717 module.AddProperties(&module.properties)
1718 android.InitAndroidModule(module)
1719 return module
1720}
1721
Nan Zhangf4936b02018-08-01 15:00:28 -07001722func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001723
Nan Zhangf4936b02018-08-01 15:00:28 -07001724func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001725 path := String(d.properties.Path)
1726 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001727 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001728}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001729
1730//
1731// Defaults
1732//
1733type DocDefaults struct {
1734 android.ModuleBase
1735 android.DefaultsModuleBase
1736}
1737
Nan Zhangb2b33de2018-02-23 11:18:47 -08001738func DocDefaultsFactory() android.Module {
1739 module := &DocDefaults{}
1740
1741 module.AddProperties(
1742 &JavadocProperties{},
1743 &DroiddocProperties{},
1744 )
1745
1746 android.InitDefaultsModule(module)
1747
1748 return module
1749}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001750
1751func StubsDefaultsFactory() android.Module {
1752 module := &DocDefaults{}
1753
1754 module.AddProperties(
1755 &JavadocProperties{},
1756 &DroidstubsProperties{},
1757 )
1758
1759 android.InitDefaultsModule(module)
1760
1761 return module
1762}
Colin Cross33961b52019-07-11 11:01:22 -07001763
1764func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1765 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1766
1767 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1768 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1769 srcJarList := srcJarDir.Join(ctx, "list")
1770
1771 rule.Temporary(srcJarList)
1772
1773 rule.Command().BuiltTool(ctx, "zipsync").
1774 FlagWithArg("-d ", srcJarDir.String()).
1775 FlagWithOutput("-l ", srcJarList).
1776 FlagWithArg("-f ", `"*.java"`).
1777 Inputs(srcJars)
1778
1779 return srcJarList
1780}
1781
1782func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1783 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1784}