blob: 2a65964fc22d29a486ee7a0564ee7ccc906e82ec [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 (
18 "android/soong/android"
19 "android/soong/java/config"
20 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080021 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070022 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080023 "strings"
24
25 "github.com/google/blueprint"
26)
27
28var (
29 javadoc = pctx.AndroidStaticRule("javadoc",
30 blueprint.RuleParams{
31 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070032 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhangaf322cc2018-06-19 15:15:38 -070033 `${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang581fd212018-01-10 16:06:12 -080034 `$opts $bootclasspathArgs $classpathArgs -sourcepath $sourcepath ` +
35 `-d $outDir -quiet && ` +
36 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Nan Zhange2ba5d42018-07-11 15:16:55 -070037 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds`,
Nan Zhang581fd212018-01-10 16:06:12 -080038 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070039 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080040 "${config.JavadocCmd}",
41 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080042 },
43 Rspfile: "$out.rsp",
44 RspfileContent: "$in",
45 Restat: true,
46 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070047 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhange2ba5d42018-07-11 15:16:55 -070048 "bootclasspathArgs", "classpathArgs", "sourcepath", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070049
50 apiCheck = pctx.AndroidStaticRule("apiCheck",
51 blueprint.RuleParams{
52 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
53 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090054 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070055 CommandDeps: []string{
56 "${config.ApiCheckCmd}",
57 },
58 },
59 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
60
61 updateApi = pctx.AndroidStaticRule("updateApi",
62 blueprint.RuleParams{
63 Command: `( ( cp -f $apiFileToCheck $apiFile && cp -f $removedApiFileToCheck $removedApiFile ) ` +
64 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
65 },
66 "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck")
Nan Zhang79614d12018-04-19 18:03:39 -070067
68 metalava = pctx.AndroidStaticRule("metalava",
69 blueprint.RuleParams{
70 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
71 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang357466b2018-04-17 17:38:36 -070072 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Nan Zhang16c0a312018-06-13 17:42:48 -070073 `$bootclasspathArgs $classpathArgs -sourcepath $sourcepath --no-banner --color --quiet ` +
74 `--stubs $stubsDir $opts && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070075 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
76 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
77 CommandDeps: []string{
78 "${config.ZipSyncCmd}",
79 "${config.JavaCmd}",
80 "${config.MetalavaJar}",
81 "${config.JavadocCmd}",
82 "${config.SoongZipCmd}",
83 },
84 Rspfile: "$out.rsp",
85 RspfileContent: "$in",
86 Restat: true,
87 },
Nan Zhang357466b2018-04-17 17:38:36 -070088 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
89 "classpathArgs", "sourcepath", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -080090)
91
92func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080093 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
94
Nan Zhang581fd212018-01-10 16:06:12 -080095 android.RegisterModuleType("droiddoc", DroiddocFactory)
96 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Dan Willemsencc090972018-02-26 14:33:31 -080097 android.RegisterModuleType("droiddoc_template", DroiddocTemplateFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080098 android.RegisterModuleType("javadoc", JavadocFactory)
99 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
100}
101
Colin Crossa1ce2a02018-06-20 15:19:39 -0700102var (
103 srcsLibTag = dependencyTag{name: "sources from javalib"}
104)
105
Nan Zhang581fd212018-01-10 16:06:12 -0800106type JavadocProperties struct {
107 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
108 // or .aidl files.
109 Srcs []string `android:"arch_variant"`
110
111 // list of directories rooted at the Android.bp file that will
112 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800113 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800114
115 // list of source files that should not be used to build the Java module.
116 // This is most useful in the arch/multilib variants to remove non-common files
117 // filegroup or genrule can be included within this property.
118 Exclude_srcs []string `android:"arch_variant"`
119
Nan Zhangb2b33de2018-02-23 11:18:47 -0800120 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800121 Libs []string `android:"arch_variant"`
122
Nan Zhange66c7272018-03-06 12:59:27 -0800123 // don't build against the framework libraries (legacy-test, core-junit,
124 // ext, and framework for device targets)
125 No_framework_libs *bool
126
Nan Zhangb2b33de2018-02-23 11:18:47 -0800127 // the java library (in classpath) for documentation that provides java srcs and srcjars.
128 Srcs_lib *string
129
130 // the base dirs under srcs_lib will be scanned for java srcs.
131 Srcs_lib_whitelist_dirs []string
132
133 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
134 Srcs_lib_whitelist_pkgs []string
135
Nan Zhang581fd212018-01-10 16:06:12 -0800136 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800137 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800138
139 // if not blank, set to the version of the sdk to compile against
140 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900141
142 Aidl struct {
143 // Top level directories to pass to aidl tool
144 Include_dirs []string
145
146 // Directories rooted at the Android.bp file to pass to aidl tool
147 Local_include_dirs []string
148 }
Nan Zhang357466b2018-04-17 17:38:36 -0700149
150 // If not blank, set the java version passed to javadoc as -source
151 Java_version *string
Nan Zhang581fd212018-01-10 16:06:12 -0800152}
153
Nan Zhang61819ce2018-05-04 18:49:16 -0700154type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900155 // path to the API txt file that the new API extracted from source code is checked
156 // against. The path can be local to the module or from other module (via :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700157 Api_file *string
158
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900159 // path to the API txt file that the new @removed API extractd from source code is
160 // checked against. The path can be local to the module or from other module (via
161 // :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700162 Removed_api_file *string
163
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900164 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700165 Args *string
166}
167
Nan Zhang581fd212018-01-10 16:06:12 -0800168type DroiddocProperties struct {
169 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800170 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800171
Nan Zhanga40da042018-08-01 12:48:00 -0700172 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800173 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800174
175 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800176 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800177
178 // proofread file contains all of the text content of the javadocs concatenated into one file,
179 // suitable for spell-checking and other goodness.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800180 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800181
182 // a todo file lists the program elements that are missing documentation.
183 // At some point, this might be improved to show more warnings.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800184 Todo_file *string
185
186 // directory under current module source that provide additional resources (images).
187 Resourcesdir *string
188
189 // resources output directory under out/soong/.intermediates.
190 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800191
192 // local files that are used within user customized droiddoc options.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800193 Arg_files []string
Nan Zhang581fd212018-01-10 16:06:12 -0800194
195 // user customized droiddoc args.
196 // Available variables for substitution:
197 //
198 // $(location <label>): the path to the arg_files with name <label>
Nan Zhangb2b33de2018-02-23 11:18:47 -0800199 Args *string
Nan Zhang581fd212018-01-10 16:06:12 -0800200
201 // names of the output files used in args that will be generated
Nan Zhangb2b33de2018-02-23 11:18:47 -0800202 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800203
Nan Zhange2ba5d42018-07-11 15:16:55 -0700204 // if set to true, collect the values used by the Dev tools and
205 // write them in files packaged with the SDK. Defaults to false.
206 Write_sdk_values *bool
207
208 // index.html under current module will be copied to docs out dir, if not null.
209 Static_doc_index_redirect *string
210
211 // source.properties under current module will be copied to docs out dir, if not null.
212 Static_doc_properties *string
213
Nan Zhang581fd212018-01-10 16:06:12 -0800214 // a list of files under current module source dir which contains known tags in Java sources.
215 // filegroup or genrule can be included within this property.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800216 Knowntags []string
Nan Zhang28c68b92018-03-13 16:17:01 -0700217
218 // the tag name used to distinguish if the API files belong to public/system/test.
219 Api_tag_name *string
220
221 // the generated public API filename by Doclava.
222 Api_filename *string
223
David Brazdilfbe4cc32018-05-31 13:56:46 +0100224 // the generated public Dex API filename by Doclava.
225 Dex_api_filename *string
226
Nan Zhang28c68b92018-03-13 16:17:01 -0700227 // the generated private API filename by Doclava.
228 Private_api_filename *string
229
230 // the generated private Dex API filename by Doclava.
231 Private_dex_api_filename *string
232
233 // the generated removed API filename by Doclava.
234 Removed_api_filename *string
235
David Brazdilaac0c3c2018-04-24 16:23:29 +0100236 // the generated removed Dex API filename by Doclava.
237 Removed_dex_api_filename *string
238
Mathew Inwood76c3de12018-06-22 15:28:11 +0100239 // mapping of dex signatures to source file and line number. This is a temporary property and
240 // will be deleted; you probably shouldn't be using it.
241 Dex_mapping_filename *string
242
Nan Zhang28c68b92018-03-13 16:17:01 -0700243 // the generated exact API filename by Doclava.
244 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700245
246 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
247 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700248
249 Check_api struct {
250 Last_released ApiToCheck
251
252 Current ApiToCheck
253 }
Nan Zhang79614d12018-04-19 18:03:39 -0700254
255 // if set to true, create stubs through Metalava instead of Doclava. Javadoc/Doclava is
256 // currently still used for documentation generation, and will be replaced by Dokka soon.
257 Metalava_enabled *bool
258
259 // user can specify the version of previous released API file in order to do compatibility check.
260 Metalava_previous_api *string
261
262 // is set to true, Metalava will allow framework SDK to contain annotations.
263 Metalava_annotations_enabled *bool
264
Pete Gillinb13a0152018-07-19 17:56:49 +0100265 // a list of top-level directories containing files to merge annotations from.
266 Metalava_merge_annotations_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800267}
268
Nan Zhanga40da042018-08-01 12:48:00 -0700269//
270// Common flags passed down to build rule
271//
272type droiddocBuilderFlags struct {
273 args string
274 bootClasspathArgs string
275 classpathArgs string
276 aidlFlags string
277
278 doclavaDocsFlags string
279 doclavaStubsFlags string
280 postDoclavaCmds string
281
282 metalavaAnnotationsFlags string
283 metalavaDocsFlags string
284 metalavaStubsFlags string
285
286 dokkaFlags string
287}
288
289func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
290 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
291 android.InitDefaultableModule(module)
292}
293
294//
295// Javadoc
296//
Nan Zhang581fd212018-01-10 16:06:12 -0800297type Javadoc struct {
298 android.ModuleBase
299 android.DefaultableModuleBase
300
301 properties JavadocProperties
302
303 srcJars android.Paths
304 srcFiles android.Paths
305 sourcepaths android.Paths
306
Nan Zhangccff0f72018-03-08 17:26:16 -0800307 docZip android.WritablePath
308 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800309}
310
Nan Zhangb2b33de2018-02-23 11:18:47 -0800311func (j *Javadoc) Srcs() android.Paths {
312 return android.Paths{j.stubsSrcJar}
313}
314
Nan Zhang581fd212018-01-10 16:06:12 -0800315func JavadocFactory() android.Module {
316 module := &Javadoc{}
317
318 module.AddProperties(&module.properties)
319
320 InitDroiddocModule(module, android.HostAndDeviceSupported)
321 return module
322}
323
324func JavadocHostFactory() android.Module {
325 module := &Javadoc{}
326
327 module.AddProperties(&module.properties)
328
329 InitDroiddocModule(module, android.HostSupported)
330 return module
331}
332
Nan Zhanga40da042018-08-01 12:48:00 -0700333var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800334
Colin Cross83bb3162018-06-25 15:48:06 -0700335func (j *Javadoc) sdkVersion() string {
336 return String(j.properties.Sdk_version)
337}
338
339func (j *Javadoc) minSdkVersion() string {
340 return j.sdkVersion()
341}
342
Nan Zhang581fd212018-01-10 16:06:12 -0800343func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
344 if ctx.Device() {
Colin Cross83bb3162018-06-25 15:48:06 -0700345 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800346 if sdkDep.useDefaultLibs {
347 ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700348 if ctx.Config().TargetOpenJDK9() {
349 ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
350 }
Nan Zhang9cbe6772018-03-21 17:56:39 -0700351 if !Bool(j.properties.No_framework_libs) {
Nan Zhange66c7272018-03-06 12:59:27 -0800352 ctx.AddDependency(ctx.Module(), libTag, []string{"ext", "framework"}...)
353 }
Nan Zhang581fd212018-01-10 16:06:12 -0800354 } else if sdkDep.useModule {
Nan Zhang357466b2018-04-17 17:38:36 -0700355 if ctx.Config().TargetOpenJDK9() {
356 ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
357 }
Colin Cross86a60ae2018-05-29 14:44:55 -0700358 ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.modules...)
Nan Zhang581fd212018-01-10 16:06:12 -0800359 }
360 }
361
362 ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700363 if j.properties.Srcs_lib != nil {
364 ctx.AddDependency(ctx.Module(), srcsLibTag, *j.properties.Srcs_lib)
365 }
Nan Zhang581fd212018-01-10 16:06:12 -0800366
367 android.ExtractSourcesDeps(ctx, j.properties.Srcs)
368
369 // exclude_srcs may contain filegroup or genrule.
370 android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
371}
372
Nan Zhangb2b33de2018-02-23 11:18:47 -0800373func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
374 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
375 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900376 // convert foo.bar.baz to foo/bar/baz
377 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
378 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800379 if _, found := whitelistPathPrefixes[prefix]; !found {
380 whitelistPathPrefixes[prefix] = true
381 }
382 }
383 }
384}
385
Nan Zhanga40da042018-08-01 12:48:00 -0700386func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
387 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900388
389 // aidl flags.
390 aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
391 if len(aidlFlags) > 0 {
392 // optimization.
393 ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
394 flags.aidlFlags = "$aidlFlags"
395 }
396
397 return flags
398}
399
400func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
401 aidlIncludeDirs android.Paths) []string {
402
403 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
404 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
405
406 var flags []string
407 if aidlPreprocess.Valid() {
408 flags = append(flags, "-p"+aidlPreprocess.String())
409 } else {
410 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
411 }
412
413 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
414 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
415 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
416 flags = append(flags, "-I"+src.String())
417 }
418
419 return flags
420}
421
422func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700423 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900424
425 outSrcFiles := make(android.Paths, 0, len(srcFiles))
426
427 for _, srcFile := range srcFiles {
428 switch srcFile.Ext() {
429 case ".aidl":
430 javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
431 outSrcFiles = append(outSrcFiles, javaFile)
432 default:
433 outSrcFiles = append(outSrcFiles, srcFile)
434 }
435 }
436
437 return outSrcFiles
438}
439
Nan Zhang581fd212018-01-10 16:06:12 -0800440func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
441 var deps deps
442
Colin Cross83bb3162018-06-25 15:48:06 -0700443 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800444 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700445 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800446 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700447 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800448 }
449
450 ctx.VisitDirectDeps(func(module android.Module) {
451 otherName := ctx.OtherModuleName(module)
452 tag := ctx.OtherModuleDependencyTag(module)
453
Colin Cross2d24c1b2018-05-23 10:59:18 -0700454 switch tag {
455 case bootClasspathTag:
456 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800457 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700458 } else {
459 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
460 }
461 case libTag:
462 switch dep := module.(type) {
463 case Dependency:
Nan Zhang581fd212018-01-10 16:06:12 -0800464 deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700465 case SdkLibraryDependency:
Colin Cross83bb3162018-06-25 15:48:06 -0700466 sdkVersion := j.sdkVersion()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900467 linkType := javaSdk
468 if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
469 linkType = javaSystem
470 } else if sdkVersion == "" {
471 linkType = javaPlatform
472 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900473 deps.classpath = append(deps.classpath, dep.ImplementationJars(linkType)...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700474 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800475 checkProducesJars(ctx, dep)
476 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800477 default:
478 ctx.ModuleErrorf("depends on non-java module %q", otherName)
479 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700480 case srcsLibTag:
481 switch dep := module.(type) {
482 case Dependency:
483 srcs := dep.(SrcDependency).CompiledSrcs()
484 whitelistPathPrefixes := make(map[string]bool)
485 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
486 for _, src := range srcs {
487 if _, ok := src.(android.WritablePath); ok { // generated sources
488 deps.srcs = append(deps.srcs, src)
489 } else { // select source path for documentation based on whitelist path prefixs.
490 for k, _ := range whitelistPathPrefixes {
491 if strings.HasPrefix(src.Rel(), k) {
492 deps.srcs = append(deps.srcs, src)
493 break
494 }
495 }
496 }
497 }
498 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
499 default:
500 ctx.ModuleErrorf("depends on non-java module %q", otherName)
501 }
Nan Zhang357466b2018-04-17 17:38:36 -0700502 case systemModulesTag:
503 if deps.systemModules != nil {
504 panic("Found two system module dependencies")
505 }
506 sm := module.(*SystemModules)
507 if sm.outputFile == nil {
508 panic("Missing directory for system module dependency")
509 }
510 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800511 }
512 })
513 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
514 // may contain filegroup or genrule.
515 srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700516 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900517 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800518
519 // srcs may depend on some genrule output.
520 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800521 j.srcJars = append(j.srcJars, deps.srcJars...)
522
Nan Zhang581fd212018-01-10 16:06:12 -0800523 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800524 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800525
526 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800527 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800528
529 if j.properties.Local_sourcepaths == nil {
530 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
531 }
532 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800533
534 return deps
535}
536
537func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
538 j.addDeps(ctx)
539}
540
541func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
542 deps := j.collectDeps(ctx)
543
544 var implicits android.Paths
545 implicits = append(implicits, deps.bootClasspath...)
546 implicits = append(implicits, deps.classpath...)
547
548 var bootClasspathArgs, classpathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700549
Colin Cross83bb3162018-06-25 15:48:06 -0700550 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700551 if len(deps.bootClasspath) > 0 {
552 var systemModules classpath
553 if deps.systemModules != nil {
554 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800555 }
Colin Cross997262f2018-06-19 22:49:39 -0700556 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
557 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800558 }
559 if len(deps.classpath.Strings()) > 0 {
560 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
561 }
562
563 implicits = append(implicits, j.srcJars...)
564
Nan Zhangaf322cc2018-06-19 15:15:38 -0700565 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800566
567 ctx.Build(pctx, android.BuildParams{
568 Rule: javadoc,
569 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800570 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800571 ImplicitOutput: j.docZip,
572 Inputs: j.srcFiles,
573 Implicits: implicits,
574 Args: map[string]string{
575 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
576 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
577 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
578 "srcJars": strings.Join(j.srcJars.Strings(), " "),
579 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700580 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800581 "classpathArgs": classpathArgs,
582 "sourcepath": strings.Join(j.sourcepaths.Strings(), ":"),
583 "docZip": j.docZip.String(),
584 },
585 })
586}
587
Nan Zhanga40da042018-08-01 12:48:00 -0700588//
589// Droiddoc
590//
591type Droiddoc struct {
592 Javadoc
593
594 properties DroiddocProperties
595 apiFile android.WritablePath
596 dexApiFile android.WritablePath
597 privateApiFile android.WritablePath
598 privateDexApiFile android.WritablePath
599 removedApiFile android.WritablePath
600 removedDexApiFile android.WritablePath
601 exactApiFile android.WritablePath
602 apiMappingFile android.WritablePath
603
604 checkCurrentApiTimestamp android.WritablePath
605 updateCurrentApiTimestamp android.WritablePath
606 checkLastReleasedApiTimestamp android.WritablePath
607
608 annotationsZip android.WritablePath
609
610 apiFilePath android.Path
611}
612
613type ApiFilePath interface {
614 ApiFilePath() android.Path
615}
616
617func DroiddocFactory() android.Module {
618 module := &Droiddoc{}
619
620 module.AddProperties(&module.properties,
621 &module.Javadoc.properties)
622
623 InitDroiddocModule(module, android.HostAndDeviceSupported)
624 return module
625}
626
627func DroiddocHostFactory() android.Module {
628 module := &Droiddoc{}
629
630 module.AddProperties(&module.properties,
631 &module.Javadoc.properties)
632
633 InitDroiddocModule(module, android.HostSupported)
634 return module
635}
636
637func (d *Droiddoc) ApiFilePath() android.Path {
638 return d.apiFilePath
639}
640
Nan Zhang61819ce2018-05-04 18:49:16 -0700641func (d *Droiddoc) checkCurrentApi() bool {
642 if String(d.properties.Check_api.Current.Api_file) != "" &&
643 String(d.properties.Check_api.Current.Removed_api_file) != "" {
644 return true
645 } else if String(d.properties.Check_api.Current.Api_file) != "" {
646 panic("check_api.current.removed_api_file: has to be non empty!")
647 } else if String(d.properties.Check_api.Current.Removed_api_file) != "" {
648 panic("check_api.current.api_file: has to be non empty!")
649 }
650
651 return false
652}
653
654func (d *Droiddoc) checkLastReleasedApi() bool {
655 if String(d.properties.Check_api.Last_released.Api_file) != "" &&
656 String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
657 return true
658 } else if String(d.properties.Check_api.Last_released.Api_file) != "" {
659 panic("check_api.last_released.removed_api_file: has to be non empty!")
660 } else if String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
661 panic("check_api.last_released.api_file: has to be non empty!")
662 }
663
664 return false
665}
666
Nan Zhang581fd212018-01-10 16:06:12 -0800667func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
668 d.Javadoc.addDeps(ctx)
669
Nan Zhang79614d12018-04-19 18:03:39 -0700670 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800671 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
672 }
673
Nan Zhanga40da042018-08-01 12:48:00 -0700674 // arg_files may contains filegroup or genrule.
Nan Zhang581fd212018-01-10 16:06:12 -0800675 android.ExtractSourcesDeps(ctx, d.properties.Arg_files)
676
677 // knowntags may contain filegroup or genrule.
678 android.ExtractSourcesDeps(ctx, d.properties.Knowntags)
Nan Zhang61819ce2018-05-04 18:49:16 -0700679
Nan Zhange2ba5d42018-07-11 15:16:55 -0700680 if String(d.properties.Static_doc_index_redirect) != "" {
681 android.ExtractSourceDeps(ctx, d.properties.Static_doc_index_redirect)
682 }
683
684 if String(d.properties.Static_doc_properties) != "" {
685 android.ExtractSourceDeps(ctx, d.properties.Static_doc_properties)
686 }
687
Nan Zhang61819ce2018-05-04 18:49:16 -0700688 if d.checkCurrentApi() {
689 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
690 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
691 }
692
693 if d.checkLastReleasedApi() {
694 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
695 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
696 }
Nan Zhang79614d12018-04-19 18:03:39 -0700697
698 if String(d.properties.Metalava_previous_api) != "" {
699 android.ExtractSourceDeps(ctx, d.properties.Metalava_previous_api)
700 }
Nan Zhang581fd212018-01-10 16:06:12 -0800701}
702
Nan Zhanga40da042018-08-01 12:48:00 -0700703func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths, deps deps) (droiddocBuilderFlags, error) {
704 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800705
Nan Zhanga40da042018-08-01 12:48:00 -0700706 *implicits = append(*implicits, deps.bootClasspath...)
707 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800708
Nan Zhangc94f9d82018-06-26 10:02:26 -0700709 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
710 // since it doesn't support system modules yet.
711 if len(deps.bootClasspath.Strings()) > 0 {
712 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700713 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700714 }
Nan Zhanga40da042018-08-01 12:48:00 -0700715 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700716
Nan Zhang581fd212018-01-10 16:06:12 -0800717 argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
718 argFilesMap := map[string]android.Path{}
719
720 for _, f := range argFiles {
Nan Zhanga40da042018-08-01 12:48:00 -0700721 *implicits = append(*implicits, f)
Nan Zhang581fd212018-01-10 16:06:12 -0800722 if _, exists := argFilesMap[f.Rel()]; !exists {
723 argFilesMap[f.Rel()] = f
724 } else {
725 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
726 f, argFilesMap[f.Rel()], f.Rel())
727 }
728 }
729
Nan Zhanga40da042018-08-01 12:48:00 -0700730 var err error
731 flags.args, err = android.Expand(String(d.properties.Args), func(name string) (string, error) {
Nan Zhang581fd212018-01-10 16:06:12 -0800732 if strings.HasPrefix(name, "location ") {
733 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
734 if f, ok := argFilesMap[label]; ok {
735 return f.String(), nil
736 } else {
737 return "", fmt.Errorf("unknown location label %q", label)
738 }
739 } else if name == "genDir" {
740 return android.PathForModuleGen(ctx).String(), nil
741 }
742 return "", fmt.Errorf("unknown variable '$(%s)'", name)
743 })
744
745 if err != nil {
Nan Zhang79614d12018-04-19 18:03:39 -0700746 ctx.PropertyErrorf("args", "%s", err.Error())
Nan Zhanga40da042018-08-01 12:48:00 -0700747 return droiddocBuilderFlags{}, err
Nan Zhang581fd212018-01-10 16:06:12 -0800748 }
Nan Zhanga40da042018-08-01 12:48:00 -0700749 return flags, nil
750}
Nan Zhang581fd212018-01-10 16:06:12 -0800751
Nan Zhanga40da042018-08-01 12:48:00 -0700752func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
753 javaVersion string, jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800754
Nan Zhanga40da042018-08-01 12:48:00 -0700755 *implicits = append(*implicits, jsilver)
756 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700757
Nan Zhang46130972018-06-04 11:28:01 -0700758 var date string
759 if runtime.GOOS == "darwin" {
760 date = `date -r`
761 } else {
762 date = `date -d`
763 }
764
Nan Zhanga40da042018-08-01 12:48:00 -0700765 args := " -source " + javaVersion + " -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700766 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800767 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700768 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700769
Nan Zhanga40da042018-08-01 12:48:00 -0700770 if String(d.properties.Custom_template) == "" {
771 // TODO: This is almost always droiddoc-templates-sdk
772 ctx.PropertyErrorf("custom_template", "must specify a template")
773 }
774
775 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
776 if t, ok := m.(*DroiddocTemplate); ok {
777 *implicits = append(*implicits, t.deps...)
778 args = args + " -templatedir " + t.dir.String()
779 } else {
780 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
781 }
782 })
783
784 if len(d.properties.Html_dirs) > 0 {
785 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
786 *implicits = append(*implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
787 args = args + " -htmldir " + htmlDir.String()
788 }
789
790 if len(d.properties.Html_dirs) > 1 {
791 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
792 *implicits = append(*implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
793 args = args + " -htmldir2 " + htmlDir2.String()
794 }
795
796 if len(d.properties.Html_dirs) > 2 {
797 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
798 }
799
800 knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
801 *implicits = append(*implicits, knownTags...)
802
803 for _, kt := range knownTags {
804 args = args + " -knowntags " + kt.String()
805 }
806
807 for _, hdf := range d.properties.Hdf {
808 args = args + " -hdf " + hdf
809 }
810
811 if String(d.properties.Proofread_file) != "" {
812 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
813 args = args + " -proofread " + proofreadFile.String()
814 }
815
816 if String(d.properties.Todo_file) != "" {
817 // tricky part:
818 // we should not compute full path for todo_file through PathForModuleOut().
819 // the non-standard doclet will get the full path relative to "-o".
820 args = args + " -todo " + String(d.properties.Todo_file)
821 }
822
823 if String(d.properties.Resourcesdir) != "" {
824 // TODO: should we add files under resourcesDir to the implicits? It seems that
825 // resourcesDir is one sub dir of htmlDir
826 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
827 args = args + " -resourcesdir " + resourcesDir.String()
828 }
829
830 if String(d.properties.Resourcesoutdir) != "" {
831 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
832 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
833 }
834 return args
835}
836
837func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext, implicitOutputs *android.WritablePaths) (string, string) {
838 var doclavaFlags, MetalavaFlags string
839 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Api_filename) != "" {
840 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
841 doclavaFlags += " -api " + d.apiFile.String()
842 MetalavaFlags = MetalavaFlags + " --api " + d.apiFile.String()
843 *implicitOutputs = append(*implicitOutputs, d.apiFile)
844 d.apiFilePath = d.apiFile
845 }
846
847 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Removed_api_filename) != "" {
848 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
849 doclavaFlags += " -removedApi " + d.removedApiFile.String()
850 MetalavaFlags = MetalavaFlags + " --removed-api " + d.removedApiFile.String()
851 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
852 }
853
854 if String(d.properties.Private_api_filename) != "" {
855 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
856 doclavaFlags += " -privateApi " + d.privateApiFile.String()
857 MetalavaFlags = MetalavaFlags + " --private-api " + d.privateApiFile.String()
858 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
859 }
860
861 if String(d.properties.Dex_api_filename) != "" {
862 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
863 doclavaFlags += " -dexApi " + d.dexApiFile.String()
864 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
865 }
866
867 if String(d.properties.Private_dex_api_filename) != "" {
868 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
869 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
870 MetalavaFlags = MetalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
871 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
872 }
873
874 if String(d.properties.Removed_dex_api_filename) != "" {
875 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
876 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
877 MetalavaFlags = MetalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
878 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
879 }
880
881 if String(d.properties.Exact_api_filename) != "" {
882 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
883 doclavaFlags += " -exactApi " + d.exactApiFile.String()
884 MetalavaFlags = MetalavaFlags + " --exact-api " + d.exactApiFile.String()
885 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
886 }
887
888 if String(d.properties.Dex_mapping_filename) != "" {
889 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
890 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
891 // Omitted: metalava support
892 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
893 }
894
895 if BoolDefault(d.properties.Create_stubs, true) {
896 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String()
897 }
898
899 if Bool(d.properties.Write_sdk_values) {
900 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "docs", "out").String()
901 }
902 return doclavaFlags, MetalavaFlags
903}
904
905func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
906 var cmds string
907 if String(d.properties.Static_doc_index_redirect) != "" {
908 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
909 "static_doc_index_redirect")
910 *implicits = append(*implicits, static_doc_index_redirect)
911 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
912 android.PathForModuleOut(ctx, "docs", "out", "index.html").String()
913 }
914
915 if String(d.properties.Static_doc_properties) != "" {
916 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
917 "static_doc_properties")
918 *implicits = append(*implicits, static_doc_properties)
919 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
920 android.PathForModuleOut(ctx, "docs", "out", "source.properties").String()
921 }
922 return cmds
923}
924
925func (d *Droiddoc) collectMetalavaAnnotationsFlags(
926 ctx android.ModuleContext, implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
927 var flags string
928 if String(d.properties.Metalava_previous_api) != "" {
929 previousApi := ctx.ExpandSource(String(d.properties.Metalava_previous_api),
930 "metalava_previous_api")
931 flags += " --previous-api " + previousApi.String()
932 *implicits = append(*implicits, previousApi)
933 }
934
935 if Bool(d.properties.Metalava_annotations_enabled) {
936 if String(d.properties.Metalava_previous_api) == "" {
937 ctx.PropertyErrorf("metalava_previous_api",
938 "has to be non-empty if annotations was enabled!")
939 }
940 flags += " --include-annotations --migrate-nullness"
941
942 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
943 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
944
945 if len(d.properties.Metalava_merge_annotations_dirs) == 0 {
946 ctx.PropertyErrorf("metalava_merge_annotations_dirs",
947 "has to be non-empty if annotations was enabled!")
948 }
949 mergeAnnotationsDirs := android.PathsForSource(ctx, d.properties.Metalava_merge_annotations_dirs)
950
951 flags += " --extract-annotations " + d.annotationsZip.String()
952 for _, mergeAnnotationsDir := range mergeAnnotationsDirs {
953 flags += " --merge-annotations " + mergeAnnotationsDir.String()
954 }
955 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
956 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction "
957 }
958
959 return flags
960}
961
962func (d *Droiddoc) collectMetalavaDocsFlags(ctx android.ModuleContext,
963 bootClasspathArgs, classpathArgs string) string {
964 return " --doc-stubs " + android.PathForModuleOut(ctx, "docs", "docStubsDir").String() +
965 " --write-doc-stubs-source-list $outDir/doc_stubs_src_list " +
966 " --generate-documentation ${config.JavadocCmd} -encoding UTF-8 DOC_STUBS_SOURCE_LIST " +
967 bootClasspathArgs + " " + classpathArgs + " " + " -sourcepath " +
968 android.PathForModuleOut(ctx, "docs", "docStubsDir").String() + " -quiet -d $outDir "
969}
970
971func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
972 deps := d.Javadoc.collectDeps(ctx)
973
974 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
975 // Doclava has problem with "-source 1.9", so override javaVersion when Doclava
976 // is running with EXPERIMENTAL_USE_OPENJDK9=true. And eventually Doclava will be
977 // replaced by Metalava.
Nan Zhang79614d12018-04-19 18:03:39 -0700978 if !Bool(d.properties.Metalava_enabled) {
Nan Zhanga40da042018-08-01 12:48:00 -0700979 javaVersion = "1.8"
980 }
Nan Zhang581fd212018-01-10 16:06:12 -0800981
Nan Zhanga40da042018-08-01 12:48:00 -0700982 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
983 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
984 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
985 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
Nan Zhang581fd212018-01-10 16:06:12 -0800986
Nan Zhanga40da042018-08-01 12:48:00 -0700987 var implicits android.Paths
988 implicits = append(implicits, d.Javadoc.srcJars...)
989
990 var implicitOutputs android.WritablePaths
991 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
992 for _, o := range d.properties.Out {
993 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
994 }
995
996 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
997 if err != nil {
998 return
999 }
1000
1001 flags.doclavaStubsFlags, flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1002 if Bool(d.properties.Metalava_enabled) {
1003 opts := flags.metalavaStubsFlags
1004 flags.metalavaAnnotationsFlags = d.collectMetalavaAnnotationsFlags(ctx, &implicits, &implicitOutputs)
1005 opts += flags.metalavaAnnotationsFlags
1006 if strings.Contains(flags.args, "--generate-documentation") {
1007 // TODO(nanzhang): Add a Soong property to handle documentation args.
1008 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, javaVersion, jsilver, doclava)
1009 flags.metalavaDocsFlags = d.collectMetalavaDocsFlags(ctx, flags.bootClasspathArgs, flags.classpathArgs)
1010 opts += " " + strings.Split(flags.args, "--generate-documentation")[0] + " " +
1011 flags.metalavaDocsFlags + flags.doclavaDocsFlags +
1012 " " + strings.Split(flags.args, "--generate-documentation")[1]
1013 } else {
1014 opts += " " + flags.args
Nan Zhang79614d12018-04-19 18:03:39 -07001015 }
Nan Zhanga40da042018-08-01 12:48:00 -07001016 ctx.Build(pctx, android.BuildParams{
1017 Rule: metalava,
1018 Description: "Metalava",
1019 Output: d.Javadoc.stubsSrcJar,
1020 Inputs: d.Javadoc.srcFiles,
1021 Implicits: implicits,
1022 ImplicitOutputs: implicitOutputs,
1023 Args: map[string]string{
1024 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
1025 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
1026 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
1027 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1028 "javaVersion": javaVersion,
1029 "bootclasspathArgs": flags.bootClasspathArgs,
1030 "classpathArgs": flags.classpathArgs,
1031 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
1032 "docZip": d.Javadoc.docZip.String(),
1033 "opts": opts,
1034 },
1035 })
1036 } else {
1037 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, javaVersion, jsilver, doclava)
1038 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
Nan Zhang79614d12018-04-19 18:03:39 -07001039 ctx.Build(pctx, android.BuildParams{
1040 Rule: javadoc,
1041 Description: "Droiddoc",
1042 Output: d.Javadoc.stubsSrcJar,
1043 Inputs: d.Javadoc.srcFiles,
1044 Implicits: implicits,
1045 ImplicitOutputs: implicitOutputs,
1046 Args: map[string]string{
1047 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
1048 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
1049 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
1050 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhanga40da042018-08-01 12:48:00 -07001051 "opts": flags.doclavaDocsFlags + flags.doclavaStubsFlags + " " + flags.args,
1052 "bootclasspathArgs": flags.bootClasspathArgs,
1053 "classpathArgs": flags.classpathArgs,
Nan Zhang79614d12018-04-19 18:03:39 -07001054 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
1055 "docZip": d.Javadoc.docZip.String(),
Nan Zhanga40da042018-08-01 12:48:00 -07001056 "postDoclavaCmds": flags.postDoclavaCmds,
Nan Zhang79614d12018-04-19 18:03:39 -07001057 },
1058 })
Nan Zhang79614d12018-04-19 18:03:39 -07001059 }
Nan Zhang61819ce2018-05-04 18:49:16 -07001060
Nan Zhang61819ce2018-05-04 18:49:16 -07001061 if d.checkCurrentApi() && !ctx.Config().IsPdkBuild() {
1062 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1063
1064 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1065 "check_api.current.api_file")
1066 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1067 "check_api.current_removed_api_file")
1068
1069 ctx.Build(pctx, android.BuildParams{
1070 Rule: apiCheck,
1071 Description: "Current API check",
1072 Output: d.checkCurrentApiTimestamp,
1073 Inputs: nil,
1074 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1075 checkApiClasspath...),
1076 Args: map[string]string{
1077 "classpath": checkApiClasspath.FormJavaClassPath(""),
1078 "opts": String(d.properties.Check_api.Current.Args),
1079 "apiFile": apiFile.String(),
1080 "apiFileToCheck": d.apiFile.String(),
1081 "removedApiFile": removedApiFile.String(),
1082 "removedApiFileToCheck": d.removedApiFile.String(),
1083 "msg": fmt.Sprintf(`\n******************************\n`+
1084 `You have tried to change the API from what has been previously approved.\n\n`+
1085 `To make these errors go away, you have two choices:\n`+
1086 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1087 ` errors above.\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +09001088 ` 2. You can update current.txt by executing the following command:\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -07001089 ` make %s-update-current-api\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +09001090 ` To submit the revised current.txt to the main Android repository,\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -07001091 ` you will need approval.\n`+
1092 `******************************\n`, ctx.ModuleName()),
1093 },
1094 })
1095
1096 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang61819ce2018-05-04 18:49:16 -07001097 ctx.Build(pctx, android.BuildParams{
1098 Rule: updateApi,
1099 Description: "update current API",
1100 Output: d.updateCurrentApiTimestamp,
1101 Implicits: append(android.Paths{}, apiFile, removedApiFile, d.apiFile, d.removedApiFile),
1102 Args: map[string]string{
1103 "apiFile": apiFile.String(),
1104 "apiFileToCheck": d.apiFile.String(),
1105 "removedApiFile": removedApiFile.String(),
1106 "removedApiFileToCheck": d.removedApiFile.String(),
1107 },
1108 })
1109 }
Nan Zhanga40da042018-08-01 12:48:00 -07001110
Nan Zhang61819ce2018-05-04 18:49:16 -07001111 if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
1112 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1113
1114 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1115 "check_api.last_released.api_file")
1116 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1117 "check_api.last_released.removed_api_file")
1118
1119 ctx.Build(pctx, android.BuildParams{
1120 Rule: apiCheck,
1121 Description: "Last Released API check",
1122 Output: d.checkLastReleasedApiTimestamp,
1123 Inputs: nil,
1124 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1125 checkApiClasspath...),
1126 Args: map[string]string{
1127 "classpath": checkApiClasspath.FormJavaClassPath(""),
1128 "opts": String(d.properties.Check_api.Last_released.Args),
1129 "apiFile": apiFile.String(),
1130 "apiFileToCheck": d.apiFile.String(),
1131 "removedApiFile": removedApiFile.String(),
1132 "removedApiFileToCheck": d.removedApiFile.String(),
1133 "msg": `\n******************************\n` +
1134 `You have tried to change the API from what has been previously released in\n` +
1135 `an SDK. Please fix the errors listed above.\n` +
1136 `******************************\n`,
1137 },
1138 })
1139 }
Nan Zhang581fd212018-01-10 16:06:12 -08001140}
Dan Willemsencc090972018-02-26 14:33:31 -08001141
Nan Zhanga40da042018-08-01 12:48:00 -07001142//
1143// Droiddoc Template
1144//
Dan Willemsencc090972018-02-26 14:33:31 -08001145var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
1146
1147type DroiddocTemplateProperties struct {
1148 // path to the directory containing the droiddoc templates.
1149 Path *string
1150}
1151
1152type DroiddocTemplate struct {
1153 android.ModuleBase
1154
1155 properties DroiddocTemplateProperties
1156
1157 deps android.Paths
1158 dir android.Path
1159}
1160
1161func DroiddocTemplateFactory() android.Module {
1162 module := &DroiddocTemplate{}
1163 module.AddProperties(&module.properties)
1164 android.InitAndroidModule(module)
1165 return module
1166}
1167
1168func (d *DroiddocTemplate) DepsMutator(android.BottomUpMutatorContext) {}
1169
1170func (d *DroiddocTemplate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1171 path := android.PathForModuleSrc(ctx, String(d.properties.Path))
1172 d.dir = path
1173 d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
1174}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001175
1176//
1177// Defaults
1178//
1179type DocDefaults struct {
1180 android.ModuleBase
1181 android.DefaultsModuleBase
1182}
1183
1184func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1185}
1186
1187func (d *DocDefaults) DepsMutator(ctx android.BottomUpMutatorContext) {
1188}
1189
1190func DocDefaultsFactory() android.Module {
1191 module := &DocDefaults{}
1192
1193 module.AddProperties(
1194 &JavadocProperties{},
1195 &DroiddocProperties{},
1196 )
1197
1198 android.InitDefaultsModule(module)
1199
1200 return module
1201}