Allow Soong to generate its own build documentation
Add a rule in soong that re-executes soong_build in order to generate build documentation. This allows Soong to customize the documentation. Bug: 70516282 Test: m soong_docs Change-Id: If143cfacd6ac20274cd7bb8d8fab0c07025a5553
This commit is contained in:
parent
59014396ba
commit
e87040b2eb
6 changed files with 234 additions and 2 deletions
|
@ -61,6 +61,7 @@ bootstrap_go_package {
|
|||
"android/testing.go",
|
||||
"android/util.go",
|
||||
"android/variable.go",
|
||||
"android/writedocs.go",
|
||||
|
||||
// Lock down environment access last
|
||||
"android/env.go",
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
"github.com/google/blueprint/proptools"
|
||||
)
|
||||
|
||||
|
@ -67,6 +68,7 @@ type config struct {
|
|||
FileConfigurableOptions
|
||||
ProductVariables productVariables
|
||||
|
||||
PrimaryBuilder string
|
||||
ConfigFileName string
|
||||
ProductVariablesFileName string
|
||||
|
||||
|
@ -91,6 +93,8 @@ type config struct {
|
|||
useOpenJDK9 bool // Use OpenJDK9, but possibly target 1.8
|
||||
targetOpenJDK9 bool // Use OpenJDK9 and target 1.9
|
||||
|
||||
stopBefore bootstrap.StopBefore
|
||||
|
||||
OncePer
|
||||
}
|
||||
|
||||
|
@ -312,14 +316,22 @@ func (c *config) fromEnv() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *config) RemoveAbandonedFiles() bool {
|
||||
return false
|
||||
func (c *config) StopBefore() bootstrap.StopBefore {
|
||||
return c.stopBefore
|
||||
}
|
||||
|
||||
func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) {
|
||||
c.stopBefore = stopBefore
|
||||
}
|
||||
|
||||
var _ bootstrap.ConfigStopBefore = (*config)(nil)
|
||||
|
||||
func (c *config) BlueprintToolLocation() string {
|
||||
return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin")
|
||||
}
|
||||
|
||||
var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
|
||||
|
||||
// HostSystemTool looks for non-hermetic tools from the system we're running on.
|
||||
// Generally shouldn't be used, but useful to find the XCode SDK, etc.
|
||||
func (c *config) HostSystemTool(name string) string {
|
||||
|
|
73
android/writedocs.go
Normal file
73
android/writedocs.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2015 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 android
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
func init() {
|
||||
RegisterSingletonType("writedocs", DocsSingleton)
|
||||
}
|
||||
|
||||
func DocsSingleton() Singleton {
|
||||
return &docsSingleton{}
|
||||
}
|
||||
|
||||
type docsSingleton struct{}
|
||||
|
||||
func primaryBuilderPath(ctx SingletonContext) Path {
|
||||
primaryBuilder, err := filepath.Rel(ctx.Config().BuildDir(), os.Args[0])
|
||||
if err != nil {
|
||||
ctx.Errorf("path to primary builder %q is not in build dir %q",
|
||||
os.Args[0], ctx.Config().BuildDir())
|
||||
}
|
||||
|
||||
return PathForOutput(ctx, primaryBuilder)
|
||||
}
|
||||
|
||||
func (c *docsSingleton) GenerateBuildActions(ctx SingletonContext) {
|
||||
// Generate build system docs for the primary builder. Generating docs reads the source
|
||||
// files used to build the primary builder, but that dependency will be picked up through
|
||||
// the dependency on the primary builder itself. There are no dependencies on the
|
||||
// Blueprints files, as any relevant changes to the Blueprints files would have caused
|
||||
// a rebuild of the primary builder.
|
||||
docsFile := PathForOutput(ctx, "docs", "soong_build.html")
|
||||
primaryBuilder := primaryBuilderPath(ctx)
|
||||
soongDocs := ctx.Rule(pctx, "soongDocs",
|
||||
blueprint.RuleParams{
|
||||
Command: fmt.Sprintf("%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()),
|
||||
})
|
||||
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: soongDocs,
|
||||
Output: docsFile,
|
||||
})
|
||||
|
||||
// Add a phony target for building the documentation
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: blueprint.Phony,
|
||||
Output: PathForPhony(ctx, "soong_docs"),
|
||||
Input: docsFile,
|
||||
})
|
||||
}
|
|
@ -23,6 +23,7 @@ bootstrap_go_binary {
|
|||
],
|
||||
srcs: [
|
||||
"main.go",
|
||||
"writedocs.go",
|
||||
],
|
||||
primaryBuilder: true,
|
||||
}
|
||||
|
|
|
@ -25,6 +25,14 @@ import (
|
|||
"android/soong/android"
|
||||
)
|
||||
|
||||
var (
|
||||
docFile string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
|
||||
}
|
||||
|
||||
func newNameResolver(config android.Config) *android.NameResolver {
|
||||
namespacePathsToExport := make(map[string]bool)
|
||||
|
||||
|
@ -56,9 +64,17 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
if docFile != "" {
|
||||
configuration.SetStopBefore(bootstrap.StopBeforePrepareBuildActions)
|
||||
}
|
||||
|
||||
ctx.SetNameInterface(newNameResolver(configuration))
|
||||
|
||||
ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
|
||||
|
||||
bootstrap.Main(ctx.Context, configuration, configuration.ConfigFileName, configuration.ProductVariablesFileName)
|
||||
|
||||
if docFile != "" {
|
||||
writeDocs(ctx, docFile)
|
||||
}
|
||||
}
|
||||
|
|
129
cmd/soong_build/writedocs.go
Normal file
129
cmd/soong_build/writedocs.go
Normal file
|
@ -0,0 +1,129 @@
|
|||
// Copyright 2017 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 main
|
||||
|
||||
import (
|
||||
"android/soong/android"
|
||||
"bytes"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
)
|
||||
|
||||
func writeDocs(ctx *android.Context, filename string) error {
|
||||
moduleTypeList, err := bootstrap.ModuleTypeDocs(ctx.Context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
unique := 0
|
||||
|
||||
tmpl, err := template.New("file").Funcs(map[string]interface{}{
|
||||
"unique": func() int {
|
||||
unique++
|
||||
return unique
|
||||
}}).Parse(fileTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tmpl.Execute(buf, moduleTypeList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
fileTemplate = `
|
||||
<html>
|
||||
<head>
|
||||
<title>Build Docs</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Build Docs</h1>
|
||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
{{range .}}
|
||||
{{ $collapseIndex := unique }}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="heading{{$collapseIndex}}">
|
||||
<h2 class="panel-title">
|
||||
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{$collapseIndex}}" aria-expanded="false" aria-controls="collapse{{$collapseIndex}}">
|
||||
{{.Name}}
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="collapse{{$collapseIndex}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{$collapseIndex}}">
|
||||
<div class="panel-body">
|
||||
<p>{{.Text}}</p>
|
||||
{{range .PropertyStructs}}
|
||||
<p>{{.Text}}</p>
|
||||
{{template "properties" .Properties}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
{{define "properties"}}
|
||||
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
{{range .}}
|
||||
{{$collapseIndex := unique}}
|
||||
{{if .Properties}}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading" role="tab" id="heading{{$collapseIndex}}">
|
||||
<h4 class="panel-title">
|
||||
<a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{$collapseIndex}}" aria-expanded="false" aria-controls="collapse{{$collapseIndex}}">
|
||||
{{.Name}}{{range .OtherNames}}, {{.}}{{end}}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div id="collapse{{$collapseIndex}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{$collapseIndex}}">
|
||||
<div class="panel-body">
|
||||
<p>{{.Text}}</p>
|
||||
{{range .OtherTexts}}<p>{{.}}</p>{{end}}
|
||||
{{template "properties" .Properties}}
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div>
|
||||
<h4>{{.Name}}{{range .OtherNames}}, {{.}}{{end}}</h4>
|
||||
<p>{{.Text}}</p>
|
||||
{{range .OtherTexts}}<p>{{.}}</p>{{end}}
|
||||
<p><i>Type: {{.Type}}</i></p>
|
||||
{{if .Default}}<p><i>Default: {{.Default}}</i></p>{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
`
|
||||
)
|
Loading…
Reference in a new issue