Skip to content

Commit 9a36fe9

Browse files
MaxDesiatovrauhul
andauthored
[5.9] Enable armv7em CPU and none OS triples (#6720)
Adds preliminary knowledge of `armv7em` CPU and `none` OS environments to SwiftPM. Future diffs will be required to fully support these triples. This change allows a `armv7em-apple-none-macho` build via a destination v3 bundle to make it further through SwiftPM. (cherry picked from commit da7d339) Co-authored-by: Rauhul Varma <[email protected]>
1 parent fc14c26 commit 9a36fe9

15 files changed

+69
-42
lines changed

Sources/Basics/Triple.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public struct Triple: Encodable, Equatable, Sendable {
4848
case aarch64
4949
case amd64
5050
case armv7
51+
case armv7em
5152
case armv6
5253
case armv5
5354
case arm
@@ -73,6 +74,8 @@ public struct Triple: Encodable, Equatable, Sendable {
7374
case windows
7475
case wasi
7576
case openbsd
77+
// 'OS' suffix purely to avoid name clash with Optional.none
78+
case noneOS = "none"
7679
}
7780

7881
public enum ABI: Encodable, Equatable, RawRepresentable, Sendable {
@@ -265,6 +268,8 @@ extension Triple {
265268
return ".dll"
266269
case .wasi:
267270
return ".wasm"
271+
case .noneOS:
272+
fatalError("Cannot create dynamic libraries for os \"none\".")
268273
}
269274
}
270275

@@ -278,6 +283,8 @@ extension Triple {
278283
return ".wasm"
279284
case .windows:
280285
return ".exe"
286+
case .noneOS:
287+
return ""
281288
}
282289
}
283290

Sources/Build/BuildDescription/ProductBuildDescription.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,12 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
137137
let librarian = self.buildParameters.toolchain.librarianPath.pathString
138138
let triple = self.buildParameters.triple
139139
if triple.isWindows(), librarian.hasSuffix("link") || librarian.hasSuffix("link.exe") {
140-
return [librarian, "/LIB", "/OUT:\(binaryPath.pathString)", "@\(self.linkFileListPath.pathString)"]
140+
return try [librarian, "/LIB", "/OUT:\(binaryPath.pathString)", "@\(self.linkFileListPath.pathString)"]
141141
}
142142
if triple.isDarwin(), librarian.hasSuffix("libtool") {
143-
return [librarian, "-static", "-o", binaryPath.pathString, "@\(self.linkFileListPath.pathString)"]
143+
return try [librarian, "-static", "-o", binaryPath.pathString, "@\(self.linkFileListPath.pathString)"]
144144
}
145-
return [librarian, "crs", binaryPath.pathString, "@\(self.linkFileListPath.pathString)"]
145+
return try [librarian, "crs", binaryPath.pathString, "@\(self.linkFileListPath.pathString)"]
146146
}
147147

148148
/// The arguments to link and create this product.
@@ -166,7 +166,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
166166
}
167167

168168
args += ["-L", self.buildParameters.buildPath.pathString]
169-
args += ["-o", binaryPath.pathString]
169+
args += try ["-o", binaryPath.pathString]
170170
args += ["-module-name", self.product.name.spm_mangledToC99ExtendedIdentifier()]
171171
args += self.dylibs.map { "-l" + $0.product.name }
172172

