| package extensions |
| |
| import ( |
| "strings" |
| |
| "github.com/google/blueprint/parser" |
| |
| "android/soong/bpfix/bpfix" |
| ) |
| |
| var fixSteps = bpfix.FixStepsExtension{ |
| Name: "partner-include-dirs", |
| Steps: []bpfix.FixStep{ |
| { |
| Name: "fixIncludeDirs", |
| Fix: fixIncludeDirs, |
| }, |
| }, |
| } |
| |
| func init() { |
| bpfix.RegisterFixStepExtension(&fixSteps) |
| } |
| |
| type includeDirFix struct { |
| libName string |
| libType string |
| variable string |
| subdir string |
| } |
| |
| var commonIncludeDirs = []includeDirFix{ |
| { |
| libName: "my_header_lib", |
| libType: "header_libs", |
| variable: "TARGET_OUT_HEADERS", |
| subdir: "/my_headers", |
| }, |
| } |
| |
| func findHeaderLib(e parser.Expression) (*includeDirFix, bool) { |
| if op, ok := e.(*parser.Operator); ok { |
| if op.Operator != '+' { |
| return nil, false |
| } |
| arg0, ok := op.Args[0].(*parser.Variable) |
| arg1, ok1 := op.Args[1].(*parser.String) |
| if !ok || !ok1 { |
| return nil, false |
| } |
| for _, lib := range commonIncludeDirs { |
| if arg0.Name == lib.variable && arg1.Value == lib.subdir { |
| return &lib, true |
| } |
| } |
| } |
| return nil, false |
| } |
| func searchThroughOperatorList(mod *parser.Module, e parser.Expression) { |
| if list, ok := e.(*parser.List); ok { |
| newList := make([]parser.Expression, 0, len(list.Values)) |
| for _, item := range list.Values { |
| if lib, found := findHeaderLib(item); found { |
| if lib.libName != "" { |
| addLibrary(mod, lib.libType, lib.libName) |
| } |
| } else { |
| newList = append(newList, item) |
| } |
| } |
| list.Values = newList |
| } |
| if op, ok := e.(*parser.Operator); ok { |
| searchThroughOperatorList(mod, op.Args[0]) |
| searchThroughOperatorList(mod, op.Args[1]) |
| } |
| } |
| func getLiteralListProperty(mod *parser.Module, name string) (list *parser.List, found bool) { |
| prop, ok := mod.GetProperty(name) |
| if !ok { |
| return nil, false |
| } |
| list, ok = prop.Value.(*parser.List) |
| return list, ok |
| } |
| func addLibrary(mod *parser.Module, libType string, libName string) { |
| var list, ok = getLiteralListProperty(mod, libType) |
| if !ok { |
| list = new(parser.List) |
| prop := new(parser.Property) |
| prop.Name = libType |
| prop.Value = list |
| mod.Properties = append(mod.Properties, prop) |
| } else { |
| for _, v := range list.Values { |
| if stringValue, ok := v.(*parser.String); ok && stringValue.Value == libName { |
| return |
| } |
| } |
| } |
| lib := new(parser.String) |
| lib.Value = libName |
| list.Values = append(list.Values, lib) |
| } |
| func fixIncludeDirs(f *bpfix.Fixer) error { |
| tree := f.Tree() |
| for _, def := range tree.Defs { |
| mod, ok := def.(*parser.Module) |
| if !ok { |
| continue |
| } |
| if !strings.HasPrefix(mod.Type, "cc_") { |
| continue |
| } |
| if prop, ok := mod.GetProperty("include_dirs"); ok { |
| searchThroughOperatorList(mod, prop.Value) |
| } |
| } |
| return nil |
| } |