Skip to content
5 changes: 5 additions & 0 deletions Sources/Build/BuildOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,16 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
/// File rules to determine resource handling behavior.
private let additionalFileRules: [FileRuleDescription]

private let pkgConfigDirectory: AbsolutePath?

public init(
buildParameters: BuildParameters,
cacheBuildManifest: Bool,
packageGraphLoader: @escaping () throws -> PackageGraph,
additionalFileRules: [FileRuleDescription],
pluginScriptRunner: PluginScriptRunner,
pluginWorkDirectory: AbsolutePath,
pkgConfigDirectory: AbsolutePath?,
Comment thread
MaxDesiatov marked this conversation as resolved.
Outdated
disableSandboxForPluginCommands: Bool,
outputStream: OutputByteStream,
logLevel: Basics.Diagnostic.Severity,
Expand All @@ -118,6 +121,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
self.additionalFileRules = additionalFileRules
self.pluginScriptRunner = pluginScriptRunner
self.pluginWorkDirectory = pluginWorkDirectory
self.pkgConfigDirectory = pkgConfigDirectory
self.disableSandboxForPluginCommands = disableSandboxForPluginCommands
self.outputStream = outputStream
self.logLevel = logLevel
Expand Down Expand Up @@ -399,6 +403,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
builtToolsDir: self.buildParameters.buildPath,
buildEnvironment: self.buildParameters.buildEnvironment,
toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory],
pkgConfigDirectory: self.pkgConfigDirectory,
pluginScriptRunner: self.pluginScriptRunner,
observabilityScope: self.observabilityScope,
fileSystem: self.fileSystem
Expand Down
7 changes: 6 additions & 1 deletion Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2416,7 +2416,12 @@ public class BuildPlan: SPMBuildCore.BuildPlan {
else {
pkgConfigCache[target] = ([], [])
}
let results = try pkgConfigArgs(for: target, fileSystem: self.fileSystem, observabilityScope: self.observabilityScope)
let results = try pkgConfigArgs(
for: target,
pkgConfigDirectory: buildParameters.pkgConfigDirectory,
fileSystem: fileSystem,
observabilityScope: observabilityScope
)
var ret: [(cFlags: [String], libs: [String])] = []
for result in results {
ret.append((result.cFlags, result.libs))
Expand Down
1 change: 1 addition & 0 deletions Sources/CoreCommands/BuildSystemSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extension SwiftTool {
additionalFileRules: FileRuleDescription.swiftpmFileTypes,
pluginScriptRunner: self.getPluginScriptRunner(),
pluginWorkDirectory: try self.getActiveWorkspace().location.pluginWorkingDirectory,
pkgConfigDirectory: self.options.locations.pkgConfigDirectory,
disableSandboxForPluginCommands: self.options.security.shouldDisableSandbox,
outputStream: customOutputStream ?? self.outputStream,
logLevel: customLogLevel ?? self.logLevel,
Expand Down
6 changes: 6 additions & 0 deletions Sources/CoreCommands/Options.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ public struct LocationOptions: ParsableArguments {

@Option(name: .customLong("experimental-destinations-path"), help: .hidden, completion: .directory)
var crossCompilationDestinationsDirectory: AbsolutePath?

@Option(
name: .customLong("pkg-config-path"),
help: "Specify alternate paths to search for pkg-config `.pc` files,",
completion: .directory)
public var pkgConfigDirectory: AbsolutePath?
}

public struct CachingOptions: ParsableArguments {
Expand Down
12 changes: 8 additions & 4 deletions Sources/CoreCommands/SwiftTool.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ public final class SwiftTool {
/// Path to the cross-compilation SDK directory.
public let sharedCrossCompilationDestinationsDirectory: AbsolutePath?

public let pkgConfigDirectory: AbsolutePath?

/// Cancellator to handle cancellation of outstanding work when handling SIGINT
public let cancellator: Cancellator

Expand Down Expand Up @@ -296,10 +298,11 @@ public final class SwiftTool {
(packageRoot ?? cwd).appending(component: ".build")

// make sure common directories are created
self.sharedSecurityDirectory = try getSharedSecurityDirectory(options: self.options, fileSystem: fileSystem)
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(options: self.options, fileSystem: fileSystem)
self.sharedCacheDirectory = try getSharedCacheDirectory(options: self.options, fileSystem: fileSystem)
self.sharedCrossCompilationDestinationsDirectory = try getSharedCrossCompilationDestinationsDirectory(options: self.options, fileSystem: fileSystem)
self.sharedSecurityDirectory = try getSharedSecurityDirectory(options: options, fileSystem: fileSystem)
self.sharedConfigurationDirectory = try getSharedConfigurationDirectory(options: options, fileSystem: fileSystem)
self.sharedCacheDirectory = try getSharedCacheDirectory(options: options, fileSystem: fileSystem)
self.sharedCrossCompilationDestinationsDirectory = try getSharedCrossCompilationDestinationsDirectory(options: options, fileSystem: fileSystem)
self.pkgConfigDirectory = options.locations.pkgConfigDirectory
Comment thread
MaxDesiatov marked this conversation as resolved.
Outdated

// set global process logging handler
Process.loggingHandler = { self.observabilityScope.emit(debug: $0) }
Expand Down Expand Up @@ -591,6 +594,7 @@ public final class SwiftTool {
archs: options.build.archs,
flags: options.build.buildFlags,
xcbuildFlags: options.build.xcbuildFlags,
pkgConfigDirectory: options.locations.pkgConfigDirectory,
jobs: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
shouldLinkStaticSwiftStdlib: options.linker.shouldLinkStaticSwiftStdlib,
canRenameEntrypointFunctionName: DriverSupport.checkSupportedFrontendFlags(
Expand Down
30 changes: 21 additions & 9 deletions Sources/PackageLoading/Target+PkgConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,25 @@ public struct PkgConfigResult {
}

/// Get pkgConfig result for a system library target.
public func pkgConfigArgs(for target: SystemLibraryTarget, brewPrefix: AbsolutePath? = .none, fileSystem: FileSystem, observabilityScope: ObservabilityScope) throws -> [PkgConfigResult] {
public func pkgConfigArgs(
for target: SystemLibraryTarget,
pkgConfigDirectory: AbsolutePath?,
brewPrefix: AbsolutePath? = .none,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope
) throws -> [PkgConfigResult] {
// If there is no pkg config name defined, we're done.
guard let pkgConfigNames = target.pkgConfig else { return [] }

// Compute additional search paths for the provider, if any.
let provider = target.providers?.first { $0.isAvailable }
let additionalSearchPaths = try provider?.pkgConfigSearchPath(brewPrefixOverride: brewPrefix) ?? []
var additionalSearchPaths = try provider?.pkgConfigSearchPath(brewPrefixOverride: brewPrefix) ?? []
if let pkgConfigDirectory = pkgConfigDirectory {
// Give priority to `pkgConfigPath` passed as an argument to this function.
additionalSearchPaths.insert(pkgConfigDirectory, at: 0)
}

var ret: [PkgConfigResult] = []
var ret: [PkgConfigResult] = []
// Get the pkg config flags.
for pkgConfigName in pkgConfigNames.components(separatedBy: " ") {
let result: PkgConfigResult
Expand All @@ -92,19 +102,21 @@ public func pkgConfigArgs(for target: SystemLibraryTarget, brewPrefix: AbsoluteP
}

result = PkgConfigResult(
pkgConfigName: pkgConfigName,
cFlags: cFlags,
libs: libs,
error: error,
provider: provider
pkgConfigName: pkgConfigName,
cFlags: cFlags,
libs: libs,
error: error,
provider: provider
)
Comment thread
MaxDesiatov marked this conversation as resolved.
} catch {
result = PkgConfigResult(pkgConfigName: pkgConfigName, error: error, provider: provider)
}

// If there is no pc file on system and we have an available provider, emit a warning.
if let provider = result.provider, result.couldNotFindConfigFile {
observabilityScope.emit(warning: "you may be able to install \(result.pkgConfigName) using your system-packager:\n\(provider.installText)")
observabilityScope.emit(
warning: "you may be able to install \(result.pkgConfigName) using your system-packager:\n\(provider.installText)"
)
} else if let error = result.error {
observabilityScope.emit(
warning: "\(error)",
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageModel/BuildEnvironment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//

/// A build environment with which to evaluation conditions.
/// A build environment with which to evaluate conditions.
public struct BuildEnvironment: Codable {
public let platform: Platform
public let configuration: BuildConfiguration?
Expand Down
4 changes: 4 additions & 0 deletions Sources/SPMBuildCore/BuildParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ public struct BuildParameters: Encodable {
/// Extra build flags.
public var flags: BuildFlags

public var pkgConfigDirectory: AbsolutePath?

/// How many jobs should llbuild and the Swift compiler spawn
public var jobs: UInt32

Expand Down Expand Up @@ -231,6 +233,7 @@ public struct BuildParameters: Encodable {
archs: [String] = [],
flags: BuildFlags,
xcbuildFlags: [String] = [],
pkgConfigDirectory: AbsolutePath?,
jobs: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount),
shouldLinkStaticSwiftStdlib: Bool = false,
shouldEnableManifestCaching: Bool = false,
Expand Down Expand Up @@ -261,6 +264,7 @@ public struct BuildParameters: Encodable {
self.triple = triple
self.archs = archs
self.flags = flags
self.pkgConfigDirectory = pkgConfigDirectory
self.xcbuildFlags = xcbuildFlags
self.jobs = jobs
self.shouldLinkStaticSwiftStdlib = shouldLinkStaticSwiftStdlib
Expand Down
8 changes: 7 additions & 1 deletion Sources/SPMBuildCore/PluginContextSerializer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ typealias WireInput = HostToPluginMessage.InputContext
internal struct PluginContextSerializer {
let fileSystem: FileSystem
let buildEnvironment: BuildEnvironment
let pkgConfigDirectory: AbsolutePath?
var paths: [WireInput.Path] = []
var pathsToIds: [AbsolutePath: WireInput.Path.Id] = [:]
var targets: [WireInput.Target] = []
Expand Down Expand Up @@ -105,7 +106,12 @@ internal struct PluginContextSerializer {
var ldFlags: [String] = []
// FIXME: What do we do with any diagnostics here?
let observabilityScope = ObservabilitySystem({ _, _ in }).topScope
for result in try pkgConfigArgs(for: target, fileSystem: self.fileSystem, observabilityScope: observabilityScope) {
for result in try pkgConfigArgs(
for: target,
pkgConfigDirectory: pkgConfigDirectory,
fileSystem: fileSystem,
observabilityScope: observabilityScope
) {
if let error = result.error {
observabilityScope.emit(
warning: "\(error)",
Expand Down
10 changes: 9 additions & 1 deletion Sources/SPMBuildCore/PluginInvocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ extension PluginTarget {
/// - workingDirectory: The initial working directory of the invoked plugin.
/// - outputDirectory: A directory under which the plugin can write anything it wants to.
/// - toolNamesToPaths: A mapping from name of tools available to the plugin to the corresponding absolute paths.
/// - pkgConfigDirectory: A directory for searching `pkg-config` `.pc` files in it.
/// - fileSystem: The file system to which all of the paths refers.
///
/// - Returns: A PluginInvocationResult that contains the results of invoking the plugin.
Expand All @@ -58,6 +59,7 @@ extension PluginTarget {
toolNamesToTriples: [String: [String]],
writableDirectories: [AbsolutePath],
readOnlyDirectories: [AbsolutePath],
pkgConfigDirectory: AbsolutePath?,
fileSystem: FileSystem,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue,
Expand All @@ -75,7 +77,11 @@ extension PluginTarget {
// Serialize the plugin action to send as the initial message.
let initialMessage: Data
do {
var serializer = PluginContextSerializer(fileSystem: fileSystem, buildEnvironment: buildEnvironment)
var serializer = PluginContextSerializer(
fileSystem: fileSystem,
buildEnvironment: buildEnvironment,
pkgConfigDirectory: pkgConfigDirectory
)
let pluginWorkDirId = try serializer.serialize(path: outputDirectory)
let toolSearchDirIds = try toolSearchDirectories.map{ try serializer.serialize(path: $0) }
let toolNamesToPathIds = try toolNamesToPaths.mapValues{ try serializer.serialize(path: $0) }
Expand Down Expand Up @@ -318,6 +324,7 @@ extension PackageGraph {
builtToolsDir: AbsolutePath,
buildEnvironment: BuildEnvironment,
toolSearchDirectories: [AbsolutePath],
pkgConfigDirectory: AbsolutePath?,
pluginScriptRunner: PluginScriptRunner,
observabilityScope: ObservabilityScope,
fileSystem: FileSystem
Expand Down Expand Up @@ -468,6 +475,7 @@ extension PackageGraph {
toolNamesToTriples: toolNamesToTriples,
writableDirectories: writableDirectories,
readOnlyDirectories: readOnlyDirectories,
pkgConfigDirectory: pkgConfigDirectory,
fileSystem: fileSystem,
observabilityScope: observabilityScope,
callbackQueue: delegateQueue,
Expand Down
23 changes: 10 additions & 13 deletions Sources/XCBuildSupport/PIFBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,15 @@ import SPMBuildCore
struct PIFBuilderParameters {

/// Whether or not build for testability is enabled.
public let enableTestability: Bool
let enableTestability: Bool

/// Whether to create dylibs for dynamic library products.
public let shouldCreateDylibForDynamicProducts: Bool
let shouldCreateDylibForDynamicProducts: Bool

/// The path to the library directory of the active toolchain.
public let toolchainLibDir: AbsolutePath
let toolchainLibDir: AbsolutePath

/// Creates a `PIFBuilderParameters` instance.
/// - Parameters:
/// - enableTestability: Whether or not build for testability is enabled.
/// - shouldCreateDylibForDynamicProducts: Whether to create dylibs for dynamic library products.
public init(enableTestability: Bool, shouldCreateDylibForDynamicProducts: Bool, toolchainLibDir: AbsolutePath) {
self.enableTestability = enableTestability
self.shouldCreateDylibForDynamicProducts = shouldCreateDylibForDynamicProducts
self.toolchainLibDir = toolchainLibDir
}
let pkgConfigDirectory: AbsolutePath?
Comment thread
MaxDesiatov marked this conversation as resolved.
Outdated
}

/// PIF object builder for a package graph.
Expand Down Expand Up @@ -708,7 +700,12 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
var impartedSettings = PIF.BuildSettings()

var cFlags: [String] = []
for result in try pkgConfigArgs(for: systemTarget, fileSystem: fileSystem, observabilityScope: self.observabilityScope) {
for result in try pkgConfigArgs(
for: systemTarget,
pkgConfigDirectory: parameters.pkgConfigDirectory,
fileSystem: fileSystem,
observabilityScope: observabilityScope
) {
if let error = result.error {
self.observabilityScope.emit(
warning: "\(error)",
Expand Down
3 changes: 2 additions & 1 deletion Sources/XCBuildSupport/XcodeBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ extension PIFBuilderParameters {
self.init(
enableTestability: buildParameters.enableTestability,
shouldCreateDylibForDynamicProducts: buildParameters.shouldCreateDylibForDynamicProducts,
toolchainLibDir: (try? buildParameters.toolchain.toolchainLibDir) ?? .root
toolchainLibDir: (try? buildParameters.toolchain.toolchainLibDir) ?? .root,
pkgConfigDirectory: buildParameters.pkgConfigDirectory
)
}
}
Expand Down
1 change: 1 addition & 0 deletions Tests/BuildTests/MockBuildTestHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func mockBuildParameters(
hostTriple: hostTriple,
destinationTriple: destinationTriple,
flags: flags,
pkgConfigDirectory: nil,
jobs: 3,
shouldLinkStaticSwiftStdlib: shouldLinkStaticSwiftStdlib,
canRenameEntrypointFunctionName: canRenameEntrypointFunctionName,
Expand Down
Loading