diff --git a/android/writedocs.go b/android/writedocs.go
index 9737030e0..7262ad810 100644
--- a/android/writedocs.go
+++ b/android/writedocs.go
@@ -53,15 +53,19 @@ func (c *docsSingleton) GenerateBuildActions(ctx SingletonContext) {
primaryBuilder := primaryBuilderPath(ctx)
soongDocs := ctx.Rule(pctx, "soongDocs",
blueprint.RuleParams{
- Command: fmt.Sprintf("%s --soong_docs %s %s",
+ Command: fmt.Sprintf("rm -f ${outDir}/* && %s --soong_docs %s %s",
primaryBuilder.String(), docsFile.String(), strings.Join(os.Args[1:], " ")),
CommandDeps: []string{primaryBuilder.String()},
Description: fmt.Sprintf("%s docs $out", primaryBuilder.Base()),
- })
+ },
+ "outDir")
ctx.Build(pctx, BuildParams{
Rule: soongDocs,
Output: docsFile,
+ Args: map[string]string{
+ "outDir": PathForOutput(ctx, "docs").String(),
+ },
})
// Add a phony target for building the documentation
diff --git a/cmd/soong_build/writedocs.go b/cmd/soong_build/writedocs.go
index 74c854a39..de2182fe2 100644
--- a/cmd/soong_build/writedocs.go
+++ b/cmd/soong_build/writedocs.go
@@ -19,6 +19,7 @@ import (
"bytes"
"html/template"
"io/ioutil"
+ "path/filepath"
"reflect"
"sort"
@@ -26,6 +27,11 @@ import (
"github.com/google/blueprint/bootstrap/bpdoc"
)
+type perPackageTemplateData struct {
+ Name string
+ Modules []moduleTypeTemplateData
+}
+
type moduleTypeTemplateData struct {
Name string
Synopsis string
@@ -44,22 +50,7 @@ var propertyRank = map[string]int{
}
// For each module type, extract its documentation and convert it to the template data.
-func moduleTypeDocsToTemplates(ctx *android.Context) ([]moduleTypeTemplateData, error) {
- moduleTypeFactories := android.ModuleTypeFactories()
- bpModuleTypeFactories := make(map[string]reflect.Value)
- for moduleType, factory := range moduleTypeFactories {
- bpModuleTypeFactories[moduleType] = reflect.ValueOf(factory)
- }
-
- packages, err := bootstrap.ModuleTypeDocs(ctx.Context, bpModuleTypeFactories)
- if err != nil {
- return []moduleTypeTemplateData{}, err
- }
- var moduleTypeList []*bpdoc.ModuleType
- for _, pkg := range packages {
- moduleTypeList = append(moduleTypeList, pkg.ModuleTypes...)
- }
-
+func moduleTypeDocsToTemplates(moduleTypeList []*bpdoc.ModuleType) []moduleTypeTemplateData {
result := make([]moduleTypeTemplateData, 0)
// Combine properties from all PropertyStruct's and reorder them -- first the ones
@@ -101,39 +92,121 @@ func moduleTypeDocsToTemplates(ctx *android.Context) ([]moduleTypeTemplateData,
result = append(result, item)
}
sort.Slice(result, func(i, j int) bool { return result[i].Name < result[j].Name })
- return result, err
+ return result
}
func writeDocs(ctx *android.Context, filename string) error {
- buf := &bytes.Buffer{}
+ moduleTypeFactories := android.ModuleTypeFactories()
+ bpModuleTypeFactories := make(map[string]reflect.Value)
+ for moduleType, factory := range moduleTypeFactories {
+ bpModuleTypeFactories[moduleType] = reflect.ValueOf(factory)
+ }
- // We need a module name getter/setter function because I couldn't
- // find a way to keep it in a variable defined within the template.
- currentModuleName := ""
- data, err := moduleTypeDocsToTemplates(ctx)
+ packages, err := bootstrap.ModuleTypeDocs(ctx.Context, bpModuleTypeFactories)
if err != nil {
return err
}
- tmpl, err := template.New("file").Funcs(map[string]interface{}{
- "setModule": func(moduleName string) string {
- currentModuleName = moduleName
- return ""
- },
- "getModule": func() string {
- return currentModuleName
- },
- }).Parse(fileTemplate)
+
+ // Produce the top-level, package list page first.
+ tmpl, err := template.New("file").Parse(packageListTemplate)
+ if err != nil {
+ return err
+ }
+ buf := &bytes.Buffer{}
if err == nil {
- err = tmpl.Execute(buf, data)
+ err = tmpl.Execute(buf, packages)
}
if err == nil {
err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
}
+
+ // Now, produce per-package module lists with detailed information.
+ for _, pkg := range packages {
+ // We need a module name getter/setter function because I couldn't
+ // find a way to keep it in a variable defined within the template.
+ currentModuleName := ""
+ tmpl, err := template.New("file").Funcs(map[string]interface{}{
+ "setModule": func(moduleName string) string {
+ currentModuleName = moduleName
+ return ""
+ },
+ "getModule": func() string {
+ return currentModuleName
+ },
+ }).Parse(perPackageTemplate)
+ if err != nil {
+ return err
+ }
+ buf := &bytes.Buffer{}
+ modules := moduleTypeDocsToTemplates(pkg.ModuleTypes)
+ data := perPackageTemplateData{Name: pkg.Name, Modules: modules}
+ err = tmpl.Execute(buf, data)
+ if err != nil {
+ return err
+ }
+ pkgFileName := filepath.Join(filepath.Dir(filename), pkg.Name+".html")
+ err = ioutil.WriteFile(pkgFileName, buf.Bytes(), 0666)
+ if err != nil {
+ return err
+ }
+ }
return err
}
+// TODO(jungjw): Consider ordering by name.
const (
- fileTemplate = `
+ packageListTemplate = `
+
+
+Build Docs
+
+
+
+
+
+
Soong Modules Reference
+The latest versions of Android use the Soong build system, which greatly simplifies build
+configuration over the previous Make-based system. This site contains the generated reference
+files for the Soong build system.
+
+
{{/* Main panel with H1 section per module type */}}
-
Soong Modules Reference
-The latest versions of Android use the Soong build system, which greatly simplifies build
-configuration over the previous Make-based system. This site contains the generated reference
-files for the Soong build system.
-
-See the Android Build System
-description for an overview of Soong and examples for its use.
-
-{{range $imodule, $moduleType := .}}
+{{range $moduleType := .Modules}}
{{setModule $moduleType.Name}}
{{$moduleType.Name}}
@@ -225,7 +290,6 @@ description for an overview of Soong and examples for its use.
{{- end}}
{{- end -}}
{{- end -}}
-