blob: 6c762627920feaffca69f2d7f8e8df506f1402c8 [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"`
Jiyong Park1e440682018-05-23 18:42:04 +0900113
114 Aidl struct {
115 // Top level directories to pass to aidl tool
116 Include_dirs []string
117
118 // Directories rooted at the Android.bp file to pass to aidl tool
119 Local_include_dirs []string
120 }
Nan Zhang581fd212018-01-10 16:06:12 -0800121}
122
Nan Zhang61819ce2018-05-04 18:49:16 -0700123type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900124 // path to the API txt file that the new API extracted from source code is checked
125 // against. The path can be local to the module or from other module (via :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700126 Api_file *string
127
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900128 // path to the API txt file that the new @removed API extractd from source code is
129 // checked against. The path can be local to the module or from other module (via
130 // :module syntax).
Nan Zhang61819ce2018-05-04 18:49:16 -0700131 Removed_api_file *string
132
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900133 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700134 Args *string
135}
136
Nan Zhang581fd212018-01-10 16:06:12 -0800137type DroiddocProperties struct {
138 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800139 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800140
141 // directories relative to top of the source tree which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800142 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800143
144 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800145 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800146
147 // proofread file contains all of the text content of the javadocs concatenated into one file,
148 // suitable for spell-checking and other goodness.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800149 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800150
151 // a todo file lists the program elements that are missing documentation.
152 // At some point, this might be improved to show more warnings.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800153 Todo_file *string
154
155 // directory under current module source that provide additional resources (images).
156 Resourcesdir *string
157
158 // resources output directory under out/soong/.intermediates.
159 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800160
161 // local files that are used within user customized droiddoc options.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800162 Arg_files []string
Nan Zhang581fd212018-01-10 16:06:12 -0800163
164 // user customized droiddoc args.
165 // Available variables for substitution:
166 //
167 // $(location <label>): the path to the arg_files with name <label>
Nan Zhangb2b33de2018-02-23 11:18:47 -0800168 Args *string
Nan Zhang581fd212018-01-10 16:06:12 -0800169
170 // names of the output files used in args that will be generated
Nan Zhangb2b33de2018-02-23 11:18:47 -0800171 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800172
173 // a list of files under current module source dir which contains known tags in Java sources.
174 // filegroup or genrule can be included within this property.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800175 Knowntags []string
Nan Zhang28c68b92018-03-13 16:17:01 -0700176
177 // the tag name used to distinguish if the API files belong to public/system/test.
178 Api_tag_name *string
179
180 // the generated public API filename by Doclava.
181 Api_filename *string
182
183 // the generated private API filename by Doclava.
184 Private_api_filename *string
185
186 // the generated private Dex API filename by Doclava.
187 Private_dex_api_filename *string
188
189 // the generated removed API filename by Doclava.
190 Removed_api_filename *string
191
David Brazdilaac0c3c2018-04-24 16:23:29 +0100192 // the generated removed Dex API filename by Doclava.
193 Removed_dex_api_filename *string
194
Nan Zhang28c68b92018-03-13 16:17:01 -0700195 // the generated exact API filename by Doclava.
196 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700197
198 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
199 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700200
201 Check_api struct {
202 Last_released ApiToCheck
203
204 Current ApiToCheck
205 }
Nan Zhang581fd212018-01-10 16:06:12 -0800206}
207
208type Javadoc struct {
209 android.ModuleBase
210 android.DefaultableModuleBase
211
212 properties JavadocProperties
213
214 srcJars android.Paths
215 srcFiles android.Paths
216 sourcepaths android.Paths
217
Nan Zhangccff0f72018-03-08 17:26:16 -0800218 docZip android.WritablePath
219 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800220}
221
Nan Zhangb2b33de2018-02-23 11:18:47 -0800222func (j *Javadoc) Srcs() android.Paths {
223 return android.Paths{j.stubsSrcJar}
224}
225
226var _ android.SourceFileProducer = (*Javadoc)(nil)
227
Nan Zhang581fd212018-01-10 16:06:12 -0800228type Droiddoc struct {
229 Javadoc
230
Nan Zhang28c68b92018-03-13 16:17:01 -0700231 properties DroiddocProperties
232 apiFile android.WritablePath
233 privateApiFile android.WritablePath
234 privateDexApiFile android.WritablePath
235 removedApiFile android.WritablePath
David Brazdilaac0c3c2018-04-24 16:23:29 +0100236 removedDexApiFile android.WritablePath
Nan Zhang28c68b92018-03-13 16:17:01 -0700237 exactApiFile android.WritablePath
Nan Zhang61819ce2018-05-04 18:49:16 -0700238
239 checkCurrentApiTimestamp android.WritablePath
240 updateCurrentApiTimestamp android.WritablePath
241 checkLastReleasedApiTimestamp android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800242}
243
244func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
245 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
246 android.InitDefaultableModule(module)
247}
248
249func JavadocFactory() android.Module {
250 module := &Javadoc{}
251
252 module.AddProperties(&module.properties)
253
254 InitDroiddocModule(module, android.HostAndDeviceSupported)
255 return module
256}
257
258func JavadocHostFactory() android.Module {
259 module := &Javadoc{}
260
261 module.AddProperties(&module.properties)
262
263 InitDroiddocModule(module, android.HostSupported)
264 return module
265}
266
267func DroiddocFactory() android.Module {
268 module := &Droiddoc{}
269
270 module.AddProperties(&module.properties,
271 &module.Javadoc.properties)
272
273 InitDroiddocModule(module, android.HostAndDeviceSupported)
274 return module
275}
276
277func DroiddocHostFactory() android.Module {
278 module := &Droiddoc{}
279
280 module.AddProperties(&module.properties,
281 &module.Javadoc.properties)
282
283 InitDroiddocModule(module, android.HostSupported)
284 return module
285}
286
287func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
288 if ctx.Device() {
289 sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version))
290 if sdkDep.useDefaultLibs {
291 ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
Nan Zhang9cbe6772018-03-21 17:56:39 -0700292 if !Bool(j.properties.No_framework_libs) {
Nan Zhange66c7272018-03-06 12:59:27 -0800293 ctx.AddDependency(ctx.Module(), libTag, []string{"ext", "framework"}...)
294 }
Nan Zhang581fd212018-01-10 16:06:12 -0800295 } else if sdkDep.useModule {
Colin Cross86a60ae2018-05-29 14:44:55 -0700296 ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.modules...)
Nan Zhang581fd212018-01-10 16:06:12 -0800297 }
298 }
299
300 ctx.AddDependency(ctx.Module(), libTag, j.properties.Libs...)
301
302 android.ExtractSourcesDeps(ctx, j.properties.Srcs)
303
304 // exclude_srcs may contain filegroup or genrule.
305 android.ExtractSourcesDeps(ctx, j.properties.Exclude_srcs)
306}
307
Nan Zhangb2b33de2018-02-23 11:18:47 -0800308func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
309 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
310 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900311 // convert foo.bar.baz to foo/bar/baz
312 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
313 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800314 if _, found := whitelistPathPrefixes[prefix]; !found {
315 whitelistPathPrefixes[prefix] = true
316 }
317 }
318 }
319}
320
Jiyong Park1e440682018-05-23 18:42:04 +0900321func (j *Javadoc) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
322 var flags javaBuilderFlags
323
324 // aidl flags.
325 aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
326 if len(aidlFlags) > 0 {
327 // optimization.
328 ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
329 flags.aidlFlags = "$aidlFlags"
330 }
331
332 return flags
333}
334
335func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
336 aidlIncludeDirs android.Paths) []string {
337
338 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
339 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
340
341 var flags []string
342 if aidlPreprocess.Valid() {
343 flags = append(flags, "-p"+aidlPreprocess.String())
344 } else {
345 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
346 }
347
348 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
349 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
350 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
351 flags = append(flags, "-I"+src.String())
352 }
353
354 return flags
355}
356
357func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
358 flags javaBuilderFlags) android.Paths {
359
360 outSrcFiles := make(android.Paths, 0, len(srcFiles))
361
362 for _, srcFile := range srcFiles {
363 switch srcFile.Ext() {
364 case ".aidl":
365 javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
366 outSrcFiles = append(outSrcFiles, javaFile)
367 default:
368 outSrcFiles = append(outSrcFiles, srcFile)
369 }
370 }
371
372 return outSrcFiles
373}
374
Nan Zhang581fd212018-01-10 16:06:12 -0800375func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
376 var deps deps
377
378 sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version))
379 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700380 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800381 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700382 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800383 }
384
385 ctx.VisitDirectDeps(func(module android.Module) {
386 otherName := ctx.OtherModuleName(module)
387 tag := ctx.OtherModuleDependencyTag(module)
388
389 switch dep := module.(type) {
390 case Dependency:
391 switch tag {
392 case bootClasspathTag:
393 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
394 case libTag:
395 deps.classpath = append(deps.classpath, dep.ImplementationJars()...)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800396 if otherName == String(j.properties.Srcs_lib) {
397 srcs := dep.(SrcDependency).CompiledSrcs()
398 whitelistPathPrefixes := make(map[string]bool)
399 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
400 for _, src := range srcs {
401 if _, ok := src.(android.WritablePath); ok { // generated sources
402 deps.srcs = append(deps.srcs, src)
403 } else { // select source path for documentation based on whitelist path prefixs.
404 for k, _ := range whitelistPathPrefixes {
405 if strings.HasPrefix(src.Rel(), k) {
406 deps.srcs = append(deps.srcs, src)
407 break
408 }
409 }
410 }
411 }
412 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
413 }
Nan Zhang581fd212018-01-10 16:06:12 -0800414 default:
415 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
416 }
Jiyong Parkc678ad32018-04-10 13:07:10 +0900417 case SdkLibraryDependency:
418 switch tag {
419 case libTag:
420 sdkVersion := String(j.properties.Sdk_version)
421 linkType := javaSdk
422 if strings.HasPrefix(sdkVersion, "system_") || strings.HasPrefix(sdkVersion, "test_") {
423 linkType = javaSystem
424 } else if sdkVersion == "" {
425 linkType = javaPlatform
426 }
427 deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
428 default:
429 ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
430 }
Nan Zhang581fd212018-01-10 16:06:12 -0800431 case android.SourceFileProducer:
432 switch tag {
433 case libTag:
434 checkProducesJars(ctx, dep)
435 deps.classpath = append(deps.classpath, dep.Srcs()...)
436 case android.DefaultsDepTag, android.SourceDepTag:
437 // Nothing to do
438 default:
439 ctx.ModuleErrorf("dependency on genrule %q may only be in srcs, libs", otherName)
440 }
441 default:
442 switch tag {
Dan Willemsencc090972018-02-26 14:33:31 -0800443 case android.DefaultsDepTag, android.SourceDepTag, droiddocTemplateTag:
Nan Zhang581fd212018-01-10 16:06:12 -0800444 // Nothing to do
445 default:
446 ctx.ModuleErrorf("depends on non-java module %q", otherName)
447 }
448 }
449 })
450 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
451 // may contain filegroup or genrule.
452 srcFiles := ctx.ExpandSources(j.properties.Srcs, j.properties.Exclude_srcs)
Jiyong Park1e440682018-05-23 18:42:04 +0900453 flags := j.collectBuilderFlags(ctx, deps)
454 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800455
456 // srcs may depend on some genrule output.
457 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800458 j.srcJars = append(j.srcJars, deps.srcJars...)
459
Nan Zhang581fd212018-01-10 16:06:12 -0800460 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800461 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800462
463 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800464 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800465
466 if j.properties.Local_sourcepaths == nil {
467 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
468 }
469 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800470
471 return deps
472}
473
474func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
475 j.addDeps(ctx)
476}
477
478func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
479 deps := j.collectDeps(ctx)
480
481 var implicits android.Paths
482 implicits = append(implicits, deps.bootClasspath...)
483 implicits = append(implicits, deps.classpath...)
484
485 var bootClasspathArgs, classpathArgs string
486 if ctx.Config().UseOpenJDK9() {
487 if len(deps.bootClasspath) > 0 {
488 // For OpenJDK 9 we use --patch-module to define the core libraries code.
489 // TODO(tobiast): Reorganize this when adding proper support for OpenJDK 9
490 // modules. Here we treat all code in core libraries as being in java.base
491 // to work around the OpenJDK 9 module system. http://b/62049770
492 bootClasspathArgs = "--patch-module=java.base=" + strings.Join(deps.bootClasspath.Strings(), ":")
493 }
494 } else {
495 if len(deps.bootClasspath.Strings()) > 0 {
496 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
497 bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
498 }
499 }
500 if len(deps.classpath.Strings()) > 0 {
501 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
502 }
503
504 implicits = append(implicits, j.srcJars...)
505
506 opts := "-J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
507
508 ctx.Build(pctx, android.BuildParams{
509 Rule: javadoc,
510 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800511 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800512 ImplicitOutput: j.docZip,
513 Inputs: j.srcFiles,
514 Implicits: implicits,
515 Args: map[string]string{
516 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
517 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
518 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
519 "srcJars": strings.Join(j.srcJars.Strings(), " "),
520 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700521 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800522 "classpathArgs": classpathArgs,
523 "sourcepath": strings.Join(j.sourcepaths.Strings(), ":"),
524 "docZip": j.docZip.String(),
525 },
526 })
527}
528
Nan Zhang61819ce2018-05-04 18:49:16 -0700529func (d *Droiddoc) checkCurrentApi() bool {
530 if String(d.properties.Check_api.Current.Api_file) != "" &&
531 String(d.properties.Check_api.Current.Removed_api_file) != "" {
532 return true
533 } else if String(d.properties.Check_api.Current.Api_file) != "" {
534 panic("check_api.current.removed_api_file: has to be non empty!")
535 } else if String(d.properties.Check_api.Current.Removed_api_file) != "" {
536 panic("check_api.current.api_file: has to be non empty!")
537 }
538
539 return false
540}
541
542func (d *Droiddoc) checkLastReleasedApi() bool {
543 if String(d.properties.Check_api.Last_released.Api_file) != "" &&
544 String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
545 return true
546 } else if String(d.properties.Check_api.Last_released.Api_file) != "" {
547 panic("check_api.last_released.removed_api_file: has to be non empty!")
548 } else if String(d.properties.Check_api.Last_released.Removed_api_file) != "" {
549 panic("check_api.last_released.api_file: has to be non empty!")
550 }
551
552 return false
553}
554
Nan Zhang581fd212018-01-10 16:06:12 -0800555func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
556 d.Javadoc.addDeps(ctx)
557
Dan Willemsencc090972018-02-26 14:33:31 -0800558 if String(d.properties.Custom_template) == "" {
559 // TODO: This is almost always droiddoc-templates-sdk
560 ctx.PropertyErrorf("custom_template", "must specify a template")
561 } else {
562 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
563 }
564
Nan Zhang581fd212018-01-10 16:06:12 -0800565 // extra_arg_files may contains filegroup or genrule.
566 android.ExtractSourcesDeps(ctx, d.properties.Arg_files)
567
568 // knowntags may contain filegroup or genrule.
569 android.ExtractSourcesDeps(ctx, d.properties.Knowntags)
Nan Zhang61819ce2018-05-04 18:49:16 -0700570
571 if d.checkCurrentApi() {
572 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Api_file)
573 android.ExtractSourceDeps(ctx, d.properties.Check_api.Current.Removed_api_file)
574 }
575
576 if d.checkLastReleasedApi() {
577 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Api_file)
578 android.ExtractSourceDeps(ctx, d.properties.Check_api.Last_released.Removed_api_file)
579 }
Nan Zhang581fd212018-01-10 16:06:12 -0800580}
581
582func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
583 deps := d.Javadoc.collectDeps(ctx)
584
585 var implicits android.Paths
586 implicits = append(implicits, deps.bootClasspath...)
587 implicits = append(implicits, deps.classpath...)
588
589 argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
590 argFilesMap := map[string]android.Path{}
591
592 for _, f := range argFiles {
593 implicits = append(implicits, f)
594 if _, exists := argFilesMap[f.Rel()]; !exists {
595 argFilesMap[f.Rel()] = f
596 } else {
597 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
598 f, argFilesMap[f.Rel()], f.Rel())
599 }
600 }
601
602 args, err := android.Expand(String(d.properties.Args), func(name string) (string, error) {
603 if strings.HasPrefix(name, "location ") {
604 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
605 if f, ok := argFilesMap[label]; ok {
606 return f.String(), nil
607 } else {
608 return "", fmt.Errorf("unknown location label %q", label)
609 }
610 } else if name == "genDir" {
611 return android.PathForModuleGen(ctx).String(), nil
612 }
613 return "", fmt.Errorf("unknown variable '$(%s)'", name)
614 })
615
616 if err != nil {
617 ctx.PropertyErrorf("extra_args", "%s", err.Error())
618 return
619 }
620
621 var bootClasspathArgs, classpathArgs string
622 if len(deps.bootClasspath.Strings()) > 0 {
623 bootClasspathArgs = "-bootclasspath " + strings.Join(deps.bootClasspath.Strings(), ":")
624 }
625 if len(deps.classpath.Strings()) > 0 {
626 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
627 }
628
Dan Willemsencc090972018-02-26 14:33:31 -0800629 var templateDir string
630 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
631 if t, ok := m.(*DroiddocTemplate); ok {
632 implicits = append(implicits, t.deps...)
633 templateDir = t.dir.String()
634 } else {
635 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
636 }
637 })
Nan Zhang581fd212018-01-10 16:06:12 -0800638
639 var htmlDirArgs string
640 if len(d.properties.Html_dirs) > 0 {
Dan Willemsencc090972018-02-26 14:33:31 -0800641 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
642 implicits = append(implicits, ctx.Glob(htmlDir.Join(ctx, "**/*").String(), nil)...)
643 htmlDirArgs = "-htmldir " + htmlDir.String()
Nan Zhang581fd212018-01-10 16:06:12 -0800644 }
645
646 var htmlDir2Args string
647 if len(d.properties.Html_dirs) > 1 {
Dan Willemsencc090972018-02-26 14:33:31 -0800648 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
649 implicits = append(implicits, ctx.Glob(htmlDir2.Join(ctx, "**/*").String(), nil)...)
650 htmlDir2Args = "-htmldir2 " + htmlDir2.String()
651 }
652
653 if len(d.properties.Html_dirs) > 2 {
654 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
Nan Zhang581fd212018-01-10 16:06:12 -0800655 }
656
657 knownTags := ctx.ExpandSources(d.properties.Knowntags, nil)
658 implicits = append(implicits, knownTags...)
659
660 for _, kt := range knownTags {
661 args = args + " -knowntags " + kt.String()
662 }
663 for _, hdf := range d.properties.Hdf {
664 args = args + " -hdf " + hdf
665 }
666
667 if String(d.properties.Proofread_file) != "" {
668 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
669 args = args + " -proofread " + proofreadFile.String()
670 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800671
Nan Zhang581fd212018-01-10 16:06:12 -0800672 if String(d.properties.Todo_file) != "" {
673 // tricky part:
674 // we should not compute full path for todo_file through PathForModuleOut().
675 // the non-standard doclet will get the full path relative to "-o".
676 args = args + " -todo " + String(d.properties.Todo_file)
677 }
678
Nan Zhangb2b33de2018-02-23 11:18:47 -0800679 if String(d.properties.Resourcesdir) != "" {
680 // TODO: should we add files under resourcesDir to the implicits? It seems that
681 // resourcesDir is one sub dir of htmlDir
682 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
683 args = args + " -resourcesdir " + resourcesDir.String()
684 }
685
686 if String(d.properties.Resourcesoutdir) != "" {
687 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
688 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
689 }
690
Nan Zhang28c68b92018-03-13 16:17:01 -0700691 var implicitOutputs android.WritablePaths
Nan Zhang61819ce2018-05-04 18:49:16 -0700692
693 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Api_filename) != "" {
694 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
Nan Zhang28c68b92018-03-13 16:17:01 -0700695 args = args + " -api " + d.apiFile.String()
696 implicitOutputs = append(implicitOutputs, d.apiFile)
697 }
698
Nan Zhang61819ce2018-05-04 18:49:16 -0700699 if d.checkCurrentApi() || d.checkLastReleasedApi() || String(d.properties.Removed_api_filename) != "" {
700 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
701 args = args + " -removedApi " + d.removedApiFile.String()
702 implicitOutputs = append(implicitOutputs, d.removedApiFile)
703 }
704
Nan Zhang28c68b92018-03-13 16:17:01 -0700705 if String(d.properties.Private_api_filename) != "" {
706 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
707 args = args + " -privateApi " + d.privateApiFile.String()
708 implicitOutputs = append(implicitOutputs, d.privateApiFile)
709 }
710
711 if String(d.properties.Private_dex_api_filename) != "" {
712 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
713 args = args + " -privateDexApi " + d.privateDexApiFile.String()
714 implicitOutputs = append(implicitOutputs, d.privateDexApiFile)
715 }
716
David Brazdilaac0c3c2018-04-24 16:23:29 +0100717 if String(d.properties.Removed_dex_api_filename) != "" {
718 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
719 args = args + " -removedDexApi " + d.removedDexApiFile.String()
720 implicitOutputs = append(implicitOutputs, d.removedDexApiFile)
721 }
722
Nan Zhang28c68b92018-03-13 16:17:01 -0700723 if String(d.properties.Exact_api_filename) != "" {
724 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
725 args = args + " -exactApi " + d.exactApiFile.String()
726 implicitOutputs = append(implicitOutputs, d.exactApiFile)
727 }
728
Nan Zhang581fd212018-01-10 16:06:12 -0800729 implicits = append(implicits, d.Javadoc.srcJars...)
730
Nan Zhang30963742018-04-23 09:59:14 -0700731 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
732 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
733 implicits = append(implicits, jsilver)
734 implicits = append(implicits, doclava)
735
Nan Zhang581fd212018-01-10 16:06:12 -0800736 opts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700737 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross480cd762018-02-22 14:39:17 -0800738 "-templatedir " + templateDir + " " + htmlDirArgs + " " + htmlDir2Args + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800739 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang853f4202018-04-12 16:55:56 -0700740 "-hdf page.now " + `"$$(date -d @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")"` +
741 " " + args
742 if BoolDefault(d.properties.Create_stubs, true) {
743 opts += " -stubs " + android.PathForModuleOut(ctx, "docs", "stubsDir").String()
744 }
Nan Zhang581fd212018-01-10 16:06:12 -0800745
Nan Zhang581fd212018-01-10 16:06:12 -0800746 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
747 for _, o := range d.properties.Out {
748 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
749 }
750
751 ctx.Build(pctx, android.BuildParams{
752 Rule: javadoc,
753 Description: "Droiddoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800754 Output: d.Javadoc.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800755 Inputs: d.Javadoc.srcFiles,
756 Implicits: implicits,
757 ImplicitOutputs: implicitOutputs,
758 Args: map[string]string{
759 "outDir": android.PathForModuleOut(ctx, "docs", "out").String(),
760 "srcJarDir": android.PathForModuleOut(ctx, "docs", "srcjars").String(),
761 "stubsDir": android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
762 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
763 "opts": opts,
764 "bootclasspathArgs": bootClasspathArgs,
765 "classpathArgs": classpathArgs,
766 "sourcepath": strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
767 "docZip": d.Javadoc.docZip.String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800768 },
769 })
Nan Zhang61819ce2018-05-04 18:49:16 -0700770
771 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
772
773 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
774
775 if d.checkCurrentApi() && !ctx.Config().IsPdkBuild() {
776 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
777
778 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
779 "check_api.current.api_file")
780 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
781 "check_api.current_removed_api_file")
782
783 ctx.Build(pctx, android.BuildParams{
784 Rule: apiCheck,
785 Description: "Current API check",
786 Output: d.checkCurrentApiTimestamp,
787 Inputs: nil,
788 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
789 checkApiClasspath...),
790 Args: map[string]string{
791 "classpath": checkApiClasspath.FormJavaClassPath(""),
792 "opts": String(d.properties.Check_api.Current.Args),
793 "apiFile": apiFile.String(),
794 "apiFileToCheck": d.apiFile.String(),
795 "removedApiFile": removedApiFile.String(),
796 "removedApiFileToCheck": d.removedApiFile.String(),
797 "msg": fmt.Sprintf(`\n******************************\n`+
798 `You have tried to change the API from what has been previously approved.\n\n`+
799 `To make these errors go away, you have two choices:\n`+
800 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
801 ` errors above.\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900802 ` 2. You can update current.txt by executing the following command:\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -0700803 ` make %s-update-current-api\n\n`+
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900804 ` To submit the revised current.txt to the main Android repository,\n`+
Nan Zhang61819ce2018-05-04 18:49:16 -0700805 ` you will need approval.\n`+
806 `******************************\n`, ctx.ModuleName()),
807 },
808 })
809
810 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
811
812 ctx.Build(pctx, android.BuildParams{
813 Rule: updateApi,
814 Description: "update current API",
815 Output: d.updateCurrentApiTimestamp,
816 Implicits: append(android.Paths{}, apiFile, removedApiFile, d.apiFile, d.removedApiFile),
817 Args: map[string]string{
818 "apiFile": apiFile.String(),
819 "apiFileToCheck": d.apiFile.String(),
820 "removedApiFile": removedApiFile.String(),
821 "removedApiFileToCheck": d.removedApiFile.String(),
822 },
823 })
824 }
825
826 if d.checkLastReleasedApi() && !ctx.Config().IsPdkBuild() {
827 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
828
829 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
830 "check_api.last_released.api_file")
831 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
832 "check_api.last_released.removed_api_file")
833
834 ctx.Build(pctx, android.BuildParams{
835 Rule: apiCheck,
836 Description: "Last Released API check",
837 Output: d.checkLastReleasedApiTimestamp,
838 Inputs: nil,
839 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
840 checkApiClasspath...),
841 Args: map[string]string{
842 "classpath": checkApiClasspath.FormJavaClassPath(""),
843 "opts": String(d.properties.Check_api.Last_released.Args),
844 "apiFile": apiFile.String(),
845 "apiFileToCheck": d.apiFile.String(),
846 "removedApiFile": removedApiFile.String(),
847 "removedApiFileToCheck": d.removedApiFile.String(),
848 "msg": `\n******************************\n` +
849 `You have tried to change the API from what has been previously released in\n` +
850 `an SDK. Please fix the errors listed above.\n` +
851 `******************************\n`,
852 },
853 })
854 }
Nan Zhang581fd212018-01-10 16:06:12 -0800855}
Dan Willemsencc090972018-02-26 14:33:31 -0800856
857var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
858
859type DroiddocTemplateProperties struct {
860 // path to the directory containing the droiddoc templates.
861 Path *string
862}
863
864type DroiddocTemplate struct {
865 android.ModuleBase
866
867 properties DroiddocTemplateProperties
868
869 deps android.Paths
870 dir android.Path
871}
872
873func DroiddocTemplateFactory() android.Module {
874 module := &DroiddocTemplate{}
875 module.AddProperties(&module.properties)
876 android.InitAndroidModule(module)
877 return module
878}
879
880func (d *DroiddocTemplate) DepsMutator(android.BottomUpMutatorContext) {}
881
882func (d *DroiddocTemplate) GenerateAndroidBuildActions(ctx android.ModuleContext) {
883 path := android.PathForModuleSrc(ctx, String(d.properties.Path))
884 d.dir = path
885 d.deps = ctx.Glob(path.Join(ctx, "**/*").String(), nil)
886}
Nan Zhangb2b33de2018-02-23 11:18:47 -0800887
888//
889// Defaults
890//
891type DocDefaults struct {
892 android.ModuleBase
893 android.DefaultsModuleBase
894}
895
896func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
897}
898
899func (d *DocDefaults) DepsMutator(ctx android.BottomUpMutatorContext) {
900}
901
902func DocDefaultsFactory() android.Module {
903 module := &DocDefaults{}
904
905 module.AddProperties(
906 &JavadocProperties{},
907 &DroiddocProperties{},
908 )
909
910 android.InitDefaultsModule(module)
911
912 return module
913}