@@ -104,6 +104,15 @@ public struct PCFileFinder {
104
104
}
105
105
}
106
106
107
+ /// Informations to track circular dependencies and other PkgConfig issues
108
+ public class LoadingContext {
109
+ public init ( ) {
110
+ pkgConfigStack = [ String] ( )
111
+ }
112
+
113
+ public var pkgConfigStack : [ String ]
114
+ }
115
+
107
116
/// Information on an individual `pkg-config` supported package.
108
117
public struct PkgConfig {
109
118
/// The name of the package.
@@ -138,8 +147,10 @@ public struct PkgConfig {
138
147
additionalSearchPaths: [ AbsolutePath ] = [ ] ,
139
148
diagnostics: DiagnosticsEngine ,
140
149
fileSystem: FileSystem = localFileSystem,
141
- brewPrefix: AbsolutePath ?
150
+ brewPrefix: AbsolutePath ? ,
151
+ loadingContext: LoadingContext = LoadingContext ( )
142
152
) throws {
153
+ loadingContext. pkgConfigStack. append ( name)
143
154
144
155
if let path = try ? AbsolutePath ( validating: name) {
145
156
guard fileSystem. isFile ( path) else { throw PkgConfigError . couldNotFindConfigFile ( name: name) }
@@ -163,13 +174,19 @@ public struct PkgConfig {
163
174
var libs = [ String] ( )
164
175
165
176
for dep in dependencies {
177
+ if let index = loadingContext. pkgConfigStack. firstIndex ( of: dep) {
178
+ diagnostics. emit ( warning: " circular dependency detected while parsing \( loadingContext. pkgConfigStack [ 0 ] ) : \( loadingContext. pkgConfigStack [ index..< loadingContext. pkgConfigStack. count] . joined ( separator: " -> " ) ) -> \( dep) " )
179
+ continue
180
+ }
181
+
166
182
// FIXME: This is wasteful, we should be caching the PkgConfig result.
167
183
let pkg = try PkgConfig (
168
- name: dep,
184
+ name: dep,
169
185
additionalSearchPaths: additionalSearchPaths,
170
186
diagnostics: diagnostics,
171
187
fileSystem: fileSystem,
172
- brewPrefix: brewPrefix
188
+ brewPrefix: brewPrefix,
189
+ loadingContext: loadingContext
173
190
)
174
191
175
192
cFlags += pkg. cFlags
@@ -184,6 +201,8 @@ public struct PkgConfig {
184
201
185
202
self . cFlags = parser. cFlags + dependencyFlags. cFlags + privateDependencyFlags. cFlags
186
203
self . libs = parser. libs + dependencyFlags. libs
204
+
205
+ loadingContext. pkgConfigStack. removeLast ( ) ;
187
206
}
188
207
189
208
private static var envSearchPaths : [ AbsolutePath ] {
@@ -408,3 +427,4 @@ public struct PkgConfigParser {
408
427
return splits
409
428
}
410
429
}
430
+
0 commit comments