@@ -209,7 +209,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
209209
case .library(.dynamic):
210210
args += ["-emit-library"]
211211
if self.buildParameters.triple.isDarwin() {
212-
let relativePath = "@rpath/\(buildParameters.binaryRelativePath(for: self.product).pathString)"
212+
let relativePath = try "@rpath/\(buildParameters.binaryRelativePath(for: self.product).pathString)"
213213
args += ["-Xlinker", "-install_name", "-Xlinker", relativePath]
214214
}
215215
args += self.deadStripArguments

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ public final class SwiftTargetBuildDescription {
385385
#else
386386
try self.requiredMacroProducts.forEach { macro in
387387
if let macroTarget = macro.targets.first {
388-
let executablePath = self.buildParameters.binaryPath(for: macro).pathString
388+
let executablePath = try self.buildParameters.binaryPath(for: macro).pathString
389389
args += ["-Xfrontend", "-load-plugin-executable", "-Xfrontend", "\(executablePath)#\(macroTarget.c99name)"]
390390
} else {
391391
throw InternalError("macro product \(macro.name) has no targets") // earlier validation should normally catch this

Sources/Build/BuildOperation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
431431
) { name, path in
432432
try buildOperationForPluginDependencies.build(subset: .product(name))
433433
if let builtTool = try buildOperationForPluginDependencies.buildPlan.buildProducts.first(where: { $0.product.name == name}) {
434-
return builtTool.binaryPath
434+
return try builtTool.binaryPath
435435
} else {
436436
return nil
437437
}

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ public struct BuildDescription: Codable {
357357
)
358358
self.swiftTargetScanArgs = targetCommandLines
359359
self.generatedSourceTargetSet = Set(generatedSourceTargets)
360-
self.builtTestProducts = plan.buildProducts.filter { $0.product.type == .test }.map { desc in
361-
BuiltTestProduct(
360+
self.builtTestProducts = try plan.buildProducts.filter { $0.product.type == .test }.map { desc in
361+
try BuiltTestProduct(
362362
productName: desc.product.name,
363363
binaryPath: desc.binaryPath
364364
)

Sources/Build/LLBuildManifestBuilder.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ extension LLBuildManifestBuilder {
661661
guard let planProduct = plan.productMap[product] else {
662662
throw InternalError("unknown product \(product)")
663663
}
664-
inputs.append(file: planProduct.binaryPath)
664+
try inputs.append(file: planProduct.binaryPath)
665665
}
666666
return
667667
}
@@ -690,7 +690,7 @@ extension LLBuildManifestBuilder {
690690
throw InternalError("unknown product \(product)")
691691
}
692692
// Establish a dependency on binary of the product.
693-
inputs.append(file: planProduct.binaryPath)
693+
try inputs.append(file: planProduct.binaryPath)
694694

695695
// For automatic and static libraries, and plugins, add their targets as static input.
696696
case .library(.automatic), .library(.static), .plugin:
@@ -828,7 +828,7 @@ extension LLBuildManifestBuilder {
828828
throw InternalError("unknown product \(product)")
829829
}
830830
// Establish a dependency on binary of the product.
831-
let binary = planProduct.binaryPath
831+
let binary = try planProduct.binaryPath
832832
inputs.append(file: binary)
833833

834834
case .library(.automatic), .library(.static), .plugin:
@@ -983,7 +983,7 @@ extension LLBuildManifestBuilder {
983983

984984
switch buildProduct.product.type {
985985
case .library(.static):
986-
self.manifest.addShellCmd(
986+
try self.manifest.addShellCmd(
987987
name: cmdName,
988988
description: "Archiving \(buildProduct.binaryPath.prettyPath())",
989989
inputs: buildProduct.objects.map(Node.file),
@@ -992,9 +992,9 @@ extension LLBuildManifestBuilder {
992992
)
993993

994994
default:
995-
let inputs = buildProduct.objects + buildProduct.dylibs.map(\.binaryPath)
995+
let inputs = try buildProduct.objects + buildProduct.dylibs.map{ try $0.binaryPath }
996996

997-
self.manifest.addShellCmd(
997+
try self.manifest.addShellCmd(
998998
name: cmdName,
999999
description: "Linking \(buildProduct.binaryPath.prettyPath())",
10001000
inputs: inputs.map(Node.file),
@@ -1008,7 +1008,7 @@ extension LLBuildManifestBuilder {
10081008
let output: Node = .virtual(targetName)
10091009

10101010
self.manifest.addNode(output, toTarget: targetName)
1011-
self.manifest.addPhonyCmd(
1011+
try self.manifest.addPhonyCmd(
10121012
name: output.name,
10131013
inputs: [.file(buildProduct.binaryPath)],
10141014
outputs: [output]

Sources/Commands/PackageTools/PluginCommand.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ struct PluginCommand: SwiftCommand {
259259
// Build the product referenced by the tool, and add the executable to the tool map. Product dependencies are not supported within a package, so if the tool happens to be from the same package, we instead find the executable that corresponds to the product. There is always one, because of autogeneration of implicit executables with the same name as the target if there isn't an explicit one.
260260
try buildSystem.build(subset: .product(name))
261261
if let builtTool = try buildSystem.buildPlan.buildProducts.first(where: { $0.product.name == name }) {
262-
return builtTool.binaryPath
262+
return try builtTool.binaryPath
263263
} else {
264264
return nil
265265
}

Sources/Commands/Utilities/PluginDelegate.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ final class PluginDelegate: PluginInvocationDelegate {
129129
return $0.product.name == name
130130
}
131131
}
132-
let builtArtifacts: [PluginInvocationBuildResult.BuiltArtifact] = builtProducts.compactMap {
132+
let builtArtifacts: [PluginInvocationBuildResult.BuiltArtifact] = try builtProducts.compactMap {
133133
switch $0.product.type {
134134
case .library(let kind):
135-
return .init(
135+
return try .init(
136136
path: $0.binaryPath.pathString,
137137
kind: (kind == .dynamic) ? .dynamicLibrary : .staticLibrary
138138
)
139139
case .executable:
140-
return .init(path: $0.binaryPath.pathString, kind: .executable)
140+
return try .init(path: $0.binaryPath.pathString, kind: .executable)
141141
default:
142142
return nil
143143
}

Sources/PackageLoading/PackageBuilder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,7 @@ public final class PackageBuilder {
10391039

10401040
// Ensure that the search path is contained within the package.
10411041
_ = try RelativePath(validating: value)
1042-
let path = try AbsolutePath(value, relativeTo: targetRoot)
1042+
let path = try AbsolutePath(validating: value, relativeTo: targetRoot)
10431043
guard path.isDescendantOfOrEqual(to: self.packagePath) else {
10441044
throw ModuleError.invalidHeaderSearchPath(value)
10451045
}

Sources/SPMBuildCore/BinaryTarget+Extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ extension Triple.OS {
9797
/// Returns a representation of the receiver that can be compared with platform strings declared in an XCFramework.
9898
fileprivate var asXCFrameworkPlatformString: String? {
9999
switch self {
100-
case .darwin, .linux, .wasi, .windows, .openbsd:
100+
case .darwin, .linux, .wasi, .windows, .openbsd, .noneOS:
101101
return nil // XCFrameworks do not support any of these platforms today.
102102
case .macOS:
103103
return "macos"

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,22 +387,26 @@ public struct BuildParameters: Encodable {
387387
}
388388

389389
/// Returns the path to the binary of a product for the current build parameters.
390-
public func binaryPath(for product: ResolvedProduct) -> AbsolutePath {
391-
return buildPath.appending(binaryRelativePath(for: product))
390+
public func binaryPath(for product: ResolvedProduct) throws -> AbsolutePath {
391+
return try buildPath.appending(binaryRelativePath(for: product))
392+
}
393+
394+
/// Returns the path to the dynamic library of a product for the current build parameters.
395+
func potentialDynamicLibraryPath(for product: ResolvedProduct) throws -> RelativePath {
396+
try RelativePath(validating: "\(triple.dynamicLibraryPrefix)\(product.name)\(triple.dynamicLibraryExtension)")
392397
}
393398

394399
/// Returns the path to the binary of a product for the current build parameters, relative to the build directory.
395-
public func binaryRelativePath(for product: ResolvedProduct) -> RelativePath {
396-
let potentialExecutablePath = RelativePath("\(product.name)\(triple.executableExtension)")
397-
let potentialLibraryPath = RelativePath("\(triple.dynamicLibraryPrefix)\(product.name)\(triple.dynamicLibraryExtension)")
400+
public func binaryRelativePath(for product: ResolvedProduct) throws -> RelativePath {
401+
let potentialExecutablePath = try RelativePath(validating: "\(product.name)\(triple.executableExtension)")
398402

399403
switch product.type {
400404
case .executable, .snippet:
401405
return potentialExecutablePath
402406
case .library(.static):
403407
return RelativePath("lib\(product.name)\(triple.staticLibraryExtension)")
404408
case .library(.dynamic):
405-
return potentialLibraryPath
409+
return try potentialDynamicLibraryPath(for: product)
406410
case .library(.automatic), .plugin:
407411
fatalError()
408412
case .test:
@@ -418,7 +422,7 @@ public struct BuildParameters: Encodable {
418422
}
419423
case .macro:
420424
#if BUILD_MACROS_AS_DYLIBS
421-
return potentialLibraryPath
425+
return try potentialDynamicLibraryPath(for: product)
422426
#else
423427
return potentialExecutablePath
424428
#endif

Sources/SPMBuildCore/BuildSystem.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ public protocol ProductBuildDescription {
7474
extension ProductBuildDescription {
7575
/// The path to the product binary produced.
7676
public var binaryPath: AbsolutePath {
77-
return buildParameters.binaryPath(for: product)
77+
get throws {
78+
return try buildParameters.binaryPath(for: product)
79+
}
7880
}
7981
}
8082

Sources/XCBuildSupport/XcodeBuildSystem.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,19 @@ public final class XcodeBuildSystem: SPMBuildCore.BuildSystem {
4646
var builtProducts: [BuiltTestProduct] = []
4747

4848
for package in graph.rootPackages {
49-
for product in package.products where product.type == .test {
50-
let binaryPath = buildParameters.binaryPath(for: product)
51-
builtProducts.append(
52-
BuiltTestProduct(
53-
productName: product.name,
54-
binaryPath: binaryPath
49+
do {
50+
for product in package.products where product.type == .test {
51+
let binaryPath = try buildParameters.binaryPath(for: product)
52+
builtProducts.append(
53+
BuiltTestProduct(
54+
productName: product.name,
55+
binaryPath: binaryPath
56+
)
5557
)
56-
)
58+
}
59+
} catch {
60+
self.observabilityScope.emit(error)
61+
return []
5762
}
5863
}
5964

Tests/BuildTests/BuildPlanTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3030,7 +3030,7 @@ final class BuildPlanTests: XCTestCase {
30303030
]
30313031
)
30323032

3033-
let executablePathExtension = appBuildDescription.binaryPath.extension
3033+
let executablePathExtension = try appBuildDescription.binaryPath.extension
30343034
XCTAssertEqual(executablePathExtension, "wasm")
30353035

30363036
let testBuildDescription = try result.buildProduct(for: "PkgPackageTests")
@@ -3047,7 +3047,7 @@ final class BuildPlanTests: XCTestCase {
30473047
]
30483048
)
30493049

3050-
let testPathExtension = testBuildDescription.binaryPath.extension
3050+
let testPathExtension = try testBuildDescription.binaryPath.extension
30513051
XCTAssertEqual(testPathExtension, "wasm")
30523052
}
30533053

Tests/BuildTests/ModuleAliasingBuildTests.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,10 @@ final class ModuleAliasingBuildTests: XCTestCase {
355355
XCTAssertTrue(result.targetMap.values.contains { $0.target.name == "BarLogging" && $0.target.moduleAliases?["Logging"] == "BarLogging" })
356356
#if os(macOS)
357357
let dylib = try result.buildProduct(for: "Logging")
358-
XCTAssertTrue(dylib.binaryPath.basename == "libLogging.dylib" && dylib.package.identity.description == "barpkg")
358+
XCTAssertTrue(
359+
try dylib.binaryPath.basename == "libLogging.dylib" && dylib.package.identity
360+
.description == "barpkg"
361+
)
359362
#endif
360363
}
361364

@@ -422,7 +425,10 @@ final class ModuleAliasingBuildTests: XCTestCase {
422425
XCTAssertTrue(result.targetMap.values.contains { $0.target.name == "BazLogging" && $0.target.moduleAliases?["Logging"] == "BazLogging" })
423426
#if os(macOS)
424427
let staticlib = try result.buildProduct(for: "Logging")
425-
XCTAssertTrue(staticlib.binaryPath.basename == "libLogging.a" && staticlib.package.identity.description == "bazpkg")
428+
XCTAssertTrue(
429+
try staticlib.binaryPath.basename == "libLogging.a" && staticlib.package.identity
430+
.description == "bazpkg"
431+
)
426432
#endif
427433
}
428434

@@ -525,7 +531,10 @@ final class ModuleAliasingBuildTests: XCTestCase {
525531
XCTAssertTrue(result.targetMap.values.contains { $0.target.name == "B" && $0.target.moduleAliases == nil })
526532
#if os(macOS)
527533
let dylib = try result.buildProduct(for: "Logging")
528-
XCTAssertTrue(dylib.binaryPath.basename == "libLogging.dylib" && dylib.package.identity.description == "xpkg")
534+
XCTAssertTrue(
535+
try dylib.binaryPath.basename == "libLogging.dylib" && dylib.package.identity
536+
.description == "xpkg"
537+
)
529538
#endif
530539
}
531540

0 commit comments

Comments
 (0)