Skip to content

Commit eef6247

Browse files
committed
Add FreeBSD support
This allows building Swift Build for FreeBSD hosts, as well as building for a FreeBSD target from a FreeBSD host. Also adds some speculative support for targeting OpenBSD on OpenBSD hosts, since SwiftPM has minimal support.
1 parent 712bddf commit eef6247

22 files changed

+118
-25
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ let package = Package(
110110
"SWBBuildSystem",
111111
"SWBServiceCore",
112112
"SWBTaskExecution",
113-
.product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .android, .windows])),
113+
.product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .openbsd, .android, .windows, .custom("freebsd")])),
114114
],
115115
exclude: ["CMakeLists.txt"],
116116
swiftSettings: swiftSettings(languageMode: .v5)),
@@ -201,7 +201,7 @@ let package = Package(
201201
"SWBCSupport",
202202
"SWBLibc",
203203
.product(name: "ArgumentParser", package: "swift-argument-parser"),
204-
.product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .android, .windows])),
204+
.product(name: "SystemPackage", package: "swift-system", condition: .when(platforms: [.linux, .openbsd, .android, .windows, .custom("freebsd")])),
205205
],
206206
exclude: ["CMakeLists.txt"],
207207
swiftSettings: swiftSettings(languageMode: .v5)),

Sources/SWBCore/Settings/Settings.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5331,6 +5331,10 @@ extension OperatingSystem {
53315331
return "windows"
53325332
case .linux:
53335333
return "linux"
5334+
case .freebsd:
5335+
return "freebsd"
5336+
case .openbsd:
5337+
return "openbsd"
53345338
case .android:
53355339
return "android"
53365340
case .unknown:

Sources/SWBGenericUnixPlatform/Plugin.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ struct GenericUnixPlatformSpecsExtension: SpecificationsExtension {
3939
}
4040

4141
func specificationDomains() -> [String: [String]] {
42-
["linux": ["generic-unix"]]
42+
[
43+
"linux": ["generic-unix"],
44+
"freebsd": ["generic-unix"],
45+
"openbsd": ["generic-unix"],
46+
]
4347
}
4448
}
4549

