30
30
package builder
31
31
32
32
import (
33
- "path/filepath"
34
- "strings"
33
+ "fmt"
35
34
36
- "github.com/arduino/arduino-builder/constants"
37
35
"github.com/arduino/arduino-builder/types"
38
- "github.com/arduino/arduino-builder/utils"
39
- "github.com/bcmi-labs/arduino-cli/arduino/cores"
40
36
"github.com/bcmi-labs/arduino-cli/arduino/libraries"
41
37
)
42
38
43
39
func ResolveLibrary (ctx * types.Context , header string ) * libraries.Library {
44
- headerToLibraries := ctx .HeaderToLibraries
45
- platforms := []* cores.PlatformRelease {ctx .ActualPlatform , ctx .TargetPlatform }
46
- libraryResolutionResults := ctx .LibrariesResolutionResults
40
+ resolver := ctx .LibrariesResolver
47
41
importedLibraries := ctx .ImportedLibraries
48
42
49
- libs := append ([]* libraries.Library {}, headerToLibraries [header ]... )
43
+ candidates := resolver .AlternativesFor (header )
44
+ fmt .Printf ("ResolveLibrary(%s)\n " , header )
45
+ fmt .Printf (" -> candidates: %s\n " , candidates )
50
46
51
- if libs == nil || len (libs ) == 0 {
47
+ if candidates == nil || len (candidates ) == 0 {
52
48
return nil
53
49
}
54
50
55
- if importedLibraryContainsOneOfCandidates (importedLibraries , libs ) {
56
- return nil
57
- }
58
-
59
- if len (libs ) == 1 {
60
- return libs [0 ]
61
- }
62
-
63
- reverse (libs )
64
-
65
- var library * libraries.Library
66
-
67
- for _ , platform := range platforms {
68
- if platform != nil {
69
- library = findBestLibraryWithHeader (header , librariesCompatibleWithPlatform (libs , platform , true ))
51
+ for _ , candidate := range candidates {
52
+ if importedLibraries .Contains (candidate ) {
53
+ return nil
70
54
}
71
55
}
72
56
73
- if library == nil {
74
- library = findBestLibraryWithHeader (header , libs )
75
- }
76
-
77
- if library == nil {
78
- // reorder libraries to promote fully compatible ones
79
- for _ , platform := range platforms {
80
- if platform != nil {
81
- libs = append (librariesCompatibleWithPlatform (libs , platform , false ), libs ... )
82
- }
83
- }
84
- library = libs [0 ]
57
+ selected := resolver .ResolveFor (header , ctx .TargetPlatform .Platform .Architecture )
58
+ if alreadyImported := importedLibraries .FindByName (selected .Name ); alreadyImported != nil {
59
+ selected = alreadyImported
85
60
}
86
61
87
- library = useAlreadyImportedLibraryWithSameNameIfExists (library , importedLibraries )
88
-
89
- libraryResolutionResults [header ] = types.LibraryResolutionResult {
90
- Library : library ,
91
- NotUsedLibraries : filterOutLibraryFrom (libs , library ),
62
+ ctx .LibrariesResolutionResults [header ] = types.LibraryResolutionResult {
63
+ Library : selected ,
64
+ NotUsedLibraries : filterOutLibraryFrom (candidates , selected ),
92
65
}
93
66
94
- return library
95
- }
96
-
97
- //facepalm. sort.Reverse needs an Interface that implements Len/Less/Swap. It's a slice! What else for reversing it?!?
98
- func reverse (data []* libraries.Library ) {
99
- for i , j := 0 , len (data )- 1 ; i < j ; i , j = i + 1 , j - 1 {
100
- data [i ], data [j ] = data [j ], data [i ]
101
- }
67
+ return selected
102
68
}
103
69
104
- func importedLibraryContainsOneOfCandidates (imported []* libraries.Library , candidates []* libraries.Library ) bool {
105
- for _ , i := range imported {
106
- for _ , j := range candidates {
107
- if i == j {
108
- return true
109
- }
110
- }
111
- }
112
- return false
113
- }
114
-
115
- func useAlreadyImportedLibraryWithSameNameIfExists (library * libraries.Library , imported []* libraries.Library ) * libraries.Library {
116
- for _ , lib := range imported {
117
- if lib .Name == library .Name {
118
- return lib
119
- }
120
- }
121
- return library
122
- }
123
-
124
- func filterOutLibraryFrom (libs []* libraries.Library , libraryToRemove * libraries.Library ) []* libraries.Library {
70
+ func filterOutLibraryFrom (libs libraries.List , libraryToRemove * libraries.Library ) libraries.List {
125
71
filteredOutLibraries := []* libraries.Library {}
126
72
for _ , lib := range libs {
127
73
if lib != libraryToRemove {
@@ -130,107 +76,3 @@ func filterOutLibraryFrom(libs []*libraries.Library, libraryToRemove *libraries.
130
76
}
131
77
return filteredOutLibraries
132
78
}
133
-
134
- func libraryCompatibleWithPlatform (library * libraries.Library , platform * cores.PlatformRelease ) (bool , bool ) {
135
- if len (library .Architectures ) == 0 {
136
- return true , true
137
- }
138
- if utils .SliceContains (library .Architectures , constants .LIBRARY_ALL_ARCHS ) {
139
- return true , true
140
- }
141
- return utils .SliceContains (library .Architectures , platform .Platform .Architecture ), false
142
- }
143
-
144
- func libraryCompatibleWithAllPlatforms (library * libraries.Library ) bool {
145
- if utils .SliceContains (library .Architectures , constants .LIBRARY_ALL_ARCHS ) {
146
- return true
147
- }
148
- return false
149
- }
150
-
151
- func librariesCompatibleWithPlatform (libs []* libraries.Library , platform * cores.PlatformRelease , reorder bool ) []* libraries.Library {
152
- var compatibleLibraries []* libraries.Library
153
- for _ , library := range libs {
154
- compatible , generic := libraryCompatibleWithPlatform (library , platform )
155
- if compatible {
156
- if ! generic && len (compatibleLibraries ) != 0 && libraryCompatibleWithAllPlatforms (compatibleLibraries [0 ]) && reorder == true {
157
- //priority inversion
158
- compatibleLibraries = append ([]* libraries.Library {library }, compatibleLibraries ... )
159
- } else {
160
- compatibleLibraries = append (compatibleLibraries , library )
161
- }
162
- }
163
- }
164
-
165
- return compatibleLibraries
166
- }
167
-
168
- func findBestLibraryWithHeader (header string , libs []* libraries.Library ) * libraries.Library {
169
- headerName := strings .Replace (header , filepath .Ext (header ), constants .EMPTY_STRING , - 1 )
170
-
171
- var library * libraries.Library
172
- for _ , headerName := range []string {headerName , strings .ToLower (headerName )} {
173
- library = findLibWithName (headerName , libs )
174
- if library != nil {
175
- return library
176
- }
177
- library = findLibWithName (headerName + "-master" , libs )
178
- if library != nil {
179
- return library
180
- }
181
- library = findLibWithNameStartingWith (headerName , libs )
182
- if library != nil {
183
- return library
184
- }
185
- library = findLibWithNameEndingWith (headerName , libs )
186
- if library != nil {
187
- return library
188
- }
189
- library = findLibWithNameContaining (headerName , libs )
190
- if library != nil {
191
- return library
192
- }
193
- }
194
-
195
- return nil
196
- }
197
-
198
- func findLibWithName (name string , libraries []* libraries.Library ) * libraries.Library {
199
- for _ , library := range libraries {
200
- if simplifyName (library .Name ) == simplifyName (name ) {
201
- return library
202
- }
203
- }
204
- return nil
205
- }
206
-
207
- func findLibWithNameStartingWith (name string , libraries []* libraries.Library ) * libraries.Library {
208
- for _ , library := range libraries {
209
- if strings .HasPrefix (simplifyName (library .Name ), simplifyName (name )) {
210
- return library
211
- }
212
- }
213
- return nil
214
- }
215
-
216
- func findLibWithNameEndingWith (name string , libraries []* libraries.Library ) * libraries.Library {
217
- for _ , library := range libraries {
218
- if strings .HasSuffix (simplifyName (library .Name ), simplifyName (name )) {
219
- return library
220
- }
221
- }
222
- return nil
223
- }
224
-
225
- func findLibWithNameContaining (name string , libraries []* libraries.Library ) * libraries.Library {
226
- for _ , library := range libraries {
227
- if strings .Contains (simplifyName (library .Name ), simplifyName (name )) {
228
- return library
229
- }
230
- }
231
- return nil
232
- }
233
-
234
- func simplifyName (name string ) string {
235
- return strings .ToLower (strings .Replace (name , "_" , " " , - 1 ))
236
- }
0 commit comments