blob: 04138fccb1f8d07b64a49cd01ed064affbb2ffe1 [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
23 "github.com/google/blueprint"
Jeongik Cha6bd33c12019-06-25 16:26:18 +090024 "github.com/google/blueprint/proptools"
Colin Crossab054432019-07-15 16:13:59 -070025
26 "android/soong/android"
27 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080028)
29
30var (
31 javadoc = pctx.AndroidStaticRule("javadoc",
32 blueprint.RuleParams{
33 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070034 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang40b41b42018-10-02 16:11:17 -070035 `${config.SoongJavacWrapper} ${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070036 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080037 `-d $outDir -quiet && ` +
38 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080039 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
40 `rm -rf "$srcJarDir"`,
41
Nan Zhang581fd212018-01-10 16:06:12 -080042 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070043 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080044 "${config.JavadocCmd}",
45 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080046 },
Nan Zhang40b41b42018-10-02 16:11:17 -070047 CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
48 Rspfile: "$out.rsp",
49 RspfileContent: "$in",
50 Restat: true,
Nan Zhang581fd212018-01-10 16:06:12 -080051 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070052 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070053 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang581fd212018-01-10 16:06:12 -080054)
55
56func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080057 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070058 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -080059
Nan Zhang581fd212018-01-10 16:06:12 -080060 android.RegisterModuleType("droiddoc", DroiddocFactory)
61 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070062 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080063 android.RegisterModuleType("javadoc", JavadocFactory)
64 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -070065
66 android.RegisterModuleType("droidstubs", DroidstubsFactory)
67 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080068}
69
Colin Crossa1ce2a02018-06-20 15:19:39 -070070var (
71 srcsLibTag = dependencyTag{name: "sources from javalib"}
72)
73
Nan Zhang581fd212018-01-10 16:06:12 -080074type JavadocProperties struct {
75 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
76 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080077 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080078
79 // list of directories rooted at the Android.bp file that will
80 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080081 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080082
83 // list of source files that should not be used to build the Java module.
84 // This is most useful in the arch/multilib variants to remove non-common files
85 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080086 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080087
Nan Zhangb2b33de2018-02-23 11:18:47 -080088 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080089 Libs []string `android:"arch_variant"`
90
Nan Zhangb2b33de2018-02-23 11:18:47 -080091 // the java library (in classpath) for documentation that provides java srcs and srcjars.
92 Srcs_lib *string
93
94 // the base dirs under srcs_lib will be scanned for java srcs.
95 Srcs_lib_whitelist_dirs []string
96
97 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
98 Srcs_lib_whitelist_pkgs []string
99
Nan Zhang581fd212018-01-10 16:06:12 -0800100 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800101 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800102
103 // if not blank, set to the version of the sdk to compile against
104 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900105
106 Aidl struct {
107 // Top level directories to pass to aidl tool
108 Include_dirs []string
109
110 // Directories rooted at the Android.bp file to pass to aidl tool
111 Local_include_dirs []string
112 }
Nan Zhang357466b2018-04-17 17:38:36 -0700113
114 // If not blank, set the java version passed to javadoc as -source
115 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700116
117 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800118 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700119
120 // user customized droiddoc args.
121 // Available variables for substitution:
122 //
123 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700124 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700125 Args *string
126
127 // names of the output files used in args that will be generated
128 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800129}
130
Nan Zhang61819ce2018-05-04 18:49:16 -0700131type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900132 // path to the API txt file that the new API extracted from source code is checked
133 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800134 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700135
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900136 // path to the API txt file that the new @removed API extractd from source code is
137 // checked against. The path can be local to the module or from other module (via
138 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800139 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700140
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900141 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700142 Args *string
143}
144
Nan Zhang581fd212018-01-10 16:06:12 -0800145type DroiddocProperties struct {
146 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800147 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800148
Nan Zhanga40da042018-08-01 12:48:00 -0700149 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800150 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800151
152 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800153 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800154
155 // proofread file contains all of the text content of the javadocs concatenated into one file,
156 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700157 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800158
159 // a todo file lists the program elements that are missing documentation.
160 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800161 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800162
163 // directory under current module source that provide additional resources (images).
164 Resourcesdir *string
165
166 // resources output directory under out/soong/.intermediates.
167 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800168
Nan Zhange2ba5d42018-07-11 15:16:55 -0700169 // if set to true, collect the values used by the Dev tools and
170 // write them in files packaged with the SDK. Defaults to false.
171 Write_sdk_values *bool
172
173 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800174 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700175
176 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800177 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700178
Nan Zhang581fd212018-01-10 16:06:12 -0800179 // a list of files under current module source dir which contains known tags in Java sources.
180 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800181 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700182
183 // the tag name used to distinguish if the API files belong to public/system/test.
184 Api_tag_name *string
185
186 // the generated public API filename by Doclava.
187 Api_filename *string
188
David Brazdilfbe4cc32018-05-31 13:56:46 +0100189 // the generated public Dex API filename by Doclava.
190 Dex_api_filename *string
191
Nan Zhang28c68b92018-03-13 16:17:01 -0700192 // the generated private API filename by Doclava.
193 Private_api_filename *string
194
195 // the generated private Dex API filename by Doclava.
196 Private_dex_api_filename *string
197
198 // the generated removed API filename by Doclava.
199 Removed_api_filename *string
200
David Brazdilaac0c3c2018-04-24 16:23:29 +0100201 // the generated removed Dex API filename by Doclava.
202 Removed_dex_api_filename *string
203
Mathew Inwood76c3de12018-06-22 15:28:11 +0100204 // mapping of dex signatures to source file and line number. This is a temporary property and
205 // will be deleted; you probably shouldn't be using it.
206 Dex_mapping_filename *string
207
Nan Zhang28c68b92018-03-13 16:17:01 -0700208 // the generated exact API filename by Doclava.
209 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700210
Nan Zhang66dc2362018-08-14 20:41:04 -0700211 // the generated proguard filename by Doclava.
212 Proguard_filename *string
213
Nan Zhang853f4202018-04-12 16:55:56 -0700214 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
215 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700216
217 Check_api struct {
218 Last_released ApiToCheck
219
220 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900221
222 // do not perform API check against Last_released, in the case that both two specified API
223 // files by Last_released are modules which don't exist.
224 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700225 }
Nan Zhang79614d12018-04-19 18:03:39 -0700226
Nan Zhang1598a9e2018-09-04 17:14:32 -0700227 // if set to true, generate docs through Dokka instead of Doclava.
228 Dokka_enabled *bool
229}
230
231type DroidstubsProperties struct {
232 // the tag name used to distinguish if the API files belong to public/system/test.
233 Api_tag_name *string
234
Nan Zhang199645c2018-09-19 12:40:06 -0700235 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700236 Api_filename *string
237
Nan Zhang199645c2018-09-19 12:40:06 -0700238 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700239 Dex_api_filename *string
240
Nan Zhang199645c2018-09-19 12:40:06 -0700241 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700242 Private_api_filename *string
243
Nan Zhang199645c2018-09-19 12:40:06 -0700244 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700245 Private_dex_api_filename *string
246
Nan Zhang199645c2018-09-19 12:40:06 -0700247 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700248 Removed_api_filename *string
249
Nan Zhang199645c2018-09-19 12:40:06 -0700250 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700251 Removed_dex_api_filename *string
252
Nan Zhang9c69a122018-08-22 10:22:08 -0700253 // mapping of dex signatures to source file and line number. This is a temporary property and
254 // will be deleted; you probably shouldn't be using it.
255 Dex_mapping_filename *string
256
Nan Zhang199645c2018-09-19 12:40:06 -0700257 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700258 Exact_api_filename *string
259
Nan Zhang199645c2018-09-19 12:40:06 -0700260 // the generated proguard filename by Metalava.
261 Proguard_filename *string
262
Nan Zhang1598a9e2018-09-04 17:14:32 -0700263 Check_api struct {
264 Last_released ApiToCheck
265
266 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900267
268 // do not perform API check against Last_released, in the case that both two specified API
269 // files by Last_released are modules which don't exist.
270 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700271 }
Nan Zhang79614d12018-04-19 18:03:39 -0700272
273 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800274 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700275
276 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700277 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700278
Pete Gillin77167902018-09-19 18:16:26 +0100279 // 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 -0700280 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700281
Pete Gillin77167902018-09-19 18:16:26 +0100282 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
283 Merge_inclusion_annotations_dirs []string
284
Pete Gillinc382a562018-11-14 18:45:46 +0000285 // a file containing a list of classes to do nullability validation for.
286 Validate_nullability_from_list *string
287
Pete Gillin581d6082018-10-22 15:55:04 +0100288 // a file containing expected warnings produced by validation of nullability annotations.
289 Check_nullability_warnings *string
290
Nan Zhang1598a9e2018-09-04 17:14:32 -0700291 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
292 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700293
294 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
295 Api_levels_annotations_enabled *bool
296
297 // the dirs which Metalava extracts API levels annotations from.
298 Api_levels_annotations_dirs []string
299
300 // if set to true, collect the values used by the Dev tools and
301 // write them in files packaged with the SDK. Defaults to false.
302 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700303
304 // If set to true, .xml based public API file will be also generated, and
305 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
306 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800307}
308
Nan Zhanga40da042018-08-01 12:48:00 -0700309//
310// Common flags passed down to build rule
311//
312type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700313 bootClasspathArgs string
314 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700315 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700316 dokkaClasspathArgs string
317 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700318 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700319
Nan Zhanga40da042018-08-01 12:48:00 -0700320 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700321 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700322 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700323}
324
325func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
326 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
327 android.InitDefaultableModule(module)
328}
329
Nan Zhang1598a9e2018-09-04 17:14:32 -0700330func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
331 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
332 return true
333 } else if String(apiToCheck.Api_file) != "" {
334 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
335 } else if String(apiToCheck.Removed_api_file) != "" {
336 panic("for " + apiVersionTag + " api_file has to be non-empty!")
337 }
338
339 return false
340}
341
Inseob Kim38449af2019-02-28 14:24:05 +0900342func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
343 api_file := String(apiToCheck.Api_file)
344 removed_api_file := String(apiToCheck.Removed_api_file)
345
346 api_module := android.SrcIsModule(api_file)
347 removed_api_module := android.SrcIsModule(removed_api_file)
348
349 if api_module == "" || removed_api_module == "" {
350 return
351 }
352
353 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
354 return
355 }
356
357 apiToCheck.Api_file = nil
358 apiToCheck.Removed_api_file = nil
359}
360
Nan Zhang1598a9e2018-09-04 17:14:32 -0700361type ApiFilePath interface {
362 ApiFilePath() android.Path
363}
364
Nan Zhanga40da042018-08-01 12:48:00 -0700365//
366// Javadoc
367//
Nan Zhang581fd212018-01-10 16:06:12 -0800368type Javadoc struct {
369 android.ModuleBase
370 android.DefaultableModuleBase
371
372 properties JavadocProperties
373
374 srcJars android.Paths
375 srcFiles android.Paths
376 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700377 argFiles android.Paths
378
379 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800380
Nan Zhangccff0f72018-03-08 17:26:16 -0800381 docZip android.WritablePath
382 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800383}
384
Colin Cross41955e82019-05-29 14:40:35 -0700385func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
386 switch tag {
387 case "":
388 return android.Paths{j.stubsSrcJar}, nil
389 default:
390 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
391 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800392}
393
Colin Crossa3002fc2019-07-08 16:48:04 -0700394// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800395func JavadocFactory() android.Module {
396 module := &Javadoc{}
397
398 module.AddProperties(&module.properties)
399
400 InitDroiddocModule(module, android.HostAndDeviceSupported)
401 return module
402}
403
Colin Crossa3002fc2019-07-08 16:48:04 -0700404// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800405func JavadocHostFactory() android.Module {
406 module := &Javadoc{}
407
408 module.AddProperties(&module.properties)
409
410 InitDroiddocModule(module, android.HostSupported)
411 return module
412}
413
Colin Cross41955e82019-05-29 14:40:35 -0700414var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800415
Colin Cross83bb3162018-06-25 15:48:06 -0700416func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900417 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700418}
419
420func (j *Javadoc) minSdkVersion() string {
421 return j.sdkVersion()
422}
423
Dan Willemsen419290a2018-10-31 15:28:47 -0700424func (j *Javadoc) targetSdkVersion() string {
425 return j.sdkVersion()
426}
427
Nan Zhang581fd212018-01-10 16:06:12 -0800428func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
429 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100430 sdkDep := decodeSdkDep(ctx, sdkContext(j))
431 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700432 if sdkDep.useDefaultLibs {
433 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
434 if ctx.Config().TargetOpenJDK9() {
435 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
436 }
Paul Duffin250e6192019-06-07 10:44:37 +0100437 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700438 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
439 }
440 } else if sdkDep.useModule {
441 if ctx.Config().TargetOpenJDK9() {
442 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
443 }
444 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700445 }
Nan Zhang581fd212018-01-10 16:06:12 -0800446 }
447 }
448
Colin Cross42d48b72018-08-29 14:10:52 -0700449 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700450 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700451 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700452 }
Nan Zhang581fd212018-01-10 16:06:12 -0800453}
454
Nan Zhangb2b33de2018-02-23 11:18:47 -0800455func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
456 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
457 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900458 // convert foo.bar.baz to foo/bar/baz
459 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
460 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800461 if _, found := whitelistPathPrefixes[prefix]; !found {
462 whitelistPathPrefixes[prefix] = true
463 }
464 }
465 }
466}
467
Nan Zhanga40da042018-08-01 12:48:00 -0700468func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
469 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900470
Colin Cross3047fa22019-04-18 10:56:44 -0700471 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900472
473 return flags
474}
475
476func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700477 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900478
479 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
480 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
481
482 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700483 var deps android.Paths
484
Jiyong Park1e440682018-05-23 18:42:04 +0900485 if aidlPreprocess.Valid() {
486 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700487 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900488 } else {
489 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
490 }
491
492 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
493 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
494 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
495 flags = append(flags, "-I"+src.String())
496 }
497
Colin Cross3047fa22019-04-18 10:56:44 -0700498 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900499}
500
501func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700502 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900503
504 outSrcFiles := make(android.Paths, 0, len(srcFiles))
505
506 for _, srcFile := range srcFiles {
507 switch srcFile.Ext() {
508 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700509 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900510 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900511 case ".sysprop":
512 javaFile := genSysprop(ctx, srcFile)
513 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900514 default:
515 outSrcFiles = append(outSrcFiles, srcFile)
516 }
517 }
518
519 return outSrcFiles
520}
521
Nan Zhang581fd212018-01-10 16:06:12 -0800522func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
523 var deps deps
524
Colin Cross83bb3162018-06-25 15:48:06 -0700525 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800526 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700527 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800528 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700529 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800530 }
531
532 ctx.VisitDirectDeps(func(module android.Module) {
533 otherName := ctx.OtherModuleName(module)
534 tag := ctx.OtherModuleDependencyTag(module)
535
Colin Cross2d24c1b2018-05-23 10:59:18 -0700536 switch tag {
537 case bootClasspathTag:
538 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800539 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700540 } else {
541 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
542 }
543 case libTag:
544 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800545 case SdkLibraryDependency:
546 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700547 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900548 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700549 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800550 checkProducesJars(ctx, dep)
551 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800552 default:
553 ctx.ModuleErrorf("depends on non-java module %q", otherName)
554 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700555 case srcsLibTag:
556 switch dep := module.(type) {
557 case Dependency:
558 srcs := dep.(SrcDependency).CompiledSrcs()
559 whitelistPathPrefixes := make(map[string]bool)
560 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
561 for _, src := range srcs {
562 if _, ok := src.(android.WritablePath); ok { // generated sources
563 deps.srcs = append(deps.srcs, src)
564 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700565 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700566 if strings.HasPrefix(src.Rel(), k) {
567 deps.srcs = append(deps.srcs, src)
568 break
569 }
570 }
571 }
572 }
573 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
574 default:
575 ctx.ModuleErrorf("depends on non-java module %q", otherName)
576 }
Nan Zhang357466b2018-04-17 17:38:36 -0700577 case systemModulesTag:
578 if deps.systemModules != nil {
579 panic("Found two system module dependencies")
580 }
581 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000582 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700583 panic("Missing directory for system module dependency")
584 }
Colin Crossb77043e2019-07-16 13:57:13 -0700585 deps.systemModules = &systemModules{sm.outputDir, sm.outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800586 }
587 })
588 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
589 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800590 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700591 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900592 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800593
594 // srcs may depend on some genrule output.
595 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800596 j.srcJars = append(j.srcJars, deps.srcJars...)
597
Nan Zhang581fd212018-01-10 16:06:12 -0800598 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800599 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800600
601 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800602 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800603
Nan Zhang9c69a122018-08-22 10:22:08 -0700604 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800605 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
606 }
607 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800608
Colin Cross8a497952019-03-05 22:25:09 -0800609 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000610 argFilesMap := map[string]string{}
611 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700612
Paul Duffin99e4a502019-02-11 15:38:42 +0000613 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800614 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000615 if _, exists := argFilesMap[label]; !exists {
616 argFilesMap[label] = strings.Join(paths.Strings(), " ")
617 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700618 } else {
619 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000620 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700621 }
622 }
623
624 var err error
Colin Cross15638152019-07-11 11:11:35 -0700625 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700626 if strings.HasPrefix(name, "location ") {
627 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000628 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700629 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700630 } else {
Colin Cross15638152019-07-11 11:11:35 -0700631 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000632 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700633 }
634 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700635 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700636 }
Colin Cross15638152019-07-11 11:11:35 -0700637 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700638 })
639
640 if err != nil {
641 ctx.PropertyErrorf("args", "%s", err.Error())
642 }
643
Nan Zhang581fd212018-01-10 16:06:12 -0800644 return deps
645}
646
647func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
648 j.addDeps(ctx)
649}
650
651func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
652 deps := j.collectDeps(ctx)
653
654 var implicits android.Paths
655 implicits = append(implicits, deps.bootClasspath...)
656 implicits = append(implicits, deps.classpath...)
657
Nan Zhang1598a9e2018-09-04 17:14:32 -0700658 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700659
Colin Cross83bb3162018-06-25 15:48:06 -0700660 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700661 if len(deps.bootClasspath) > 0 {
Colin Crossb77043e2019-07-16 13:57:13 -0700662 var systemModulesDeps android.Paths
663 bootClasspathArgs, systemModulesDeps = deps.systemModules.FormJavaSystemModulesPath(ctx.Device())
Colin Cross997262f2018-06-19 22:49:39 -0700664 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Colin Crossb77043e2019-07-16 13:57:13 -0700665 implicits = append(implicits, systemModulesDeps...)
Nan Zhang581fd212018-01-10 16:06:12 -0800666 }
667 if len(deps.classpath.Strings()) > 0 {
668 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
669 }
670
671 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700672 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800673
Nan Zhangaf322cc2018-06-19 15:15:38 -0700674 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800675
Nan Zhang1598a9e2018-09-04 17:14:32 -0700676 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
677
Nan Zhang581fd212018-01-10 16:06:12 -0800678 ctx.Build(pctx, android.BuildParams{
679 Rule: javadoc,
680 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800681 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800682 ImplicitOutput: j.docZip,
683 Inputs: j.srcFiles,
684 Implicits: implicits,
685 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700686 "outDir": android.PathForModuleOut(ctx, "out").String(),
687 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
688 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800689 "srcJars": strings.Join(j.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -0700690 "opts": proptools.NinjaEscape(opts),
Nan Zhang853f4202018-04-12 16:55:56 -0700691 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800692 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700693 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800694 "docZip": j.docZip.String(),
695 },
696 })
697}
698
Nan Zhanga40da042018-08-01 12:48:00 -0700699//
700// Droiddoc
701//
702type Droiddoc struct {
703 Javadoc
704
705 properties DroiddocProperties
706 apiFile android.WritablePath
707 dexApiFile android.WritablePath
708 privateApiFile android.WritablePath
709 privateDexApiFile android.WritablePath
710 removedApiFile android.WritablePath
711 removedDexApiFile android.WritablePath
712 exactApiFile android.WritablePath
713 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700714 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700715
716 checkCurrentApiTimestamp android.WritablePath
717 updateCurrentApiTimestamp android.WritablePath
718 checkLastReleasedApiTimestamp android.WritablePath
719
Nan Zhanga40da042018-08-01 12:48:00 -0700720 apiFilePath android.Path
721}
722
Colin Crossa3002fc2019-07-08 16:48:04 -0700723// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700724func DroiddocFactory() android.Module {
725 module := &Droiddoc{}
726
727 module.AddProperties(&module.properties,
728 &module.Javadoc.properties)
729
730 InitDroiddocModule(module, android.HostAndDeviceSupported)
731 return module
732}
733
Colin Crossa3002fc2019-07-08 16:48:04 -0700734// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700735func DroiddocHostFactory() android.Module {
736 module := &Droiddoc{}
737
738 module.AddProperties(&module.properties,
739 &module.Javadoc.properties)
740
741 InitDroiddocModule(module, android.HostSupported)
742 return module
743}
744
745func (d *Droiddoc) ApiFilePath() android.Path {
746 return d.apiFilePath
747}
748
Nan Zhang581fd212018-01-10 16:06:12 -0800749func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
750 d.Javadoc.addDeps(ctx)
751
Inseob Kim38449af2019-02-28 14:24:05 +0900752 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
753 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
754 }
755
Nan Zhang79614d12018-04-19 18:03:39 -0700756 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800757 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
758 }
Nan Zhang581fd212018-01-10 16:06:12 -0800759}
760
Colin Crossab054432019-07-15 16:13:59 -0700761func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Nan Zhang46130972018-06-04 11:28:01 -0700762 var date string
763 if runtime.GOOS == "darwin" {
764 date = `date -r`
765 } else {
766 date = `date -d`
767 }
768
Nan Zhang443fa522018-08-20 20:58:28 -0700769 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
770 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
771 // 1.9 language features.
Colin Crossab054432019-07-15 16:13:59 -0700772 cmd.FlagWithArg("-source ", "1.8").
773 Flag("-J-Xmx1600m").
774 Flag("-J-XX:-OmitStackTraceInFastThrow").
775 Flag("-XDignore.symbol.file").
776 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
777 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
778 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-"+ctx.Config().BuildNumberFromFile()).
779 FlagWithArg("-hdf page.now ", `"$(`+date+` @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700780
Nan Zhanga40da042018-08-01 12:48:00 -0700781 if String(d.properties.Custom_template) == "" {
782 // TODO: This is almost always droiddoc-templates-sdk
783 ctx.PropertyErrorf("custom_template", "must specify a template")
784 }
785
786 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700787 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700788 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700789 } else {
790 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
791 }
792 })
793
794 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700795 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
796 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
797 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700798 }
799
800 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700801 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
802 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
803 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700804 }
805
806 if len(d.properties.Html_dirs) > 2 {
807 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
808 }
809
Colin Cross8a497952019-03-05 22:25:09 -0800810 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700811 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700812
Colin Crossab054432019-07-15 16:13:59 -0700813 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700814
815 if String(d.properties.Proofread_file) != "" {
816 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700817 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700818 }
819
820 if String(d.properties.Todo_file) != "" {
821 // tricky part:
822 // we should not compute full path for todo_file through PathForModuleOut().
823 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700824 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
825 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700826 }
827
828 if String(d.properties.Resourcesdir) != "" {
829 // TODO: should we add files under resourcesDir to the implicits? It seems that
830 // resourcesDir is one sub dir of htmlDir
831 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700832 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700833 }
834
835 if String(d.properties.Resourcesoutdir) != "" {
836 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700837 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700838 }
Nan Zhanga40da042018-08-01 12:48:00 -0700839}
840
Colin Crossab054432019-07-15 16:13:59 -0700841func (d *Droiddoc) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700842 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
843 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
844 String(d.properties.Api_filename) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700845
Nan Zhanga40da042018-08-01 12:48:00 -0700846 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Crossab054432019-07-15 16:13:59 -0700847 cmd.FlagWithOutput("-api ", d.apiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700848 d.apiFilePath = d.apiFile
849 }
850
Nan Zhang1598a9e2018-09-04 17:14:32 -0700851 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
852 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
853 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700854 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Crossab054432019-07-15 16:13:59 -0700855 cmd.FlagWithOutput("-removedApi ", d.removedApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700856 }
857
858 if String(d.properties.Private_api_filename) != "" {
859 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700860 cmd.FlagWithOutput("-privateApi ", d.privateApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700861 }
862
863 if String(d.properties.Dex_api_filename) != "" {
864 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700865 cmd.FlagWithOutput("-dexApi ", d.dexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700866 }
867
868 if String(d.properties.Private_dex_api_filename) != "" {
869 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700870 cmd.FlagWithOutput("-privateDexApi ", d.privateDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700871 }
872
873 if String(d.properties.Removed_dex_api_filename) != "" {
874 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700875 cmd.FlagWithOutput("-removedDexApi ", d.removedDexApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700876 }
877
878 if String(d.properties.Exact_api_filename) != "" {
879 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Crossab054432019-07-15 16:13:59 -0700880 cmd.FlagWithOutput("-exactApi ", d.exactApiFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700881 }
882
883 if String(d.properties.Dex_mapping_filename) != "" {
884 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Crossab054432019-07-15 16:13:59 -0700885 cmd.FlagWithOutput("-apiMapping ", d.apiMappingFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700886 }
887
Nan Zhang66dc2362018-08-14 20:41:04 -0700888 if String(d.properties.Proguard_filename) != "" {
889 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Crossab054432019-07-15 16:13:59 -0700890 cmd.FlagWithOutput("-proguard ", d.proguardFile)
Nan Zhang66dc2362018-08-14 20:41:04 -0700891 }
892
Nan Zhanga40da042018-08-01 12:48:00 -0700893 if BoolDefault(d.properties.Create_stubs, true) {
Colin Crossab054432019-07-15 16:13:59 -0700894 cmd.FlagWithArg("-stubs ", stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700895 }
896
897 if Bool(d.properties.Write_sdk_values) {
Colin Crossab054432019-07-15 16:13:59 -0700898 cmd.FlagWithArg("-sdkvalues ", android.PathForModuleOut(ctx, "out").String())
Nan Zhanga40da042018-08-01 12:48:00 -0700899 }
Nan Zhanga40da042018-08-01 12:48:00 -0700900}
901
Colin Crossab054432019-07-15 16:13:59 -0700902func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700903 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700904 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
905 rule.Command().Text("cp").
906 Input(staticDocIndexRedirect).
907 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700908 }
909
910 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700911 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
912 rule.Command().Text("cp").
913 Input(staticDocProperties).
914 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700915 }
Nan Zhanga40da042018-08-01 12:48:00 -0700916}
917
Colin Crossab054432019-07-15 16:13:59 -0700918func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
919 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
920 sourcepaths android.Paths) *android.RuleBuilderCommand {
921
922 cmd := rule.Command().
923 BuiltTool(ctx, "soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
924 Flag(config.JavacVmFlags).
925 FlagWithArg("-encoding ", "UTF-8").
926 FlagWithArg("-source ", "1.8").
927 FlagWithRspFileInputList("@", srcs).
928 FlagWithInput("@", srcJarList)
929
930 if len(bootclasspath) > 0 {
931 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
932 }
933
934 if len(classpath) > 0 {
935 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
936 }
937
938 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
939 // based stubs generation.
940 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
941 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
942 // the correct package name base path.
943 if len(sourcepaths) > 0 {
944 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
945 } else {
946 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
947 }
948
949 cmd.FlagWithArg("-d ", outDir.String()).
950 Flag("-quiet")
951
952 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700953}
954
Colin Crossab054432019-07-15 16:13:59 -0700955func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
956 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700957
Colin Crossab054432019-07-15 16:13:59 -0700958 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
959 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
960
961 return rule.Command().
962 BuiltTool(ctx, "dokka").
963 Flag(config.JavacVmFlags).
964 Flag(srcJarDir.String()).
965 FlagWithInputList("-classpath ", dokkaClasspath, ":").
966 FlagWithArg("-format ", "dac").
967 FlagWithArg("-dacRoot ", "/reference/kotlin").
968 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700969}
970
971func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
972 deps := d.Javadoc.collectDeps(ctx)
973
974 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
975 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
976 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
977 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
978
Colin Crossab054432019-07-15 16:13:59 -0700979 outDir := android.PathForModuleOut(ctx, "out")
980 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
981 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700982
Colin Crossab054432019-07-15 16:13:59 -0700983 rule := android.NewRuleBuilder()
Nan Zhang1598a9e2018-09-04 17:14:32 -0700984
Colin Crossab054432019-07-15 16:13:59 -0700985 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
986 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700987
Colin Crossab054432019-07-15 16:13:59 -0700988 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
989
990 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700992 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700993 } else {
Colin Crossab054432019-07-15 16:13:59 -0700994 cmd = javadocCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
995 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700996 }
997
Colin Crossab054432019-07-15 16:13:59 -0700998 d.stubsFlags(ctx, cmd, stubsDir)
999
1000 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1001
1002 var desc string
1003 if Bool(d.properties.Dokka_enabled) {
1004 desc = "dokka"
1005 } else {
1006 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
1007
1008 for _, o := range d.Javadoc.properties.Out {
1009 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1010 }
1011
1012 d.postDoclavaCmds(ctx, rule)
1013 desc = "doclava"
1014 }
1015
1016 rule.Command().
1017 BuiltTool(ctx, "soong_zip").
1018 Flag("-write_if_changed").
1019 Flag("-d").
1020 FlagWithOutput("-o ", d.docZip).
1021 FlagWithArg("-C ", outDir.String()).
1022 FlagWithArg("-D ", outDir.String())
1023
1024 rule.Command().
1025 BuiltTool(ctx, "soong_zip").
1026 Flag("-write_if_changed").
1027 Flag("-jar").
1028 FlagWithOutput("-o ", d.stubsSrcJar).
1029 FlagWithArg("-C ", stubsDir.String()).
1030 FlagWithArg("-D ", stubsDir.String())
1031
1032 rule.Restat()
1033
1034 zipSyncCleanupCmd(rule, srcJarDir)
1035
1036 rule.Build(pctx, ctx, "javadoc", desc)
1037
Nan Zhang1598a9e2018-09-04 17:14:32 -07001038 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1039 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001040
1041 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1042 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001043
1044 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001045
1046 rule := android.NewRuleBuilder()
1047
1048 rule.Command().Text("( true")
1049
1050 rule.Command().
1051 BuiltTool(ctx, "apicheck").
1052 Flag("-JXmx1024m").
1053 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1054 OptionalFlag(d.properties.Check_api.Current.Args).
1055 Input(apiFile).
1056 Input(d.apiFile).
1057 Input(removedApiFile).
1058 Input(d.removedApiFile)
1059
1060 msg := fmt.Sprintf(`\n******************************\n`+
1061 `You have tried to change the API from what has been previously approved.\n\n`+
1062 `To make these errors go away, you have two choices:\n`+
1063 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1064 ` errors above.\n\n`+
1065 ` 2. You can update current.txt by executing the following command:\n`+
1066 ` make %s-update-current-api\n\n`+
1067 ` To submit the revised current.txt to the main Android repository,\n`+
1068 ` you will need approval.\n`+
1069 `******************************\n`, ctx.ModuleName())
1070
1071 rule.Command().
1072 Text("touch").Output(d.checkCurrentApiTimestamp).
1073 Text(") || (").
1074 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1075 Text("; exit 38").
1076 Text(")")
1077
1078 rule.Build(pctx, ctx, "doclavaCurrentApiCheck", "check current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001079
1080 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001081
1082 // update API rule
1083 rule = android.NewRuleBuilder()
1084
1085 rule.Command().Text("( true")
1086
1087 rule.Command().
1088 Text("cp").Flag("-f").
1089 Input(d.apiFile).Flag(apiFile.String())
1090
1091 rule.Command().
1092 Text("cp").Flag("-f").
1093 Input(d.removedApiFile).Flag(removedApiFile.String())
1094
1095 msg = "failed to update public API"
1096
1097 rule.Command().
1098 Text("touch").Output(d.updateCurrentApiTimestamp).
1099 Text(") || (").
1100 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1101 Text("; exit 38").
1102 Text(")")
1103
1104 rule.Build(pctx, ctx, "doclavaCurrentApiUpdate", "update current API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001105 }
1106
1107 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1108 !ctx.Config().IsPdkBuild() {
Colin Crossab054432019-07-15 16:13:59 -07001109
1110 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1111 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang1598a9e2018-09-04 17:14:32 -07001112
1113 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Colin Crossab054432019-07-15 16:13:59 -07001114
1115 rule := android.NewRuleBuilder()
1116
1117 rule.Command().
1118 Text("(").
1119 BuiltTool(ctx, "apicheck").
1120 Flag("-JXmx1024m").
1121 FlagWithInputList("-Jclasspath\\ ", checkApiClasspath.Paths(), ":").
1122 OptionalFlag(d.properties.Check_api.Last_released.Args).
1123 Input(apiFile).
1124 Input(d.apiFile).
1125 Input(removedApiFile).
1126 Input(d.removedApiFile)
1127
1128 msg := `\n******************************\n` +
1129 `You have tried to change the API from what has been previously released in\n` +
1130 `an SDK. Please fix the errors listed above.\n` +
1131 `******************************\n`
1132
1133 rule.Command().
1134 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1135 Text(") || (").
1136 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1137 Text("; exit 38").
1138 Text(")")
1139
1140 rule.Build(pctx, ctx, "doclavaLastApiCheck", "check last API")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001141 }
1142}
1143
1144//
1145// Droidstubs
1146//
1147type Droidstubs struct {
1148 Javadoc
1149
Pete Gillin581d6082018-10-22 15:55:04 +01001150 properties DroidstubsProperties
1151 apiFile android.WritablePath
1152 apiXmlFile android.WritablePath
1153 lastReleasedApiXmlFile android.WritablePath
1154 dexApiFile android.WritablePath
1155 privateApiFile android.WritablePath
1156 privateDexApiFile android.WritablePath
1157 removedApiFile android.WritablePath
1158 removedDexApiFile android.WritablePath
1159 apiMappingFile android.WritablePath
1160 exactApiFile android.WritablePath
1161 proguardFile android.WritablePath
1162 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001163
1164 checkCurrentApiTimestamp android.WritablePath
1165 updateCurrentApiTimestamp android.WritablePath
1166 checkLastReleasedApiTimestamp android.WritablePath
1167
Pete Gillin581d6082018-10-22 15:55:04 +01001168 checkNullabilityWarningsTimestamp android.WritablePath
1169
Nan Zhang1598a9e2018-09-04 17:14:32 -07001170 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001171 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001172
1173 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001174
1175 jdiffDocZip android.WritablePath
1176 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001177}
1178
Colin Crossa3002fc2019-07-08 16:48:04 -07001179// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1180// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1181// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001182func DroidstubsFactory() android.Module {
1183 module := &Droidstubs{}
1184
1185 module.AddProperties(&module.properties,
1186 &module.Javadoc.properties)
1187
1188 InitDroiddocModule(module, android.HostAndDeviceSupported)
1189 return module
1190}
1191
Colin Crossa3002fc2019-07-08 16:48:04 -07001192// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1193// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1194// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1195// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001196func DroidstubsHostFactory() android.Module {
1197 module := &Droidstubs{}
1198
1199 module.AddProperties(&module.properties,
1200 &module.Javadoc.properties)
1201
1202 InitDroiddocModule(module, android.HostSupported)
1203 return module
1204}
1205
1206func (d *Droidstubs) ApiFilePath() android.Path {
1207 return d.apiFilePath
1208}
1209
1210func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1211 d.Javadoc.addDeps(ctx)
1212
Inseob Kim38449af2019-02-28 14:24:05 +09001213 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1214 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1215 }
1216
Nan Zhang1598a9e2018-09-04 17:14:32 -07001217 if len(d.properties.Merge_annotations_dirs) != 0 {
1218 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1219 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1220 }
1221 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001222
Pete Gillin77167902018-09-19 18:16:26 +01001223 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1224 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1225 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1226 }
1227 }
1228
Nan Zhang9c69a122018-08-22 10:22:08 -07001229 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1230 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1231 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1232 }
1233 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001234}
1235
Colin Cross33961b52019-07-11 11:01:22 -07001236func (d *Droidstubs) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.WritablePath) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001237 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1238 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1239 String(d.properties.Api_filename) != "" {
1240 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001241 cmd.FlagWithOutput("--api ", d.apiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001242 d.apiFilePath = d.apiFile
1243 }
1244
1245 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1246 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1247 String(d.properties.Removed_api_filename) != "" {
1248 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001249 cmd.FlagWithOutput("--removed-api ", d.removedApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250 }
1251
1252 if String(d.properties.Private_api_filename) != "" {
1253 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001254 cmd.FlagWithOutput("--private-api ", d.privateApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255 }
1256
1257 if String(d.properties.Dex_api_filename) != "" {
1258 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001259 cmd.FlagWithOutput("--dex-api ", d.dexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260 }
1261
1262 if String(d.properties.Private_dex_api_filename) != "" {
1263 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001264 cmd.FlagWithOutput("--private-dex-api ", d.privateDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001265 }
1266
1267 if String(d.properties.Removed_dex_api_filename) != "" {
1268 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001269 cmd.FlagWithOutput("--removed-dex-api ", d.removedDexApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001270 }
1271
1272 if String(d.properties.Exact_api_filename) != "" {
1273 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001274 cmd.FlagWithOutput("--exact-api ", d.exactApiFile)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001275 }
1276
Nan Zhang9c69a122018-08-22 10:22:08 -07001277 if String(d.properties.Dex_mapping_filename) != "" {
1278 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001279 cmd.FlagWithOutput("--dex-api-mapping ", d.apiMappingFile)
Nan Zhang9c69a122018-08-22 10:22:08 -07001280 }
1281
Nan Zhang199645c2018-09-19 12:40:06 -07001282 if String(d.properties.Proguard_filename) != "" {
1283 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
Colin Cross33961b52019-07-11 11:01:22 -07001284 cmd.FlagWithOutput("--proguard ", d.proguardFile)
Nan Zhang199645c2018-09-19 12:40:06 -07001285 }
1286
Nan Zhang9c69a122018-08-22 10:22:08 -07001287 if Bool(d.properties.Write_sdk_values) {
Colin Cross33961b52019-07-11 11:01:22 -07001288 cmd.FlagWithArg("--sdk-values ", android.PathForModuleOut(ctx, "out").String())
Nan Zhang9c69a122018-08-22 10:22:08 -07001289 }
1290
Nan Zhang1598a9e2018-09-04 17:14:32 -07001291 if Bool(d.properties.Create_doc_stubs) {
Colin Cross33961b52019-07-11 11:01:22 -07001292 cmd.FlagWithArg("--doc-stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001293 } else {
Colin Cross33961b52019-07-11 11:01:22 -07001294 cmd.FlagWithArg("--stubs ", stubsDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -07001295 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001296}
1297
Colin Cross33961b52019-07-11 11:01:22 -07001298func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang1598a9e2018-09-04 17:14:32 -07001299 if Bool(d.properties.Annotations_enabled) {
Colin Cross33961b52019-07-11 11:01:22 -07001300 cmd.Flag("--include-annotations")
1301
Pete Gillinc382a562018-11-14 18:45:46 +00001302 validatingNullability :=
1303 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1304 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001305 migratingNullability := String(d.properties.Previous_api) != ""
Colin Cross33961b52019-07-11 11:01:22 -07001306
Pete Gillina262c052018-09-14 14:25:48 +01001307 if !(migratingNullability || validatingNullability) {
1308 ctx.PropertyErrorf("previous_api",
1309 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001310 }
Colin Cross33961b52019-07-11 11:01:22 -07001311
Pete Gillina262c052018-09-14 14:25:48 +01001312 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001313 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Colin Cross33961b52019-07-11 11:01:22 -07001314 cmd.FlagWithInput("--migrate-nullness ", previousApi)
Pete Gillina262c052018-09-14 14:25:48 +01001315 }
Colin Cross33961b52019-07-11 11:01:22 -07001316
Pete Gillinc382a562018-11-14 18:45:46 +00001317 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross33961b52019-07-11 11:01:22 -07001318 cmd.FlagWithInput("--validate-nullability-from-list ", android.PathForModuleSrc(ctx, s))
Pete Gillinc382a562018-11-14 18:45:46 +00001319 }
Colin Cross33961b52019-07-11 11:01:22 -07001320
Pete Gillina262c052018-09-14 14:25:48 +01001321 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001322 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
Colin Cross33961b52019-07-11 11:01:22 -07001323 cmd.FlagWithOutput("--nullability-warnings-txt ", d.nullabilityWarningsFile)
Pete Gillina262c052018-09-14 14:25:48 +01001324 }
Nan Zhanga40da042018-08-01 12:48:00 -07001325
1326 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
Colin Cross33961b52019-07-11 11:01:22 -07001327 cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
Nan Zhangf4936b02018-08-01 15:00:28 -07001328
Nan Zhang1598a9e2018-09-04 17:14:32 -07001329 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001330 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001331 "has to be non-empty if annotations was enabled!")
1332 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001333
Colin Cross33961b52019-07-11 11:01:22 -07001334 d.mergeAnnoDirFlags(ctx, cmd)
1335
1336 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
1337 cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
1338 FlagWithArg("--hide ", "SuperfluousPrefix").
1339 FlagWithArg("--hide ", "AnnotationExtraction")
1340 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001341}
1342
Colin Cross33961b52019-07-11 11:01:22 -07001343func (d *Droidstubs) mergeAnnoDirFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
1344 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1345 if t, ok := m.(*ExportedDroiddocDir); ok {
1346 cmd.FlagWithArg("--merge-qualifier-annotations ", t.dir.String()).Implicits(t.deps)
1347 } else {
1348 ctx.PropertyErrorf("merge_annotations_dirs",
1349 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1350 }
1351 })
1352}
1353
1354func (d *Droidstubs) inclusionAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Pete Gillin77167902018-09-19 18:16:26 +01001355 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1356 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Cross33961b52019-07-11 11:01:22 -07001357 cmd.FlagWithArg("--merge-inclusion-annotations ", t.dir.String()).Implicits(t.deps)
Pete Gillin77167902018-09-19 18:16:26 +01001358 } else {
1359 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1360 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1361 }
1362 })
Nan Zhanga40da042018-08-01 12:48:00 -07001363}
1364
Colin Cross33961b52019-07-11 11:01:22 -07001365func (d *Droidstubs) apiLevelsAnnotationsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001366 if Bool(d.properties.Api_levels_annotations_enabled) {
1367 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
Nan Zhang9c69a122018-08-22 10:22:08 -07001368
1369 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1370 ctx.PropertyErrorf("api_levels_annotations_dirs",
1371 "has to be non-empty if api levels annotations was enabled!")
1372 }
1373
Colin Cross33961b52019-07-11 11:01:22 -07001374 cmd.FlagWithOutput("--generate-api-levels ", d.apiVersionsXml)
1375 cmd.FlagWithInput("--apply-api-levels ", d.apiVersionsXml)
1376 cmd.FlagWithArg("--current-version ", ctx.Config().PlatformSdkVersion())
1377 cmd.FlagWithArg("--current-codename ", ctx.Config().PlatformSdkCodename())
Nan Zhang9c69a122018-08-22 10:22:08 -07001378
1379 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1380 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhang9c69a122018-08-22 10:22:08 -07001381 for _, dep := range t.deps {
1382 if strings.HasSuffix(dep.String(), "android.jar") {
Colin Cross33961b52019-07-11 11:01:22 -07001383 cmd.Implicit(dep)
Nan Zhang9c69a122018-08-22 10:22:08 -07001384 }
1385 }
Colin Cross33961b52019-07-11 11:01:22 -07001386 cmd.FlagWithArg("--android-jar-pattern ", t.dir.String()+"/%/public/android.jar")
Nan Zhang9c69a122018-08-22 10:22:08 -07001387 } else {
1388 ctx.PropertyErrorf("api_levels_annotations_dirs",
1389 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1390 }
1391 })
1392
1393 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001394}
1395
Colin Cross33961b52019-07-11 11:01:22 -07001396func (d *Droidstubs) apiToXmlFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
Nan Zhang71bbe632018-09-17 14:32:21 -07001397 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1398 if d.apiFile.String() == "" {
1399 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1400 }
1401
1402 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001403 cmd.FlagWithOutput("--api-xml ", d.apiXmlFile)
Nan Zhang71bbe632018-09-17 14:32:21 -07001404
1405 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1406 ctx.PropertyErrorf("check_api.last_released.api_file",
1407 "has to be non-empty if jdiff was enabled!")
1408 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001409
Colin Cross33961b52019-07-11 11:01:22 -07001410 lastReleasedApi := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
Nan Zhang71bbe632018-09-17 14:32:21 -07001411 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
Colin Cross33961b52019-07-11 11:01:22 -07001412 cmd.FlagWithInput("--convert-to-jdiff ", lastReleasedApi).Output(d.lastReleasedApiXmlFile)
1413 }
1414}
Nan Zhang71bbe632018-09-17 14:32:21 -07001415
Colin Cross33961b52019-07-11 11:01:22 -07001416func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion string, srcs android.Paths,
1417 srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
1418 cmd := rule.Command().BuiltTool(ctx, "metalava").
1419 Flag(config.JavacVmFlags).
1420 FlagWithArg("-encoding ", "UTF-8").
1421 FlagWithArg("-source ", javaVersion).
1422 FlagWithRspFileInputList("@", srcs).
1423 FlagWithInput("@", srcJarList)
1424
1425 if len(bootclasspath) > 0 {
1426 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
Nan Zhang71bbe632018-09-17 14:32:21 -07001427 }
1428
Colin Cross33961b52019-07-11 11:01:22 -07001429 if len(classpath) > 0 {
1430 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
1431 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001432
Colin Cross33961b52019-07-11 11:01:22 -07001433 if len(sourcepaths) > 0 {
1434 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
1435 } else {
1436 cmd.FlagWithArg("-sourcepath ", `""`)
1437 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001438
Colin Cross33961b52019-07-11 11:01:22 -07001439 cmd.Flag("--no-banner").
1440 Flag("--color").
1441 Flag("--quiet").
1442 Flag("--format=v2")
Nan Zhang86d2d552018-08-09 15:33:27 -07001443
Colin Cross33961b52019-07-11 11:01:22 -07001444 return cmd
Nan Zhang71bbe632018-09-17 14:32:21 -07001445}
1446
Nan Zhang1598a9e2018-09-04 17:14:32 -07001447func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001448 deps := d.Javadoc.collectDeps(ctx)
1449
1450 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001451
Colin Cross33961b52019-07-11 11:01:22 -07001452 // Create rule for metalava
Nan Zhanga40da042018-08-01 12:48:00 -07001453
Colin Cross33961b52019-07-11 11:01:22 -07001454 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
1455 stubsDir := android.PathForModuleOut(ctx, "stubsDir")
Nan Zhanga40da042018-08-01 12:48:00 -07001456
Colin Cross33961b52019-07-11 11:01:22 -07001457 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001458
Colin Cross33961b52019-07-11 11:01:22 -07001459 rule.Command().Text("rm -rf").Text(stubsDir.String())
1460 rule.Command().Text("mkdir -p").Text(stubsDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -07001461
Colin Cross33961b52019-07-11 11:01:22 -07001462 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1463
1464 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1465 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1466
1467 d.stubsFlags(ctx, cmd, stubsDir)
1468
1469 d.annotationsFlags(ctx, cmd)
1470 d.inclusionAnnotationsFlags(ctx, cmd)
1471 d.apiLevelsAnnotationsFlags(ctx, cmd)
1472 d.apiToXmlFlags(ctx, cmd)
Nan Zhang71bbe632018-09-17 14:32:21 -07001473
Nan Zhang1598a9e2018-09-04 17:14:32 -07001474 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1475 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1476 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1477 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1478 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001479 }
Colin Cross33961b52019-07-11 11:01:22 -07001480
1481 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles)
1482 for _, o := range d.Javadoc.properties.Out {
1483 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
1484 }
1485
1486 rule.Command().
1487 BuiltTool(ctx, "soong_zip").
1488 Flag("-write_if_changed").
1489 Flag("-jar").
1490 FlagWithOutput("-o ", d.Javadoc.stubsSrcJar).
1491 FlagWithArg("-C ", stubsDir.String()).
1492 FlagWithArg("-D ", stubsDir.String())
1493 rule.Restat()
1494
1495 zipSyncCleanupCmd(rule, srcJarDir)
1496
1497 rule.Build(pctx, ctx, "metalava", "metalava")
1498
1499 // Create rule for apicheck
Nan Zhang61819ce2018-05-04 18:49:16 -07001500
Nan Zhang1598a9e2018-09-04 17:14:32 -07001501 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1502 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001503
1504 if len(d.Javadoc.properties.Out) > 0 {
1505 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1506 }
1507
1508 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
1509 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001510
Nan Zhang2760dfc2018-08-24 17:32:54 +00001511 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001512
Colin Cross33961b52019-07-11 11:01:22 -07001513 rule := android.NewRuleBuilder()
1514
1515 rule.Command().Text("( true")
1516
1517 srcJarDir := android.PathForModuleOut(ctx, "current-apicheck", "srcjars")
1518 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1519
1520 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1521 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1522
1523 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1524 FlagWithInput("--check-compatibility:api:current ", apiFile).
1525 FlagWithInput("--check-compatibility:removed:current ", removedApiFile)
1526
1527 d.inclusionAnnotationsFlags(ctx, cmd)
1528 d.mergeAnnoDirFlags(ctx, cmd)
1529
1530 zipSyncCleanupCmd(rule, srcJarDir)
1531
1532 msg := fmt.Sprintf(`\n******************************\n`+
1533 `You have tried to change the API from what has been previously approved.\n\n`+
1534 `To make these errors go away, you have two choices:\n`+
1535 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1536 ` errors above.\n\n`+
1537 ` 2. You can update current.txt by executing the following command:\n`+
1538 ` make %s-update-current-api\n\n`+
1539 ` To submit the revised current.txt to the main Android repository,\n`+
1540 ` you will need approval.\n`+
1541 `******************************\n`, ctx.ModuleName())
1542
1543 rule.Command().
1544 Text("touch").Output(d.checkCurrentApiTimestamp).
1545 Text(") || (").
1546 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1547 Text("; exit 38").
1548 Text(")")
1549
1550 rule.Build(pctx, ctx, "metalavaCurrentApiCheck", "metalava check current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001551
1552 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001553
1554 // update API rule
1555 rule = android.NewRuleBuilder()
1556
1557 rule.Command().Text("( true")
1558
1559 rule.Command().
1560 Text("cp").Flag("-f").
1561 Input(d.apiFile).Flag(apiFile.String())
1562
1563 rule.Command().
1564 Text("cp").Flag("-f").
1565 Input(d.removedApiFile).Flag(removedApiFile.String())
1566
1567 msg = "failed to update public API"
1568
1569 rule.Command().
1570 Text("touch").Output(d.updateCurrentApiTimestamp).
1571 Text(") || (").
1572 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1573 Text("; exit 38").
1574 Text(")")
1575
1576 rule.Build(pctx, ctx, "metalavaCurrentApiUpdate", "update current API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001577 }
Nan Zhanga40da042018-08-01 12:48:00 -07001578
Nan Zhang1598a9e2018-09-04 17:14:32 -07001579 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1580 !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001581
1582 if len(d.Javadoc.properties.Out) > 0 {
1583 ctx.PropertyErrorf("out", "out property may not be combined with check_api")
1584 }
1585
1586 apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
1587 removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
Nan Zhang61819ce2018-05-04 18:49:16 -07001588
Nan Zhang2760dfc2018-08-24 17:32:54 +00001589 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Nan Zhang2760dfc2018-08-24 17:32:54 +00001590
Colin Cross33961b52019-07-11 11:01:22 -07001591 rule := android.NewRuleBuilder()
1592
1593 rule.Command().Text("( true")
1594
1595 srcJarDir := android.PathForModuleOut(ctx, "last-apicheck", "srcjars")
1596 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1597
1598 cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
1599 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
1600
1601 cmd.Flag(d.Javadoc.args).Implicits(d.Javadoc.argFiles).
1602 FlagWithInput("--check-compatibility:api:released ", apiFile)
1603
1604 d.inclusionAnnotationsFlags(ctx, cmd)
1605
1606 cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
1607
1608 d.mergeAnnoDirFlags(ctx, cmd)
1609
1610 zipSyncCleanupCmd(rule, srcJarDir)
1611
1612 msg := `\n******************************\n` +
1613 `You have tried to change the API from what has been previously released in\n` +
1614 `an SDK. Please fix the errors listed above.\n` +
1615 `******************************\n`
1616 rule.Command().
1617 Text("touch").Output(d.checkLastReleasedApiTimestamp).
1618 Text(") || (").
1619 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1620 Text("; exit 38").
1621 Text(")")
1622
1623 rule.Build(pctx, ctx, "metalavaLastApiCheck", "metalava check last API")
Nan Zhang61819ce2018-05-04 18:49:16 -07001624 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001625
Pete Gillin581d6082018-10-22 15:55:04 +01001626 if String(d.properties.Check_nullability_warnings) != "" {
1627 if d.nullabilityWarningsFile == nil {
1628 ctx.PropertyErrorf("check_nullability_warnings",
1629 "Cannot specify check_nullability_warnings unless validating nullability")
1630 }
Colin Cross33961b52019-07-11 11:01:22 -07001631
1632 checkNullabilityWarnings := android.PathForModuleSrc(ctx, String(d.properties.Check_nullability_warnings))
1633
Pete Gillin581d6082018-10-22 15:55:04 +01001634 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
Colin Cross33961b52019-07-11 11:01:22 -07001635
Pete Gillin581d6082018-10-22 15:55:04 +01001636 msg := fmt.Sprintf(`\n******************************\n`+
1637 `The warnings encountered during nullability annotation validation did\n`+
1638 `not match the checked in file of expected warnings. The diffs are shown\n`+
1639 `above. You have two options:\n`+
1640 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1641 ` 2. Update the file of expected warnings by running:\n`+
1642 ` cp %s %s\n`+
1643 ` and submitting the updated file as part of your change.`,
1644 d.nullabilityWarningsFile, checkNullabilityWarnings)
Colin Cross33961b52019-07-11 11:01:22 -07001645
1646 rule := android.NewRuleBuilder()
1647
1648 rule.Command().
1649 Text("(").
1650 Text("diff").Input(checkNullabilityWarnings).Input(d.nullabilityWarningsFile).
1651 Text("&&").
1652 Text("touch").Output(d.checkNullabilityWarningsTimestamp).
1653 Text(") || (").
1654 Text("echo").Flag("-e").Flag(`"` + msg + `"`).
1655 Text("; exit 38").
1656 Text(")")
1657
1658 rule.Build(pctx, ctx, "nullabilityWarningsCheck", "nullability warnings check")
Pete Gillin581d6082018-10-22 15:55:04 +01001659 }
1660
Nan Zhang71bbe632018-09-17 14:32:21 -07001661 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
Colin Cross33961b52019-07-11 11:01:22 -07001662 if len(d.Javadoc.properties.Out) > 0 {
1663 ctx.PropertyErrorf("out", "out property may not be combined with jdiff")
1664 }
1665
1666 outDir := android.PathForModuleOut(ctx, "jdiff-out")
1667 srcJarDir := android.PathForModuleOut(ctx, "jdiff-srcjars")
1668 stubsDir := android.PathForModuleOut(ctx, "jdiff-stubsDir")
1669
1670 rule := android.NewRuleBuilder()
Nan Zhang71bbe632018-09-17 14:32:21 -07001671
Nan Zhang86b06202018-09-21 17:09:21 -07001672 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1673 // since there's cron job downstream that fetch this .zip file periodically.
1674 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001675 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1676 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1677
Nan Zhang71bbe632018-09-17 14:32:21 -07001678 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
Nan Zhang71bbe632018-09-17 14:32:21 -07001679
Colin Cross33961b52019-07-11 11:01:22 -07001680 rule.Command().Text("rm -rf").Text(outDir.String()).Text(stubsDir.String())
1681 rule.Command().Text("mkdir -p").Text(outDir.String()).Text(stubsDir.String())
Nan Zhang71bbe632018-09-17 14:32:21 -07001682
Colin Cross33961b52019-07-11 11:01:22 -07001683 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
1684
Colin Crossab054432019-07-15 16:13:59 -07001685 cmd := javadocCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
1686 deps.bootClasspath, deps.classpath, d.sourcepaths)
1687
1688 cmd.Flag("-J-Xmx1600m").
Colin Cross33961b52019-07-11 11:01:22 -07001689 Flag("-XDignore.symbol.file").
1690 FlagWithArg("-doclet ", "jdiff.JDiff").
1691 FlagWithInput("-docletpath ", jdiff).
1692 Flag("-quiet").
1693 FlagWithArg("-newapi ", strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext())).
1694 FlagWithArg("-newapidir ", filepath.Dir(d.apiXmlFile.String())).
1695 Implicit(d.apiXmlFile).
1696 FlagWithArg("-oldapi ", strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext())).
1697 FlagWithArg("-oldapidir ", filepath.Dir(d.lastReleasedApiXmlFile.String())).
1698 Implicit(d.lastReleasedApiXmlFile)
1699
Colin Cross33961b52019-07-11 11:01:22 -07001700 rule.Command().
1701 BuiltTool(ctx, "soong_zip").
1702 Flag("-write_if_changed").
1703 Flag("-d").
1704 FlagWithOutput("-o ", d.jdiffDocZip).
1705 FlagWithArg("-C ", outDir.String()).
1706 FlagWithArg("-D ", outDir.String())
1707
1708 rule.Command().
1709 BuiltTool(ctx, "soong_zip").
1710 Flag("-write_if_changed").
1711 Flag("-jar").
1712 FlagWithOutput("-o ", d.jdiffStubsSrcJar).
1713 FlagWithArg("-C ", stubsDir.String()).
1714 FlagWithArg("-D ", stubsDir.String())
1715
1716 rule.Restat()
1717
1718 zipSyncCleanupCmd(rule, srcJarDir)
1719
1720 rule.Build(pctx, ctx, "jdiff", "jdiff")
Nan Zhang71bbe632018-09-17 14:32:21 -07001721 }
Nan Zhang581fd212018-01-10 16:06:12 -08001722}
Dan Willemsencc090972018-02-26 14:33:31 -08001723
Nan Zhanga40da042018-08-01 12:48:00 -07001724//
Nan Zhangf4936b02018-08-01 15:00:28 -07001725// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001726//
Dan Willemsencc090972018-02-26 14:33:31 -08001727var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001728var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001729var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001730var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001731
Nan Zhangf4936b02018-08-01 15:00:28 -07001732type ExportedDroiddocDirProperties struct {
1733 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001734 Path *string
1735}
1736
Nan Zhangf4936b02018-08-01 15:00:28 -07001737type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001738 android.ModuleBase
1739
Nan Zhangf4936b02018-08-01 15:00:28 -07001740 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001741
1742 deps android.Paths
1743 dir android.Path
1744}
1745
Colin Crossa3002fc2019-07-08 16:48:04 -07001746// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001747func ExportedDroiddocDirFactory() android.Module {
1748 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001749 module.AddProperties(&module.properties)
1750 android.InitAndroidModule(module)
1751 return module
1752}
1753
Nan Zhangf4936b02018-08-01 15:00:28 -07001754func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001755
Nan Zhangf4936b02018-08-01 15:00:28 -07001756func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001757 path := String(d.properties.Path)
1758 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001759 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001760}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001761
1762//
1763// Defaults
1764//
1765type DocDefaults struct {
1766 android.ModuleBase
1767 android.DefaultsModuleBase
1768}
1769
Nan Zhangb2b33de2018-02-23 11:18:47 -08001770func DocDefaultsFactory() android.Module {
1771 module := &DocDefaults{}
1772
1773 module.AddProperties(
1774 &JavadocProperties{},
1775 &DroiddocProperties{},
1776 )
1777
1778 android.InitDefaultsModule(module)
1779
1780 return module
1781}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001782
1783func StubsDefaultsFactory() android.Module {
1784 module := &DocDefaults{}
1785
1786 module.AddProperties(
1787 &JavadocProperties{},
1788 &DroidstubsProperties{},
1789 )
1790
1791 android.InitDefaultsModule(module)
1792
1793 return module
1794}
Colin Cross33961b52019-07-11 11:01:22 -07001795
1796func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
1797 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
1798
1799 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1800 rule.Command().Text("mkdir -p").Text(srcJarDir.String())
1801 srcJarList := srcJarDir.Join(ctx, "list")
1802
1803 rule.Temporary(srcJarList)
1804
1805 rule.Command().BuiltTool(ctx, "zipsync").
1806 FlagWithArg("-d ", srcJarDir.String()).
1807 FlagWithOutput("-l ", srcJarList).
1808 FlagWithArg("-f ", `"*.java"`).
1809 Inputs(srcJars)
1810
1811 return srcJarList
1812}
1813
1814func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
1815 rule.Command().Text("rm -rf").Text(srcJarDir.String())
1816}