blob: b34c39367c67b6433b133b1b4b9c92fb06ac5f04 [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 Zhang581fd212018-01-10 16:06:12 -080022 "strings"
23
24 "github.com/google/blueprint"
25)
26
27var (
28 javadoc = pctx.AndroidStaticRule("javadoc",
29 blueprint.RuleParams{
30 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070031 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang581fd212018-01-10 16:06:12 -080032 `${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
33 `$opts $bootclasspathArgs $classpathArgs -sourcepath $sourcepath ` +
34 `-d $outDir -quiet && ` +
35 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
36 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir`,
37 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070038 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080039 "${config.JavadocCmd}",
40 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080041 },
42 Rspfile: "$out.rsp",
43 RspfileContent: "$in",
44 Restat: true,
45 },
46 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang30963742018-04-23 09:59:14 -070047 "bootclasspathArgs", "classpathArgs", "sourcepath", "docZip")
Nan Zhang61819ce2018-05-04 18:49:16 -070048
49 apiCheck = pctx.AndroidStaticRule("apiCheck",
50 blueprint.RuleParams{
51 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
52 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090053 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070054 CommandDeps: []string{
55 "${config.ApiCheckCmd}",
56 },
57 },
58 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
59
60 updateApi = pctx.AndroidStaticRule("updateApi",
61 blueprint.RuleParams{
62 Command: `( ( cp -f $apiFileToCheck $apiFile && cp -f $removedApiFileToCheck $removedApiFile ) ` +
63 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
64 },
65 "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck")
Nan Zhang581fd212018-01-10 16:06:12 -080066)
67
68func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -080069 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
70
Nan Zhang581fd212018-01-10 16:06:12 -080071 android.RegisterModuleType("droiddoc", DroiddocFactory)
72 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Dan Willemsencc090972018-02-26 14:33:31 -080073 android.RegisterModuleType("droiddoc_template", DroiddocTemplateFactory)
Nan Zhang581fd212018-01-10 16:06:12 -080074 android.RegisterModuleType("javadoc", JavadocFactory)
75 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
76}
77
78type JavadocProperties struct {
79 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
80 // or .aidl files.
81 Srcs []string `android:"arch_variant"`
82
83 // list of directories rooted at the Android.bp file that will
84 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -080085 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -080086
87 // list of source files that should not be used to build the Java module.
88 // This is most useful in the arch/multilib variants to remove non-common files
89 // filegroup or genrule can be included within this property.
90 Exclude_srcs []string `android:"arch_variant"`
91
Nan Zhangb2b33de2018-02-23 11:18:47 -080092 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080093 Libs []string `android:"arch_variant"`
94
Nan Zhange66c7272018-03-06 12:59:27 -080095 // don't build against the framework libraries (legacy-test, core-junit,
96 // ext, and framework for device targets)
97 No_framework_libs *bool
98
Nan Zhangb2b33de2018-02-23 11:18:47 -080099 // the java library (in classpath) for documentation that provides java srcs and srcjars.
100 Srcs_lib *string
101
102 // the base dirs under srcs_lib will be scanned for java srcs.
103 Srcs_lib_whitelist_dirs []string
104
105 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
106 Srcs_lib_whitelist_pkgs []string
107
Nan Zhang581fd212018-01-10 16:06:12 -0800108 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800109 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800110
111 // if not blank, set to the version of the sdk to compile against
112 Sdk_version *string `android:"arch_variant"`
113}
114
Nan Zhang61819ce2018-05-04 18:49:16 -0700115type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900116 // path to the API txt file that the new API extracted from source code is checked
117 // against. The path can be local to the module or from other module (via :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Api_file *string
119
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900120 // path to the API txt file that the new @removed API extractd from source code is
121 // checked against. The path can be local to the module or from other module (via
122 // :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700123 Removed_api_file *string
124
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900125 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700126 Args *string
127}
128
Nan Zhang581fd212018-01-10 16:06:12 -0800129type DroiddocProperties struct {
130 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800131 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800132
133 // directories relative to top of the source tree which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800134 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800135
136 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800137 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800138
139 // proofread file contains all of the text content of the javadocs concatenated into one file,
140 // suitable for spell-checking and other goodness.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800141 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800142
143 // a todo file lists the program elements that are missing documentation.
144 // At some point, this might be improved to show more warnings.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800145 Todo_file *string
146
147 // directory under current module source that provide additional resources (images).
148 Resourcesdir *string
149
150 // resources output directory under out/soong/.intermediates.
151 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800152
153 // local files that are used within user customized droiddoc options.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800154 Arg_files []string
Nan Zhang581fd212018-01-10 16:06:12 -0800155
156 // user customized droiddoc args.
157 // Available variables for substitution:
158 //
159 // $(location <label>): the path to the arg_files with name <label>
Nan Zhangb2b33de2018-02-23 11:18:47 -0800160 Args *string
Nan Zhang581fd212018-01-10 16:06:12 -0800161
162 // names of the output files used in args that will be generated
Nan Zhangb2b33de2018-02-23 11:18:47 -0800163 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800164
165 // a list of files under current module source dir which contains known tags in Java sources.
166 // filegroup or genrule can be included within this property.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800167 Knowntags []string
Nan Zhang28c68b92018-03-13 16:17:01 -0700168
169 // the tag name used to distinguish if the API files belong to public/system/test.
170 Api_tag_name *string
171
172 // the generated public API filename by Doclava.
173 Api_filename *string
174
175 // the generated private API filename by Doclava.
176 Private_api_filename *string
177
178 // the generated private Dex API filename by Doclava.
179 Private_dex_api_filename *string
180
181 // the generated removed API filename by Doclava.
182 Removed_api_filename *string
183
David Brazdilaac0c3c2018-04-24 16:23:29 +0100184 // the generated removed Dex API filename by Doclava.
185 Removed_dex_api_filename *string
186
Nan Zhang28c68b92018-03-13 16:17:01 -0700187 // the generated exact API filename by Doclava.
188 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700189
190 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
191 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700192
193 Check_api struct {
194 Last_released ApiToCheck
195
196 Current ApiToCheck
197 }
Nan Zhang581fd212018-01-10 16:06:12 -0800198}
199
200type Javadoc struct {
201 android.ModuleBase
202 android.DefaultableModuleBase
203
204 properties JavadocProperties
205
206 srcJars android.Paths
207 srcFiles android.Paths
208 sourcepaths android.Paths
209
Nan Zhangccff0f72018-03-08 17:26:16 -0800210 docZip android.WritablePath
211 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800212}
213
Nan Zhangb2b33de2018-02-23 11:18:47 -0800214func (j *Javadoc) Srcs() android.Paths {
215 return android.Paths{j.stubsSrcJar}
216}
217
218var _ android.SourceFileProducer = (*Javadoc)(nil)
219
Nan Zhang581fd212018-01-10 16:06:12 -0800220type Droiddoc struct {
221 Javadoc
222
Nan Zhang28c68b92018-03-13 16:17:01 -0700223 properties DroiddocProperties
224 apiFile android.WritablePath
225 privateApiFile android.WritablePath
226 privateDexApiFile android.WritablePath
227 removedApiFile android.WritablePath
David Brazdilaac0c3c2018-04-24 16:23:29 +0100228 removedDexApiFile android.WritablePath
Nan Zhang28c68b92018-03-13 16:17:01 -0700229 exactApiFile android.WritablePath
Nan Zhang61819ce2018-05-04 18:49:16 -0700230
231 checkCurrentApiTimestamp android.WritablePath
232 updateCurrentApiTimestamp android.WritablePath
233 checkLastReleasedApiTimestamp android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800234}
235
236func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
237 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
238 android.InitDefaultableModule(module)
239}
240
241func JavadocFactory() android.Module {
242 module := &Javadoc{}
243
244 module.AddProperties(&module.properties)
245
246 InitDroiddocModule(module, android.HostAndDeviceSupported)
247 return module
248}
249
250func JavadocHostFactory() android.Module {
251 module := &Javadoc{}
252
253 module.AddProperties(&module.properties)
254
255 InitDroiddocModule(module, android.HostSupported)
256 return module
257}
258
259func DroiddocFactory() android.Module {
260 module := &Droiddoc{}
261
262 module.AddProperties(&module.properties,
263 &module.Javadoc.properties)
264
265 InitDroiddocModule(module, android.HostAndDeviceSupported)
266 return module
267}
268
269func DroiddocHostFactory() android.Module {
270 module := &Droiddoc{}
271
272 module.AddProperties(&module.properties,
273 &module.Javadoc.properties)
274
275 InitDroiddocModule(module, android.HostSupported)
276 return module
277}
278
279func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
280 if ctx.Device() {
281 sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version))
282 if sdkDep.useDefaultLibs {
283 ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
Nan Zhang9cbe6772018-03-21 17:56:39 -0700284 if !Bool(j.properties.No_framework_libs) {
Nan Zhange66c7272018-03-06 12:59:27 -0800285 ctx.AddDependency(ctx.Module(), libTag, []string{"ext", "framework"}...)
286 }
Nan Zhang581fd212018-01-10 16:06:12 -0800287 } else if sdkDep.useModule {
288 ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.module)
289 }
290 }
291
292 ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
293
294 android.ExtractSourcesDeps(ctx, j.properties.Srcs)
295
296 // exclude_srcs may contain filegroup or genrule.
297 android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
298}
299
Nan Zhangb2b33de2018-02-23 11:18:47 -0800300func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
301 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
302 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900303 // convert foo.bar.baz to foo/bar/baz
304 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
305 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800306 if _, found := whitelistPathPrefixes[prefix]; !found {
307 whitelistPathPrefixes[prefix] = true
308 }
309 }
310 }
311}
312
Nan Zhang581fd212018-01-10 16:06:12 -0800313func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
314 var deps deps
315
316 sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version))
317 if sdkDep.invalidVersion {
318 ctx.AddMissingDependencies([]string{sdkDep.module})
319 } else if sdkDep.useFiles {
320 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jar)
321 }
322
323 ctx.VisitDirectDeps(func(module android.Module) {
324 otherName := ctx.OtherModuleName(module)
325 tag := ctx.OtherModuleDependencyTag(module)
326
327 switch dep := module.(type) {
328 case Dependency:
329 switch tag {
330 case bootClasspathTag:
331 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
332 case libTag:
333 deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800334 if otherName == String(j.properties.Srcs_lib) {
335 srcs := dep.(SrcDependency).CompiledSrcs()
336 whitelistPathPrefixes := make(map[string]bool)
337 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
338 for _, src := range srcs {
339 if _, ok := src.(android.WritablePath); ok { // generated sources
340 deps.srcs = append(deps.srcs, src)
341 } else { // select source path for documentation based on whitelist path prefixs.
342 for k, _ := range whitelistPathPrefixes {
343 if strings.HasPrefix(src.Rel(), k) {
344 deps.srcs = append(deps.srcs, src)
345 break
346 }
347 }
348 }
349 }
350 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
351 }
Nan Zhang581fd212018-01-10 16:06:12 -0800352 default:
353 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
354 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900355 case SdkLibraryDependency:
356 switch tag {
357 case libTag:
358 sdkVersion := String(j.properties.Sdk_version)
359 linkType := javaSdk
360 if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
361 linkType = javaSystem
362 } else if sdkVersion == "" {
363 linkType = javaPlatform
364 }
365 deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
366 default:
367 ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
368 }
Nan Zhang581fd212018-01-10 16:06:12 -0800369 case android.SourceFileProducer:
370 switch tag {
371 case libTag:
372 checkProducesJars(ctx, dep)
373 deps.classpath = append(deps.classpath, dep.Srcs()...)
374 case android.DefaultsDepTag, android.SourceDepTag:
375 // Nothing to do
376 default:
377 ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs", otherName)
378 }
379 default:
380 switch tag {
Dan Willemsencc090972018-02-26 14:33:31 -0800381 case android.DefaultsDepTag, android.SourceDepTag, droiddocTemplateTag:
Nan Zhang581fd212018-01-10 16:06:12 -0800382 // Nothing to do
383 default:
384 ctx.ModuleErrorf("depends on non-java module %q", otherName)
385 }
386 }
387 })
388 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
389 // may contain filegroup or genrule.
390 srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
391
392 // srcs may depend on some genrule output.
393 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800394 j.srcJars = append(j.srcJars, deps.srcJars...)
395
Nan Zhang581fd212018-01-10 16:06:12 -0800396 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800397 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800398
399 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800400 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800401
402 if j.properties.Local_sourcepaths == nil {
403 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
404 }
405 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800406
407 return deps
408}
409
410func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
411 j.addDeps(ctx)
412}
413
414func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
415 deps := j.collectDeps(ctx)
416
417 var implicits android.Paths
418 implicits = append(implicits, deps.bootClasspath...)
419 implicits = append(implicits, deps.classpath...)
420
421 var bootClasspathArgs, classpathArgs string
422 if ctx.Config().UseOpenJDK9() {
423 if len(deps.bootClasspath) > 0 {
424 // For OpenJDK 9 we use --patch-module to define the core libraries code.
425 // TODO(tobiast): Reorganize this when adding proper support for OpenJDK 9
426 // modules. Here we treat all code in core libraries as being in java.base
427 // to work around the OpenJDK 9 module system. http://b/62049770
428 bootClasspathArgs = "--patch-module=java.base=" + strings.Join(deps.bootClasspath.Strings(), ":")
429 }
430 } else {
431 if len(deps.bootClasspath.Strings()) > 0 {
432 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
433 bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
434 }
435 }
436 if len(deps.classpath.Strings()) > 0 {
437 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
438 }
439
440 implicits = append(implicits, j.srcJars...)
441
442 opts := "-J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
443
444 ctx.Build(pctx, android.BuildParams{
445 Rule: javadoc,
446 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800447 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800448 ImplicitOutput: j.docZip,
449 Inputs: j.srcFiles,
450 Implicits: implicits,
451 Args: map[string]string{
452 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
453 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
454 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
455 "srcJars": strings.Join(j.srcJars.Strings(), " "),
456 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700457 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800458 "classpathArgs": classpathArgs,
459 "sourcepath": strings.Join(j.sourcepaths.Strings(), ":"),
460 "docZip": j.docZip.String(),
461 },
462 })
463}
464
Nan Zhang61819ce2018-05-04 18:49:16 -0700465func (d *Droiddoc) checkCurrentApi() bool {
466 if String(d.properties.Check_api.Current.Api_file) != "" &&
467 String(d.properties.Check_api.Current.Removed_api_file) != "" {
468 return true
469 } else if String(d.properties.Check_api.Current.Api_file) != "" {
470 panic("check_api.current.removed_api_file: has to be non empty!")
471 } else if String(d.properties.Check_api.Current.Removed_api_file) != "" {
472 panic("check_api.current.api_file: has to be non empty!")
473 }
474
475 return false
476}
477
478func (d *Droiddoc) checkLastReleasedApi() bool {
479 if String(d.properties.Check_api.Last_released.Api_file) != "" &&
480 String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
481 return true
482 } else if String(d.properties.Check_api.Last_released.Api_file) != "" {
483 panic("check_api.last_released.removed_api_file: has to be non empty!")
484 } else if String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
485 panic("check_api.last_released.api_file: has to be non empty!")
486 }
487
488 return false
489}
490
Nan Zhang581fd212018-01-10 16:06:12 -0800491func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
492 d.Javadoc.addDeps(ctx)
493
Dan Willemsencc090972018-02-26 14:33:31 -0800494 if String(d.properties.Custom_template) == "" {
495 // TODO: This is almost always droiddoc-templates-sdk
496 ctx.PropertyErrorf("custom_template", "must specify a template")
497 } else {
498 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
499 }
500
Nan Zhang581fd212018-01-10 16:06:12 -0800501 // extra_arg_files may contains filegroup or genrule.
502 android.ExtractSourcesDeps(ctx, d.properties.Arg_files)
503
504 // knowntags may contain filegroup or genrule.
505 android.ExtractSourcesDeps(ctx, d.properties.Knowntags)
Nan Zhang61819ce2018-05-04 18:49:16 -0700506
507 if d.checkCurrentApi() {
508 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
509 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
510 }
511
512 if d.checkLastReleasedApi() {
513 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
514 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
515 }
Nan Zhang581fd212018-01-10 16:06:12 -0800516}
517
518func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
519 deps := d.Javadoc.collectDeps(ctx)
520
521 var implicits android.Paths
522 implicits = append(implicits, deps.bootClasspath...)
523 implicits = append(implicits, deps.classpath...)
524
525 argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
526 argFilesMap := map[string]android.Path{}
527
528 for _, f := range argFiles {
529 implicits = append(implicits, f)
530 if _, exists := argFilesMap[f.Rel()]; !exists {
531 argFilesMap[f.Rel()] = f
532 } else {
533 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
534 f, argFilesMap[f.Rel()], f.Rel())
535 }
536 }
537
538 args, err := android.Expand(String(d.properties.Args), func(name string) (string, error) {
539 if strings.HasPrefix(name, "location ") {
540 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
541 if f, ok := argFilesMap[label]; ok {
542 return f.String(), nil
543 } else {
544 return "", fmt.Errorf("unknown location label %q", label)
545 }
546 } else if name == "genDir" {
547 return android.PathForModuleGen(ctx).String(), nil
548 }
549 return "", fmt.Errorf("unknown variable '$(%s)'", name)
550 })
551
552 if err != nil {
553 ctx.PropertyErrorf("extra_args", "%s", err.Error())
554 return
555 }
556
557 var bootClasspathArgs, classpathArgs string
558 if len(deps.bootClasspath.Strings()) > 0 {
559 bootClasspathArgs = "-bootclasspath " + strings.Join(deps.bootClasspath.Strings(), ":")
560 }
561 if len(deps.classpath.Strings()) > 0 {
562 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
563 }
564
Dan Willemsencc090972018-02-26 14:33:31 -0800565 var templateDir string
566 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
567 if t, ok := m.(*DroiddocTemplate); ok {
568 implicits = append(implicits, t.deps...)
569 templateDir = t.dir.String()
570 } else {
571 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
572 }
573 })
Nan Zhang581fd212018-01-10 16:06:12 -0800574
575 var htmlDirArgs string
576 if len(d.properties.Html_dirs) > 0 {
Dan Willemsencc090972018-02-26 14:33:31 -0800577 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
578 implicits = append(implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
579 htmlDirArgs = "-htmldir " + htmlDir.String()
Nan Zhang581fd212018-01-10 16:06:12 -0800580 }
581
582 var htmlDir2Args string
583 if len(d.properties.Html_dirs) > 1 {
Dan Willemsencc090972018-02-26 14:33:31 -0800584 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
585 implicits = append(implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
586 htmlDir2Args = "-htmldir2 " + htmlDir2.String()
587 }
588
589 if len(d.properties.Html_dirs) > 2 {
590 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
Nan Zhang581fd212018-01-10 16:06:12 -0800591 }
592
593 knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
594 implicits = append(implicits, knownTags...)
595
596 for _, kt := range knownTags {
597 args = args + " -knowntags " + kt.String()
598 }
599 for _, hdf := range d.properties.Hdf {
600 args = args + " -hdf " + hdf
601 }
602
603 if String(d.properties.Proofread_file) != "" {
604 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
605 args = args + " -proofread " + proofreadFile.String()
606 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800607
Nan Zhang581fd212018-01-10 16:06:12 -0800608 if String(d.properties.Todo_file) != "" {
609 // tricky part:
610 // we should not compute full path for todo_file through PathForModuleOut().
611 // the non-standard doclet will get the full path relative to "-o".
612 args = args + " -todo " + String(d.properties.Todo_file)
613 }
614
Nan Zhangb2b33de2018-02-23 11:18:47 -0800615 if String(d.properties.Resourcesdir) != "" {
616 // TODO: should we add files under resourcesDir to the implicits? It seems that
617 // resourcesDir is one sub dir of htmlDir
618 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
619 args = args + " -resourcesdir " + resourcesDir.String()
620 }
621
622 if String(d.properties.Resourcesoutdir) != "" {
623 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
624 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
625 }
626
Nan Zhang28c68b92018-03-13 16:17:01 -0700627 var implicitOutputs android.WritablePaths
Nan Zhang61819ce2018-05-04 18:49:16 -0700628
629 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Api_filename) != "" {
630 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Nan Zhang28c68b92018-03-13 16:17:01 -0700631 args = args + " -api " + d.apiFile.String()
632 implicitOutputs = append(implicitOutputs, d.apiFile)
633 }
634
Nan Zhang61819ce2018-05-04 18:49:16 -0700635 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Removed_api_filename) != "" {
636 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
637 args = args + " -removedApi " + d.removedApiFile.String()
638 implicitOutputs = append(implicitOutputs, d.removedApiFile)
639 }
640
Nan Zhang28c68b92018-03-13 16:17:01 -0700641 if String(d.properties.Private_api_filename) != "" {
642 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
643 args = args + " -privateApi " + d.privateApiFile.String()
644 implicitOutputs = append(implicitOutputs, d.privateApiFile)
645 }
646
647 if String(d.properties.Private_dex_api_filename) != "" {
648 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
649 args = args + " -privateDexApi " + d.privateDexApiFile.String()
650 implicitOutputs = append(implicitOutputs, d.privateDexApiFile)
651 }
652
David Brazdilaac0c3c2018-04-24 16:23:29 +0100653 if String(d.properties.Removed_dex_api_filename) != "" {
654 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
655 args = args + " -removedDexApi " + d.removedDexApiFile.String()
656 implicitOutputs = append(implicitOutputs, d.removedDexApiFile)
657 }
658
Nan Zhang28c68b92018-03-13 16:17:01 -0700659 if String(d.properties.Exact_api_filename) != "" {
660 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
661 args = args + " -exactApi " + d.exactApiFile.String()
662 implicitOutputs = append(implicitOutputs, d.exactApiFile)
663 }
664
Nan Zhang581fd212018-01-10 16:06:12 -0800665 implicits = append(implicits, d.Javadoc.srcJars...)
666
Nan Zhang30963742018-04-23 09:59:14 -0700667 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
668 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
669 implicits = append(implicits, jsilver)
670 implicits = append(implicits, doclava)
671
Nan Zhang581fd212018-01-10 16:06:12 -0800672 opts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700673 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross480cd762018-02-22 14:39:17 -0800674 "-templatedir " + templateDir + " " + htmlDirArgs + " " + htmlDir2Args + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800675 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang853f4202018-04-12 16:55:56 -0700676 "-hdf page.now " + `"$$(date -d @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")"` +
677 " " + args
678 if BoolDefault(d.properties.Create_stubs, true) {
679 opts += " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String()
680 }
Nan Zhang581fd212018-01-10 16:06:12 -0800681
Nan Zhang581fd212018-01-10 16:06:12 -0800682 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
683 for _, o := range d.properties.Out {
684 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
685 }
686
687 ctx.Build(pctx, android.BuildParams{
688 Rule: javadoc,
689 Description: "Droiddoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800690 Output: d.Javadoc.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800691 Inputs: d.Javadoc.srcFiles,
692 Implicits: implicits,
693 ImplicitOutputs: implicitOutputs,
694 Args: map[string]string{
695 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
696 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
697 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
698 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
699 "opts": opts,
700 "bootclasspathArgs": bootClasspathArgs,
701 "classpathArgs": classpathArgs,
702 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
703 "docZip": d.Javadoc.docZip.String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800704 },
705 })
Nan Zhang61819ce2018-05-04 18:49:16 -0700706
707 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
708
709 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
710
711 if d.checkCurrentApi() && !ctx.Config().IsPdkBuild() {
712 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
713
714 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
715 "check_api.current.api_file")
716 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
717 "check_api.current_removed_api_file")
718
719 ctx.Build(pctx, android.BuildParams{
720 Rule: apiCheck,
721 Description: "Current API check",
722 Output: d.checkCurrentApiTimestamp,
723 Inputs: nil,
724 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
725 checkApiClasspath...),
726 Args: map[string]string{
727 "classpath": checkApiClasspath.FormJavaClassPath(""),
728 "opts": String(d.properties.Check_api.Current.Args),
729 "apiFile": apiFile.String(),
730 "apiFileToCheck": d.apiFile.String(),
731 "removedApiFile": removedApiFile.String(),
732 "removedApiFileToCheck": d.removedApiFile.String(),
733 "msg": fmt.Sprintf(`\n******************************\n`+
734 `You have tried to change the API from what has been previously approved.\n\n`+
735 `To make these errors go away, you have two choices:\n`+
736 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
737 ` errors above.\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900738 ` 2. You can update current.txt by executing the following command:\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -0700739 ` make %s-update-current-api\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900740 ` To submit the revised current.txt to the main Android repository,\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -0700741 ` you will need approval.\n`+
742 `******************************\n`, ctx.ModuleName()),
743 },
744 })
745
746 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
747
748 ctx.Build(pctx, android.BuildParams{
749 Rule: updateApi,
750 Description: "update current API",
751 Output: d.updateCurrentApiTimestamp,
752 Implicits: append(android.Paths{}, apiFile, removedApiFile, d.apiFile, d.removedApiFile),
753 Args: map[string]string{
754 "apiFile": apiFile.String(),
755 "apiFileToCheck": d.apiFile.String(),
756 "removedApiFile": removedApiFile.String(),
757 "removedApiFileToCheck": d.removedApiFile.String(),
758 },
759 })
760 }
761
762 if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
763 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
764
765 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
766 "check_api.last_released.api_file")
767 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
768 "check_api.last_released.removed_api_file")
769
770 ctx.Build(pctx, android.BuildParams{
771 Rule: apiCheck,
772 Description: "Last Released API check",
773 Output: d.checkLastReleasedApiTimestamp,
774 Inputs: nil,
775 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
776 checkApiClasspath...),
777 Args: map[string]string{
778 "classpath": checkApiClasspath.FormJavaClassPath(""),
779 "opts": String(d.properties.Check_api.Last_released.Args),
780 "apiFile": apiFile.String(),
781 "apiFileToCheck": d.apiFile.String(),
782 "removedApiFile": removedApiFile.String(),
783 "removedApiFileToCheck": d.removedApiFile.String(),
784 "msg": `\n******************************\n` +
785 `You have tried to change the API from what has been previously released in\n` +
786 `an SDK. Please fix the errors listed above.\n` +
787 `******************************\n`,
788 },
789 })
790 }
Nan Zhang581fd212018-01-10 16:06:12 -0800791}
Dan Willemsencc090972018-02-26 14:33:31 -0800792
793var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
794
795type DroiddocTemplateProperties struct {
796 // path to the directory containing the droiddoc templates.
797 Path *string
798}
799
800type DroiddocTemplate struct {
801 android.ModuleBase
802
803 properties DroiddocTemplateProperties
804
805 deps android.Paths
806 dir android.Path
807}
808
809func DroiddocTemplateFactory() android.Module {
810 module := &DroiddocTemplate{}
811 module.AddProperties(&module.properties)
812 android.InitAndroidModule(module)
813 return module
814}
815
816func (d *DroiddocTemplate) DepsMutator(android.BottomUpMutatorContext) {}
817
818func (d *DroiddocTemplate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
819 path := android.PathForModuleSrc(ctx, String(d.properties.Path))
820 d.dir = path
821 d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
822}
Nan Zhangb2b33de2018-02-23 11:18:47 -0800823
824//
825// Defaults
826//
827type DocDefaults struct {
828 android.ModuleBase
829 android.DefaultsModuleBase
830}
831
832func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
833}
834
835func (d *DocDefaults) DepsMutator(ctx android.BottomUpMutatorContext) {
836}
837
838func DocDefaultsFactory() android.Module {
839 module := &DocDefaults{}
840
841 module.AddProperties(
842 &JavadocProperties{},
843 &DroiddocProperties{},
844 )
845
846 android.InitDefaultsModule(module)
847
848 return module
849}