Skip to content

Get run and test working against Swift Build. #8331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 12, 2025
6 changes: 3 additions & 3 deletions Sources/Commands/SwiftRunCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,10 @@ public struct SwiftRunCommand: AsyncSwiftCommand {
#else
let number_fds = getdtablesize()
#endif /* os(Android) */
// 2. close all file descriptors.

// 2. set to close all file descriptors on exec
for i in 3..<number_fds {
close(i)
_ = fcntl(i, F_SETFD, FD_CLOEXEC)
}
#endif /* os(FreeBSD) || os(OpenBSD) */
#endif
Expand Down
28 changes: 24 additions & 4 deletions Sources/CoreCommands/SwiftCommandState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ public final class SwiftCommandState {
self.observabilityHandler.progress,
self.observabilityHandler.prompt
)
let isXcodeBuildSystemEnabled = self.options.build.buildSystem.usesXcodeBuildEngine
let workspace = try Workspace(
fileSystem: self.fileSystem,
location: .init(
Expand All @@ -473,9 +472,9 @@ public final class SwiftCommandState {
configuration: .init(
skipDependenciesUpdates: options.resolver.skipDependencyUpdate,
prefetchBasedOnResolvedFile: options.resolver.shouldEnableResolverPrefetching,
shouldCreateMultipleTestProducts: toolWorkspaceConfiguration.wantsMultipleTestProducts || options.build.buildSystem.usesXcodeBuildEngine,
shouldCreateMultipleTestProducts: toolWorkspaceConfiguration.wantsMultipleTestProducts || options.build.buildSystem.shouldCreateMultipleTestProducts,
createREPLProduct: toolWorkspaceConfiguration.wantsREPLProduct,
additionalFileRules: isXcodeBuildSystemEnabled ? FileRuleDescription.xcbuildFileTypes : FileRuleDescription.swiftpmFileTypes,
additionalFileRules: options.build.buildSystem.additionalFileRules,
sharedDependenciesCacheEnabled: self.options.caching.useDependenciesCache,
fingerprintCheckingMode: self.options.security.fingerprintCheckingMode,
signingEntityCheckingMode: self.options.security.signingEntityCheckingMode,
Expand Down Expand Up @@ -805,12 +804,12 @@ public final class SwiftCommandState {
toolchain: toolchain,
triple: triple,
flags: options.build.buildFlags,
buildSystemKind: options.build.buildSystem,
pkgConfigDirectories: options.locations.pkgConfigDirectories,
architectures: options.build.architectures,
workers: options.build.jobs ?? UInt32(ProcessInfo.processInfo.activeProcessorCount),
sanitizers: options.build.enabledSanitizers,
indexStoreMode: options.build.indexStoreMode.buildParameter,
isXcodeBuildSystemEnabled: options.build.buildSystem.usesXcodeBuildEngine,
prepareForIndexing: prepareForIndexingMode,
debuggingParameters: .init(
debugInfoFormat: options.build.debugInfoFormat.buildParameter,
Expand Down Expand Up @@ -1035,6 +1034,26 @@ public final class SwiftCommandState {
}
}

extension BuildSystemProvider.Kind {
fileprivate var shouldCreateMultipleTestProducts: Bool {
switch self {
case .xcode, .swiftbuild:
return true
case .native:
return false
}
}

fileprivate var additionalFileRules: [FileRuleDescription] {
switch self {
case .xcode, .swiftbuild:
return FileRuleDescription.xcbuildFileTypes
case .native:
return FileRuleDescription.swiftpmFileTypes
}
}
}

/// Returns path of the nearest directory containing the manifest file w.r.t
/// current working directory.
private func findPackageRoot(fileSystem: FileSystem) -> AbsolutePath? {
Expand Down Expand Up @@ -1202,3 +1221,4 @@ extension Basics.Diagnostic {
.error(arguments.map { "'\($0)'" }.spm_localizedJoin(type: .conjunction) + " are mutually exclusive")
}
}

21 changes: 14 additions & 7 deletions Sources/SPMBuildCore/BuildParameters/BuildParameters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,7 @@ public struct BuildParameters: Encodable {
}
}

/// Whether the Xcode build system is used.
public var isXcodeBuildSystemEnabled: Bool
public var buildSystemKind: BuildSystemProvider.Kind

public var shouldSkipBuilding: Bool

Expand Down Expand Up @@ -152,13 +151,13 @@ public struct BuildParameters: Encodable {
toolchain: Toolchain,
triple: Triple? = nil,
flags: BuildFlags,
buildSystemKind: BuildSystemProvider.Kind = .native,
pkgConfigDirectories: [AbsolutePath] = [],
architectures: [String]? = nil,
workers: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount),
shouldCreateDylibForDynamicProducts: Bool = true,
sanitizers: EnabledSanitizers = EnabledSanitizers(),
indexStoreMode: IndexStoreMode = .auto,
isXcodeBuildSystemEnabled: Bool = false,
shouldSkipBuilding: Bool = false,
prepareForIndexing: PrepareForIndexingMode = .off,
debuggingParameters: Debugging? = nil,
Expand All @@ -179,6 +178,7 @@ public struct BuildParameters: Encodable {
self.configuration = configuration
self._toolchain = _Toolchain(toolchain: toolchain)
self.triple = triple
self.buildSystemKind = buildSystemKind
switch self.debuggingParameters.debugInfoFormat {
case .dwarf:
var flags = flags
Expand Down Expand Up @@ -214,7 +214,6 @@ public struct BuildParameters: Encodable {
self.shouldCreateDylibForDynamicProducts = shouldCreateDylibForDynamicProducts
self.sanitizers = sanitizers
self.indexStoreMode = indexStoreMode
self.isXcodeBuildSystemEnabled = isXcodeBuildSystemEnabled
self.shouldSkipBuilding = shouldSkipBuilding
self.prepareForIndexing = prepareForIndexing
self.driverParameters = driverParameters
Expand All @@ -225,9 +224,17 @@ public struct BuildParameters: Encodable {

/// The path to the build directory (inside the data directory).
public var buildPath: AbsolutePath {
if isXcodeBuildSystemEnabled {
return dataPath.appending(components: "Products", configuration.dirname.capitalized)
} else {
// TODO: query the build system for this.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I filed swiftlang/swift-build#286 to track the API needed for this.

switch buildSystemKind {
case .xcode, .swiftbuild:
var configDir: String = configuration.dirname.capitalized
if self.triple.isWindows() {
configDir += "-windows"
} else if self.triple.isLinux() {
configDir += "-linux"
}
return dataPath.appending(components: "Products", configDir)
case .native:
return dataPath.appending(component: configuration.dirname)
}
}
Expand Down
11 changes: 1 addition & 10 deletions Sources/SPMBuildCore/BuildSystem/BuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public protocol BuildSystemFactory {

public struct BuildSystemProvider {
// TODO: In the future, we may want this to be about specific capabilities of a build system rather than choosing a concrete one.
public enum Kind: String, CaseIterable {
public enum Kind: String, Codable, CaseIterable {
case native
case swiftbuild
case xcode
Expand Down Expand Up @@ -169,15 +169,6 @@ public struct BuildSystemProvider {
}
}

extension BuildSystemProvider.Kind {
public var usesXcodeBuildEngine: Bool {
switch self {
case .native: return false
case .swiftbuild: return false
case .xcode: return true
}
}
}
private enum Errors: Swift.Error {
case buildSystemProviderNotRegistered(kind: BuildSystemProvider.Kind)
}
Expand Down
13 changes: 9 additions & 4 deletions Sources/SPMBuildCore/Triple+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@ extension Triple {

extension Triple {
public func platformBuildPathComponent(buildSystem: BuildSystemProvider.Kind) -> String {
// Use "apple" as the subdirectory because in theory Xcode build system
// can be used to build for any Apple platform and it has its own
// conventions for build subpaths based on platforms.
buildSystem.usesXcodeBuildEngine ? "apple" : self.platformBuildPathComponent
switch buildSystem {
case .xcode:
// Use "apple" as the subdirectory because in theory Xcode build system
// can be used to build for any Apple platform and it has its own
// conventions for build subpaths based on platforms.
return "apple"
case .swiftbuild, .native:
return self.platformBuildPathComponent
}
}
}
Loading