blob: a7e92d9ef9d465825027131704f7ef8da8a109a5 [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Nan Zhang581fd212018-01-10 16:06:12 -080018 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080019 "path/filepath"
Nan Zhang581fd212018-01-10 16:06:12 -080020 "strings"
21
Jeongik Cha6bd33c12019-06-25 16:26:18 +090022 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080023
Colin Crossab054432019-07-15 16:13:59 -070024 "android/soong/android"
25 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080026)
27
28func init() {
Paul Duffin884363e2019-12-19 10:21:09 +000029 RegisterDocsBuildComponents(android.InitRegistrationContext)
Nan Zhang581fd212018-01-10 16:06:12 -080030}
31
Paul Duffin884363e2019-12-19 10:21:09 +000032func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
33 ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
34
35 ctx.RegisterModuleType("droiddoc", DroiddocFactory)
36 ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
37 ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
38 ctx.RegisterModuleType("javadoc", JavadocFactory)
39 ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
40}
41
Nan Zhang581fd212018-01-10 16:06:12 -080042type JavadocProperties struct {
43 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
44 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080045 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080046
Nan Zhang581fd212018-01-10 16:06:12 -080047 // list of source files that should not be used to build the Java module.
48 // This is most useful in the arch/multilib variants to remove non-common files
49 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080050 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080051
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090052 // list of package names that should actually be used. If this property is left unspecified,
53 // all the sources from the srcs property is used.
54 Filter_packages []string
55
Nan Zhangb2b33de2018-02-23 11:18:47 -080056 // list of java libraries that will be in the classpath.
Cole Faustb7493472024-08-28 11:55:52 -070057 Libs proptools.Configurable[[]string] `android:"arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080058
59 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080060 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080061
Paul Duffine25c6442019-10-11 13:50:28 +010062 // if not blank, set to the version of the sdk to compile against.
63 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080064 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090065
Paul Duffine25c6442019-10-11 13:50:28 +010066 // When targeting 1.9 and above, override the modules to use with --system,
67 // otherwise provides defaults libraries to add to the bootclasspath.
68 // Defaults to "none"
69 System_modules *string
70
Jiyong Park1e440682018-05-23 18:42:04 +090071 Aidl struct {
72 // Top level directories to pass to aidl tool
73 Include_dirs []string
74
75 // Directories rooted at the Android.bp file to pass to aidl tool
76 Local_include_dirs []string
77 }
Nan Zhang357466b2018-04-17 17:38:36 -070078
79 // If not blank, set the java version passed to javadoc as -source
80 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070081
82 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080083 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070084
Liz Kammer585cac22020-07-06 09:12:57 -070085 // user customized droiddoc args. Deprecated, use flags instead.
Nan Zhang1598a9e2018-09-04 17:14:32 -070086 // Available variables for substitution:
87 //
88 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070089 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070090 Args *string
91
Liz Kammer585cac22020-07-06 09:12:57 -070092 // user customized droiddoc args. Not compatible with property args.
93 // Available variables for substitution:
94 //
95 // $(location <label>): the path to the arg_files with name <label>
96 // $$: a literal $
97 Flags []string
98
Nan Zhang1598a9e2018-09-04 17:14:32 -070099 // names of the output files used in args that will be generated
100 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800101}
102
Nan Zhang61819ce2018-05-04 18:49:16 -0700103type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900104 // path to the API txt file that the new API extracted from source code is checked
105 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800106 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700107
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900108 // path to the API txt file that the new @removed API extractd from source code is
109 // checked against. The path can be local to the module or from other module (via
110 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800111 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700112
Adrian Roos14f75a92019-08-12 17:54:09 +0200113 // If not blank, path to the baseline txt file for approved API check violations.
114 Baseline_file *string `android:"path"`
115
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900116 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700117 Args *string
118}
119
Nan Zhang581fd212018-01-10 16:06:12 -0800120type DroiddocProperties struct {
121 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800122 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800123
Nan Zhanga40da042018-08-01 12:48:00 -0700124 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800125 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800126
127 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800128 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800129
130 // proofread file contains all of the text content of the javadocs concatenated into one file,
131 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700132 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800133
134 // a todo file lists the program elements that are missing documentation.
135 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800136 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800137
Anton Hanssonb06bb572023-10-03 12:11:35 +0000138 // A file containing a baseline for allowed lint errors.
139 Lint_baseline *string `android:"path"`
140
Nan Zhangb2b33de2018-02-23 11:18:47 -0800141 // directory under current module source that provide additional resources (images).
142 Resourcesdir *string
143
144 // resources output directory under out/soong/.intermediates.
145 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800146
Nan Zhange2ba5d42018-07-11 15:16:55 -0700147 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800148 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700149
150 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800151 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700152
Nan Zhang581fd212018-01-10 16:06:12 -0800153 // a list of files under current module source dir which contains known tags in Java sources.
154 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800155 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700156
Nan Zhang1598a9e2018-09-04 17:14:32 -0700157 // if set to true, generate docs through Dokka instead of Doclava.
158 Dokka_enabled *bool
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000159
160 // Compat config XML. Generates compat change documentation if set.
161 Compat_config *string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700162}
163
Nan Zhanga40da042018-08-01 12:48:00 -0700164// Common flags passed down to build rule
Nan Zhanga40da042018-08-01 12:48:00 -0700165type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700166 bootClasspathArgs string
167 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700168 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700169 dokkaClasspathArgs string
170 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700171 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700172
Nan Zhanga40da042018-08-01 12:48:00 -0700173 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700174 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700175 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700176}
177
178func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
179 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
180 android.InitDefaultableModule(module)
181}
182
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200183func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
184 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
Jihoon Kang91bf3dd2024-01-24 00:40:23 +0000185 if ctx.Config().BuildFromTextStub() {
186 ctx.ModuleErrorf("Generating stubs from api signature files is not available " +
187 "with WITHOUT_CHECK_API=true, as sync between the source Java files and the " +
188 "api signature files is not guaranteed.\n" +
189 "In order to utilize WITHOUT_CHECK_API, generate stubs from the source Java " +
190 "files with BUILD_FROM_SOURCE_STUB=true.\n" +
191 "However, the usage of WITHOUT_CHECK_API is not preferred as the incremental " +
192 "build is slower when generating stubs from the source Java files.\n" +
193 "Consider updating the api signature files and generating the stubs from " +
194 "them instead.")
195 }
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200196 return false
197 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700198 return true
199 } else if String(apiToCheck.Api_file) != "" {
200 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
201 } else if String(apiToCheck.Removed_api_file) != "" {
202 panic("for " + apiVersionTag + " api_file has to be non-empty!")
203 }
204
205 return false
206}
207
Nan Zhanga40da042018-08-01 12:48:00 -0700208// Javadoc
Nan Zhang581fd212018-01-10 16:06:12 -0800209type Javadoc struct {
210 android.ModuleBase
211 android.DefaultableModuleBase
212
213 properties JavadocProperties
214
215 srcJars android.Paths
216 srcFiles android.Paths
217 sourcepaths android.Paths
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400218 implicits android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700219
Nan Zhangccff0f72018-03-08 17:26:16 -0800220 docZip android.WritablePath
221 stubsSrcJar android.WritablePath
Jihoon Kang3c89f042023-12-19 02:40:22 +0000222
223 exportableStubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800224}
225
Colin Crossa3002fc2019-07-08 16:48:04 -0700226// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800227func JavadocFactory() android.Module {
228 module := &Javadoc{}
229
230 module.AddProperties(&module.properties)
231
232 InitDroiddocModule(module, android.HostAndDeviceSupported)
233 return module
234}
235
Colin Crossa3002fc2019-07-08 16:48:04 -0700236// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800237func JavadocHostFactory() android.Module {
238 module := &Javadoc{}
239
240 module.AddProperties(&module.properties)
241
242 InitDroiddocModule(module, android.HostSupported)
243 return module
244}
245
Jiyong Park92315372021-04-02 08:45:46 +0900246func (j *Javadoc) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
247 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700248}
249
Jiyong Parkf1691d22021-03-29 20:11:58 +0900250func (j *Javadoc) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +0100251 return proptools.String(j.properties.System_modules)
252}
253
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000254func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
255 return j.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -0700256}
257
Spandan Dasa26eda72023-03-02 00:56:06 +0000258func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
259 return j.SdkVersion(ctx).ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000260}
261
Spandan Dasca70fc42023-03-01 23:38:49 +0000262func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
263 return j.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -0700264}
265
Nan Zhang581fd212018-01-10 16:06:12 -0800266func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
267 if ctx.Device() {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900268 sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
Pete Gilline3d44b22020-06-29 11:28:51 +0100269 if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700270 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100271 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700272 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Liz Kammeref28a4c2022-09-23 16:50:56 -0400273 ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800274 }
275 }
276
Cole Faustb7493472024-08-28 11:55:52 -0700277 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs.GetOrDefault(ctx, nil)...)
Nan Zhang581fd212018-01-10 16:06:12 -0800278}
279
Nan Zhanga40da042018-08-01 12:48:00 -0700280func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
281 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900282
Colin Cross3047fa22019-04-18 10:56:44 -0700283 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900284
285 return flags
286}
287
288func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700289 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900290
291 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
292 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
293
294 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700295 var deps android.Paths
296
Jiyong Park1e440682018-05-23 18:42:04 +0900297 if aidlPreprocess.Valid() {
298 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700299 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900300 } else {
301 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
302 }
303
304 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
Colin Crossf96b0012023-10-26 14:01:51 -0700305 flags = append(flags, "-I"+ctx.ModuleDir())
Jiyong Park1e440682018-05-23 18:42:04 +0900306 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
307 flags = append(flags, "-I"+src.String())
308 }
309
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000310 minSdkVersion := j.MinSdkVersion(ctx).FinalOrFutureInt()
Spandan Das757b6662022-11-17 04:29:59 +0000311 flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion))
312
Colin Cross3047fa22019-04-18 10:56:44 -0700313 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900314}
315
Jiyong Parkd90d7412019-08-20 22:49:19 +0900316// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900317func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700318 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900319
320 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700321 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900322
Sam Delmerico2351eac2022-05-24 17:10:02 +0000323 aidlIncludeFlags := genAidlIncludeFlags(ctx, srcFiles, android.Paths{})
Jiyong Park1112c4c2019-08-16 21:12:10 +0900324
Jiyong Park1e440682018-05-23 18:42:04 +0900325 for _, srcFile := range srcFiles {
326 switch srcFile.Ext() {
327 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700328 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900329 case ".logtags":
330 javaFile := genLogtags(ctx, srcFile)
331 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900332 default:
333 outSrcFiles = append(outSrcFiles, srcFile)
334 }
335 }
336
Colin Crossc0806172019-06-14 18:51:47 -0700337 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
338 if len(aidlSrcs) > 0 {
Thiébaud Weksteende8417c2022-02-10 15:41:46 +1100339 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
Colin Crossc0806172019-06-14 18:51:47 -0700340 outSrcFiles = append(outSrcFiles, srcJarFiles...)
341 }
342
Jiyong Park1e440682018-05-23 18:42:04 +0900343 return outSrcFiles
344}
345
Nan Zhang581fd212018-01-10 16:06:12 -0800346func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
347 var deps deps
348
Jiyong Parkf1691d22021-03-29 20:11:58 +0900349 sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800350 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700351 ctx.AddMissingDependencies(sdkDep.bootclasspath)
352 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800353 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700354 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Anton Hansson26bf49b2020-02-08 20:26:29 +0000355 deps.aidlPreprocess = sdkDep.aidl
356 } else {
357 deps.aidlPreprocess = sdkDep.aidl
Nan Zhang581fd212018-01-10 16:06:12 -0800358 }
359
360 ctx.VisitDirectDeps(func(module android.Module) {
361 otherName := ctx.OtherModuleName(module)
362 tag := ctx.OtherModuleDependencyTag(module)
363
Colin Cross2d24c1b2018-05-23 10:59:18 -0700364 switch tag {
365 case bootClasspathTag:
Colin Cross313aa542023-12-13 13:47:44 -0800366 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
Colin Crossdcf71b22021-02-01 13:59:03 -0800367 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
Colin Crossb61c2262024-08-08 14:04:42 -0700368 } else if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
Paul Duffine25c6442019-10-11 13:50:28 +0100369 // A system modules dependency has been added to the bootclasspath
370 // so add its libs to the bootclasspath.
Colin Crossb61c2262024-08-08 14:04:42 -0700371 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700372 } else {
373 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
374 }
Liz Kammeref28a4c2022-09-23 16:50:56 -0400375 case libTag, sdkLibTag:
Jihoon Kangc4db1092024-09-18 23:10:55 +0000376 if _, ok := module.(SdkLibraryDependency); ok {
377 sdkInfo, _ := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider)
378 generatingLibsString := android.PrettyConcat(
379 getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or")
380 ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString)
Colin Cross313aa542023-12-13 13:47:44 -0800381 } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
Colin Crossdcf71b22021-02-01 13:59:03 -0800382 deps.classpath = append(deps.classpath, dep.HeaderJars...)
383 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
Jihoon Kang3921f0b2024-03-12 23:51:37 +0000384 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
Colin Crossdcf71b22021-02-01 13:59:03 -0800385 } else if dep, ok := module.(android.SourceFileProducer); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800386 checkProducesJars(ctx, dep)
387 deps.classpath = append(deps.classpath, dep.Srcs()...)
Colin Crossdcf71b22021-02-01 13:59:03 -0800388 } else {
Nan Zhang581fd212018-01-10 16:06:12 -0800389 ctx.ModuleErrorf("depends on non-java module %q", otherName)
390 }
Jihoon Kang3921f0b2024-03-12 23:51:37 +0000391
Colin Cross6cef4812019-10-17 14:23:50 -0700392 case java9LibTag:
Colin Cross313aa542023-12-13 13:47:44 -0800393 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
Colin Crossdcf71b22021-02-01 13:59:03 -0800394 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
395 } else {
Colin Cross6cef4812019-10-17 14:23:50 -0700396 ctx.ModuleErrorf("depends on non-java module %q", otherName)
397 }
Nan Zhang357466b2018-04-17 17:38:36 -0700398 case systemModulesTag:
399 if deps.systemModules != nil {
400 panic("Found two system module dependencies")
401 }
Colin Crossb61c2262024-08-08 14:04:42 -0700402 if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
403 deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps}
404 } else {
405 ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
406 ctx.OtherModuleName(module))
407 }
Jihoon Kang6592e872023-12-19 01:13:16 +0000408 case aconfigDeclarationTag:
409 if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigDeclarationsProviderKey); ok {
410 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPath)
Yu Liu67a28422024-03-05 00:36:31 +0000411 } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
Jihoon Kang38e4f252024-02-13 20:49:47 +0000412 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
Jihoon Kang6592e872023-12-19 01:13:16 +0000413 } else {
Jihoon Kang38e4f252024-02-13 20:49:47 +0000414 ctx.ModuleErrorf("Only aconfig_declarations and aconfig_declarations_group "+
415 "module type is allowed for flags_packages property, but %s is neither "+
416 "of these supported module types",
Jihoon Kang6592e872023-12-19 01:13:16 +0000417 module.Name(),
418 )
419 }
Nan Zhang581fd212018-01-10 16:06:12 -0800420 }
421 })
422 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
423 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800424 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400425 j.implicits = append(j.implicits, srcFiles...)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900426
Jihoon Kang3921f0b2024-03-12 23:51:37 +0000427 // Module can depend on a java_aconfig_library module using the ":module_name{.tag}" syntax.
428 // Find the corresponding aconfig_declarations module name for such case.
429 for _, src := range j.properties.Srcs {
430 if moduleName, tag := android.SrcIsModuleWithTag(src); moduleName != "" {
431 otherModule := android.GetModuleFromPathDep(ctx, moduleName, tag)
432 if otherModule != nil {
433 if dep, ok := android.OtherModuleProvider(ctx, otherModule, android.CodegenInfoProvider); ok {
434 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...)
435 }
436 }
437 }
438 }
439
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900440 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
441 if filterPackages == nil {
442 return srcs
443 }
444 filtered := []android.Path{}
445 for _, src := range srcs {
446 if src.Ext() != ".java" {
447 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
448 // but otherwise metalava emits stub sources having references to the generated AIDL classes
449 // in filtered-out pacages (e.g. com.android.internal.*).
450 // TODO(b/141149570) We need to fix this by introducing default private constructors or
451 // fixing metalava to not emit constructors having references to unknown classes.
452 filtered = append(filtered, src)
453 continue
454 }
455 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800456 if android.HasAnyPrefix(packageName, filterPackages) {
457 filtered = append(filtered, src)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900458 }
459 }
460 return filtered
461 }
462 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
463
Liz Kammer585cac22020-07-06 09:12:57 -0700464 aidlFlags := j.collectAidlFlags(ctx, deps)
465 srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
Nan Zhang581fd212018-01-10 16:06:12 -0800466
467 // srcs may depend on some genrule output.
468 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800469 j.srcJars = append(j.srcJars, deps.srcJars...)
470
Nan Zhang581fd212018-01-10 16:06:12 -0800471 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800472 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800473
Liz Kammere1ab2502020-09-10 15:29:25 +0000474 if len(j.srcFiles) > 0 {
475 j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
Nan Zhang581fd212018-01-10 16:06:12 -0800476 }
Nan Zhang581fd212018-01-10 16:06:12 -0800477
Colin Crossbc139922021-03-25 18:33:16 -0700478 return deps
479}
480
481func (j *Javadoc) expandArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
482 var argFiles android.Paths
Paul Duffin99e4a502019-02-11 15:38:42 +0000483 argFilesMap := map[string]string{}
484 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700485
Paul Duffin99e4a502019-02-11 15:38:42 +0000486 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800487 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000488 if _, exists := argFilesMap[label]; !exists {
Colin Crossbc139922021-03-25 18:33:16 -0700489 argFilesMap[label] = strings.Join(cmd.PathsForInputs(paths), " ")
Paul Duffin99e4a502019-02-11 15:38:42 +0000490 argFileLabels = append(argFileLabels, label)
Colin Crossbc139922021-03-25 18:33:16 -0700491 argFiles = append(argFiles, paths...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700492 } else {
493 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000494 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700495 }
496 }
497
Liz Kammer585cac22020-07-06 09:12:57 -0700498 var argsPropertyName string
499 flags := make([]string, 0)
500 if j.properties.Args != nil && j.properties.Flags != nil {
501 ctx.PropertyErrorf("args", "flags is set. Cannot set args")
502 } else if args := proptools.String(j.properties.Args); args != "" {
503 flags = append(flags, args)
504 argsPropertyName = "args"
505 } else {
506 flags = append(flags, j.properties.Flags...)
507 argsPropertyName = "flags"
508 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700509
Liz Kammer585cac22020-07-06 09:12:57 -0700510 for _, flag := range flags {
Colin Crossbc139922021-03-25 18:33:16 -0700511 expanded, err := android.Expand(flag, func(name string) (string, error) {
Liz Kammer585cac22020-07-06 09:12:57 -0700512 if strings.HasPrefix(name, "location ") {
513 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
514 if paths, ok := argFilesMap[label]; ok {
515 return paths, nil
516 } else {
517 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
518 label, strings.Join(argFileLabels, ", "))
519 }
520 } else if name == "genDir" {
521 return android.PathForModuleGen(ctx).String(), nil
522 }
523 return "", fmt.Errorf("unknown variable '$(%s)'", name)
524 })
525
526 if err != nil {
527 ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
528 }
Colin Crossbc139922021-03-25 18:33:16 -0700529 cmd.Flag(expanded)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700530 }
531
Colin Crossbc139922021-03-25 18:33:16 -0700532 cmd.Implicits(argFiles)
Nan Zhang581fd212018-01-10 16:06:12 -0800533}
534
535func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
536 j.addDeps(ctx)
537}
538
539func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
540 deps := j.collectDeps(ctx)
541
Colin Crossdaa4c672019-07-15 22:53:46 -0700542 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800543
Colin Crossdaa4c672019-07-15 22:53:46 -0700544 outDir := android.PathForModuleOut(ctx, "out")
545 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
546
547 j.stubsSrcJar = nil
548
Colin Crossf1a035e2020-11-16 17:32:30 -0800549 rule := android.NewRuleBuilder(pctx, ctx)
Colin Crossdaa4c672019-07-15 22:53:46 -0700550
551 rule.Command().Text("rm -rf").Text(outDir.String())
552 rule.Command().Text("mkdir -p").Text(outDir.String())
553
554 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700555
Jiyong Parkf1691d22021-03-29 20:11:58 +0900556 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800557
Colin Crossdaa4c672019-07-15 22:53:46 -0700558 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
559 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800560
Colin Cross1e743852019-10-28 11:37:20 -0700561 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700562 Flag("-J-Xmx1024m").
563 Flag("-XDignore.symbol.file").
564 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800565
Colin Crossbc139922021-03-25 18:33:16 -0700566 j.expandArgs(ctx, cmd)
567
Colin Crossdaa4c672019-07-15 22:53:46 -0700568 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800569 BuiltTool("soong_zip").
Colin Crossdaa4c672019-07-15 22:53:46 -0700570 Flag("-write_if_changed").
571 Flag("-d").
572 FlagWithOutput("-o ", j.docZip).
573 FlagWithArg("-C ", outDir.String()).
574 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700575
Colin Crossdaa4c672019-07-15 22:53:46 -0700576 rule.Restat()
577
578 zipSyncCleanupCmd(rule, srcJarDir)
579
Colin Crossf1a035e2020-11-16 17:32:30 -0800580 rule.Build("javadoc", "javadoc")
mrziwang74e50212024-06-27 10:14:24 -0700581
582 ctx.SetOutputFiles(android.Paths{j.stubsSrcJar}, "")
583 ctx.SetOutputFiles(android.Paths{j.docZip}, ".docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800584}
585
Nan Zhanga40da042018-08-01 12:48:00 -0700586// Droiddoc
Nan Zhanga40da042018-08-01 12:48:00 -0700587type Droiddoc struct {
588 Javadoc
589
Liz Kammere1ab2502020-09-10 15:29:25 +0000590 properties DroiddocProperties
Nan Zhanga40da042018-08-01 12:48:00 -0700591}
592
Colin Crossa3002fc2019-07-08 16:48:04 -0700593// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700594func DroiddocFactory() android.Module {
595 module := &Droiddoc{}
596
597 module.AddProperties(&module.properties,
598 &module.Javadoc.properties)
599
600 InitDroiddocModule(module, android.HostAndDeviceSupported)
601 return module
602}
603
Colin Crossa3002fc2019-07-08 16:48:04 -0700604// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700605func DroiddocHostFactory() android.Module {
606 module := &Droiddoc{}
607
608 module.AddProperties(&module.properties,
609 &module.Javadoc.properties)
610
611 InitDroiddocModule(module, android.HostSupported)
612 return module
613}
614
Nan Zhang581fd212018-01-10 16:06:12 -0800615func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
616 d.Javadoc.addDeps(ctx)
617
Nan Zhang79614d12018-04-19 18:03:39 -0700618 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800619 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
620 }
Nan Zhang581fd212018-01-10 16:06:12 -0800621}
622
Colin Crossab054432019-07-15 16:13:59 -0700623func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Colin Cross2a2e0db2020-02-21 16:55:46 -0800624 buildNumberFile := ctx.Config().BuildNumberFile(ctx)
Nan Zhang443fa522018-08-20 20:58:28 -0700625 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
626 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
627 // 1.9 language features.
Jihoon Kangff878bf2022-12-22 21:26:06 +0000628 cmd.FlagWithArg("-source ", getStubsJavaVersion().String()).
Colin Crossab054432019-07-15 16:13:59 -0700629 Flag("-J-Xmx1600m").
630 Flag("-J-XX:-OmitStackTraceInFastThrow").
631 Flag("-XDignore.symbol.file").
Sorin Bascad528d562022-10-24 15:10:25 +0100632 Flag("--ignore-source-errors").
Sorin Bascaae995ae2023-03-01 08:47:42 +0000633 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
Colin Crossab054432019-07-15 16:13:59 -0700634 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
Sorin Bascaae995ae2023-03-01 08:47:42 +0000635 FlagWithArg("-Xmaxerrs ", "10").
636 FlagWithArg("-Xmaxwarns ", "10").
Sorin Bascad528d562022-10-24 15:10:25 +0100637 Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED").
Sorin Bascaa7b777f2023-06-09 09:19:36 +0000638 Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED").
639 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED").
640 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED").
641 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED").
642 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED").
Sorin Bascad528d562022-10-24 15:10:25 +0100643 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED").
Colin Cross2a2e0db2020-02-21 16:55:46 -0800644 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
Elliott Hughes26bce342019-09-12 15:05:13 -0700645 FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
Nan Zhang46130972018-06-04 11:28:01 -0700646
Nan Zhanga40da042018-08-01 12:48:00 -0700647 if String(d.properties.Custom_template) == "" {
648 // TODO: This is almost always droiddoc-templates-sdk
649 ctx.PropertyErrorf("custom_template", "must specify a template")
650 }
651
652 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700653 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700654 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700655 } else {
Paul Duffin884363e2019-12-19 10:21:09 +0000656 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
Nan Zhanga40da042018-08-01 12:48:00 -0700657 }
658 })
659
660 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700661 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
662 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
663 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700664 }
665
666 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700667 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
668 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
669 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700670 }
671
672 if len(d.properties.Html_dirs) > 2 {
673 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
674 }
675
Colin Cross8a497952019-03-05 22:25:09 -0800676 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700677 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700678
Colin Crossab054432019-07-15 16:13:59 -0700679 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700680
681 if String(d.properties.Proofread_file) != "" {
682 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700683 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700684 }
685
686 if String(d.properties.Todo_file) != "" {
687 // tricky part:
688 // we should not compute full path for todo_file through PathForModuleOut().
689 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700690 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
691 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700692 }
693
Anton Hanssonb06bb572023-10-03 12:11:35 +0000694 if String(d.properties.Lint_baseline) != "" {
695 cmd.FlagWithInput("-lintbaseline ", android.PathForModuleSrc(ctx, String(d.properties.Lint_baseline)))
696 }
697
Nan Zhanga40da042018-08-01 12:48:00 -0700698 if String(d.properties.Resourcesdir) != "" {
699 // TODO: should we add files under resourcesDir to the implicits? It seems that
700 // resourcesDir is one sub dir of htmlDir
701 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700702 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700703 }
704
705 if String(d.properties.Resourcesoutdir) != "" {
706 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700707 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700708 }
Nan Zhanga40da042018-08-01 12:48:00 -0700709}
710
Colin Crossab054432019-07-15 16:13:59 -0700711func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700712 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700713 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
714 rule.Command().Text("cp").
715 Input(staticDocIndexRedirect).
716 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700717 }
718
719 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700720 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
721 rule.Command().Text("cp").
722 Input(staticDocProperties).
723 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700724 }
Nan Zhanga40da042018-08-01 12:48:00 -0700725}
726
Colin Crossab054432019-07-15 16:13:59 -0700727func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700728 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700729
730 cmd := rule.Command().
Sorin Bascad528d562022-10-24 15:10:25 +0100731 BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
Colin Crossab054432019-07-15 16:13:59 -0700732 Flag(config.JavacVmFlags).
Colin Cross70c47412021-03-12 17:48:14 -0800733 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
Colin Crossab054432019-07-15 16:13:59 -0700734 FlagWithInput("@", srcJarList)
735
Colin Crossab054432019-07-15 16:13:59 -0700736 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
737 // based stubs generation.
738 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
739 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
740 // the correct package name base path.
741 if len(sourcepaths) > 0 {
742 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
743 } else {
744 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
745 }
746
747 cmd.FlagWithArg("-d ", outDir.String()).
748 Flag("-quiet")
749
750 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700751}
752
Colin Crossdaa4c672019-07-15 22:53:46 -0700753func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
754 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
755 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
756
757 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
758
759 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
760 cmd.Flag(flag).Implicits(deps)
761
762 cmd.FlagWithArg("--patch-module ", "java.base=.")
763
764 if len(classpath) > 0 {
765 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
766 }
767
768 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700769}
770
Colin Crossdaa4c672019-07-15 22:53:46 -0700771func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
772 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
773 sourcepaths android.Paths) *android.RuleBuilderCommand {
774
775 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
776
777 if len(bootclasspath) == 0 && ctx.Device() {
778 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
779 // ensure java does not fall back to the default bootclasspath.
780 cmd.FlagWithArg("-bootclasspath ", `""`)
781 } else if len(bootclasspath) > 0 {
782 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
783 }
784
785 if len(classpath) > 0 {
786 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
787 }
788
789 return cmd
790}
791
Colin Crossab054432019-07-15 16:13:59 -0700792func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
793 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700794
Colin Crossab054432019-07-15 16:13:59 -0700795 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
796 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
797
798 return rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800799 BuiltTool("dokka").
Colin Crossab054432019-07-15 16:13:59 -0700800 Flag(config.JavacVmFlags).
Sorin Basca1d68e482022-09-08 16:48:01 +0100801 Flag("-J--add-opens=java.base/java.lang=ALL-UNNAMED").
Colin Crossab054432019-07-15 16:13:59 -0700802 Flag(srcJarDir.String()).
803 FlagWithInputList("-classpath ", dokkaClasspath, ":").
804 FlagWithArg("-format ", "dac").
805 FlagWithArg("-dacRoot ", "/reference/kotlin").
806 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700807}
808
809func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
810 deps := d.Javadoc.collectDeps(ctx)
811
Colin Crossdaa4c672019-07-15 22:53:46 -0700812 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Colin Crossdaa4c672019-07-15 22:53:46 -0700813
Colin Crossae5330a2021-11-03 13:31:22 -0700814 jsilver := ctx.Config().HostJavaToolPath(ctx, "jsilver.jar")
815 doclava := ctx.Config().HostJavaToolPath(ctx, "doclava.jar")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700816
Colin Crossab054432019-07-15 16:13:59 -0700817 outDir := android.PathForModuleOut(ctx, "out")
818 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700819
Colin Crossf1a035e2020-11-16 17:32:30 -0800820 rule := android.NewRuleBuilder(pctx, ctx)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700821
Colin Crossab054432019-07-15 16:13:59 -0700822 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
823
824 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700825 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700826 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700827 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700828 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700829 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700830 }
831
Colin Crossbc139922021-03-25 18:33:16 -0700832 d.expandArgs(ctx, cmd)
Colin Crossab054432019-07-15 16:13:59 -0700833
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000834 if d.properties.Compat_config != nil {
835 compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
836 cmd.FlagWithInput("-compatconfig ", compatConfig)
837 }
838
Colin Crossab054432019-07-15 16:13:59 -0700839 var desc string
840 if Bool(d.properties.Dokka_enabled) {
841 desc = "dokka"
842 } else {
Sorin Bascaae995ae2023-03-01 08:47:42 +0000843 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
Colin Crossab054432019-07-15 16:13:59 -0700844
845 for _, o := range d.Javadoc.properties.Out {
846 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
847 }
848
849 d.postDoclavaCmds(ctx, rule)
850 desc = "doclava"
851 }
852
853 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800854 BuiltTool("soong_zip").
Colin Crossab054432019-07-15 16:13:59 -0700855 Flag("-write_if_changed").
856 Flag("-d").
857 FlagWithOutput("-o ", d.docZip).
858 FlagWithArg("-C ", outDir.String()).
859 FlagWithArg("-D ", outDir.String())
860
Sorin Bascaae995ae2023-03-01 08:47:42 +0000861 rule.Restat()
Colin Crossab054432019-07-15 16:13:59 -0700862
Sorin Bascaae995ae2023-03-01 08:47:42 +0000863 zipSyncCleanupCmd(rule, srcJarDir)
Colin Crossab054432019-07-15 16:13:59 -0700864
Colin Crossf1a035e2020-11-16 17:32:30 -0800865 rule.Build("javadoc", desc)
mrziwang74e50212024-06-27 10:14:24 -0700866
867 ctx.SetOutputFiles(android.Paths{d.Javadoc.docZip}, "")
868 ctx.SetOutputFiles(android.Paths{d.Javadoc.docZip}, ".docs.zip")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700869}
870
Nan Zhangf4936b02018-08-01 15:00:28 -0700871// Exported Droiddoc Directory
Dan Willemsencc090972018-02-26 14:33:31 -0800872var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
873
Nan Zhangf4936b02018-08-01 15:00:28 -0700874type ExportedDroiddocDirProperties struct {
875 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -0800876 Path *string
877}
878
Nan Zhangf4936b02018-08-01 15:00:28 -0700879type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -0800880 android.ModuleBase
881
Nan Zhangf4936b02018-08-01 15:00:28 -0700882 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -0800883
884 deps android.Paths
885 dir android.Path
886}
887
Colin Crossa3002fc2019-07-08 16:48:04 -0700888// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -0700889func ExportedDroiddocDirFactory() android.Module {
890 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -0800891 module.AddProperties(&module.properties)
892 android.InitAndroidModule(module)
893 return module
894}
895
Nan Zhangf4936b02018-08-01 15:00:28 -0700896func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -0800897
Nan Zhangf4936b02018-08-01 15:00:28 -0700898func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -0800899 path := String(d.properties.Path)
900 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -0800901 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -0800902}
Nan Zhangb2b33de2018-02-23 11:18:47 -0800903
Nan Zhangb2b33de2018-02-23 11:18:47 -0800904// Defaults
Nan Zhangb2b33de2018-02-23 11:18:47 -0800905type DocDefaults struct {
906 android.ModuleBase
907 android.DefaultsModuleBase
908}
909
Nan Zhangb2b33de2018-02-23 11:18:47 -0800910func DocDefaultsFactory() android.Module {
911 module := &DocDefaults{}
912
913 module.AddProperties(
914 &JavadocProperties{},
915 &DroiddocProperties{},
916 )
917
918 android.InitDefaultsModule(module)
919
920 return module
921}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700922
Colin Cross33961b52019-07-11 11:01:22 -0700923func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
924 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
925
Colin Cross1661aff2021-03-12 17:56:51 -0800926 cmd := rule.Command()
927 cmd.Text("rm -rf").Text(cmd.PathForOutput(srcJarDir))
928 cmd = rule.Command()
929 cmd.Text("mkdir -p").Text(cmd.PathForOutput(srcJarDir))
Colin Cross33961b52019-07-11 11:01:22 -0700930 srcJarList := srcJarDir.Join(ctx, "list")
931
932 rule.Temporary(srcJarList)
933
Colin Cross1661aff2021-03-12 17:56:51 -0800934 cmd = rule.Command()
935 cmd.BuiltTool("zipsync").
936 FlagWithArg("-d ", cmd.PathForOutput(srcJarDir)).
Colin Cross33961b52019-07-11 11:01:22 -0700937 FlagWithOutput("-l ", srcJarList).
938 FlagWithArg("-f ", `"*.java"`).
939 Inputs(srcJars)
940
941 return srcJarList
942}
943
944func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
945 rule.Command().Text("rm -rf").Text(srcJarDir.String())
946}