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
|
Cpuprofile string
|
||||||
Memprofile string
|
Memprofile string
|
||||||
TraceFile string
|
TraceFile string
|
||||||
|
|
||||||
|
// Debug data json file
|
||||||
|
ModuleDebugFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterGoModuleTypes adds module types to build tools written in golang
|
// 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...)
|
ninjaDeps = append(ninjaDeps, buildActionsDeps...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if args.ModuleDebugFile != "" {
|
||||||
|
ctx.GenerateModuleDebugInfo(args.ModuleDebugFile)
|
||||||
|
}
|
||||||
|
|
||||||
if stopBefore == StopBeforeWriteNinja {
|
if stopBefore == StopBeforeWriteNinja {
|
||||||
return ninjaDeps, nil
|
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) {
|
func (c *Context) requireNinjaVersion(major, minor, micro int) {
|
||||||
if major != 1 {
|
if major != 1 {
|
||||||
panic("ninja version with major version != 1 not supported")
|
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()
|
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 = `******************************************************************************
|
var fileHeaderTemplate = `******************************************************************************
|
||||||
*** This file is generated and should not be edited ***
|
*** This file is generated and should not be edited ***
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
|
|
Loading…
Reference in a new issue