123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899 |
- // Copyright 2018 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package java
- import (
- "fmt"
- "path/filepath"
- "strings"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- "android/soong/java/config"
- )
- func init() {
- RegisterDocsBuildComponents(android.InitRegistrationContext)
- }
- func RegisterDocsBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("doc_defaults", DocDefaultsFactory)
- ctx.RegisterModuleType("droiddoc", DroiddocFactory)
- ctx.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
- ctx.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
- ctx.RegisterModuleType("javadoc", JavadocFactory)
- ctx.RegisterModuleType("javadoc_host", JavadocHostFactory)
- }
- type JavadocProperties struct {
- // list of source files used to compile the Java module. May be .java, .logtags, .proto,
- // or .aidl files.
- Srcs []string `android:"path,arch_variant"`
- // list of source files that should not be used to build the Java module.
- // This is most useful in the arch/multilib variants to remove non-common files
- // filegroup or genrule can be included within this property.
- Exclude_srcs []string `android:"path,arch_variant"`
- // list of package names that should actually be used. If this property is left unspecified,
- // all the sources from the srcs property is used.
- Filter_packages []string
- // list of java libraries that will be in the classpath.
- Libs []string `android:"arch_variant"`
- // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
- Installable *bool
- // if not blank, set to the version of the sdk to compile against.
- // Defaults to compiling against the current platform.
- Sdk_version *string `android:"arch_variant"`
- // When targeting 1.9 and above, override the modules to use with --system,
- // otherwise provides defaults libraries to add to the bootclasspath.
- // Defaults to "none"
- System_modules *string
- Aidl struct {
- // Top level directories to pass to aidl tool
- Include_dirs []string
- // Directories rooted at the Android.bp file to pass to aidl tool
- Local_include_dirs []string
- }
- // If not blank, set the java version passed to javadoc as -source
- Java_version *string
- // local files that are used within user customized droiddoc options.
- Arg_files []string `android:"path"`
- // user customized droiddoc args. Deprecated, use flags instead.
- // Available variables for substitution:
- //
- // $(location <label>): the path to the arg_files with name <label>
- // $$: a literal $
- Args *string
- // user customized droiddoc args. Not compatible with property args.
- // Available variables for substitution:
- //
- // $(location <label>): the path to the arg_files with name <label>
- // $$: a literal $
- Flags []string
- // names of the output files used in args that will be generated
- Out []string
- }
- type ApiToCheck struct {
- // path to the API txt file that the new API extracted from source code is checked
- // against. The path can be local to the module or from other module (via :module syntax).
- Api_file *string `android:"path"`
- // path to the API txt file that the new @removed API extractd from source code is
- // checked against. The path can be local to the module or from other module (via
- // :module syntax).
- Removed_api_file *string `android:"path"`
- // If not blank, path to the baseline txt file for approved API check violations.
- Baseline_file *string `android:"path"`
- // Arguments to the apicheck tool.
- Args *string
- }
- type DroiddocProperties struct {
- // directory relative to top of the source tree that contains doc templates files.
- Custom_template *string
- // directories under current module source which contains html/jd files.
- Html_dirs []string
- // set a value in the Clearsilver hdf namespace.
- Hdf []string
- // proofread file contains all of the text content of the javadocs concatenated into one file,
- // suitable for spell-checking and other goodness.
- Proofread_file *string
- // a todo file lists the program elements that are missing documentation.
- // At some point, this might be improved to show more warnings.
- Todo_file *string `android:"path"`
- // directory under current module source that provide additional resources (images).
- Resourcesdir *string
- // resources output directory under out/soong/.intermediates.
- Resourcesoutdir *string
- // index.html under current module will be copied to docs out dir, if not null.
- Static_doc_index_redirect *string `android:"path"`
- // source.properties under current module will be copied to docs out dir, if not null.
- Static_doc_properties *string `android:"path"`
- // a list of files under current module source dir which contains known tags in Java sources.
- // filegroup or genrule can be included within this property.
- Knowntags []string `android:"path"`
- // if set to true, generate docs through Dokka instead of Doclava.
- Dokka_enabled *bool
- // Compat config XML. Generates compat change documentation if set.
- Compat_config *string `android:"path"`
- }
- // Common flags passed down to build rule
- type droiddocBuilderFlags struct {
- bootClasspathArgs string
- classpathArgs string
- sourcepathArgs string
- dokkaClasspathArgs string
- aidlFlags string
- aidlDeps android.Paths
- doclavaStubsFlags string
- doclavaDocsFlags string
- postDoclavaCmds string
- }
- func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
- android.InitAndroidArchModule(module, hod, android.MultilibCommon)
- android.InitDefaultableModule(module)
- }
- func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
- if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
- return false
- } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
- return true
- } else if String(apiToCheck.Api_file) != "" {
- panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
- } else if String(apiToCheck.Removed_api_file) != "" {
- panic("for " + apiVersionTag + " api_file has to be non-empty!")
- }
- return false
- }
- // Javadoc
- type Javadoc struct {
- android.ModuleBase
- android.DefaultableModuleBase
- properties JavadocProperties
- srcJars android.Paths
- srcFiles android.Paths
- sourcepaths android.Paths
- implicits android.Paths
- docZip android.WritablePath
- stubsSrcJar android.WritablePath
- }
- func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return android.Paths{j.stubsSrcJar}, nil
- case ".docs.zip":
- return android.Paths{j.docZip}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
- }
- // javadoc converts .java source files to documentation using javadoc.
- func JavadocFactory() android.Module {
- module := &Javadoc{}
- module.AddProperties(&module.properties)
- InitDroiddocModule(module, android.HostAndDeviceSupported)
- return module
- }
- // javadoc_host converts .java source files to documentation using javadoc.
- func JavadocHostFactory() android.Module {
- module := &Javadoc{}
- module.AddProperties(&module.properties)
- InitDroiddocModule(module, android.HostSupported)
- return module
- }
- var _ android.OutputFileProducer = (*Javadoc)(nil)
- func (j *Javadoc) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
- return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version))
- }
- func (j *Javadoc) SystemModules() string {
- return proptools.String(j.properties.System_modules)
- }
- func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
- return j.SdkVersion(ctx)
- }
- func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec {
- return j.SdkVersion(ctx)
- }
- func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
- return j.SdkVersion(ctx)
- }
- func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
- if ctx.Device() {
- sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
- if sdkDep.useModule {
- ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...)
- ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
- ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...)
- ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...)
- }
- }
- ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
- }
- func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
- var flags droiddocBuilderFlags
- flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
- return flags
- }
- func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
- aidlIncludeDirs android.Paths) (string, android.Paths) {
- aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
- aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
- var flags []string
- var deps android.Paths
- if aidlPreprocess.Valid() {
- flags = append(flags, "-p"+aidlPreprocess.String())
- deps = append(deps, aidlPreprocess.Path())
- } else {
- flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
- }
- flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
- flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
- if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
- flags = append(flags, "-I"+src.String())
- }
- return strings.Join(flags, " "), deps
- }
- // TODO: remove the duplication between this and the one in gen.go
- func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
- flags droiddocBuilderFlags) android.Paths {
- outSrcFiles := make(android.Paths, 0, len(srcFiles))
- var aidlSrcs android.Paths
- aidlIncludeFlags := genAidlIncludeFlags(srcFiles)
- for _, srcFile := range srcFiles {
- switch srcFile.Ext() {
- case ".aidl":
- aidlSrcs = append(aidlSrcs, srcFile)
- case ".logtags":
- javaFile := genLogtags(ctx, srcFile)
- outSrcFiles = append(outSrcFiles, javaFile)
- default:
- outSrcFiles = append(outSrcFiles, srcFile)
- }
- }
- // Process all aidl files together to support sharding them into one or more rules that produce srcjars.
- if len(aidlSrcs) > 0 {
- srcJarFiles := genAidl(ctx, aidlSrcs, flags.aidlFlags+aidlIncludeFlags, nil, flags.aidlDeps)
- outSrcFiles = append(outSrcFiles, srcJarFiles...)
- }
- return outSrcFiles
- }
- func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
- var deps deps
- sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
- if sdkDep.invalidVersion {
- ctx.AddMissingDependencies(sdkDep.bootclasspath)
- ctx.AddMissingDependencies(sdkDep.java9Classpath)
- } else if sdkDep.useFiles {
- deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
- deps.aidlPreprocess = sdkDep.aidl
- } else {
- deps.aidlPreprocess = sdkDep.aidl
- }
- ctx.VisitDirectDeps(func(module android.Module) {
- otherName := ctx.OtherModuleName(module)
- tag := ctx.OtherModuleDependencyTag(module)
- switch tag {
- case bootClasspathTag:
- if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
- dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
- deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars...)
- } else if sm, ok := module.(SystemModulesProvider); ok {
- // A system modules dependency has been added to the bootclasspath
- // so add its libs to the bootclasspath.
- deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...)
- } else {
- panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
- }
- case libTag:
- if dep, ok := module.(SdkLibraryDependency); ok {
- deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
- } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
- dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
- deps.classpath = append(deps.classpath, dep.HeaderJars...)
- deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
- } else if dep, ok := module.(android.SourceFileProducer); ok {
- checkProducesJars(ctx, dep)
- deps.classpath = append(deps.classpath, dep.Srcs()...)
- } else {
- ctx.ModuleErrorf("depends on non-java module %q", otherName)
- }
- case java9LibTag:
- if ctx.OtherModuleHasProvider(module, JavaInfoProvider) {
- dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
- deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
- } else {
- ctx.ModuleErrorf("depends on non-java module %q", otherName)
- }
- case systemModulesTag:
- if deps.systemModules != nil {
- panic("Found two system module dependencies")
- }
- sm := module.(SystemModulesProvider)
- outputDir, outputDeps := sm.OutputDirAndDeps()
- deps.systemModules = &systemModules{outputDir, outputDeps}
- }
- })
- // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
- // may contain filegroup or genrule.
- srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
- j.implicits = append(j.implicits, srcFiles...)
- filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
- if filterPackages == nil {
- return srcs
- }
- filtered := []android.Path{}
- for _, src := range srcs {
- if src.Ext() != ".java" {
- // Don't filter-out non-Java (=generated sources) by package names. This is not ideal,
- // but otherwise metalava emits stub sources having references to the generated AIDL classes
- // in filtered-out pacages (e.g. com.android.internal.*).
- // TODO(b/141149570) We need to fix this by introducing default private constructors or
- // fixing metalava to not emit constructors having references to unknown classes.
- filtered = append(filtered, src)
- continue
- }
- packageName := strings.ReplaceAll(filepath.Dir(src.Rel()), "/", ".")
- if android.HasAnyPrefix(packageName, filterPackages) {
- filtered = append(filtered, src)
- }
- }
- return filtered
- }
- srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
- aidlFlags := j.collectAidlFlags(ctx, deps)
- srcFiles = j.genSources(ctx, srcFiles, aidlFlags)
- // srcs may depend on some genrule output.
- j.srcJars = srcFiles.FilterByExt(".srcjar")
- j.srcJars = append(j.srcJars, deps.srcJars...)
- j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
- j.srcFiles = append(j.srcFiles, deps.srcs...)
- if len(j.srcFiles) > 0 {
- j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
- }
- return deps
- }
- func (j *Javadoc) expandArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
- var argFiles android.Paths
- argFilesMap := map[string]string{}
- argFileLabels := []string{}
- for _, label := range j.properties.Arg_files {
- var paths = android.PathsForModuleSrc(ctx, []string{label})
- if _, exists := argFilesMap[label]; !exists {
- argFilesMap[label] = strings.Join(cmd.PathsForInputs(paths), " ")
- argFileLabels = append(argFileLabels, label)
- argFiles = append(argFiles, paths...)
- } else {
- ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
- label, argFilesMap[label], paths)
- }
- }
- var argsPropertyName string
- flags := make([]string, 0)
- if j.properties.Args != nil && j.properties.Flags != nil {
- ctx.PropertyErrorf("args", "flags is set. Cannot set args")
- } else if args := proptools.String(j.properties.Args); args != "" {
- flags = append(flags, args)
- argsPropertyName = "args"
- } else {
- flags = append(flags, j.properties.Flags...)
- argsPropertyName = "flags"
- }
- for _, flag := range flags {
- expanded, err := android.Expand(flag, func(name string) (string, error) {
- if strings.HasPrefix(name, "location ") {
- label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
- if paths, ok := argFilesMap[label]; ok {
- return paths, nil
- } else {
- return "", fmt.Errorf("unknown location label %q, expecting one of %q",
- label, strings.Join(argFileLabels, ", "))
- }
- } else if name == "genDir" {
- return android.PathForModuleGen(ctx).String(), nil
- }
- return "", fmt.Errorf("unknown variable '$(%s)'", name)
- })
- if err != nil {
- ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
- }
- cmd.Flag(expanded)
- }
- cmd.Implicits(argFiles)
- }
- func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
- j.addDeps(ctx)
- }
- func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- deps := j.collectDeps(ctx)
- j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
- outDir := android.PathForModuleOut(ctx, "out")
- srcJarDir := android.PathForModuleOut(ctx, "srcjars")
- j.stubsSrcJar = nil
- rule := android.NewRuleBuilder(pctx, ctx)
- rule.Command().Text("rm -rf").Text(outDir.String())
- rule.Command().Text("mkdir -p").Text(outDir.String())
- srcJarList := zipSyncCmd(ctx, rule, srcJarDir, j.srcJars)
- javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j))
- cmd := javadocSystemModulesCmd(ctx, rule, j.srcFiles, outDir, srcJarDir, srcJarList,
- deps.systemModules, deps.classpath, j.sourcepaths)
- cmd.FlagWithArg("-source ", javaVersion.String()).
- Flag("-J-Xmx1024m").
- Flag("-XDignore.symbol.file").
- Flag("-Xdoclint:none")
- j.expandArgs(ctx, cmd)
- rule.Command().
- BuiltTool("soong_zip").
- Flag("-write_if_changed").
- Flag("-d").
- FlagWithOutput("-o ", j.docZip).
- FlagWithArg("-C ", outDir.String()).
- FlagWithArg("-D ", outDir.String())
- rule.Restat()
- zipSyncCleanupCmd(rule, srcJarDir)
- rule.Build("javadoc", "javadoc")
- }
- // Droiddoc
- type Droiddoc struct {
- Javadoc
- properties DroiddocProperties
- }
- // droiddoc converts .java source files to documentation using doclava or dokka.
- func DroiddocFactory() android.Module {
- module := &Droiddoc{}
- module.AddProperties(&module.properties,
- &module.Javadoc.properties)
- InitDroiddocModule(module, android.HostAndDeviceSupported)
- return module
- }
- // droiddoc_host converts .java source files to documentation using doclava or dokka.
- func DroiddocHostFactory() android.Module {
- module := &Droiddoc{}
- module.AddProperties(&module.properties,
- &module.Javadoc.properties)
- InitDroiddocModule(module, android.HostSupported)
- return module
- }
- func (d *Droiddoc) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "", ".docs.zip":
- return android.Paths{d.Javadoc.docZip}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
- }
- func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
- d.Javadoc.addDeps(ctx)
- if String(d.properties.Custom_template) != "" {
- ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
- }
- }
- func (d *Droiddoc) doclavaDocsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, docletPath classpath) {
- buildNumberFile := ctx.Config().BuildNumberFile(ctx)
- // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
- // sources, droiddoc will get sources produced by metalava which will have already stripped out the
- // 1.9 language features.
- cmd.FlagWithArg("-source ", "1.8").
- Flag("-J-Xmx1600m").
- Flag("-J-XX:-OmitStackTraceInFastThrow").
- Flag("-XDignore.symbol.file").
- FlagWithArg("-doclet ", "com.google.doclava.Doclava").
- FlagWithInputList("-docletpath ", docletPath.Paths(), ":").
- FlagWithArg("-hdf page.build ", ctx.Config().BuildId()+"-$(cat "+buildNumberFile.String()+")").OrderOnly(buildNumberFile).
- FlagWithArg("-hdf page.now ", `"$(date -d @$(cat `+ctx.Config().Getenv("BUILD_DATETIME_FILE")+`) "+%d %b %Y %k:%M")" `)
- if String(d.properties.Custom_template) == "" {
- // TODO: This is almost always droiddoc-templates-sdk
- ctx.PropertyErrorf("custom_template", "must specify a template")
- }
- ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
- if t, ok := m.(*ExportedDroiddocDir); ok {
- cmd.FlagWithArg("-templatedir ", t.dir.String()).Implicits(t.deps)
- } else {
- ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_exported_dir", ctx.OtherModuleName(m))
- }
- })
- if len(d.properties.Html_dirs) > 0 {
- htmlDir := android.PathForModuleSrc(ctx, d.properties.Html_dirs[0])
- cmd.FlagWithArg("-htmldir ", htmlDir.String()).
- Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")}))
- }
- if len(d.properties.Html_dirs) > 1 {
- htmlDir2 := android.PathForModuleSrc(ctx, d.properties.Html_dirs[1])
- cmd.FlagWithArg("-htmldir2 ", htmlDir2.String()).
- Implicits(android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[1], "**/*")}))
- }
- if len(d.properties.Html_dirs) > 2 {
- ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
- }
- knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
- cmd.FlagForEachInput("-knowntags ", knownTags)
- cmd.FlagForEachArg("-hdf ", d.properties.Hdf)
- if String(d.properties.Proofread_file) != "" {
- proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
- cmd.FlagWithOutput("-proofread ", proofreadFile)
- }
- if String(d.properties.Todo_file) != "" {
- // tricky part:
- // we should not compute full path for todo_file through PathForModuleOut().
- // the non-standard doclet will get the full path relative to "-o".
- cmd.FlagWithArg("-todo ", String(d.properties.Todo_file)).
- ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
- }
- if String(d.properties.Resourcesdir) != "" {
- // TODO: should we add files under resourcesDir to the implicits? It seems that
- // resourcesDir is one sub dir of htmlDir
- resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
- cmd.FlagWithArg("-resourcesdir ", resourcesDir.String())
- }
- if String(d.properties.Resourcesoutdir) != "" {
- // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
- cmd.FlagWithArg("-resourcesoutdir ", String(d.properties.Resourcesoutdir))
- }
- }
- func (d *Droiddoc) postDoclavaCmds(ctx android.ModuleContext, rule *android.RuleBuilder) {
- if String(d.properties.Static_doc_index_redirect) != "" {
- staticDocIndexRedirect := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_index_redirect))
- rule.Command().Text("cp").
- Input(staticDocIndexRedirect).
- Output(android.PathForModuleOut(ctx, "out", "index.html"))
- }
- if String(d.properties.Static_doc_properties) != "" {
- staticDocProperties := android.PathForModuleSrc(ctx, String(d.properties.Static_doc_properties))
- rule.Command().Text("cp").
- Input(staticDocProperties).
- Output(android.PathForModuleOut(ctx, "out", "source.properties"))
- }
- }
- func javadocCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
- outDir, srcJarDir, srcJarList android.Path, sourcepaths android.Paths) *android.RuleBuilderCommand {
- cmd := rule.Command().
- BuiltTool("soong_javac_wrapper").Tool(config.JavadocCmd(ctx)).
- Flag(config.JavacVmFlags).
- FlagWithArg("-encoding ", "UTF-8").
- FlagWithRspFileInputList("@", android.PathForModuleOut(ctx, "javadoc.rsp"), srcs).
- FlagWithInput("@", srcJarList)
- // TODO(ccross): Remove this if- statement once we finish migration for all Doclava
- // based stubs generation.
- // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
- // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
- // the correct package name base path.
- if len(sourcepaths) > 0 {
- cmd.FlagWithList("-sourcepath ", sourcepaths.Strings(), ":")
- } else {
- cmd.FlagWithArg("-sourcepath ", srcJarDir.String())
- }
- cmd.FlagWithArg("-d ", outDir.String()).
- Flag("-quiet")
- return cmd
- }
- func javadocSystemModulesCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
- outDir, srcJarDir, srcJarList android.Path, systemModules *systemModules,
- classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
- cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
- flag, deps := systemModules.FormJavaSystemModulesPath(ctx.Device())
- cmd.Flag(flag).Implicits(deps)
- cmd.FlagWithArg("--patch-module ", "java.base=.")
- if len(classpath) > 0 {
- cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
- }
- return cmd
- }
- func javadocBootclasspathCmd(ctx android.ModuleContext, rule *android.RuleBuilder, srcs android.Paths,
- outDir, srcJarDir, srcJarList android.Path, bootclasspath, classpath classpath,
- sourcepaths android.Paths) *android.RuleBuilderCommand {
- cmd := javadocCmd(ctx, rule, srcs, outDir, srcJarDir, srcJarList, sourcepaths)
- if len(bootclasspath) == 0 && ctx.Device() {
- // explicitly specify -bootclasspath "" if the bootclasspath is empty to
- // ensure java does not fall back to the default bootclasspath.
- cmd.FlagWithArg("-bootclasspath ", `""`)
- } else if len(bootclasspath) > 0 {
- cmd.FlagWithInputList("-bootclasspath ", bootclasspath.Paths(), ":")
- }
- if len(classpath) > 0 {
- cmd.FlagWithInputList("-classpath ", classpath.Paths(), ":")
- }
- return cmd
- }
- func dokkaCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
- outDir, srcJarDir android.Path, bootclasspath, classpath classpath) *android.RuleBuilderCommand {
- // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
- dokkaClasspath := append(bootclasspath.Paths(), classpath.Paths()...)
- return rule.Command().
- BuiltTool("dokka").
- Flag(config.JavacVmFlags).
- Flag(srcJarDir.String()).
- FlagWithInputList("-classpath ", dokkaClasspath, ":").
- FlagWithArg("-format ", "dac").
- FlagWithArg("-dacRoot ", "/reference/kotlin").
- FlagWithArg("-output ", outDir.String())
- }
- func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- deps := d.Javadoc.collectDeps(ctx)
- d.Javadoc.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
- jsilver := ctx.Config().HostJavaToolPath(ctx, "jsilver.jar")
- doclava := ctx.Config().HostJavaToolPath(ctx, "doclava.jar")
- outDir := android.PathForModuleOut(ctx, "out")
- srcJarDir := android.PathForModuleOut(ctx, "srcjars")
- rule := android.NewRuleBuilder(pctx, ctx)
- srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
- var cmd *android.RuleBuilderCommand
- if Bool(d.properties.Dokka_enabled) {
- cmd = dokkaCmd(ctx, rule, outDir, srcJarDir, deps.bootClasspath, deps.classpath)
- } else {
- cmd = javadocBootclasspathCmd(ctx, rule, d.Javadoc.srcFiles, outDir, srcJarDir, srcJarList,
- deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
- }
- d.expandArgs(ctx, cmd)
- if d.properties.Compat_config != nil {
- compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
- cmd.FlagWithInput("-compatconfig ", compatConfig)
- }
- var desc string
- if Bool(d.properties.Dokka_enabled) {
- desc = "dokka"
- } else {
- d.doclavaDocsFlags(ctx, cmd, classpath{jsilver, doclava})
- for _, o := range d.Javadoc.properties.Out {
- cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
- }
- d.postDoclavaCmds(ctx, rule)
- desc = "doclava"
- }
- rule.Command().
- BuiltTool("soong_zip").
- Flag("-write_if_changed").
- Flag("-d").
- FlagWithOutput("-o ", d.docZip).
- FlagWithArg("-C ", outDir.String()).
- FlagWithArg("-D ", outDir.String())
- rule.Restat()
- zipSyncCleanupCmd(rule, srcJarDir)
- rule.Build("javadoc", desc)
- }
- // Exported Droiddoc Directory
- var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
- type ExportedDroiddocDirProperties struct {
- // path to the directory containing Droiddoc related files.
- Path *string
- }
- type ExportedDroiddocDir struct {
- android.ModuleBase
- properties ExportedDroiddocDirProperties
- deps android.Paths
- dir android.Path
- }
- // droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
- func ExportedDroiddocDirFactory() android.Module {
- module := &ExportedDroiddocDir{}
- module.AddProperties(&module.properties)
- android.InitAndroidModule(module)
- return module
- }
- func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
- func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- path := String(d.properties.Path)
- d.dir = android.PathForModuleSrc(ctx, path)
- d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
- }
- // Defaults
- type DocDefaults struct {
- android.ModuleBase
- android.DefaultsModuleBase
- }
- func DocDefaultsFactory() android.Module {
- module := &DocDefaults{}
- module.AddProperties(
- &JavadocProperties{},
- &DroiddocProperties{},
- )
- android.InitDefaultsModule(module)
- return module
- }
- func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
- srcJarDir android.ModuleOutPath, srcJars android.Paths) android.OutputPath {
- cmd := rule.Command()
- cmd.Text("rm -rf").Text(cmd.PathForOutput(srcJarDir))
- cmd = rule.Command()
- cmd.Text("mkdir -p").Text(cmd.PathForOutput(srcJarDir))
- srcJarList := srcJarDir.Join(ctx, "list")
- rule.Temporary(srcJarList)
- cmd = rule.Command()
- cmd.BuiltTool("zipsync").
- FlagWithArg("-d ", cmd.PathForOutput(srcJarDir)).
- FlagWithOutput("-l ", srcJarList).
- FlagWithArg("-f ", `"*.java"`).
- Inputs(srcJars)
- return srcJarList
- }
- func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
- rule.Command().Text("rm -rf").Text(srcJarDir.String())
- }
|