1package extensions 2 3import ( 4 "strings" 5 6 "github.com/google/blueprint/parser" 7 8 "android/soong/bpfix/bpfix" 9) 10 11var fixSteps = bpfix.FixStepsExtension{ 12 Name: "partner-include-dirs", 13 Steps: []bpfix.FixStep{ 14 { 15 Name: "fixIncludeDirs", 16 Fix: fixIncludeDirs, 17 }, 18 }, 19} 20 21func init() { 22 bpfix.RegisterFixStepExtension(&fixSteps) 23} 24 25type includeDirFix struct { 26 libName string 27 libType string 28 variable string 29 subdir string 30} 31 32var commonIncludeDirs = []includeDirFix{ 33 { 34 libName: "my_header_lib", 35 libType: "header_libs", 36 variable: "TARGET_OUT_HEADERS", 37 subdir: "/my_headers", 38 }, 39} 40 41func findHeaderLib(e parser.Expression) (*includeDirFix, bool) { 42 if op, ok := e.(*parser.Operator); ok { 43 if op.Operator != '+' { 44 return nil, false 45 } 46 arg0, ok := op.Args[0].(*parser.Variable) 47 arg1, ok1 := op.Args[1].(*parser.String) 48 if !ok || !ok1 { 49 return nil, false 50 } 51 for _, lib := range commonIncludeDirs { 52 if arg0.Name == lib.variable && arg1.Value == lib.subdir { 53 return &lib, true 54 } 55 } 56 } 57 return nil, false 58} 59func searchThroughOperatorList(mod *parser.Module, e parser.Expression) { 60 if list, ok := e.(*parser.List); ok { 61 newList := make([]parser.Expression, 0, len(list.Values)) 62 for _, item := range list.Values { 63 if lib, found := findHeaderLib(item); found { 64 if lib.libName != "" { 65 addLibrary(mod, lib.libType, lib.libName) 66 } 67 } else { 68 newList = append(newList, item) 69 } 70 } 71 list.Values = newList 72 } 73 if op, ok := e.(*parser.Operator); ok { 74 searchThroughOperatorList(mod, op.Args[0]) 75 searchThroughOperatorList(mod, op.Args[1]) 76 } 77} 78func getLiteralListProperty(mod *parser.Module, name string) (list *parser.List, found bool) { 79 prop, ok := mod.GetProperty(name) 80 if !ok { 81 return nil, false 82 } 83 list, ok = prop.Value.(*parser.List) 84 return list, ok 85} 86func addLibrary(mod *parser.Module, libType string, libName string) { 87 var list, ok = getLiteralListProperty(mod, libType) 88 if !ok { 89 list = new(parser.List) 90 prop := new(parser.Property) 91 prop.Name = libType 92 prop.Value = list 93 mod.Properties = append(mod.Properties, prop) 94 } else { 95 for _, v := range list.Values { 96 if stringValue, ok := v.(*parser.String); ok && stringValue.Value == libName { 97 return 98 } 99 } 100 } 101 lib := new(parser.String) 102 lib.Value = libName 103 list.Values = append(list.Values, lib) 104} 105func fixIncludeDirs(f *bpfix.Fixer) error { 106 tree := f.Tree() 107 for _, def := range tree.Defs { 108 mod, ok := def.(*parser.Module) 109 if !ok { 110 continue 111 } 112 if !strings.HasPrefix(mod.Type, "cc_") { 113 continue 114 } 115 if prop, ok := mod.GetProperty("include_dirs"); ok { 116 searchThroughOperatorList(mod, prop.Value) 117 } 118 } 119 return nil 120} 121