blob: d5547d05cf204e8e96d2c6fdb94f7b93fc646bce [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"
usta72c6c6c2023-08-30 17:18:01 -040025 "android/soong/bazel"
Colin Crossab054432019-07-15 16:13:59 -070026 "android/soong/java/config"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29func init() {
Paul Duffin884363e2019-12-19 10:21:09 +000030 RegisterDocsBuildComponents(android.InitRegistrationContext)
Nan Zhang581fd212018-01-10 16:06:12 -080031}
32
Paul Duffin884363e2019-12-19 10:21:09 +000033func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
34 ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
35
36 ctx.RegisterModuleType("droiddoc", DroiddocFactory)
37 ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
38 ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
39 ctx.RegisterModuleType("javadoc", JavadocFactory)
40 ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
41}
42
Nan Zhang581fd212018-01-10 16:06:12 -080043type JavadocProperties struct {
44 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
45 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -080046 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080047
Nan Zhang581fd212018-01-10 16:06:12 -080048 // list of source files that should not be used to build the Java module.
49 // This is most useful in the arch/multilib variants to remove non-common files
50 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -080051 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -080052
Jiyong Parkc6ddccf2019-09-13 20:56:14 +090053 // list of package names that should actually be used. If this property is left unspecified,
54 // all the sources from the srcs property is used.
55 Filter_packages []string
56
Nan Zhangb2b33de2018-02-23 11:18:47 -080057 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -080058 Libs []string `android:"arch_variant"`
59
60 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -080061 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -080062
Paul Duffine25c6442019-10-11 13:50:28 +010063 // if not blank, set to the version of the sdk to compile against.
64 // Defaults to compiling against the current platform.
Nan Zhang581fd212018-01-10 16:06:12 -080065 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +090066
Paul Duffine25c6442019-10-11 13:50:28 +010067 // When targeting 1.9 and above, override the modules to use with --system,
68 // otherwise provides defaults libraries to add to the bootclasspath.
69 // Defaults to "none"
70 System_modules *string
71
Jiyong Park1e440682018-05-23 18:42:04 +090072 Aidl struct {
73 // Top level directories to pass to aidl tool
74 Include_dirs []string
75
76 // Directories rooted at the Android.bp file to pass to aidl tool
77 Local_include_dirs []string
78 }
Nan Zhang357466b2018-04-17 17:38:36 -070079
80 // If not blank, set the java version passed to javadoc as -source
81 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -070082
83 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -080084 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -070085
Liz Kammer585cac22020-07-06 09:12:57 -070086 // user customized droiddoc args. Deprecated, use flags instead.
Nan Zhang1598a9e2018-09-04 17:14:32 -070087 // Available variables for substitution:
88 //
89 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -070090 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -070091 Args *string
92
Liz Kammer585cac22020-07-06 09:12:57 -070093 // user customized droiddoc args. Not compatible with property args.
94 // Available variables for substitution:
95 //
96 // $(location <label>): the path to the arg_files with name <label>
97 // $$: a literal $
98 Flags []string
99
Nan Zhang1598a9e2018-09-04 17:14:32 -0700100 // names of the output files used in args that will be generated
101 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800102}
103
Nan Zhang61819ce2018-05-04 18:49:16 -0700104type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900105 // path to the API txt file that the new API extracted from source code is checked
106 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800107 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700108
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900109 // path to the API txt file that the new @removed API extractd from source code is
110 // checked against. The path can be local to the module or from other module (via
111 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800112 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700113
Adrian Roos14f75a92019-08-12 17:54:09 +0200114 // If not blank, path to the baseline txt file for approved API check violations.
115 Baseline_file *string `android:"path"`
116
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900117 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700118 Args *string
119}
120
Nan Zhang581fd212018-01-10 16:06:12 -0800121type DroiddocProperties struct {
122 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800123 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800124
Nan Zhanga40da042018-08-01 12:48:00 -0700125 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800126 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800127
128 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800129 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800130
131 // proofread file contains all of the text content of the javadocs concatenated into one file,
132 // suitable for spell-checking and other goodness.
Colin Crossab054432019-07-15 16:13:59 -0700133 Proofread_file *string
Nan Zhang581fd212018-01-10 16:06:12 -0800134
135 // a todo file lists the program elements that are missing documentation.
136 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800137 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800138
139 // directory under current module source that provide additional resources (images).
140 Resourcesdir *string
141
142 // resources output directory under out/soong/.intermediates.
143 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800144
Nan Zhange2ba5d42018-07-11 15:16:55 -0700145 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800146 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700147
148 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800149 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700150
Nan Zhang581fd212018-01-10 16:06:12 -0800151 // a list of files under current module source dir which contains known tags in Java sources.
152 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800153 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700154
Nan Zhang1598a9e2018-09-04 17:14:32 -0700155 // if set to true, generate docs through Dokka instead of Doclava.
156 Dokka_enabled *bool
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000157
158 // Compat config XML. Generates compat change documentation if set.
159 Compat_config *string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700160}
161
Nan Zhanga40da042018-08-01 12:48:00 -0700162// Common flags passed down to build rule
Nan Zhanga40da042018-08-01 12:48:00 -0700163type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700164 bootClasspathArgs string
165 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700166 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700167 dokkaClasspathArgs string
168 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700169 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700170
Nan Zhanga40da042018-08-01 12:48:00 -0700171 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700172 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700173 postDoclavaCmds string
Nan Zhanga40da042018-08-01 12:48:00 -0700174}
175
176func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
177 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
178 android.InitDefaultableModule(module)
179}
180
Luca Stefanid63ea0a2019-09-01 21:49:45 +0200181func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
182 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
183 return false
184 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700185 return true
186 } else if String(apiToCheck.Api_file) != "" {
187 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
188 } else if String(apiToCheck.Removed_api_file) != "" {
189 panic("for " + apiVersionTag + " api_file has to be non-empty!")
190 }
191
192 return false
193}
194
Nan Zhanga40da042018-08-01 12:48:00 -0700195// Javadoc
Nan Zhang581fd212018-01-10 16:06:12 -0800196type Javadoc struct {
197 android.ModuleBase
198 android.DefaultableModuleBase
199
200 properties JavadocProperties
201
202 srcJars android.Paths
203 srcFiles android.Paths
204 sourcepaths android.Paths
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400205 implicits android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206
Nan Zhangccff0f72018-03-08 17:26:16 -0800207 docZip android.WritablePath
208 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800209}
210
Colin Cross41955e82019-05-29 14:40:35 -0700211func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
212 switch tag {
213 case "":
214 return android.Paths{j.stubsSrcJar}, nil
Colin Crosse68e5542019-08-12 13:11:40 -0700215 case ".docs.zip":
216 return android.Paths{j.docZip}, nil
Colin Cross41955e82019-05-29 14:40:35 -0700217 default:
218 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
219 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800220}
221
Colin Crossa3002fc2019-07-08 16:48:04 -0700222// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800223func JavadocFactory() android.Module {
224 module := &Javadoc{}
225
226 module.AddProperties(&module.properties)
227
228 InitDroiddocModule(module, android.HostAndDeviceSupported)
229 return module
230}
231
Colin Crossa3002fc2019-07-08 16:48:04 -0700232// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800233func JavadocHostFactory() android.Module {
234 module := &Javadoc{}
235
236 module.AddProperties(&module.properties)
237
238 InitDroiddocModule(module, android.HostSupported)
239 return module
240}
241
Colin Cross41955e82019-05-29 14:40:35 -0700242var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800243
Jiyong Park92315372021-04-02 08:45:46 +0900244func (j *Javadoc) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
245 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
Colin Cross83bb3162018-06-25 15:48:06 -0700246}
247
Jiyong Parkf1691d22021-03-29 20:11:58 +0900248func (j *Javadoc) SystemModules() string {
Paul Duffine25c6442019-10-11 13:50:28 +0100249 return proptools.String(j.properties.System_modules)
250}
251
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000252func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
253 return j.SdkVersion(ctx).ApiLevel
Colin Cross83bb3162018-06-25 15:48:06 -0700254}
255
Spandan Dasa26eda72023-03-02 00:56:06 +0000256func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel {
257 return j.SdkVersion(ctx).ApiLevel
William Loh5a082f92022-05-17 20:21:50 +0000258}
259
Spandan Dasca70fc42023-03-01 23:38:49 +0000260func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
261 return j.SdkVersion(ctx).ApiLevel
Dan Willemsen419290a2018-10-31 15:28:47 -0700262}
263
Nan Zhang581fd212018-01-10 16:06:12 -0800264func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
265 if ctx.Device() {
Jiyong Parkf1691d22021-03-29 20:11:58 +0900266 sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
Pete Gilline3d44b22020-06-29 11:28:51 +0100267 if sdkDep.useModule {
Colin Cross6cef4812019-10-17 14:23:50 -0700268 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
Paul Duffine25c6442019-10-11 13:50:28 +0100269 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
Colin Cross6cef4812019-10-17 14:23:50 -0700270 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
Liz Kammeref28a4c2022-09-23 16:50:56 -0400271 ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800272 }
273 }
274
Colin Cross42d48b72018-08-29 14:10:52 -0700275 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800276}
277
Nan Zhanga40da042018-08-01 12:48:00 -0700278func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
279 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900280
Colin Cross3047fa22019-04-18 10:56:44 -0700281 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900282
283 return flags
284}
285
286func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700287 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900288
289 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
290 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
291
292 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700293 var deps android.Paths
294
Jiyong Park1e440682018-05-23 18:42:04 +0900295 if aidlPreprocess.Valid() {
296 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700297 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900298 } else {
299 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
300 }
301
302 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
303 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
304 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
305 flags = append(flags, "-I"+src.String())
306 }
307
Spandan Das8c9ae7e2023-03-03 21:20:36 +0000308 minSdkVersion := j.MinSdkVersion(ctx).FinalOrFutureInt()
Spandan Das757b6662022-11-17 04:29:59 +0000309 flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion))
310
Colin Cross3047fa22019-04-18 10:56:44 -0700311 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900312}
313
Jiyong Parkd90d7412019-08-20 22:49:19 +0900314// TODO: remove the duplication between this and the one in gen.go
Jiyong Park1e440682018-05-23 18:42:04 +0900315func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700316 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900317
318 outSrcFiles := make(android.Paths, 0, len(srcFiles))
Colin Crossc0806172019-06-14 18:51:47 -0700319 var aidlSrcs android.Paths
Jiyong Park1e440682018-05-23 18:42:04 +0900320
Sam Delmerico2351eac2022-05-24 17:10:02 +0000321 aidlIncludeFlags := genAidlIncludeFlags(ctx, srcFiles, android.Paths{})
Jiyong Park1112c4c2019-08-16 21:12:10 +0900322
Jiyong Park1e440682018-05-23 18:42:04 +0900323 for _, srcFile := range srcFiles {
324 switch srcFile.Ext() {
325 case ".aidl":
Colin Crossc0806172019-06-14 18:51:47 -0700326 aidlSrcs = append(aidlSrcs, srcFile)
Jiyong Parkd90d7412019-08-20 22:49:19 +0900327 case ".logtags":
328 javaFile := genLogtags(ctx, srcFile)
329 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900330 default:
331 outSrcFiles = append(outSrcFiles, srcFile)
332 }
333 }
334
Colin Crossc0806172019-06-14 18:51:47 -0700335 // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
336 if len(aidlSrcs) > 0 {
Thiébaud Weksteende8417c2022-02-10 15:41:46 +1100337 srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
Colin Crossc0806172019-06-14 18:51:47 -0700338 outSrcFiles = append(outSrcFiles, srcJarFiles...)
339 }
340
Jiyong Park1e440682018-05-23 18:42:04 +0900341 return outSrcFiles
342}
343
Nan Zhang581fd212018-01-10 16:06:12 -0800344func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
345 var deps deps
346
Jiyong Parkf1691d22021-03-29 20:11:58 +0900347 sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800348 if sdkDep.invalidVersion {
Colin Cross6cef4812019-10-17 14:23:50 -0700349 ctx.AddMissingDependencies(sdkDep.bootclasspath)
350 ctx.AddMissingDependencies(sdkDep.java9Classpath)
Nan Zhang581fd212018-01-10 16:06:12 -0800351 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700352 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Anton Hansson26bf49b2020-02-08 20:26:29 +0000353 deps.aidlPreprocess = sdkDep.aidl
354 } else {
355 deps.aidlPreprocess = sdkDep.aidl
Nan Zhang581fd212018-01-10 16:06:12 -0800356 }
357
358 ctx.VisitDirectDeps(func(module android.Module) {
359 otherName := ctx.OtherModuleName(module)
360 tag := ctx.OtherModuleDependencyTag(module)
361
Colin Cross2d24c1b2018-05-23 10:59:18 -0700362 switch tag {
363 case bootClasspathTag:
Colin Crossdcf71b22021-02-01 13:59:03 -0800364 if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
365 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
366 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
Paul Duffin83a2d962019-11-19 19:44:10 +0000367 } else if sm, ok := module.(SystemModulesProvider); ok {
Paul Duffine25c6442019-10-11 13:50:28 +0100368 // A system modules dependency has been added to the bootclasspath
369 // so add its libs to the bootclasspath.
Paul Duffin83a2d962019-11-19 19:44:10 +0000370 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700371 } else {
372 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
373 }
Liz Kammeref28a4c2022-09-23 16:50:56 -0400374 case libTag, sdkLibTag:
Colin Crossdcf71b22021-02-01 13:59:03 -0800375 if dep, ok := module.(SdkLibraryDependency); ok {
Jiyong Park92315372021-04-02 08:45:46 +0900376 deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
Colin Crossdcf71b22021-02-01 13:59:03 -0800377 } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
378 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
379 deps.classpath = append(deps.classpath, dep.HeaderJars...)
380 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
381 } else if dep, ok := module.(android.SourceFileProducer); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800382 checkProducesJars(ctx, dep)
383 deps.classpath = append(deps.classpath, dep.Srcs()...)
Colin Crossdcf71b22021-02-01 13:59:03 -0800384 } else {
Nan Zhang581fd212018-01-10 16:06:12 -0800385 ctx.ModuleErrorf("depends on non-java module %q", otherName)
386 }
Colin Cross6cef4812019-10-17 14:23:50 -0700387 case java9LibTag:
Colin Crossdcf71b22021-02-01 13:59:03 -0800388 if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
389 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
390 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
391 } else {
Colin Cross6cef4812019-10-17 14:23:50 -0700392 ctx.ModuleErrorf("depends on non-java module %q", otherName)
393 }
Nan Zhang357466b2018-04-17 17:38:36 -0700394 case systemModulesTag:
395 if deps.systemModules != nil {
396 panic("Found two system module dependencies")
397 }
Paul Duffin83a2d962019-11-19 19:44:10 +0000398 sm := module.(SystemModulesProvider)
399 outputDir, outputDeps := sm.OutputDirAndDeps()
400 deps.systemModules = &systemModules{outputDir, outputDeps}
Nan Zhang581fd212018-01-10 16:06:12 -0800401 }
402 })
403 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
404 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800405 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Ramy Medhatc7965cd2020-04-30 03:08:37 -0400406 j.implicits = append(j.implicits, srcFiles...)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900407
408 filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
409 if filterPackages == nil {
410 return srcs
411 }
412 filtered := []android.Path{}
413 for _, src := range srcs {
414 if src.Ext() != ".java" {
415 // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
416 // but otherwise metalava emits stub sources having references to the generated AIDL classes
417 // in filtered-out pacages (e.g. com.android.internal.*).
418 // TODO(b/141149570) We need to fix this by introducing default private constructors or
419 // fixing metalava to not emit constructors having references to unknown classes.
420 filtered = append(filtered, src)
421 continue
422 }
423 packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
Jaewoong Jung3aff5782020-02-11 07:54:35 -0800424 if android.HasAnyPrefix(packageName, filterPackages) {
425 filtered = append(filtered, src)
Jiyong Parkc6ddccf2019-09-13 20:56:14 +0900426 }
427 }
428 return filtered
429 }
430 srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
431
Liz Kammer585cac22020-07-06 09:12:57 -0700432 aidlFlags := j.collectAidlFlags(ctx, deps)
433 srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
Nan Zhang581fd212018-01-10 16:06:12 -0800434
435 // srcs may depend on some genrule output.
436 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800437 j.srcJars = append(j.srcJars, deps.srcJars...)
438
Nan Zhang581fd212018-01-10 16:06:12 -0800439 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800440 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800441
Liz Kammere1ab2502020-09-10 15:29:25 +0000442 if len(j.srcFiles) > 0 {
443 j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
Nan Zhang581fd212018-01-10 16:06:12 -0800444 }
Nan Zhang581fd212018-01-10 16:06:12 -0800445
Colin Crossbc139922021-03-25 18:33:16 -0700446 return deps
447}
448
449func (j *Javadoc) expandArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
450 var argFiles android.Paths
Paul Duffin99e4a502019-02-11 15:38:42 +0000451 argFilesMap := map[string]string{}
452 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700453
Paul Duffin99e4a502019-02-11 15:38:42 +0000454 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800455 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000456 if _, exists := argFilesMap[label]; !exists {
Colin Crossbc139922021-03-25 18:33:16 -0700457 argFilesMap[label] = strings.Join(cmd.PathsForInputs(paths), " ")
Paul Duffin99e4a502019-02-11 15:38:42 +0000458 argFileLabels = append(argFileLabels, label)
Colin Crossbc139922021-03-25 18:33:16 -0700459 argFiles = append(argFiles, paths...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700460 } else {
461 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000462 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700463 }
464 }
465
Liz Kammer585cac22020-07-06 09:12:57 -0700466 var argsPropertyName string
467 flags := make([]string, 0)
468 if j.properties.Args != nil && j.properties.Flags != nil {
469 ctx.PropertyErrorf("args", "flags is set. Cannot set args")
470 } else if args := proptools.String(j.properties.Args); args != "" {
471 flags = append(flags, args)
472 argsPropertyName = "args"
473 } else {
474 flags = append(flags, j.properties.Flags...)
475 argsPropertyName = "flags"
476 }
Nan Zhang1598a9e2018-09-04 17:14:32 -0700477
Liz Kammer585cac22020-07-06 09:12:57 -0700478 for _, flag := range flags {
Colin Crossbc139922021-03-25 18:33:16 -0700479 expanded, err := android.Expand(flag, func(name string) (string, error) {
Liz Kammer585cac22020-07-06 09:12:57 -0700480 if strings.HasPrefix(name, "location ") {
481 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
482 if paths, ok := argFilesMap[label]; ok {
483 return paths, nil
484 } else {
485 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
486 label, strings.Join(argFileLabels, ", "))
487 }
488 } else if name == "genDir" {
489 return android.PathForModuleGen(ctx).String(), nil
490 }
491 return "", fmt.Errorf("unknown variable '$(%s)'", name)
492 })
493
494 if err != nil {
495 ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
496 }
Colin Crossbc139922021-03-25 18:33:16 -0700497 cmd.Flag(expanded)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700498 }
499
Colin Crossbc139922021-03-25 18:33:16 -0700500 cmd.Implicits(argFiles)
Nan Zhang581fd212018-01-10 16:06:12 -0800501}
502
503func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
504 j.addDeps(ctx)
505}
506
507func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
508 deps := j.collectDeps(ctx)
509
Colin Crossdaa4c672019-07-15 22:53:46 -0700510 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhang581fd212018-01-10 16:06:12 -0800511
Colin Crossdaa4c672019-07-15 22:53:46 -0700512 outDir := android.PathForModuleOut(ctx, "out")
513 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
514
515 j.stubsSrcJar = nil
516
Colin Crossf1a035e2020-11-16 17:32:30 -0800517 rule := android.NewRuleBuilder(pctx, ctx)
Colin Crossdaa4c672019-07-15 22:53:46 -0700518
519 rule.Command().Text("rm -rf").Text(outDir.String())
520 rule.Command().Text("mkdir -p").Text(outDir.String())
521
522 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
Nan Zhang357466b2018-04-17 17:38:36 -0700523
Jiyong Parkf1691d22021-03-29 20:11:58 +0900524 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800525
Colin Crossdaa4c672019-07-15 22:53:46 -0700526 cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
527 deps.systemModules, deps.classpath, j.sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800528
Colin Cross1e743852019-10-28 11:37:20 -0700529 cmd.FlagWithArg("-source ", javaVersion.String()).
Colin Crossdaa4c672019-07-15 22:53:46 -0700530 Flag("-J-Xmx1024m").
531 Flag("-XDignore.symbol.file").
532 Flag("-Xdoclint:none")
Nan Zhang581fd212018-01-10 16:06:12 -0800533
Colin Crossbc139922021-03-25 18:33:16 -0700534 j.expandArgs(ctx, cmd)
535
Colin Crossdaa4c672019-07-15 22:53:46 -0700536 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800537 BuiltTool("soong_zip").
Colin Crossdaa4c672019-07-15 22:53:46 -0700538 Flag("-write_if_changed").
539 Flag("-d").
540 FlagWithOutput("-o ", j.docZip).
541 FlagWithArg("-C ", outDir.String()).
542 FlagWithArg("-D ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700543
Colin Crossdaa4c672019-07-15 22:53:46 -0700544 rule.Restat()
545
546 zipSyncCleanupCmd(rule, srcJarDir)
547
Colin Crossf1a035e2020-11-16 17:32:30 -0800548 rule.Build("javadoc", "javadoc")
Nan Zhang581fd212018-01-10 16:06:12 -0800549}
550
Nan Zhanga40da042018-08-01 12:48:00 -0700551// Droiddoc
Nan Zhanga40da042018-08-01 12:48:00 -0700552type Droiddoc struct {
553 Javadoc
554
Liz Kammere1ab2502020-09-10 15:29:25 +0000555 properties DroiddocProperties
Nan Zhanga40da042018-08-01 12:48:00 -0700556}
557
Colin Crossa3002fc2019-07-08 16:48:04 -0700558// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700559func DroiddocFactory() android.Module {
560 module := &Droiddoc{}
561
562 module.AddProperties(&module.properties,
563 &module.Javadoc.properties)
564
565 InitDroiddocModule(module, android.HostAndDeviceSupported)
566 return module
567}
568
Colin Crossa3002fc2019-07-08 16:48:04 -0700569// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700570func DroiddocHostFactory() android.Module {
571 module := &Droiddoc{}
572
573 module.AddProperties(&module.properties,
574 &module.Javadoc.properties)
575
576 InitDroiddocModule(module, android.HostSupported)
577 return module
578}
579
Liz Kammere1ab2502020-09-10 15:29:25 +0000580func (d *Droiddoc) OutputFiles(tag string) (android.Paths, error) {
581 switch tag {
582 case "", ".docs.zip":
583 return android.Paths{d.Javadoc.docZip}, nil
584 default:
585 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
586 }
Nan Zhanga40da042018-08-01 12:48:00 -0700587}
588
Nan Zhang581fd212018-01-10 16:06:12 -0800589func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
590 d.Javadoc.addDeps(ctx)
591
Nan Zhang79614d12018-04-19 18:03:39 -0700592 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800593 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
594 }
Nan Zhang581fd212018-01-10 16:06:12 -0800595}
596
Colin Crossab054432019-07-15 16:13:59 -0700597func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
Colin Cross2a2e0db2020-02-21 16:55:46 -0800598 buildNumberFile := ctx.Config().BuildNumberFile(ctx)
Nan Zhang443fa522018-08-20 20:58:28 -0700599 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
600 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
601 // 1.9 language features.
Jihoon Kangff878bf2022-12-22 21:26:06 +0000602 cmd.FlagWithArg("-source ", getStubsJavaVersion().String()).
Colin Crossab054432019-07-15 16:13:59 -0700603 Flag("-J-Xmx1600m").
604 Flag("-J-XX:-OmitStackTraceInFastThrow").
605 Flag("-XDignore.symbol.file").
Sorin Bascad528d562022-10-24 15:10:25 +0100606 Flag("--ignore-source-errors").
Sorin Bascaae995ae2023-03-01 08:47:42 +0000607 FlagWithArg("-doclet ", "com.google.doclava.Doclava").
Colin Crossab054432019-07-15 16:13:59 -0700608 FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
Sorin Bascaae995ae2023-03-01 08:47:42 +0000609 FlagWithArg("-Xmaxerrs ", "10").
610 FlagWithArg("-Xmaxwarns ", "10").
Sorin Bascad528d562022-10-24 15:10:25 +0100611 Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED").
Sorin Bascaa7b777f2023-06-09 09:19:36 +0000612 Flag("-J--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED").
613 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED").
614 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED").
615 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED").
616 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED").
Sorin Bascad528d562022-10-24 15:10:25 +0100617 Flag("-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED").
Colin Cross2a2e0db2020-02-21 16:55:46 -0800618 FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
Elliott Hughes26bce342019-09-12 15:05:13 -0700619 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 -0700620
Nan Zhanga40da042018-08-01 12:48:00 -0700621 if String(d.properties.Custom_template) == "" {
622 // TODO: This is almost always droiddoc-templates-sdk
623 ctx.PropertyErrorf("custom_template", "must specify a template")
624 }
625
626 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700627 if t, ok := m.(*ExportedDroiddocDir); ok {
Colin Crossab054432019-07-15 16:13:59 -0700628 cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
Nan Zhanga40da042018-08-01 12:48:00 -0700629 } else {
Paul Duffin884363e2019-12-19 10:21:09 +0000630 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
Nan Zhanga40da042018-08-01 12:48:00 -0700631 }
632 })
633
634 if len(d.properties.Html_dirs) > 0 {
Colin Crossab054432019-07-15 16:13:59 -0700635 htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
636 cmd.FlagWithArg("-htmldir ", htmlDir.String()).
637 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700638 }
639
640 if len(d.properties.Html_dirs) > 1 {
Colin Crossab054432019-07-15 16:13:59 -0700641 htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
642 cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
643 Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
Nan Zhanga40da042018-08-01 12:48:00 -0700644 }
645
646 if len(d.properties.Html_dirs) > 2 {
647 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
648 }
649
Colin Cross8a497952019-03-05 22:25:09 -0800650 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Colin Crossab054432019-07-15 16:13:59 -0700651 cmd.FlagForEachInput("-knowntags ", knownTags)
Nan Zhanga40da042018-08-01 12:48:00 -0700652
Colin Crossab054432019-07-15 16:13:59 -0700653 cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
Nan Zhanga40da042018-08-01 12:48:00 -0700654
655 if String(d.properties.Proofread_file) != "" {
656 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
Colin Crossab054432019-07-15 16:13:59 -0700657 cmd.FlagWithOutput("-proofread ", proofreadFile)
Nan Zhanga40da042018-08-01 12:48:00 -0700658 }
659
660 if String(d.properties.Todo_file) != "" {
661 // tricky part:
662 // we should not compute full path for todo_file through PathForModuleOut().
663 // the non-standard doclet will get the full path relative to "-o".
Colin Crossab054432019-07-15 16:13:59 -0700664 cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
665 ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
Nan Zhanga40da042018-08-01 12:48:00 -0700666 }
667
668 if String(d.properties.Resourcesdir) != "" {
669 // TODO: should we add files under resourcesDir to the implicits? It seems that
670 // resourcesDir is one sub dir of htmlDir
671 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
Colin Crossab054432019-07-15 16:13:59 -0700672 cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
Nan Zhanga40da042018-08-01 12:48:00 -0700673 }
674
675 if String(d.properties.Resourcesoutdir) != "" {
676 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
Colin Crossab054432019-07-15 16:13:59 -0700677 cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
Nan Zhanga40da042018-08-01 12:48:00 -0700678 }
Nan Zhanga40da042018-08-01 12:48:00 -0700679}
680
Colin Crossab054432019-07-15 16:13:59 -0700681func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
Nan Zhanga40da042018-08-01 12:48:00 -0700682 if String(d.properties.Static_doc_index_redirect) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700683 staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
684 rule.Command().Text("cp").
685 Input(staticDocIndexRedirect).
686 Output(android.PathForModuleOut(ctx, "out", "index.html"))
Nan Zhanga40da042018-08-01 12:48:00 -0700687 }
688
689 if String(d.properties.Static_doc_properties) != "" {
Colin Crossab054432019-07-15 16:13:59 -0700690 staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
691 rule.Command().Text("cp").
692 Input(staticDocProperties).
693 Output(android.PathForModuleOut(ctx, "out", "source.properties"))
Nan Zhanga40da042018-08-01 12:48:00 -0700694 }
Nan Zhanga40da042018-08-01 12:48:00 -0700695}
696
Colin Crossab054432019-07-15 16:13:59 -0700697func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
Colin Crossdaa4c672019-07-15 22:53:46 -0700698 outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
Colin Crossab054432019-07-15 16:13:59 -0700699
700 cmd := rule.Command().
Sorin Bascad528d562022-10-24 15:10:25 +0100701 BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
Colin Crossab054432019-07-15 16:13:59 -0700702 Flag(config.JavacVmFlags).
Colin Cross70c47412021-03-12 17:48:14 -0800703 FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
Colin Crossab054432019-07-15 16:13:59 -0700704 FlagWithInput("@", srcJarList)
705
Colin Crossab054432019-07-15 16:13:59 -0700706 // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
707 // based stubs generation.
708 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
709 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
710 // the correct package name base path.
711 if len(sourcepaths) > 0 {
712 cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
713 } else {
714 cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
715 }
716
717 cmd.FlagWithArg("-d ", outDir.String()).
718 Flag("-quiet")
719
720 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700721}
722
Colin Crossdaa4c672019-07-15 22:53:46 -0700723func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
724 outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
725 classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
726
727 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
728
729 flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
730 cmd.Flag(flag).Implicits(deps)
731
732 cmd.FlagWithArg("--patch-module ", "java.base=.")
733
734 if len(classpath) > 0 {
735 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
736 }
737
738 return cmd
Nan Zhang1598a9e2018-09-04 17:14:32 -0700739}
740
Colin Crossdaa4c672019-07-15 22:53:46 -0700741func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
742 outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
743 sourcepaths android.Paths) *android.RuleBuilderCommand {
744
745 cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
746
747 if len(bootclasspath) == 0 && ctx.Device() {
748 // explicitly specify -bootclasspath "" if the bootclasspath is empty to
749 // ensure java does not fall back to the default bootclasspath.
750 cmd.FlagWithArg("-bootclasspath ", `""`)
751 } else if len(bootclasspath) > 0 {
752 cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
753 }
754
755 if len(classpath) > 0 {
756 cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
757 }
758
759 return cmd
760}
761
Colin Crossab054432019-07-15 16:13:59 -0700762func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
763 outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700764
Colin Crossab054432019-07-15 16:13:59 -0700765 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
766 dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
767
768 return rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800769 BuiltTool("dokka").
Colin Crossab054432019-07-15 16:13:59 -0700770 Flag(config.JavacVmFlags).
Sorin Basca1d68e482022-09-08 16:48:01 +0100771 Flag("-J--add-opens=java.base/java.lang=ALL-UNNAMED").
Colin Crossab054432019-07-15 16:13:59 -0700772 Flag(srcJarDir.String()).
773 FlagWithInputList("-classpath ", dokkaClasspath, ":").
774 FlagWithArg("-format ", "dac").
775 FlagWithArg("-dacRoot ", "/reference/kotlin").
776 FlagWithArg("-output ", outDir.String())
Nan Zhang1598a9e2018-09-04 17:14:32 -0700777}
778
779func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
780 deps := d.Javadoc.collectDeps(ctx)
781
Colin Crossdaa4c672019-07-15 22:53:46 -0700782 d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Colin Crossdaa4c672019-07-15 22:53:46 -0700783
Colin Crossae5330a2021-11-03 13:31:22 -0700784 jsilver := ctx.Config().HostJavaToolPath(ctx, "jsilver.jar")
785 doclava := ctx.Config().HostJavaToolPath(ctx, "doclava.jar")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700786
Colin Crossab054432019-07-15 16:13:59 -0700787 outDir := android.PathForModuleOut(ctx, "out")
788 srcJarDir := android.PathForModuleOut(ctx, "srcjars")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700789
Colin Crossf1a035e2020-11-16 17:32:30 -0800790 rule := android.NewRuleBuilder(pctx, ctx)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700791
Colin Crossab054432019-07-15 16:13:59 -0700792 srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
793
794 var cmd *android.RuleBuilderCommand
Nan Zhang1598a9e2018-09-04 17:14:32 -0700795 if Bool(d.properties.Dokka_enabled) {
Colin Crossab054432019-07-15 16:13:59 -0700796 cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700797 } else {
Colin Crossdaa4c672019-07-15 22:53:46 -0700798 cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
Colin Crossab054432019-07-15 16:13:59 -0700799 deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700800 }
801
Colin Crossbc139922021-03-25 18:33:16 -0700802 d.expandArgs(ctx, cmd)
Colin Crossab054432019-07-15 16:13:59 -0700803
Mathew Inwoodabd49ab2019-12-19 14:27:08 +0000804 if d.properties.Compat_config != nil {
805 compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
806 cmd.FlagWithInput("-compatconfig ", compatConfig)
807 }
808
Colin Crossab054432019-07-15 16:13:59 -0700809 var desc string
810 if Bool(d.properties.Dokka_enabled) {
811 desc = "dokka"
812 } else {
Sorin Bascaae995ae2023-03-01 08:47:42 +0000813 d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
Colin Crossab054432019-07-15 16:13:59 -0700814
815 for _, o := range d.Javadoc.properties.Out {
816 cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
817 }
818
819 d.postDoclavaCmds(ctx, rule)
820 desc = "doclava"
821 }
822
823 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800824 BuiltTool("soong_zip").
Colin Crossab054432019-07-15 16:13:59 -0700825 Flag("-write_if_changed").
826 Flag("-d").
827 FlagWithOutput("-o ", d.docZip).
828 FlagWithArg("-C ", outDir.String()).
829 FlagWithArg("-D ", outDir.String())
830
Sorin Bascaae995ae2023-03-01 08:47:42 +0000831 rule.Restat()
Colin Crossab054432019-07-15 16:13:59 -0700832
Sorin Bascaae995ae2023-03-01 08:47:42 +0000833 zipSyncCleanupCmd(rule, srcJarDir)
Colin Crossab054432019-07-15 16:13:59 -0700834
Colin Crossf1a035e2020-11-16 17:32:30 -0800835 rule.Build("javadoc", desc)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700836}
837
Nan Zhangf4936b02018-08-01 15:00:28 -0700838// Exported Droiddoc Directory
Dan Willemsencc090972018-02-26 14:33:31 -0800839var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
840
Nan Zhangf4936b02018-08-01 15:00:28 -0700841type ExportedDroiddocDirProperties struct {
842 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -0800843 Path *string
844}
845
Nan Zhangf4936b02018-08-01 15:00:28 -0700846type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -0800847 android.ModuleBase
usta72c6c6c2023-08-30 17:18:01 -0400848 android.BazelModuleBase
Dan Willemsencc090972018-02-26 14:33:31 -0800849
Nan Zhangf4936b02018-08-01 15:00:28 -0700850 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -0800851
852 deps android.Paths
853 dir android.Path
854}
855
Colin Crossa3002fc2019-07-08 16:48:04 -0700856// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -0700857func ExportedDroiddocDirFactory() android.Module {
858 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -0800859 module.AddProperties(&module.properties)
860 android.InitAndroidModule(module)
usta72c6c6c2023-08-30 17:18:01 -0400861 android.InitBazelModule(module)
Dan Willemsencc090972018-02-26 14:33:31 -0800862 return module
863}
864
Nan Zhangf4936b02018-08-01 15:00:28 -0700865func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -0800866
Nan Zhangf4936b02018-08-01 15:00:28 -0700867func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -0800868 path := String(d.properties.Path)
869 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -0800870 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -0800871}
Nan Zhangb2b33de2018-02-23 11:18:47 -0800872
usta72c6c6c2023-08-30 17:18:01 -0400873// ConvertWithBp2build implements android.BazelModule.
Chris Parsons637458d2023-09-19 20:09:00 +0000874func (d *ExportedDroiddocDir) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
usta72c6c6c2023-08-30 17:18:01 -0400875 props := bazel.BazelTargetModuleProperties{
876 // Use the native py_library rule.
877 Rule_class: "droiddoc_exported_dir",
878 Bzl_load_location: "//build/bazel/rules/droiddoc:droiddoc_exported_dir.bzl",
879 }
880
881 type BazelAttrs struct {
882 Dir *string
883 Srcs bazel.LabelListAttribute
884 }
885
886 attrs := &BazelAttrs{
887 Dir: proptools.StringPtr(*d.properties.Path),
888 Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{filepath.Join(*d.properties.Path, "**/*")})),
889 }
890
891 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: d.Name()}, attrs)
892
893}
894
Nan Zhangb2b33de2018-02-23 11:18:47 -0800895// Defaults
Nan Zhangb2b33de2018-02-23 11:18:47 -0800896type DocDefaults struct {
897 android.ModuleBase
898 android.DefaultsModuleBase
899}
900
Nan Zhangb2b33de2018-02-23 11:18:47 -0800901func DocDefaultsFactory() android.Module {
902 module := &DocDefaults{}
903
904 module.AddProperties(
905 &JavadocProperties{},
906 &DroiddocProperties{},
907 )
908
909 android.InitDefaultsModule(module)
910
911 return module
912}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700913
Colin Cross33961b52019-07-11 11:01:22 -0700914func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
915 srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
916
Colin Cross1661aff2021-03-12 17:56:51 -0800917 cmd := rule.Command()
918 cmd.Text("rm -rf").Text(cmd.PathForOutput(srcJarDir))
919 cmd = rule.Command()
920 cmd.Text("mkdir -p").Text(cmd.PathForOutput(srcJarDir))
Colin Cross33961b52019-07-11 11:01:22 -0700921 srcJarList := srcJarDir.Join(ctx, "list")
922
923 rule.Temporary(srcJarList)
924
Colin Cross1661aff2021-03-12 17:56:51 -0800925 cmd = rule.Command()
926 cmd.BuiltTool("zipsync").
927 FlagWithArg("-d ", cmd.PathForOutput(srcJarDir)).
Colin Cross33961b52019-07-11 11:01:22 -0700928 FlagWithOutput("-l ", srcJarList).
929 FlagWithArg("-f ", `"*.java"`).
930 Inputs(srcJars)
931
932 return srcJarList
933}
934
935func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
936 rule.Command().Text("rm -rf").Text(srcJarDir.String())
937}