blob: 577897d91cd23d3f9f1b90a4ccb8c799fbff8975 [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{
Nan Zhangde860a42018-08-08 16:32:21 -070070 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" "$docStubsDir" && ` +
71 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" "$docStubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070072 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang357466b2018-04-17 17:38:36 -070073 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Nan Zhang16c0a312018-06-13 17:42:48 -070074 `$bootclasspathArgs $classpathArgs -sourcepath $sourcepath --no-banner --color --quiet ` +
75 `--stubs $stubsDir $opts && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070076 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
77 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
78 CommandDeps: []string{
79 "${config.ZipSyncCmd}",
80 "${config.JavaCmd}",
81 "${config.MetalavaJar}",
82 "${config.JavadocCmd}",
83 "${config.SoongZipCmd}",
84 },
85 Rspfile: "$out.rsp",
86 RspfileContent: "$in",
87 Restat: true,
88 },
Nan Zhangde860a42018-08-08 16:32:21 -070089 "outDir", "srcJarDir", "stubsDir", "docStubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
Nan Zhang357466b2018-04-17 17:38:36 -070090 "classpathArgs", "sourcepath", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -080091)
92
93func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080094 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
95
Nan Zhang581fd212018-01-10 16:06:12 -080096 android.RegisterModuleType("droiddoc", DroiddocFactory)
97 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -070098 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080099 android.RegisterModuleType("javadoc", JavadocFactory)
100 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
101}
102
Colin Crossa1ce2a02018-06-20 15:19:39 -0700103var (
104 srcsLibTag = dependencyTag{name: "sources from javalib"}
105)
106
Nan Zhang581fd212018-01-10 16:06:12 -0800107type JavadocProperties struct {
108 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
109 // or .aidl files.
110 Srcs []string `android:"arch_variant"`
111
112 // list of directories rooted at the Android.bp file that will
113 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800114 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800115
116 // list of source files that should not be used to build the Java module.
117 // This is most useful in the arch/multilib variants to remove non-common files
118 // filegroup or genrule can be included within this property.
119 Exclude_srcs []string `android:"arch_variant"`
120
Nan Zhangb2b33de2018-02-23 11:18:47 -0800121 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800122 Libs []string `android:"arch_variant"`
123
Nan Zhange66c7272018-03-06 12:59:27 -0800124 // don't build against the framework libraries (legacy-test, core-junit,
125 // ext, and framework for device targets)
126 No_framework_libs *bool
127
Nan Zhangb2b33de2018-02-23 11:18:47 -0800128 // the java library (in classpath) for documentation that provides java srcs and srcjars.
129 Srcs_lib *string
130
131 // the base dirs under srcs_lib will be scanned for java srcs.
132 Srcs_lib_whitelist_dirs []string
133
134 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
135 Srcs_lib_whitelist_pkgs []string
136
Nan Zhang581fd212018-01-10 16:06:12 -0800137 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800139
140 // if not blank, set to the version of the sdk to compile against
141 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900142
143 Aidl struct {
144 // Top level directories to pass to aidl tool
145 Include_dirs []string
146
147 // Directories rooted at the Android.bp file to pass to aidl tool
148 Local_include_dirs []string
149 }
Nan Zhang357466b2018-04-17 17:38:36 -0700150
151 // If not blank, set the java version passed to javadoc as -source
152 Java_version *string
Nan Zhang581fd212018-01-10 16:06:12 -0800153}
154
Nan Zhang61819ce2018-05-04 18:49:16 -0700155type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900156 // path to the API txt file that the new API extracted from source code is checked
157 // against. The path can be local to the module or from other module (via :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700158 Api_file *string
159
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900160 // path to the API txt file that the new @removed API extractd from source code is
161 // checked against. The path can be local to the module or from other module (via
162 // :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700163 Removed_api_file *string
164
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900165 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700166 Args *string
167}
168
Nan Zhang581fd212018-01-10 16:06:12 -0800169type DroiddocProperties struct {
170 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800171 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800172
Nan Zhanga40da042018-08-01 12:48:00 -0700173 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800174 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800175
176 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800177 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800178
179 // proofread file contains all of the text content of the javadocs concatenated into one file,
180 // suitable for spell-checking and other goodness.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800181 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800182
183 // a todo file lists the program elements that are missing documentation.
184 // At some point, this might be improved to show more warnings.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800185 Todo_file *string
186
187 // directory under current module source that provide additional resources (images).
188 Resourcesdir *string
189
190 // resources output directory under out/soong/.intermediates.
191 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800192
193 // local files that are used within user customized droiddoc options.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800194 Arg_files []string
Nan Zhang581fd212018-01-10 16:06:12 -0800195
196 // user customized droiddoc args.
197 // Available variables for substitution:
198 //
199 // $(location <label>): the path to the arg_files with name <label>
Nan Zhangb2b33de2018-02-23 11:18:47 -0800200 Args *string
Nan Zhang581fd212018-01-10 16:06:12 -0800201
202 // names of the output files used in args that will be generated
Nan Zhangb2b33de2018-02-23 11:18:47 -0800203 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800204
Nan Zhange2ba5d42018-07-11 15:16:55 -0700205 // if set to true, collect the values used by the Dev tools and
206 // write them in files packaged with the SDK. Defaults to false.
207 Write_sdk_values *bool
208
209 // index.html under current module will be copied to docs out dir, if not null.
210 Static_doc_index_redirect *string
211
212 // source.properties under current module will be copied to docs out dir, if not null.
213 Static_doc_properties *string
214
Nan Zhang581fd212018-01-10 16:06:12 -0800215 // a list of files under current module source dir which contains known tags in Java sources.
216 // filegroup or genrule can be included within this property.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800217 Knowntags []string
Nan Zhang28c68b92018-03-13 16:17:01 -0700218
219 // the tag name used to distinguish if the API files belong to public/system/test.
220 Api_tag_name *string
221
222 // the generated public API filename by Doclava.
223 Api_filename *string
224
David Brazdilfbe4cc32018-05-31 13:56:46 +0100225 // the generated public Dex API filename by Doclava.
226 Dex_api_filename *string
227
Nan Zhang28c68b92018-03-13 16:17:01 -0700228 // the generated private API filename by Doclava.
229 Private_api_filename *string
230
231 // the generated private Dex API filename by Doclava.
232 Private_dex_api_filename *string
233
234 // the generated removed API filename by Doclava.
235 Removed_api_filename *string
236
David Brazdilaac0c3c2018-04-24 16:23:29 +0100237 // the generated removed Dex API filename by Doclava.
238 Removed_dex_api_filename *string
239
Mathew Inwood76c3de12018-06-22 15:28:11 +0100240 // mapping of dex signatures to source file and line number. This is a temporary property and
241 // will be deleted; you probably shouldn't be using it.
242 Dex_mapping_filename *string
243
Nan Zhang28c68b92018-03-13 16:17:01 -0700244 // the generated exact API filename by Doclava.
245 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700246
247 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
248 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700249
250 Check_api struct {
251 Last_released ApiToCheck
252
253 Current ApiToCheck
254 }
Nan Zhang79614d12018-04-19 18:03:39 -0700255
256 // if set to true, create stubs through Metalava instead of Doclava. Javadoc/Doclava is
257 // currently still used for documentation generation, and will be replaced by Dokka soon.
258 Metalava_enabled *bool
259
260 // user can specify the version of previous released API file in order to do compatibility check.
261 Metalava_previous_api *string
262
263 // is set to true, Metalava will allow framework SDK to contain annotations.
264 Metalava_annotations_enabled *bool
265
Pete Gillinb13a0152018-07-19 17:56:49 +0100266 // a list of top-level directories containing files to merge annotations from.
267 Metalava_merge_annotations_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800268}
269
Nan Zhanga40da042018-08-01 12:48:00 -0700270//
271// Common flags passed down to build rule
272//
273type droiddocBuilderFlags struct {
274 args string
275 bootClasspathArgs string
276 classpathArgs string
277 aidlFlags string
278
279 doclavaDocsFlags string
280 doclavaStubsFlags string
281 postDoclavaCmds string
282
283 metalavaAnnotationsFlags string
284 metalavaDocsFlags string
285 metalavaStubsFlags string
286
287 dokkaFlags string
288}
289
290func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
291 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
292 android.InitDefaultableModule(module)
293}
294
295//
296// Javadoc
297//
Nan Zhang581fd212018-01-10 16:06:12 -0800298type Javadoc struct {
299 android.ModuleBase
300 android.DefaultableModuleBase
301
302 properties JavadocProperties
303
304 srcJars android.Paths
305 srcFiles android.Paths
306 sourcepaths android.Paths
307
Nan Zhangccff0f72018-03-08 17:26:16 -0800308 docZip android.WritablePath
309 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800310}
311
Nan Zhangb2b33de2018-02-23 11:18:47 -0800312func (j *Javadoc) Srcs() android.Paths {
313 return android.Paths{j.stubsSrcJar}
314}
315
Nan Zhang581fd212018-01-10 16:06:12 -0800316func JavadocFactory() android.Module {
317 module := &Javadoc{}
318
319 module.AddProperties(&module.properties)
320
321 InitDroiddocModule(module, android.HostAndDeviceSupported)
322 return module
323}
324
325func JavadocHostFactory() android.Module {
326 module := &Javadoc{}
327
328 module.AddProperties(&module.properties)
329
330 InitDroiddocModule(module, android.HostSupported)
331 return module
332}
333
Nan Zhanga40da042018-08-01 12:48:00 -0700334var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800335
Colin Cross83bb3162018-06-25 15:48:06 -0700336func (j *Javadoc) sdkVersion() string {
337 return String(j.properties.Sdk_version)
338}
339
340func (j *Javadoc) minSdkVersion() string {
341 return j.sdkVersion()
342}
343
Nan Zhang581fd212018-01-10 16:06:12 -0800344func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
345 if ctx.Device() {
Colin Cross83bb3162018-06-25 15:48:06 -0700346 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800347 if sdkDep.useDefaultLibs {
348 ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
Nan Zhang357466b2018-04-17 17:38:36 -0700349 if ctx.Config().TargetOpenJDK9() {
350 ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
351 }
Nan Zhang9cbe6772018-03-21 17:56:39 -0700352 if !Bool(j.properties.No_framework_libs) {
Nan Zhang77a69ec2018-08-02 16:28:26 -0700353 ctx.AddDependency(ctx.Module(), libTag, config.DefaultLibraries...)
Nan Zhange66c7272018-03-06 12:59:27 -0800354 }
Nan Zhang581fd212018-01-10 16:06:12 -0800355 } else if sdkDep.useModule {
Nan Zhang357466b2018-04-17 17:38:36 -0700356 if ctx.Config().TargetOpenJDK9() {
357 ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
358 }
Colin Cross86a60ae2018-05-29 14:44:55 -0700359 ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.modules...)
Nan Zhang581fd212018-01-10 16:06:12 -0800360 }
361 }
362
363 ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700364 if j.properties.Srcs_lib != nil {
365 ctx.AddDependency(ctx.Module(), srcsLibTag, *j.properties.Srcs_lib)
366 }
Nan Zhang581fd212018-01-10 16:06:12 -0800367
368 android.ExtractSourcesDeps(ctx, j.properties.Srcs)
369
370 // exclude_srcs may contain filegroup or genrule.
371 android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
372}
373
Nan Zhangb2b33de2018-02-23 11:18:47 -0800374func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
375 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
376 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900377 // convert foo.bar.baz to foo/bar/baz
378 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
379 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800380 if _, found := whitelistPathPrefixes[prefix]; !found {
381 whitelistPathPrefixes[prefix] = true
382 }
383 }
384 }
385}
386
Nan Zhanga40da042018-08-01 12:48:00 -0700387func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
388 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900389
390 // aidl flags.
391 aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
392 if len(aidlFlags) > 0 {
393 // optimization.
394 ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
395 flags.aidlFlags = "$aidlFlags"
396 }
397
398 return flags
399}
400
401func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
402 aidlIncludeDirs android.Paths) []string {
403
404 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
405 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
406
407 var flags []string
408 if aidlPreprocess.Valid() {
409 flags = append(flags, "-p"+aidlPreprocess.String())
410 } else {
411 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
412 }
413
414 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
415 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
416 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
417 flags = append(flags, "-I"+src.String())
418 }
419
420 return flags
421}
422
423func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700424 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900425
426 outSrcFiles := make(android.Paths, 0, len(srcFiles))
427
428 for _, srcFile := range srcFiles {
429 switch srcFile.Ext() {
430 case ".aidl":
431 javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
432 outSrcFiles = append(outSrcFiles, javaFile)
433 default:
434 outSrcFiles = append(outSrcFiles, srcFile)
435 }
436 }
437
438 return outSrcFiles
439}
440
Nan Zhang581fd212018-01-10 16:06:12 -0800441func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
442 var deps deps
443
Colin Cross83bb3162018-06-25 15:48:06 -0700444 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800445 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700446 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800447 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700448 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800449 }
450
451 ctx.VisitDirectDeps(func(module android.Module) {
452 otherName := ctx.OtherModuleName(module)
453 tag := ctx.OtherModuleDependencyTag(module)
454
Colin Cross2d24c1b2018-05-23 10:59:18 -0700455 switch tag {
456 case bootClasspathTag:
457 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800458 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700459 } else {
460 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
461 }
462 case libTag:
463 switch dep := module.(type) {
464 case Dependency:
Nan Zhang581fd212018-01-10 16:06:12 -0800465 deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700466 case SdkLibraryDependency:
Colin Cross83bb3162018-06-25 15:48:06 -0700467 sdkVersion := j.sdkVersion()
Jiyong Parkc678ad32018-04-10 13:07:10 +0900468 linkType := javaSdk
469 if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
470 linkType = javaSystem
471 } else if sdkVersion == "" {
472 linkType = javaPlatform
473 }
Sundong Ahn241cd372018-07-13 16:16:44 +0900474 deps.classpath = append(deps.classpath, dep.ImplementationJars(linkType)...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700475 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800476 checkProducesJars(ctx, dep)
477 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800478 default:
479 ctx.ModuleErrorf("depends on non-java module %q", otherName)
480 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700481 case srcsLibTag:
482 switch dep := module.(type) {
483 case Dependency:
484 srcs := dep.(SrcDependency).CompiledSrcs()
485 whitelistPathPrefixes := make(map[string]bool)
486 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
487 for _, src := range srcs {
488 if _, ok := src.(android.WritablePath); ok { // generated sources
489 deps.srcs = append(deps.srcs, src)
490 } else { // select source path for documentation based on whitelist path prefixs.
491 for k, _ := range whitelistPathPrefixes {
492 if strings.HasPrefix(src.Rel(), k) {
493 deps.srcs = append(deps.srcs, src)
494 break
495 }
496 }
497 }
498 }
499 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
500 default:
501 ctx.ModuleErrorf("depends on non-java module %q", otherName)
502 }
Nan Zhang357466b2018-04-17 17:38:36 -0700503 case systemModulesTag:
504 if deps.systemModules != nil {
505 panic("Found two system module dependencies")
506 }
507 sm := module.(*SystemModules)
508 if sm.outputFile == nil {
509 panic("Missing directory for system module dependency")
510 }
511 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800512 }
513 })
514 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
515 // may contain filegroup or genrule.
516 srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700517 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900518 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800519
520 // srcs may depend on some genrule output.
521 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800522 j.srcJars = append(j.srcJars, deps.srcJars...)
523
Nan Zhang581fd212018-01-10 16:06:12 -0800524 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800525 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800526
527 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800528 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800529
530 if j.properties.Local_sourcepaths == nil {
531 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
532 }
533 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800534
535 return deps
536}
537
538func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
539 j.addDeps(ctx)
540}
541
542func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
543 deps := j.collectDeps(ctx)
544
545 var implicits android.Paths
546 implicits = append(implicits, deps.bootClasspath...)
547 implicits = append(implicits, deps.classpath...)
548
549 var bootClasspathArgs, classpathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700550
Colin Cross83bb3162018-06-25 15:48:06 -0700551 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700552 if len(deps.bootClasspath) > 0 {
553 var systemModules classpath
554 if deps.systemModules != nil {
555 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800556 }
Colin Cross997262f2018-06-19 22:49:39 -0700557 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
558 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800559 }
560 if len(deps.classpath.Strings()) > 0 {
561 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
562 }
563
564 implicits = append(implicits, j.srcJars...)
565
Nan Zhangaf322cc2018-06-19 15:15:38 -0700566 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800567
568 ctx.Build(pctx, android.BuildParams{
569 Rule: javadoc,
570 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800571 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800572 ImplicitOutput: j.docZip,
573 Inputs: j.srcFiles,
574 Implicits: implicits,
575 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700576 "outDir": android.PathForModuleOut(ctx, "out").String(),
577 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
578 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800579 "srcJars": strings.Join(j.srcJars.Strings(), " "),
580 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700581 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800582 "classpathArgs": classpathArgs,
583 "sourcepath": strings.Join(j.sourcepaths.Strings(), ":"),
584 "docZip": j.docZip.String(),
585 },
586 })
587}
588
Nan Zhanga40da042018-08-01 12:48:00 -0700589//
590// Droiddoc
591//
592type Droiddoc struct {
593 Javadoc
594
595 properties DroiddocProperties
596 apiFile android.WritablePath
597 dexApiFile android.WritablePath
598 privateApiFile android.WritablePath
599 privateDexApiFile android.WritablePath
600 removedApiFile android.WritablePath
601 removedDexApiFile android.WritablePath
602 exactApiFile android.WritablePath
603 apiMappingFile android.WritablePath
604
605 checkCurrentApiTimestamp android.WritablePath
606 updateCurrentApiTimestamp android.WritablePath
607 checkLastReleasedApiTimestamp android.WritablePath
608
609 annotationsZip android.WritablePath
610
611 apiFilePath android.Path
612}
613
614type ApiFilePath interface {
615 ApiFilePath() android.Path
616}
617
618func DroiddocFactory() android.Module {
619 module := &Droiddoc{}
620
621 module.AddProperties(&module.properties,
622 &module.Javadoc.properties)
623
624 InitDroiddocModule(module, android.HostAndDeviceSupported)
625 return module
626}
627
628func DroiddocHostFactory() android.Module {
629 module := &Droiddoc{}
630
631 module.AddProperties(&module.properties,
632 &module.Javadoc.properties)
633
634 InitDroiddocModule(module, android.HostSupported)
635 return module
636}
637
638func (d *Droiddoc) ApiFilePath() android.Path {
639 return d.apiFilePath
640}
641
Nan Zhang61819ce2018-05-04 18:49:16 -0700642func (d *Droiddoc) checkCurrentApi() bool {
643 if String(d.properties.Check_api.Current.Api_file) != "" &&
644 String(d.properties.Check_api.Current.Removed_api_file) != "" {
645 return true
646 } else if String(d.properties.Check_api.Current.Api_file) != "" {
647 panic("check_api.current.removed_api_file: has to be non empty!")
648 } else if String(d.properties.Check_api.Current.Removed_api_file) != "" {
649 panic("check_api.current.api_file: has to be non empty!")
650 }
651
652 return false
653}
654
655func (d *Droiddoc) checkLastReleasedApi() bool {
656 if String(d.properties.Check_api.Last_released.Api_file) != "" &&
657 String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
658 return true
659 } else if String(d.properties.Check_api.Last_released.Api_file) != "" {
660 panic("check_api.last_released.removed_api_file: has to be non empty!")
661 } else if String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
662 panic("check_api.last_released.api_file: has to be non empty!")
663 }
664
665 return false
666}
667
Nan Zhang581fd212018-01-10 16:06:12 -0800668func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
669 d.Javadoc.addDeps(ctx)
670
Nan Zhang79614d12018-04-19 18:03:39 -0700671 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800672 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
673 }
674
Nan Zhanga40da042018-08-01 12:48:00 -0700675 // arg_files may contains filegroup or genrule.
Nan Zhang581fd212018-01-10 16:06:12 -0800676 android.ExtractSourcesDeps(ctx, d.properties.Arg_files)
677
678 // knowntags may contain filegroup or genrule.
679 android.ExtractSourcesDeps(ctx, d.properties.Knowntags)
Nan Zhang61819ce2018-05-04 18:49:16 -0700680
Nan Zhange2ba5d42018-07-11 15:16:55 -0700681 if String(d.properties.Static_doc_index_redirect) != "" {
682 android.ExtractSourceDeps(ctx, d.properties.Static_doc_index_redirect)
683 }
684
685 if String(d.properties.Static_doc_properties) != "" {
686 android.ExtractSourceDeps(ctx, d.properties.Static_doc_properties)
687 }
688
Nan Zhang61819ce2018-05-04 18:49:16 -0700689 if d.checkCurrentApi() {
690 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
691 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
692 }
693
694 if d.checkLastReleasedApi() {
695 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
696 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
697 }
Nan Zhang79614d12018-04-19 18:03:39 -0700698
699 if String(d.properties.Metalava_previous_api) != "" {
700 android.ExtractSourceDeps(ctx, d.properties.Metalava_previous_api)
701 }
Nan Zhangf4936b02018-08-01 15:00:28 -0700702
703 if len(d.properties.Metalava_merge_annotations_dirs) != 0 {
704 for _, mergeAnnotationsDir := range d.properties.Metalava_merge_annotations_dirs {
705 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
706 }
707 }
Nan Zhang581fd212018-01-10 16:06:12 -0800708}
709
Nan Zhanga40da042018-08-01 12:48:00 -0700710func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths, deps deps) (droiddocBuilderFlags, error) {
711 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800712
Nan Zhanga40da042018-08-01 12:48:00 -0700713 *implicits = append(*implicits, deps.bootClasspath...)
714 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800715
Nan Zhangc94f9d82018-06-26 10:02:26 -0700716 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
717 // since it doesn't support system modules yet.
718 if len(deps.bootClasspath.Strings()) > 0 {
719 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700720 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700721 }
Nan Zhanga40da042018-08-01 12:48:00 -0700722 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700723
Nan Zhang581fd212018-01-10 16:06:12 -0800724 argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
725 argFilesMap := map[string]android.Path{}
726
727 for _, f := range argFiles {
Nan Zhanga40da042018-08-01 12:48:00 -0700728 *implicits = append(*implicits, f)
Nan Zhang581fd212018-01-10 16:06:12 -0800729 if _, exists := argFilesMap[f.Rel()]; !exists {
730 argFilesMap[f.Rel()] = f
731 } else {
732 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
733 f, argFilesMap[f.Rel()], f.Rel())
734 }
735 }
736
Nan Zhanga40da042018-08-01 12:48:00 -0700737 var err error
738 flags.args, err = android.Expand(String(d.properties.Args), func(name string) (string, error) {
Nan Zhang581fd212018-01-10 16:06:12 -0800739 if strings.HasPrefix(name, "location ") {
740 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
741 if f, ok := argFilesMap[label]; ok {
742 return f.String(), nil
743 } else {
744 return "", fmt.Errorf("unknown location label %q", label)
745 }
746 } else if name == "genDir" {
747 return android.PathForModuleGen(ctx).String(), nil
748 }
749 return "", fmt.Errorf("unknown variable '$(%s)'", name)
750 })
751
752 if err != nil {
Nan Zhang79614d12018-04-19 18:03:39 -0700753 ctx.PropertyErrorf("args", "%s", err.Error())
Nan Zhanga40da042018-08-01 12:48:00 -0700754 return droiddocBuilderFlags{}, err
Nan Zhang581fd212018-01-10 16:06:12 -0800755 }
Nan Zhanga40da042018-08-01 12:48:00 -0700756 return flags, nil
757}
Nan Zhang581fd212018-01-10 16:06:12 -0800758
Nan Zhanga40da042018-08-01 12:48:00 -0700759func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
760 javaVersion string, jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800761
Nan Zhanga40da042018-08-01 12:48:00 -0700762 *implicits = append(*implicits, jsilver)
763 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700764
Nan Zhang46130972018-06-04 11:28:01 -0700765 var date string
766 if runtime.GOOS == "darwin" {
767 date = `date -r`
768 } else {
769 date = `date -d`
770 }
771
Nan Zhanga40da042018-08-01 12:48:00 -0700772 args := " -source " + javaVersion + " -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700773 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800774 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700775 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700776
Nan Zhanga40da042018-08-01 12:48:00 -0700777 if String(d.properties.Custom_template) == "" {
778 // TODO: This is almost always droiddoc-templates-sdk
779 ctx.PropertyErrorf("custom_template", "must specify a template")
780 }
781
782 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700783 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700784 *implicits = append(*implicits, t.deps...)
785 args = args + " -templatedir " + t.dir.String()
786 } else {
787 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
788 }
789 })
790
791 if len(d.properties.Html_dirs) > 0 {
792 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
793 *implicits = append(*implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
794 args = args + " -htmldir " + htmlDir.String()
795 }
796
797 if len(d.properties.Html_dirs) > 1 {
798 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
799 *implicits = append(*implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
800 args = args + " -htmldir2 " + htmlDir2.String()
801 }
802
803 if len(d.properties.Html_dirs) > 2 {
804 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
805 }
806
807 knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
808 *implicits = append(*implicits, knownTags...)
809
810 for _, kt := range knownTags {
811 args = args + " -knowntags " + kt.String()
812 }
813
814 for _, hdf := range d.properties.Hdf {
815 args = args + " -hdf " + hdf
816 }
817
818 if String(d.properties.Proofread_file) != "" {
819 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
820 args = args + " -proofread " + proofreadFile.String()
821 }
822
823 if String(d.properties.Todo_file) != "" {
824 // tricky part:
825 // we should not compute full path for todo_file through PathForModuleOut().
826 // the non-standard doclet will get the full path relative to "-o".
827 args = args + " -todo " + String(d.properties.Todo_file)
828 }
829
830 if String(d.properties.Resourcesdir) != "" {
831 // TODO: should we add files under resourcesDir to the implicits? It seems that
832 // resourcesDir is one sub dir of htmlDir
833 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
834 args = args + " -resourcesdir " + resourcesDir.String()
835 }
836
837 if String(d.properties.Resourcesoutdir) != "" {
838 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
839 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
840 }
841 return args
842}
843
844func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext, implicitOutputs *android.WritablePaths) (string, string) {
845 var doclavaFlags, MetalavaFlags string
846 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Api_filename) != "" {
847 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
848 doclavaFlags += " -api " + d.apiFile.String()
849 MetalavaFlags = MetalavaFlags + " --api " + d.apiFile.String()
850 *implicitOutputs = append(*implicitOutputs, d.apiFile)
851 d.apiFilePath = d.apiFile
852 }
853
854 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Removed_api_filename) != "" {
855 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
856 doclavaFlags += " -removedApi " + d.removedApiFile.String()
857 MetalavaFlags = MetalavaFlags + " --removed-api " + d.removedApiFile.String()
858 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
859 }
860
861 if String(d.properties.Private_api_filename) != "" {
862 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
863 doclavaFlags += " -privateApi " + d.privateApiFile.String()
864 MetalavaFlags = MetalavaFlags + " --private-api " + d.privateApiFile.String()
865 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
866 }
867
868 if String(d.properties.Dex_api_filename) != "" {
869 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
870 doclavaFlags += " -dexApi " + d.dexApiFile.String()
871 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
872 }
873
874 if String(d.properties.Private_dex_api_filename) != "" {
875 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
876 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
877 MetalavaFlags = MetalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
878 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
879 }
880
881 if String(d.properties.Removed_dex_api_filename) != "" {
882 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
883 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
884 MetalavaFlags = MetalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
885 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
886 }
887
888 if String(d.properties.Exact_api_filename) != "" {
889 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
890 doclavaFlags += " -exactApi " + d.exactApiFile.String()
891 MetalavaFlags = MetalavaFlags + " --exact-api " + d.exactApiFile.String()
892 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
893 }
894
895 if String(d.properties.Dex_mapping_filename) != "" {
896 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
897 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
898 // Omitted: metalava support
899 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
900 }
901
902 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -0700903 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -0700904 }
905
906 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -0700907 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -0700908 }
909 return doclavaFlags, MetalavaFlags
910}
911
912func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
913 var cmds string
914 if String(d.properties.Static_doc_index_redirect) != "" {
915 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
916 "static_doc_index_redirect")
917 *implicits = append(*implicits, static_doc_index_redirect)
918 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -0700919 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -0700920 }
921
922 if String(d.properties.Static_doc_properties) != "" {
923 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
924 "static_doc_properties")
925 *implicits = append(*implicits, static_doc_properties)
926 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -0700927 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -0700928 }
929 return cmds
930}
931
932func (d *Droiddoc) collectMetalavaAnnotationsFlags(
933 ctx android.ModuleContext, implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
934 var flags string
Nan Zhanga40da042018-08-01 12:48:00 -0700935 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 }
Nan Zhangde860a42018-08-08 16:32:21 -0700940 previousApi := ctx.ExpandSource(String(d.properties.Metalava_previous_api),
941 "metalava_previous_api")
942 *implicits = append(*implicits, previousApi)
943 flags += " --previous-api " + previousApi.String()
944
Nan Zhanga40da042018-08-01 12:48:00 -0700945 flags += " --include-annotations --migrate-nullness"
946
947 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
948 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
949
Nan Zhangf4936b02018-08-01 15:00:28 -0700950 flags += " --extract-annotations " + d.annotationsZip.String()
951
Nan Zhanga40da042018-08-01 12:48:00 -0700952 if len(d.properties.Metalava_merge_annotations_dirs) == 0 {
953 ctx.PropertyErrorf("metalava_merge_annotations_dirs",
954 "has to be non-empty if annotations was enabled!")
955 }
Nan Zhangf4936b02018-08-01 15:00:28 -0700956 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
957 if t, ok := m.(*ExportedDroiddocDir); ok {
958 *implicits = append(*implicits, t.deps...)
959 flags += " --merge-annotations " + t.dir.String()
960 } else {
961 ctx.PropertyErrorf("metalava_merge_annotations_dirs",
962 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
963 }
964 })
Nan Zhanga40da042018-08-01 12:48:00 -0700965 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
966 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction "
967 }
968
969 return flags
970}
971
972func (d *Droiddoc) collectMetalavaDocsFlags(ctx android.ModuleContext,
Nan Zhangde860a42018-08-08 16:32:21 -0700973 bootClasspathArgs, classpathArgs, outDir, docStubsDir string) string {
974 return " --doc-stubs " + docStubsDir +
975 " --write-doc-stubs-source-list " + android.PathForModuleOut(ctx, "doc_stubs.srclist").String() +
Nan Zhanga40da042018-08-01 12:48:00 -0700976 " --generate-documentation ${config.JavadocCmd} -encoding UTF-8 DOC_STUBS_SOURCE_LIST " +
977 bootClasspathArgs + " " + classpathArgs + " " + " -sourcepath " +
Nan Zhangde860a42018-08-08 16:32:21 -0700978 docStubsDir + " -quiet -d " + outDir
Nan Zhanga40da042018-08-01 12:48:00 -0700979}
980
981func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
982 deps := d.Javadoc.collectDeps(ctx)
983
984 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
985 // Doclava has problem with "-source 1.9", so override javaVersion when Doclava
986 // is running with EXPERIMENTAL_USE_OPENJDK9=true. And eventually Doclava will be
987 // replaced by Metalava.
Nan Zhang79614d12018-04-19 18:03:39 -0700988 if !Bool(d.properties.Metalava_enabled) {
Nan Zhanga40da042018-08-01 12:48:00 -0700989 javaVersion = "1.8"
990 }
Nan Zhang581fd212018-01-10 16:06:12 -0800991
Nan Zhanga40da042018-08-01 12:48:00 -0700992 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
993 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
994 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
995 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
Nan Zhang581fd212018-01-10 16:06:12 -0800996
Nan Zhanga40da042018-08-01 12:48:00 -0700997 var implicits android.Paths
998 implicits = append(implicits, d.Javadoc.srcJars...)
999
1000 var implicitOutputs android.WritablePaths
1001 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1002 for _, o := range d.properties.Out {
1003 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1004 }
1005
1006 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1007 if err != nil {
1008 return
1009 }
1010
Nan Zhangde860a42018-08-08 16:32:21 -07001011 outDir := android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001012 flags.doclavaStubsFlags, flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1013 if Bool(d.properties.Metalava_enabled) {
1014 opts := flags.metalavaStubsFlags
1015 flags.metalavaAnnotationsFlags = d.collectMetalavaAnnotationsFlags(ctx, &implicits, &implicitOutputs)
1016 opts += flags.metalavaAnnotationsFlags
Nan Zhangde860a42018-08-08 16:32:21 -07001017 docStubsDir := android.PathForModuleOut(ctx, "docStubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001018 if strings.Contains(flags.args, "--generate-documentation") {
1019 // TODO(nanzhang): Add a Soong property to handle documentation args.
1020 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, javaVersion, jsilver, doclava)
Nan Zhangde860a42018-08-08 16:32:21 -07001021 flags.metalavaDocsFlags = d.collectMetalavaDocsFlags(ctx,
1022 flags.bootClasspathArgs, flags.classpathArgs, outDir, docStubsDir)
Nan Zhanga40da042018-08-01 12:48:00 -07001023 opts += " " + strings.Split(flags.args, "--generate-documentation")[0] + " " +
1024 flags.metalavaDocsFlags + flags.doclavaDocsFlags +
1025 " " + strings.Split(flags.args, "--generate-documentation")[1]
1026 } else {
1027 opts += " " + flags.args
Nan Zhang79614d12018-04-19 18:03:39 -07001028 }
Nan Zhanga40da042018-08-01 12:48:00 -07001029 ctx.Build(pctx, android.BuildParams{
1030 Rule: metalava,
1031 Description: "Metalava",
1032 Output: d.Javadoc.stubsSrcJar,
1033 Inputs: d.Javadoc.srcFiles,
1034 Implicits: implicits,
1035 ImplicitOutputs: implicitOutputs,
1036 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -07001037 "outDir": outDir,
1038 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1039 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1040 "docStubsDir": docStubsDir,
Nan Zhanga40da042018-08-01 12:48:00 -07001041 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1042 "javaVersion": javaVersion,
1043 "bootclasspathArgs": flags.bootClasspathArgs,
1044 "classpathArgs": flags.classpathArgs,
1045 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
1046 "docZip": d.Javadoc.docZip.String(),
1047 "opts": opts,
1048 },
1049 })
1050 } else {
1051 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, javaVersion, jsilver, doclava)
1052 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
Nan Zhang79614d12018-04-19 18:03:39 -07001053 ctx.Build(pctx, android.BuildParams{
1054 Rule: javadoc,
1055 Description: "Droiddoc",
1056 Output: d.Javadoc.stubsSrcJar,
1057 Inputs: d.Javadoc.srcFiles,
1058 Implicits: implicits,
1059 ImplicitOutputs: implicitOutputs,
1060 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -07001061 "outDir": outDir,
1062 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1063 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang79614d12018-04-19 18:03:39 -07001064 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhanga40da042018-08-01 12:48:00 -07001065 "opts": flags.doclavaDocsFlags + flags.doclavaStubsFlags + " " + flags.args,
1066 "bootclasspathArgs": flags.bootClasspathArgs,
1067 "classpathArgs": flags.classpathArgs,
Nan Zhang79614d12018-04-19 18:03:39 -07001068 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
1069 "docZip": d.Javadoc.docZip.String(),
Nan Zhanga40da042018-08-01 12:48:00 -07001070 "postDoclavaCmds": flags.postDoclavaCmds,
Nan Zhang79614d12018-04-19 18:03:39 -07001071 },
1072 })
Nan Zhang79614d12018-04-19 18:03:39 -07001073 }
Nan Zhang61819ce2018-05-04 18:49:16 -07001074
Nan Zhang61819ce2018-05-04 18:49:16 -07001075 if d.checkCurrentApi() && !ctx.Config().IsPdkBuild() {
1076 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1077
1078 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1079 "check_api.current.api_file")
1080 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1081 "check_api.current_removed_api_file")
1082
1083 ctx.Build(pctx, android.BuildParams{
1084 Rule: apiCheck,
1085 Description: "Current API check",
1086 Output: d.checkCurrentApiTimestamp,
1087 Inputs: nil,
1088 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1089 checkApiClasspath...),
1090 Args: map[string]string{
1091 "classpath": checkApiClasspath.FormJavaClassPath(""),
1092 "opts": String(d.properties.Check_api.Current.Args),
1093 "apiFile": apiFile.String(),
1094 "apiFileToCheck": d.apiFile.String(),
1095 "removedApiFile": removedApiFile.String(),
1096 "removedApiFileToCheck": d.removedApiFile.String(),
1097 "msg": fmt.Sprintf(`\n******************************\n`+
1098 `You have tried to change the API from what has been previously approved.\n\n`+
1099 `To make these errors go away, you have two choices:\n`+
1100 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1101 ` errors above.\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +09001102 ` 2. You can update current.txt by executing the following command:\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -07001103 ` make %s-update-current-api\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +09001104 ` To submit the revised current.txt to the main Android repository,\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -07001105 ` you will need approval.\n`+
1106 `******************************\n`, ctx.ModuleName()),
1107 },
1108 })
1109
1110 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang61819ce2018-05-04 18:49:16 -07001111 ctx.Build(pctx, android.BuildParams{
1112 Rule: updateApi,
1113 Description: "update current API",
1114 Output: d.updateCurrentApiTimestamp,
1115 Implicits: append(android.Paths{}, apiFile, removedApiFile, d.apiFile, d.removedApiFile),
1116 Args: map[string]string{
1117 "apiFile": apiFile.String(),
1118 "apiFileToCheck": d.apiFile.String(),
1119 "removedApiFile": removedApiFile.String(),
1120 "removedApiFileToCheck": d.removedApiFile.String(),
1121 },
1122 })
1123 }
Nan Zhanga40da042018-08-01 12:48:00 -07001124
Nan Zhang61819ce2018-05-04 18:49:16 -07001125 if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
1126 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1127
1128 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1129 "check_api.last_released.api_file")
1130 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1131 "check_api.last_released.removed_api_file")
1132
1133 ctx.Build(pctx, android.BuildParams{
1134 Rule: apiCheck,
1135 Description: "Last Released API check",
1136 Output: d.checkLastReleasedApiTimestamp,
1137 Inputs: nil,
1138 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1139 checkApiClasspath...),
1140 Args: map[string]string{
1141 "classpath": checkApiClasspath.FormJavaClassPath(""),
1142 "opts": String(d.properties.Check_api.Last_released.Args),
1143 "apiFile": apiFile.String(),
1144 "apiFileToCheck": d.apiFile.String(),
1145 "removedApiFile": removedApiFile.String(),
1146 "removedApiFileToCheck": d.removedApiFile.String(),
1147 "msg": `\n******************************\n` +
1148 `You have tried to change the API from what has been previously released in\n` +
1149 `an SDK. Please fix the errors listed above.\n` +
1150 `******************************\n`,
1151 },
1152 })
1153 }
Nan Zhang581fd212018-01-10 16:06:12 -08001154}
Dan Willemsencc090972018-02-26 14:33:31 -08001155
Nan Zhanga40da042018-08-01 12:48:00 -07001156//
Nan Zhangf4936b02018-08-01 15:00:28 -07001157// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001158//
Dan Willemsencc090972018-02-26 14:33:31 -08001159var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001160var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001161
Nan Zhangf4936b02018-08-01 15:00:28 -07001162type ExportedDroiddocDirProperties struct {
1163 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001164 Path *string
1165}
1166
Nan Zhangf4936b02018-08-01 15:00:28 -07001167type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001168 android.ModuleBase
1169
Nan Zhangf4936b02018-08-01 15:00:28 -07001170 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001171
1172 deps android.Paths
1173 dir android.Path
1174}
1175
Nan Zhangf4936b02018-08-01 15:00:28 -07001176func ExportedDroiddocDirFactory() android.Module {
1177 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001178 module.AddProperties(&module.properties)
1179 android.InitAndroidModule(module)
1180 return module
1181}
1182
Nan Zhangf4936b02018-08-01 15:00:28 -07001183func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001184
Nan Zhangf4936b02018-08-01 15:00:28 -07001185func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Dan Willemsencc090972018-02-26 14:33:31 -08001186 path := android.PathForModuleSrc(ctx, String(d.properties.Path))
1187 d.dir = path
1188 d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
1189}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001190
1191//
1192// Defaults
1193//
1194type DocDefaults struct {
1195 android.ModuleBase
1196 android.DefaultsModuleBase
1197}
1198
1199func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1200}
1201
1202func (d *DocDefaults) DepsMutator(ctx android.BottomUpMutatorContext) {
1203}
1204
1205func DocDefaultsFactory() android.Module {
1206 module := &DocDefaults{}
1207
1208 module.AddProperties(
1209 &JavadocProperties{},
1210 &DroiddocProperties{},
1211 )
1212
1213 android.InitDefaultsModule(module)
1214
1215 return module
1216}