Add new soong module debug info json.
Enabled by setting GENERATE_SOONG_DEBUG=true Test: GENERATE_SOONG_DEBUG=true m nothing ; soongdbg ... Change-Id: If70c7d91cc59a5a7642e453c85278e8022693ac7
This commit is contained in:
parent
7add62142d
commit
8ad2b88c8d
2 changed files with 146 additions and 0 deletions
|
@ -40,6 +40,9 @@ type Args struct {
|
|||
Cpuprofile string
|
||||
Memprofile string
|
||||
TraceFile string
|
||||
|
||||
// Debug data json file
|
||||
ModuleDebugFile string
|
||||
}
|
||||
|
||||
// RegisterGoModuleTypes adds module types to build tools written in golang
|
||||
|
@ -131,6 +134,10 @@ func RunBlueprint(args Args, stopBefore StopBefore, ctx *blueprint.Context, conf
|
|||
ninjaDeps = append(ninjaDeps, buildActionsDeps...)
|
||||
}
|
||||
|
||||
if args.ModuleDebugFile != "" {
|
||||
ctx.GenerateModuleDebugInfo(args.ModuleDebugFile)
|
||||
}
|
||||
|
||||
if stopBefore == StopBeforeWriteNinja {
|
||||
return ninjaDeps, nil
|
||||
}
|
||||
|
|
139
context.go
139
context.go
|
@ -3820,6 +3820,25 @@ func (c *Context) visitAllModuleVariants(module *moduleInfo,
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Context) visitAllModuleInfos(visit func(*moduleInfo)) {
|
||||
var module *moduleInfo
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
panic(newPanicErrorf(r, "VisitAllModules(%s) for %s",
|
||||
funcName(visit), module))
|
||||
}
|
||||
}()
|
||||
|
||||
for _, moduleGroup := range c.sortedModuleGroups() {
|
||||
for _, moduleOrAlias := range moduleGroup.modules {
|
||||
if module = moduleOrAlias.module(); module != nil {
|
||||
visit(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) requireNinjaVersion(major, minor, micro int) {
|
||||
if major != 1 {
|
||||
panic("ninja version with major version != 1 not supported")
|
||||
|
@ -4920,6 +4939,126 @@ func funcName(f interface{}) string {
|
|||
return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
|
||||
}
|
||||
|
||||
// json representation of a dependency
|
||||
type depJson struct {
|
||||
Name string `json:"name"`
|
||||
Variant string `json:"variant"`
|
||||
TagType string `json:"tag_type"`
|
||||
}
|
||||
|
||||
// json representation of a provider
|
||||
type providerJson struct {
|
||||
Type string `json:"type"`
|
||||
Debug string `json:"debug"` // from GetDebugString on the provider data
|
||||
}
|
||||
|
||||
// interface for getting debug info from various data.
|
||||
// TODO: Consider having this return a json object instead
|
||||
type Debuggable interface {
|
||||
GetDebugString() string
|
||||
}
|
||||
|
||||
// Get the debug json for a single module. Returns thae data as
|
||||
// flattened json text for easy concatenation by GenerateModuleDebugInfo.
|
||||
func getModuleDebugJson(module *moduleInfo) []byte {
|
||||
info := struct {
|
||||
Name string `json:"name"`
|
||||
SourceFile string `json:"source_file"`
|
||||
SourceLine int `json:"source_line"`
|
||||
Type string `json:"type"`
|
||||
Variant string `json:"variant"`
|
||||
Deps []depJson `json:"deps"`
|
||||
Providers []providerJson `json:"providers"`
|
||||
Debug string `json:"debug"` // from GetDebugString on the module
|
||||
}{
|
||||
Name: module.logicModule.Name(),
|
||||
SourceFile: module.pos.Filename,
|
||||
SourceLine: module.pos.Line,
|
||||
Type: module.typeName,
|
||||
Variant: module.variant.name,
|
||||
Deps: func() []depJson {
|
||||
result := make([]depJson, len(module.directDeps))
|
||||
for i, dep := range module.directDeps {
|
||||
result[i] = depJson{
|
||||
Name: dep.module.logicModule.Name(),
|
||||
Variant: dep.module.variant.name,
|
||||
}
|
||||
t := reflect.TypeOf(dep.tag)
|
||||
if t != nil {
|
||||
result[i].TagType = t.PkgPath() + "." + t.Name()
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
Providers: func() []providerJson {
|
||||
result := make([]providerJson, 0, len(module.providers))
|
||||
for _, p := range module.providers {
|
||||
pj := providerJson{}
|
||||
include := false
|
||||
|
||||
t := reflect.TypeOf(p)
|
||||
if t != nil {
|
||||
pj.Type = t.PkgPath() + "." + t.Name()
|
||||
include = true
|
||||
}
|
||||
|
||||
if dbg, ok := p.(Debuggable); ok {
|
||||
pj.Debug = dbg.GetDebugString()
|
||||
if pj.Debug != "" {
|
||||
include = true
|
||||
}
|
||||
}
|
||||
if include {
|
||||
result = append(result, pj)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
Debug: func() string {
|
||||
if dbg, ok := module.logicModule.(Debuggable); ok {
|
||||
return dbg.GetDebugString()
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}(),
|
||||
}
|
||||
buf, _ := json.Marshal(info)
|
||||
return buf
|
||||
}
|
||||
|
||||
// Generate out/soong/soong-debug-info.json Called if GENERATE_SOONG_DEBUG=true.
|
||||
func (this *Context) GenerateModuleDebugInfo(filename string) {
|
||||
err := os.MkdirAll(filepath.Dir(filename), 0777)
|
||||
if err != nil {
|
||||
// We expect this to be writable
|
||||
panic(fmt.Sprintf("couldn't create directory for soong module debug file %s: %s", filepath.Dir(filename), err))
|
||||
}
|
||||
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
// We expect this to be writable
|
||||
panic(fmt.Sprintf("couldn't create soong module debug file %s: %s", filename, err))
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
needComma := false
|
||||
f.WriteString("{\n\"modules\": [\n")
|
||||
|
||||
// TODO: Optimize this (parallel execution, etc) if it gets slow.
|
||||
this.visitAllModuleInfos(func(module *moduleInfo) {
|
||||
if needComma {
|
||||
f.WriteString(",\n")
|
||||
} else {
|
||||
needComma = true
|
||||
}
|
||||
|
||||
moduleData := getModuleDebugJson(module)
|
||||
f.Write(moduleData)
|
||||
})
|
||||
|
||||
f.WriteString("\n]\n}")
|
||||
}
|
||||
|
||||
var fileHeaderTemplate = `******************************************************************************
|
||||
*** This file is generated and should not be edited ***
|
||||
******************************************************************************
|
||||
|
|
Loading…
Reference in a new issue