Skip to content

Commit b597e16

Browse files
authored
Enable building prebuilts on linux hosts without docker. (#8269)
Made discovery of the Linux distro reusable for the build-prebuilts script. Changed it to use arch and os conditions instead of the host toolchain. Added support for Ubuntu noble, Fedora and Debian. Removed the deletion of the stage directory so we can share it across docker invocations for each distro. Fixed the Modules directory name which wasn't working on case sensitive file systems.
1 parent b8c1edc commit b597e16

File tree

5 files changed

+244
-169
lines changed

5 files changed

+244
-169
lines changed

Sources/Workspace/Workspace+Prebuilts.swift

Lines changed: 161 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,20 @@ extension Workspace {
8686
case macos_x86_64
8787
case windows_aarch64
8888
case windows_x86_64
89-
// noble is currently missing
89+
case ubuntu_noble_aarch64
90+
case ubuntu_noble_x86_64
9091
case ubuntu_jammy_aarch64
9192
case ubuntu_jammy_x86_64
9293
case ubuntu_focal_aarch64
9394
case ubuntu_focal_x86_64
94-
// bookworm is currently missing
95-
// fedora39 is currently missing
95+
case fedora_39_aarch64
96+
case fedora_39_x86_64
9697
case amazonlinux2_aarch64
9798
case amazonlinux2_x86_64
9899
case rhel_ubi9_aarch64
99100
case rhel_ubi9_x86_64
101+
case debian_12_aarch64
102+
case debian_12_x86_64
100103

101104
public enum Arch: String {
102105
case x86_64
@@ -108,35 +111,6 @@ extension Workspace {
108111
case windows
109112
case linux
110113
}
111-
112-
public var arch: Arch {
113-
switch self {
114-
case .macos_aarch64, .windows_aarch64,
115-
.ubuntu_jammy_aarch64, .ubuntu_focal_aarch64,
116-
.amazonlinux2_aarch64,
117-
.rhel_ubi9_aarch64:
118-
return .aarch64
119-
case .macos_x86_64, .windows_x86_64,
120-
.ubuntu_jammy_x86_64, .ubuntu_focal_x86_64,
121-
.amazonlinux2_x86_64,
122-
.rhel_ubi9_x86_64:
123-
return .x86_64
124-
}
125-
}
126-
127-
public var os: OS {
128-
switch self {
129-
case .macos_aarch64, .macos_x86_64:
130-
return .macos
131-
case .windows_aarch64, .windows_x86_64:
132-
return .windows
133-
case .ubuntu_jammy_aarch64, .ubuntu_jammy_x86_64,
134-
.ubuntu_focal_aarch64, .ubuntu_focal_x86_64,
135-
.amazonlinux2_aarch64, .amazonlinux2_x86_64,
136-
.rhel_ubi9_aarch64, .rhel_ubi9_x86_64:
137-
return .linux
138-
}
139-
}
140114
}
141115
}
142116

@@ -145,15 +119,18 @@ extension Workspace {
145119
let httpClient: HTTPClient?
146120
let archiver: Archiver?
147121
let useCache: Bool?
122+
let hostPlatform: PrebuiltsManifest.Platform?
148123

149124
public init(
150125
httpClient: HTTPClient? = .none,
151126
archiver: Archiver? = .none,
152-
useCache: Bool? = .none
127+
useCache: Bool? = .none,
128+
hostPlatform: PrebuiltsManifest.Platform? = nil
153129
) {
154130
self.httpClient = httpClient
155131
self.archiver = archiver
156132
self.useCache = useCache
133+
self.hostPlatform = hostPlatform
157134
}
158135
}
159136

@@ -170,9 +147,11 @@ extension Workspace {
170147
private let delegate: Delegate?
171148
private let hashAlgorithm: HashAlgorithm = SHA256()
172149
private let prebuiltsDownloadURL: URL
150+
let hostPlatform: PrebuiltsManifest.Platform
173151

174152
init(
175153
fileSystem: FileSystem,
154+
hostPlatform: PrebuiltsManifest.Platform,
176155
authorizationProvider: AuthorizationProvider?,
177156
scratchPath: AbsolutePath,
178157
cachePath: AbsolutePath?,
@@ -182,6 +161,7 @@ extension Workspace {
182161
prebuiltsDownloadURL: String?
183162
) {
184163
self.fileSystem = fileSystem
164+
self.hostPlatform = hostPlatform
185165
self.authorizationProvider = authorizationProvider
186166
self.httpClient = customHTTPClient ?? HTTPClient()
187167
self.archiver = customArchiver ?? ZipArchiver(fileSystem: fileSystem)
@@ -515,7 +495,7 @@ extension Workspace {
515495
addedOrUpdatedPackages: [PackageReference],
516496
observabilityScope: ObservabilityScope
517497
) async throws {
518-
guard let prebuiltsManager = self.prebuiltsManager else {
498+
guard let prebuiltsManager else {
519499
// Disabled
520500
return
521501
}
@@ -536,14 +516,10 @@ extension Workspace {
536516
continue
537517
}
538518

539-
let hostPlatform = hostPrebuiltsPlatform
519+
let hostPlatform = prebuiltsManager.hostPlatform
540520

541521
for library in prebuiltManifest.libraries {
542-
for artifact in library.artifacts {
543-
guard artifact.platform == hostPlatform else {
544-
continue
545-
}
546-
522+
for artifact in library.artifacts where artifact.platform == hostPlatform {
547523
if let path = try await prebuiltsManager
548524
.downloadPrebuilt(
549525
package: prebuilt,
@@ -577,100 +553,167 @@ extension Workspace {
577553

578554
try self.state.save()
579555
}
556+
}
557+
558+
extension Workspace.PrebuiltsManifest.Platform {
559+
public var arch: Arch {
560+
switch self {
561+
case .macos_aarch64, .windows_aarch64,
562+
.ubuntu_noble_aarch64, .ubuntu_jammy_aarch64, .ubuntu_focal_aarch64,
563+
.fedora_39_aarch64,
564+
.amazonlinux2_aarch64,
565+
.rhel_ubi9_aarch64,
566+
.debian_12_aarch64:
567+
return .aarch64
568+
case .macos_x86_64, .windows_x86_64,
569+
.ubuntu_noble_x86_64, .ubuntu_jammy_x86_64, .ubuntu_focal_x86_64,
570+
.fedora_39_x86_64,
571+
.amazonlinux2_x86_64,
572+
.rhel_ubi9_x86_64,
573+
.debian_12_x86_64:
574+
return .x86_64
575+
}
576+
}
577+
578+
public var os: OS {
579+
switch self {
580+
case .macos_aarch64, .macos_x86_64:
581+
return .macos
582+
case .windows_aarch64, .windows_x86_64:
583+
return .windows
584+
case .ubuntu_noble_aarch64, .ubuntu_noble_x86_64,
585+
.ubuntu_jammy_aarch64, .ubuntu_jammy_x86_64,
586+
.ubuntu_focal_aarch64, .ubuntu_focal_x86_64,
587+
.fedora_39_aarch64, .fedora_39_x86_64,
588+
.amazonlinux2_aarch64, .amazonlinux2_x86_64,
589+
.rhel_ubi9_aarch64, .rhel_ubi9_x86_64,
590+
.debian_12_aarch64, .debian_12_x86_64:
591+
return .linux
592+
}
593+
}
580594

581-
var hostPrebuiltsPlatform: PrebuiltsManifest.Platform? {
582-
if self.hostToolchain.targetTriple.isDarwin() {
583-
switch self.hostToolchain.targetTriple.arch {
584-
case .aarch64:
585-
return .macos_aarch64
586-
case .x86_64:
587-
return .macos_x86_64
595+
/// Determine host platform based on compilation target
596+
public static var hostPlatform: Self? {
597+
let arch: Arch?
598+
#if arch(arm64)
599+
arch = .aarch64
600+
#elseif arch(x86_64)
601+
arch = .x86_64
602+
#endif
603+
guard let arch else {
604+
return nil
605+
}
606+
607+
#if os(macOS)
608+
switch arch {
609+
case .aarch64:
610+
return .macos_aarch64
611+
case .x86_64:
612+
return .macos_x86_64
613+
}
614+
#elseif os(Windows)
615+
switch arch {
616+
case .aarch64:
617+
return .windows_aarch64
618+
case .x86_64:
619+
return .windows_x86_64
620+
}
621+
#elseif os(Linux)
622+
// Load up the os-release file into a dictionary
623+
guard let osData = try? String(contentsOfFile: "/etc/os-release", encoding: .utf8)
624+
else {
625+
return nil
626+
}
627+
let osLines = osData.split(separator: "\n")
628+
let osDict = osLines.reduce(into: [Substring: String]()) {
629+
(dict, line) in
630+
let parts = line.split(separator: "=", maxSplits: 2)
631+
dict[parts[0]] = parts[1...].joined(separator: "=").trimmingCharacters(in: ["\""])
632+
}
633+
634+
switch osDict["ID"] {
635+
case "ubuntu":
636+
switch osDict["VERSION_CODENAME"] {
637+
case "noble":
638+
switch arch {
639+
case .aarch64:
640+
return .ubuntu_noble_aarch64
641+
case .x86_64:
642+
return .ubuntu_noble_x86_64
643+
}
644+
case "jammy":
645+
switch arch {
646+
case .aarch64:
647+
return .ubuntu_jammy_aarch64
648+
case .x86_64:
649+
return .ubuntu_jammy_x86_64
650+
}
651+
case "focal":
652+
switch arch {
653+
case .aarch64:
654+
return .ubuntu_focal_aarch64
655+
case .x86_64:
656+
return .ubuntu_focal_x86_64
657+
}
588658
default:
589659
return nil
590660
}
591-
} else if self.hostToolchain.targetTriple.isWindows() {
592-
switch self.hostToolchain.targetTriple.arch {
593-
case .aarch64:
594-
return .windows_aarch64
595-
case .x86_64:
596-
return .windows_x86_64
661+
case "fedora":
662+
switch osDict["VERSION_ID"] {
663+
case "39", "41":
664+
switch arch {
665+
case .aarch64:
666+
return .fedora_39_aarch64
667+
case .x86_64:
668+
return .fedora_39_x86_64
669+
}
597670
default:
598671
return nil
599672
}
600-
} else if self.hostToolchain.targetTriple.isLinux() {
601-
// Load up the os-release file into a dictionary
602-
guard let osData = try? String(contentsOfFile: "/etc/os-release", encoding: .utf8)
603-
else {
673+
case "amzn":
674+
switch osDict["VERSION_ID"] {
675+
case "2":
676+
switch arch {
677+
case .aarch64:
678+
return .amazonlinux2_aarch64
679+
case .x86_64:
680+
return .amazonlinux2_x86_64
681+
}
682+
default:
604683
return nil
605684
}
606-
let osLines = osData.split(separator: "\n")
607-
let osDict = osLines.reduce(into: [Substring: String]()) {
608-
(dict, line) in
609-
let parts = line.split(separator: "=", maxSplits: 2)
610-
dict[parts[0]] = parts[1...].joined(separator: "=").trimmingCharacters(in: ["\""])
685+
case "rhel":
686+
guard let version = osDict["VERSION_ID"] else {
687+
return nil
611688
}
612-
613-
switch osDict["ID"] {
614-
case "ubuntu":
615-
switch osDict["VERSION_CODENAME"] {
616-
case "jammy":
617-
switch self.hostToolchain.targetTriple.arch {
618-
case .aarch64:
619-
return .ubuntu_jammy_aarch64
620-
case .x86_64:
621-
return .ubuntu_jammy_x86_64
622-
default:
623-
return nil
624-
}
625-
case "focal":
626-
switch self.hostToolchain.targetTriple.arch {
627-
case .aarch64:
628-
return .ubuntu_focal_aarch64
629-
case .x86_64:
630-
return .ubuntu_focal_x86_64
631-
default:
632-
return nil
633-
}
634-
default:
635-
return nil
689+
switch version.split(separator: ".")[0] {
690+
case "9":
691+
switch arch {
692+
case .aarch64:
693+
return .rhel_ubi9_aarch64
694+
case .x86_64:
695+
return .rhel_ubi9_x86_64
636696
}
637-
case "amzn":
638-
switch osDict["VERSION_ID"] {
639-
case "2":
640-
switch self.hostToolchain.targetTriple.arch {
641-
case .aarch64:
642-
return .amazonlinux2_aarch64
643-
case .x86_64:
644-
return .amazonlinux2_x86_64
645-
default:
646-
return nil
647-
}
648-
default:
649-
return nil
650-
}
651-
case "rhel":
652-
guard let version = osDict["VERSION_ID"] else {
653-
return nil
654-
}
655-
switch version.split(separator: ".")[0] {
656-
case "9":
657-
switch self.hostToolchain.targetTriple.arch {
658-
case .aarch64:
659-
return .rhel_ubi9_aarch64
660-
case .x86_64:
661-
return .rhel_ubi9_x86_64
662-
default:
663-
return nil
664-
}
665-
default:
666-
return nil
697+
default:
698+
return nil
699+
}
700+
case "debian":
701+
switch osDict["VERSION_ID"] {
702+
case "12":
703+
switch arch {
704+
case .aarch64:
705+
return .debian_12_aarch64
706+
case .x86_64:
707+
return .debian_12_x86_64
667708
}
668709
default:
669710
return nil
670711
}
671-
} else {
712+
default:
672713
return nil
673714
}
715+
#else
716+
return nil
717+
#endif
674718
}
675-
676719
}

0 commit comments

Comments
 (0)