blob: 169dab6670a7e1d79c57f436a8a16944af6407c4 [file] [log] [blame]
Justin DeMartinoac38d7e2019-10-15 17:45:05 -07001package 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}