@@ -73,9 +77,9 @@ struct GenericUnixSDKRegistryExtension: SDKRegistryExtension {
7377

7478
let defaultProperties: [String: PropertyListItem]
7579
switch operatingSystem {
76-
case .linux:
80+
case .linux, .freebsd:
7781
defaultProperties = [
78-
// Workaround to avoid `-dependency_info` on Linux.
82+
// Workaround to avoid `-dependency_info`.
7983
"LD_DEPENDENCY_INFO_FILE": .plString(""),
8084

8185
"GENERATE_TEXT_BASED_STUBS": "NO",
@@ -167,6 +171,6 @@ struct GenericUnixToolchainRegistryExtension: ToolchainRegistryExtension {
167171
extension OperatingSystem {
168172
/// Whether the Core is allowed to create a fallback toolchain, SDK, and platform for this operating system in cases where no others have been provided.
169173
var createFallbackSystemToolchain: Bool {
170-
return self == .linux
174+
return self == .linux || self == .freebsd || self == .openbsd
171175
}
172176
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
(
14+
{
15+
Domain = freebsd;
16+
Identifier = com.apple.pbx.linkers.libtool;
17+
BasedOn = generic-unix:com.apple.pbx.linkers.libtool;
18+
Type = Linker;
19+
Options = (
20+
{
21+
Name = "LIBTOOL_USE_RESPONSE_FILE";
22+
Type = Boolean;
23+
DefaultValue = NO;
24+
},
25+
);
26+
},
27+
)

Sources/SWBTestSupport/RunDestinationTestSupport.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ extension _RunDestinationInfo {
9898
windows
9999
case .linux:
100100
linux
101+
case .freebsd:
102+
freebsd
103+
case .openbsd:
104+
openbsd
101105
case .android:
102106
android
103107
case .unknown:
@@ -259,6 +263,22 @@ extension _RunDestinationInfo {
259263
return .init(platform: "linux", sdk: "linux", sdkVariant: "linux", targetArchitecture: arch, supportedArchitectures: ["x86_64", "aarch64"], disableOnlyActiveArch: false)
260264
}
261265

266+
/// A run destination targeting FreeBSD generic device, using the public SDK.
267+
package static var freebsd: Self {
268+
guard let arch = Architecture.hostStringValue else {
269+
preconditionFailure("Unknown architecture \(Architecture.host.stringValue ?? "<nil>")")
270+
}
271+
return .init(platform: "freebsd", sdk: "freebsd", sdkVariant: "freebsd", targetArchitecture: arch, supportedArchitectures: ["x86_64", "aarch64"], disableOnlyActiveArch: false)
272+
}
273+
274+
/// A run destination targeting OpenBSD generic device, using the public SDK.
275+
package static var openbsd: Self {
276+
guard let arch = Architecture.hostStringValue else {
277+
preconditionFailure("Unknown architecture \(Architecture.host.stringValue ?? "<nil>")")
278+
}
279+
return .init(platform: "openbsd", sdk: "openbsd", sdkVariant: "openbsd", targetArchitecture: arch, supportedArchitectures: ["x86_64", "aarch64"], disableOnlyActiveArch: false)
280+
}
281+
262282
/// A run destination targeting Android generic device, using the public SDK.
263283
package static var android: Self {
264284
return .init(platform: "android", sdk: "android", sdkVariant: "android", targetArchitecture: "undefined_arch", supportedArchitectures: ["armv7", "aarch64", "riscv64", "i686", "x86_64"], disableOnlyActiveArch: true)

Sources/SWBTestSupport/SkippedTestSupport.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ extension KnownSDK {
4949
return windows
5050
case .success(.linux):
5151
return linux
52+
case .success(.freebsd):
53+
return freebsd
54+
case .success(.openbsd):
55+
return openbsd
5256
case .success(.android):
5357
return android
5458
case .success(.unknown), .failure:
@@ -69,6 +73,8 @@ extension KnownSDK {
6973
extension KnownSDK {
7074
package static let windows: Self = "windows"
7175
package static let linux: Self = "linux"
76+
package static let freebsd: Self = "freebsd"
77+
package static let openbsd: Self = "openbsd"
7278
package static let android: Self = "android"
7379
package static let qnx: Self = "qnx"
7480
package static let wasi: Self = "wasi"
@@ -196,7 +202,7 @@ extension Trait where Self == Testing.ConditionTrait {
196202
}
197203
}
198204

199-
package static func requireSystemPackages(apt: String..., yum: String..., sourceLocation: SourceLocation = #_sourceLocation) -> Self {
205+
package static func requireSystemPackages(apt: String..., yum: String..., freebsd: String..., sourceLocation: SourceLocation = #_sourceLocation) -> Self {
200206
enabled("required system packages are not installed") {
201207
func checkInstalled(hostOS: OperatingSystem, packageManagerPath: Path, args: [String], packages: [String], regex: Regex<(Substring, name: Substring)>) async throws -> Bool {
202208
if try ProcessInfo.processInfo.hostOperatingSystem() == hostOS && localFS.exists(packageManagerPath) {
@@ -222,7 +228,9 @@ extension Trait where Self == Testing.ConditionTrait {
222228
// spelled `--installed` in newer versions of yum, but Amazon Linux 2 is on older versions
223229
let yum = try await checkInstalled(hostOS: .linux, packageManagerPath: Path("/usr/bin/yum"), args: ["list", "installed", "yum"], packages: yum, regex: #/(?<name>.+)\./#)
224230

225-
return apt && yum
231+
let freebsd = try await checkInstalled(hostOS: .freebsd, packageManagerPath: Path("/usr/sbin/pkg"), args: ["info"], packages: freebsd, regex: #/^Name(?:[ ]+): (?<name>.+)$/#)
232+
233+
return apt && yum && freebsd
226234
}
227235
}
228236

Sources/SWBUtil/Architecture.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,18 @@ public struct Architecture: Sendable {
9898
if uname(&buf) == 0 {
9999
return withUnsafeBytes(of: &buf.machine) { buf in
100100
let data = Data(buf)
101-
return String(decoding: data[0...(data.lastIndex(where: { $0 != 0 }) ?? 0)], as: UTF8.self)
101+
let value = String(decoding: data[0...(data.lastIndex(where: { $0 != 0 }) ?? 0)], as: UTF8.self)
102+
#if os(FreeBSD)
103+
switch value {
104+
case "amd64":
105+
return "x86_64"
106+
case "arm64":
107+
return "aarch64"
108+
default:
109+
break
110+
}
111+
#endif
112+
return value
102113
}
103114
}
104115
return nil

Sources/SWBUtil/FSProxy.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ class LocalFS: FSProxy, @unchecked Sendable {
718718
#if os(Windows)
719719
// Implement ADS on Windows? See also https://github.com/swiftlang/swift-foundation/issues/1166
720720
return []
721+
#elseif os(FreeBSD)
722+
// FreeBSD blocked on https://github.com/swiftlang/swift/pull/77836
723+
return []
721724
#elseif os(OpenBSD)
722725
// OpenBSD no longer supports extended attributes
723726
return []
@@ -758,6 +761,8 @@ class LocalFS: FSProxy, @unchecked Sendable {
758761
func setExtendedAttribute(_ path: Path, key: String, value: ByteString) throws {
759762
#if os(Windows)
760763
// Implement ADS on Windows? See also https://github.com/swiftlang/swift-foundation/issues/1166
764+
#elseif os(FreeBSD)
765+
// FreeBSD blocked on https://github.com/swiftlang/swift/pull/77836
761766
#elseif os(OpenBSD)
762767
// OpenBSD no longer supports extended attributes
763768
#else
@@ -778,6 +783,9 @@ class LocalFS: FSProxy, @unchecked Sendable {
778783
#if os(Windows)
779784
// Implement ADS on Windows? See also https://github.com/swiftlang/swift-foundation/issues/1166
780785
return nil
786+
#elseif os(FreeBSD)
787+
// FreeBSD blocked on https://github.com/swiftlang/swift/pull/77836
788+
return nil
781789
#elseif os(OpenBSD)
782790
// OpenBSD no longer supports extended attributes
783791
return nil

Sources/SWBUtil/Lock.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public final class Lock: @unchecked Sendable {
2828
#if os(Windows)
2929
@usableFromInline
3030
let mutex: UnsafeMutablePointer<SRWLOCK> = UnsafeMutablePointer.allocate(capacity: 1)
31-
#elseif os(OpenBSD)
31+
#elseif os(FreeBSD) || os(OpenBSD)
3232
@usableFromInline
3333
let mutex: UnsafeMutablePointer<pthread_mutex_t?> = UnsafeMutablePointer.allocate(capacity: 1)
3434
#else

Sources/SWBUtil/Process.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ extension Process {
7070
case .linux:
7171
// Amazon Linux 2 has glibc 2.26, and glibc 2.29 is needed for posix_spawn_file_actions_addchdir_np support
7272
FileManager.default.contents(atPath: "/etc/system-release").map { String(decoding: $0, as: UTF8.self) == "Amazon Linux release 2 (Karoo)\n" } ?? false
73+
case .openbsd:
74+
true
7375
default:
7476
false
7577
}

0 commit comments

Comments
 (0)