Skip to content

Commit 1863e35

Browse files
authored
Add --pkg-config-path to LocationOptions (#5949)
Resolves #5815. Having a specific `--pkg-config-path` option for this means we have something that's less fragile and easier to report errors on than `PKG_CONFIG_PATH` environment variable. Added `pkgConfigDirectory` to `LocationOptions`, which is propagated to `BuildPlan` as a function or initializer argument.
1 parent aa08975 commit 1863e35

19 files changed

Lines changed: 212 additions & 54 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ Note: This is in reverse chronological order, so newer entries are added to the
33
Swift 5.8
44
-----------
55

6+
* [#5949]
7+
8+
New `--pkg-config-path` option on `build`, `test`, and `run` commands has been
9+
introduced as an alternative to passing `PKG_CONFIG_PATH` environment variable.
10+
It allows specifying alternative path to search for `.pc` files used by
11+
`pkg-config`. Use the option multiple times to specify more than one path.
12+
613
* [#5874]
714

815
In packages using tools version 5.8 or later, Foundation is no longer implicitly imported into package manifests. If Foundation APIs are used, the module needs to be imported explicitly.

Sources/Build/BuildOperation.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
7979
/// The output stream for the build delegate.
8080
private let outputStream: OutputByteStream
8181

82-
/// The verbosity level to print out at
82+
/// The verbosity level to use for diagnostics.
8383
private let logLevel: Basics.Diagnostic.Severity
8484

85-
/// File system to operate on
85+
/// File system to operate on.
8686
private let fileSystem: TSCBasic.FileSystem
8787

88-
/// ObservabilityScope with which to emit diagnostics
88+
/// ObservabilityScope with which to emit diagnostics.
8989
private let observabilityScope: ObservabilityScope
9090

9191
public var builtTestProducts: [BuiltTestProduct] {
@@ -95,6 +95,9 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
9595
/// File rules to determine resource handling behavior.
9696
private let additionalFileRules: [FileRuleDescription]
9797

98+
/// Alternative path to search for pkg-config `.pc` files.
99+
private let pkgConfigDirectories: [AbsolutePath]
100+
98101
public init(
99102
buildParameters: BuildParameters,
100103
cacheBuildManifest: Bool,
@@ -103,6 +106,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
103106
pluginScriptRunner: PluginScriptRunner,
104107
pluginWorkDirectory: AbsolutePath,
105108
disableSandboxForPluginCommands: Bool,
109+
pkgConfigDirectories: [AbsolutePath],
106110
outputStream: OutputByteStream,
107111
logLevel: Basics.Diagnostic.Severity,
108112
fileSystem: TSCBasic.FileSystem,
@@ -118,6 +122,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
118122
self.additionalFileRules = additionalFileRules
119123
self.pluginScriptRunner = pluginScriptRunner
120124
self.pluginWorkDirectory = pluginWorkDirectory
125+
self.pkgConfigDirectories = pkgConfigDirectories
121126
self.disableSandboxForPluginCommands = disableSandboxForPluginCommands
122127
self.outputStream = outputStream
123128
self.logLevel = logLevel
@@ -399,6 +404,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
399404
builtToolsDir: self.buildParameters.buildPath,
400405
buildEnvironment: self.buildParameters.buildEnvironment,
401406
toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory],
407+
pkgConfigDirectories: self.pkgConfigDirectories,
402408
pluginScriptRunner: self.pluginScriptRunner,
403409
observabilityScope: self.observabilityScope,
404410
fileSystem: self.fileSystem

Sources/Build/BuildPlan.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2416,7 +2416,12 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
24162416
else {
24172417
pkgConfigCache[target] = ([], [])
24182418
}
2419-
let results = try pkgConfigArgs(for: target, fileSystem: self.fileSystem, observabilityScope: self.observabilityScope)
2419+
let results = try pkgConfigArgs(
2420+
for: target,
2421+
pkgConfigDirectories: buildParameters.pkgConfigDirectories,
2422+
fileSystem: fileSystem,
2423+
observabilityScope: observabilityScope
2424+
)
24202425
var ret: [(cFlags: [String], libs: [String])] = []
24212426
for result in results {
24222427
ret.append((result.cFlags, result.libs))

Sources/Commands/PackageTools/PluginCommand.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ struct PluginCommand: SwiftCommand {
187187
accessibleTools: accessibleTools,
188188
writableDirectories: writableDirectories,
189189
readOnlyDirectories: readOnlyDirectories,
190+
pkgConfigDirectories: swiftTool.options.locations.pkgConfigDirectories,
190191
fileSystem: swiftTool.fileSystem,
191192
observabilityScope: swiftTool.observabilityScope,
192193
callbackQueue: delegateQueue,

Sources/CoreCommands/BuildSystemSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extension SwiftTool {
3434
pluginScriptRunner: self.getPluginScriptRunner(),
3535
pluginWorkDirectory: try self.getActiveWorkspace().location.pluginWorkingDirectory,
3636
disableSandboxForPluginCommands: self.options.security.shouldDisableSandbox,
37+
pkgConfigDirectories: self.options.locations.pkgConfigDirectories,
3738
outputStream: customOutputStream ?? self.outputStream,
3839
logLevel: customLogLevel ?? self.logLevel,
3940
fileSystem: self.fileSystem,

Sources/CoreCommands/Options.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public struct LocationOptions: ParsableArguments {
8686

8787
@Option(name: .customLong("experimental-destinations-path"), help: .hidden, completion: .directory)
8888
public var crossCompilationDestinationsDirectory: AbsolutePath?
89+
90+
@Option(
91+
name: .customLong("pkg-config-path"),
92+
help:
93+
"""
94+
Specify alternative path to search for pkg-config `.pc` files. Use the option multiple times to
95+
specify more than one path.
96+
""",
97+
completion: .directory)
98+
public var pkgConfigDirectories: [AbsolutePath] = []
8999
}
90100

91101
public struct CachingOptions: ParsableArguments {

Sources/CoreCommands/SwiftTool.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,11 @@ public final class SwiftTool {
297297
(packageRoot ?? cwd).appending(component: ".build")
298298

299299
// make sure common directories are created
300-
self.sharedSecurityDirectory = try getSharedSecurityDirectory(options: self.options, fileSystem: fileSystem)
301-
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(options: self.options, fileSystem: fileSystem)
302-
self.sharedCacheDirectory = try getSharedCacheDirectory(options: self.options, fileSystem: fileSystem)
300+
self.sharedSecurityDirectory = try getSharedSecurityDirectory(options: options, fileSystem: fileSystem)
301+
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(options: options, fileSystem: fileSystem)
302+
self.sharedCacheDirectory = try getSharedCacheDirectory(options: options, fileSystem: fileSystem)
303303
self.sharedCrossCompilationDestinationsDirectory = try fileSystem.getSharedCrossCompilationDestinationsDirectory(
304-
explicitDirectory: self.options.locations.crossCompilationDestinationsDirectory
304+
explicitDirectory: options.locations.crossCompilationDestinationsDirectory
305305
)
306306

307307
// set global process logging handler
@@ -594,6 +594,7 @@ public final class SwiftTool {
594594
archs: options.build.archs,
595595
flags: options.build.buildFlags,
596596
xcbuildFlags: options.build.xcbuildFlags,
597+
pkgConfigDirectories: options.locations.pkgConfigDirectories,
597598
jobs: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
598599
shouldLinkStaticSwiftStdlib: options.linker.shouldLinkStaticSwiftStdlib,
599600
canRenameEntrypointFunctionName: DriverSupport.checkSupportedFrontendFlags(

Sources/PackageLoading/Target+PkgConfig.swift

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,28 @@ public struct PkgConfigResult {
5858
}
5959

6060
/// Get pkgConfig result for a system library target.
61-
public func pkgConfigArgs(for target: SystemLibraryTarget, brewPrefix: AbsolutePath? = .none, fileSystem: FileSystem, observabilityScope: ObservabilityScope) throws -> [PkgConfigResult] {
61+
public func pkgConfigArgs(
62+
for target: SystemLibraryTarget,
63+
pkgConfigDirectories: [AbsolutePath],
64+
brewPrefix: AbsolutePath? = .none,
65+
fileSystem: FileSystem,
66+
observabilityScope: ObservabilityScope
67+
) throws -> [PkgConfigResult] {
6268
// If there is no pkg config name defined, we're done.
6369
guard let pkgConfigNames = target.pkgConfig else { return [] }
6470

6571
// Compute additional search paths for the provider, if any.
6672
let provider = target.providers?.first { $0.isAvailable }
67-
let additionalSearchPaths = try provider?.pkgConfigSearchPath(brewPrefixOverride: brewPrefix) ?? []
6873

69-
var ret: [PkgConfigResult] = []
74+
let additionalSearchPaths: [AbsolutePath]
75+
// Give priority to `pkgConfigDirectories` passed as an argument to this function.
76+
if let providerSearchPaths = try provider?.pkgConfigSearchPath(brewPrefixOverride: brewPrefix) {
77+
additionalSearchPaths = pkgConfigDirectories + providerSearchPaths
78+
} else {
79+
additionalSearchPaths = pkgConfigDirectories
80+
}
81+
82+
var ret: [PkgConfigResult] = []
7083
// Get the pkg config flags.
7184
for pkgConfigName in pkgConfigNames.components(separatedBy: " ") {
7285
let result: PkgConfigResult
@@ -92,19 +105,21 @@ public func pkgConfigArgs(for target: SystemLibraryTarget, brewPrefix: AbsoluteP
92105
}
93106

94107
result = PkgConfigResult(
95-
pkgConfigName: pkgConfigName,
96-
cFlags: cFlags,
97-
libs: libs,
98-
error: error,
99-
provider: provider
108+
pkgConfigName: pkgConfigName,
109+
cFlags: cFlags,
110+
libs: libs,
111+
error: error,
112+
provider: provider
100113
)
101114
} catch {
102115
result = PkgConfigResult(pkgConfigName: pkgConfigName, error: error, provider: provider)
103116
}
104117

105118
// If there is no pc file on system and we have an available provider, emit a warning.
106119
if let provider = result.provider, result.couldNotFindConfigFile {
107-
observabilityScope.emit(warning: "you may be able to install \(result.pkgConfigName) using your system-packager:\n\(provider.installText)")
120+
observabilityScope.emit(
121+
warning: "you may be able to install \(result.pkgConfigName) using your system-packager:\n\(provider.installText)"
122+
)
108123
} else if let error = result.error {
109124
observabilityScope.emit(
110125
warning: "\(error)",

Sources/PackageModel/BuildEnvironment.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
/// A build environment with which to evaluation conditions.
13+
/// A build environment with which to evaluate conditions.
1414
public struct BuildEnvironment: Codable {
1515
public let platform: Platform
1616
public let configuration: BuildConfiguration?

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ public struct BuildParameters: Encodable {
137137
/// Extra build flags.
138138
public var flags: BuildFlags
139139

140+
/// An array of paths to search for pkg-config `.pc` files.
141+
public var pkgConfigDirectories: [AbsolutePath]
142+
140143
/// How many jobs should llbuild and the Swift compiler spawn
141144
public var jobs: UInt32
142145

@@ -155,7 +158,7 @@ public struct BuildParameters: Encodable {
155158
/// Whether to enable code coverage.
156159
public var enableCodeCoverage: Bool
157160

158-
/// Whether to enable generation of `.swiftinterface` files alongside
161+
/// Whether to enable generation of `.swiftinterface` files alongside.
159162
/// `.swiftmodule`s.
160163
public var enableParseableModuleInterfaces: Bool
161164

@@ -168,10 +171,10 @@ public struct BuildParameters: Encodable {
168171
/// to a separate process.
169172
public var useIntegratedSwiftDriver: Bool
170173

171-
/// Whether to use the explicit module build flow (with the integrated driver)
174+
/// Whether to use the explicit module build flow (with the integrated driver).
172175
public var useExplicitModuleBuild: Bool
173176

174-
/// A flag that inidcates this build should check whether targets only import
177+
/// A flag that inidcates this build should check whether targets only import.
175178
/// their explicitly-declared dependencies
176179
public var explicitTargetDependencyImportCheckingMode: TargetDependencyImportCheckingMode
177180

@@ -231,6 +234,7 @@ public struct BuildParameters: Encodable {
231234
archs: [String] = [],
232235
flags: BuildFlags,
233236
xcbuildFlags: [String] = [],
237+
pkgConfigDirectories: [AbsolutePath] = [],
234238
jobs: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount),
235239
shouldLinkStaticSwiftStdlib: Bool = false,
236240
shouldEnableManifestCaching: Bool = false,
@@ -261,6 +265,7 @@ public struct BuildParameters: Encodable {
261265
self.triple = triple
262266
self.archs = archs
263267
self.flags = flags
268+
self.pkgConfigDirectories = pkgConfigDirectories
264269
self.xcbuildFlags = xcbuildFlags
265270
self.jobs = jobs
266271
self.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib

0 commit comments

Comments
 (0)