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