Skip to content

Commit 887d02d

Browse files
committed
Support macros when cross-compiling
### Motivation: Not supporting macros in cross-compilation is a major limitation, especially for libraries like https://github.com/apple/swift-mmio. ### Modifications: Added `enum BuildTriple { case buildTools, buildProducts }` and `var buildTriple: BuildTriple` on `ResolvedTarget` and `ResolvedProduct`. Corresponding value is assigned to this property depending on target and product type: `buildTools` for macros, plugins, and their dependencies, `buildProducts` for everything else (the default). Based on this property we can choose between `buildParameters.hostTriple` and `buildParameters.targetTriple` during build plan construction. ### Result: Resolves #6950 Resolves rdar://105991372
1 parent 10be402 commit 887d02d

16 files changed

+181
-70
lines changed

Sources/Build/BuildDescription/ClangTargetBuildDescription.swift

+13-8
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ public final class ClangTargetBuildDescription {
5050

5151
/// Path to the bundle generated for this module (if any).
5252
var bundlePath: AbsolutePath? {
53-
guard !resources.isEmpty else {
53+
guard !self.resources.isEmpty else {
5454
return .none
5555
}
5656

5757
if let bundleName = target.underlyingTarget.potentialBundleName {
58-
return self.buildParameters.bundlePath(named: bundleName)
58+
return self.buildParameters.bundlePath(named: bundleName, target: self.target)
5959
} else {
6060
return .none
6161
}
@@ -105,6 +105,11 @@ public final class ClangTargetBuildDescription {
105105
target.type == .test
106106
}
107107

108+
/// Triple for which this target is compiled.
109+
private var buildTriple: Triple {
110+
self.buildParameters.buildTriple(for: self.target)
111+
}
112+
108113
/// The results of applying any build tool plugins to this target.
109114
public let buildToolPluginInvocationResults: [BuildToolPluginInvocationResult]
110115

@@ -216,22 +221,23 @@ public final class ClangTargetBuildDescription {
216221

217222
var args = [String]()
218223
// Only enable ARC on macOS.
219-
if buildParameters.targetTriple.isDarwin() {
224+
if self.buildTriple.isDarwin() {
220225
args += ["-fobjc-arc"]
221226
}
222-
args += try buildParameters.targetTripleArgs(for: target)
227+
args += try self.buildParameters.buildTripleArgs(for: target)
223228

224229
args += optimizationArguments
225230
args += activeCompilationConditions
226231
args += ["-fblocks"]
227232

233+
let buildTriple = self.buildTriple
228234
// Enable index store, if appropriate.
229235
//
230236
// This feature is not widely available in OSS clang. So, we only enable
231237
// index store for Apple's clang or if explicitly asked to.
232238
if ProcessEnv.vars.keys.contains("SWIFTPM_ENABLE_CLANG_INDEX_STORE") {
233239
args += buildParameters.indexStoreArguments(for: target)
234-
} else if buildParameters.targetTriple.isDarwin(),
240+
} else if buildTriple.isDarwin(),
235241
(try? buildParameters.toolchain._isClangCompilerVendorApple()) == true
236242
{
237243
args += buildParameters.indexStoreArguments(for: target)
@@ -244,13 +250,12 @@ public final class ClangTargetBuildDescription {
244250
// 1. on Darwin when compiling for C++, because C++ modules are disabled on Apple-built Clang releases
245251
// 2. on Windows when compiling for any language, because of issues with the Windows SDK
246252
// 3. on Android when compiling for any language, because of issues with the Android SDK
247-
enableModules = !(buildParameters.targetTriple.isDarwin() && isCXX) && !buildParameters.targetTriple
248-
.isWindows() && !buildParameters.targetTriple.isAndroid()
253+
enableModules = !(buildTriple.isDarwin() && isCXX) && !buildTriple.isWindows() && !buildTriple.isAndroid()
249254
} else {
250255
// For version >= 5.8, we disable them when compiling for C++ regardless of platforms, see:
251256
// https://github.com/llvm/llvm-project/issues/55980 for clang frontend crash when module
252257
// enabled for C++ on c++17 standard and above.
253-
enableModules = !isCXX && !buildParameters.targetTriple.isWindows() && !buildParameters.targetTriple.isAndroid()
258+
enableModules = !isCXX && !buildTriple.isWindows() && !buildTriple.isAndroid()
254259
}
255260

256261
if enableModules {

Sources/Build/BuildDescription/ProductBuildDescription.swift

+19-12
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
6868
self.tempsPath.appending("Objects.LinkFileList")
6969
}
7070

71+
/// Triple for which this product is compiled.
72+
var buildTriple: Triple {
73+
self.buildParameters.buildTriple(for: self.product)
74+
}
75+
7176
/// File system reference.
7277
private let fileSystem: FileSystem
7378

@@ -110,15 +115,16 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
110115
return []
111116
}
112117

118+
let buildTriple = self.buildTriple
113119
switch self.buildParameters.configuration {
114120
case .debug:
115121
return []
116122
case .release:
117-
if self.buildParameters.targetTriple.isApple() {
123+
if buildTriple.isApple() {
118124
return ["-Xlinker", "-dead_strip"]
119-
} else if self.buildParameters.targetTriple.isWindows() {
125+
} else if buildTriple.isWindows() {
120126
return ["-Xlinker", "/OPT:REF"]
121-
} else if self.buildParameters.targetTriple.arch == .wasm32 {
127+
} else if buildTriple.arch == .wasm32 {
122128
// FIXME: wasm-ld strips data segments referenced through __start/__stop symbols
123129
// during GC, and it removes Swift metadata sections like swift5_protocols
124130
// We should add support of SHF_GNU_RETAIN-like flag for __attribute__((retain))
@@ -136,7 +142,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
136142
/// The arguments to the librarian to create a static library.
137143
public func archiveArguments() throws -> [String] {
138144
let librarian = self.buildParameters.toolchain.librarianPath.pathString
139-
let triple = self.buildParameters.targetTriple
145+
let triple = self.buildTriple
140146
if triple.isWindows(), librarian.hasSuffix("link") || librarian.hasSuffix("link.exe") {
141147
return try [librarian, "/LIB", "/OUT:\(binaryPath.pathString)", "@\(self.linkFileListPath.pathString)"]
142148
}
@@ -187,6 +193,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
187193
}
188194

189195
var isLinkingStaticStdlib = false
196+
let buildTriple = self.buildTriple
190197
switch derivedProductType {
191198
case .macro:
192199
throw InternalError("macro not supported") // should never be reached
@@ -206,7 +213,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
206213
args += self.deadStripArguments
207214
case .library(.dynamic):
208215
args += ["-emit-library"]
209-
if self.buildParameters.targetTriple.isDarwin() {
216+
if buildTriple.isDarwin() {
210217
let relativePath = try "@rpath/\(buildParameters.binaryRelativePath(for: self.product).pathString)"
211218
args += ["-Xlinker", "-install_name", "-Xlinker", relativePath]
212219
}
@@ -215,9 +222,9 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
215222
// Link the Swift stdlib statically, if requested.
216223
// TODO: unify this logic with SwiftTargetBuildDescription.stdlibArguments
217224
if self.buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib {
218-
if self.buildParameters.targetTriple.isDarwin() {
225+
if buildTriple.isDarwin() {
219226
self.observabilityScope.emit(.swiftBackDeployError)
220-
} else if self.buildParameters.targetTriple.isSupportingStaticStdlib {
227+
} else if buildTriple.isSupportingStaticStdlib {
221228
args += ["-static-stdlib"]
222229
isLinkingStaticStdlib = true
223230
}
@@ -260,9 +267,9 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
260267
// Set rpath such that dynamic libraries are looked up
261268
// adjacent to the product, unless overridden.
262269
if !self.buildParameters.linkingParameters.shouldDisableLocalRpath {
263-
if self.buildParameters.targetTriple.isLinux() {
270+
if buildTriple.isLinux() {
264271
args += ["-Xlinker", "-rpath=$ORIGIN"]
265-
} else if self.buildParameters.targetTriple.isDarwin() {
272+
} else if buildTriple.isDarwin() {
266273
let rpath = self.product.type == .test ? "@loader_path/../../../" : "@loader_path"
267274
args += ["-Xlinker", "-rpath", "-Xlinker", rpath]
268275
}
@@ -283,7 +290,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
283290

284291
// When deploying to macOS prior to macOS 12, add an rpath to the
285292
// back-deployed concurrency libraries.
286-
if useStdlibRpath, self.buildParameters.targetTriple.isMacOSX {
293+
if useStdlibRpath, buildTriple.isMacOSX {
287294
let macOSSupportedPlatform = self.package.platforms.getDerived(for: .macOS, usingXCTest: product.isLinkingXCTest)
288295
if macOSSupportedPlatform.version.major < 12 {
289296
let backDeployedStdlib = try buildParameters.toolchain.macosSwiftStdlib
@@ -308,7 +315,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
308315
// setting is the package-level right now. We might need to figure out a better
309316
// answer for libraries if/when we support specifying deployment target at the
310317
// target-level.
311-
args += try self.buildParameters.targetTripleArgs(for: self.product.targets[0])
318+
args += try self.buildParameters.buildTripleArgs(for: self.product.targets[0])
312319

313320
// Add arguments from declared build settings.
314321
args += self.buildSettingsFlags
@@ -351,7 +358,7 @@ public final class ProductBuildDescription: SPMBuildCore.ProductBuildDescription
351358
flags += libraries.map { "-l" + $0 }
352359

353360
// Linked frameworks.
354-
if self.buildParameters.targetTriple.supportsFrameworks {
361+
if self.buildTriple.supportsFrameworks {
355362
let frameworks = OrderedSet(self.staticTargets.reduce([]) {
356363
$0 + self.buildParameters.createScope(for: $1).evaluate(.LINK_FRAMEWORKS)
357364
})

Sources/Build/BuildDescription/SwiftTargetBuildDescription.swift

+15-8
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public final class SwiftTargetBuildDescription {
5858
/// Path to the bundle generated for this module (if any).
5959
var bundlePath: AbsolutePath? {
6060
if let bundleName = target.underlyingTarget.potentialBundleName, needsResourceBundle {
61-
return self.buildParameters.bundlePath(named: bundleName)
61+
return self.buildParameters.bundlePath(named: bundleName, target: self.target)
6262
} else {
6363
return .none
6464
}
@@ -102,12 +102,19 @@ public final class SwiftTargetBuildDescription {
102102
}
103103
}
104104
}
105+
106+
/// Triple for which this target is compiled.
107+
private var buildTriple: Triple {
108+
self.buildParameters.buildTriple(for: self.target)
109+
}
105110

106111
/// The path to the swiftmodule file after compilation.
107112
var moduleOutputPath: AbsolutePath {
108113
// If we're an executable and we're not allowing test targets to link against us, we hide the module.
109-
let allowLinkingAgainstExecutables = (buildParameters.targetTriple.isDarwin() || self.buildParameters.targetTriple
110-
.isLinux() || self.buildParameters.targetTriple.isWindows()) && self.toolsVersion >= .v5_5
114+
let allowLinkingAgainstExecutables = (
115+
self.buildTriple.isDarwin() ||
116+
self.buildTriple.isLinux() ||
117+
self.buildTriple.isWindows()) && self.toolsVersion >= .v5_5
111118
let dirPath = (target.type == .executable && !allowLinkingAgainstExecutables) ? self.tempsPath : self
112119
.buildParameters.buildPath
113120
return dirPath.appending(component: self.target.c99name + ".swiftmodule")
@@ -317,7 +324,7 @@ public final class SwiftTargetBuildDescription {
317324
return
318325
}
319326

320-
guard buildParameters.targetTriple.isDarwin(), buildParameters.testingParameters.experimentalTestOutput else {
327+
guard self.buildTriple.isDarwin(), self.buildParameters.testingParameters.experimentalTestOutput else {
321328
return
322329
}
323330

@@ -361,7 +368,7 @@ public final class SwiftTargetBuildDescription {
361368
guard let bundlePath else { return }
362369

363370
let mainPathSubstitution: String
364-
if self.buildParameters.targetTriple.isWASI() {
371+
if self.buildTriple.isWASI() {
365372
// We prefer compile-time evaluation of the bundle path here for WASI. There's no benefit in evaluating this
366373
// at runtime, especially as `Bundle` support in WASI Foundation is partial. We expect all resource paths to
367374
// evaluate to `/\(resourceBundleName)/\(resourcePath)`, which allows us to pass this path to JS APIs like
@@ -456,7 +463,7 @@ public final class SwiftTargetBuildDescription {
456463
/// The arguments needed to compile this target.
457464
public func compileArguments() throws -> [String] {
458465
var args = [String]()
459-
args += try self.buildParameters.targetTripleArgs(for: self.target)
466+
args += try self.buildParameters.buildTripleArgs(for: self.target)
460467
args += ["-swift-version", self.swiftVersion.rawValue]
461468

462469
// pass `-v` during verbose builds.
@@ -646,7 +653,7 @@ public final class SwiftTargetBuildDescription {
646653

647654
/// Returns true if ObjC compatibility header should be emitted.
648655
private var shouldEmitObjCCompatibilityHeader: Bool {
649-
self.buildParameters.targetTriple.isDarwin() && self.target.type == .library
656+
self.buildTriple.isDarwin() && self.target.type == .library
650657
}
651658

652659
func writeOutputFileMap() throws -> AbsolutePath {
@@ -849,7 +856,7 @@ public final class SwiftTargetBuildDescription {
849856
var arguments: [String] = []
850857

851858
let isLinkingStaticStdlib = self.buildParameters.linkingParameters.shouldLinkStaticSwiftStdlib
852-
&& self.buildParameters.targetTriple.isSupportingStaticStdlib
859+
&& self.buildParameters.buildTriple(for: self.target).isSupportingStaticStdlib
853860
if isLinkingStaticStdlib {
854861
arguments += ["-static-stdlib"]
855862
}

Sources/Build/BuildManifest/LLBuildManifestBuilder+Product.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ extension LLBuildManifestBuilder {
2020
// Add dependency on Info.plist generation on Darwin platforms.
2121
let testInputs: [AbsolutePath]
2222
if buildProduct.product.type == .test
23-
&& buildProduct.buildParameters.targetTriple.isDarwin()
23+
&& buildProduct.buildTriple.isDarwin()
2424
&& buildProduct.buildParameters.testingParameters.experimentalTestOutput {
2525
let testBundleInfoPlistPath = try buildProduct.binaryPath.parentDirectory.parentDirectory.appending(component: "Info.plist")
2626
testInputs = [testBundleInfoPlistPath]
@@ -59,7 +59,7 @@ extension LLBuildManifestBuilder {
5959
let linkedBinaryNode: Node
6060
let linkedBinaryPath = try buildProduct.binaryPath
6161
if case .executable = buildProduct.product.type,
62-
buildParameters.targetTriple.isMacOSX,
62+
buildProduct.buildTriple.isMacOSX,
6363
buildParameters.debuggingParameters.shouldEnableDebuggingEntitlement {
6464
shouldCodeSign = true
6565
linkedBinaryNode = try .file(buildProduct.binaryPath, isMutated: true)

Sources/Build/BuildManifest/LLBuildManifestBuilder+Swift.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ extension LLBuildManifestBuilder {
516516
"-modulewrap", target.moduleOutputPath.pathString,
517517
"-o", target.wrappedModuleOutputPath.pathString,
518518
]
519-
moduleWrapArgs += try self.buildParameters.targetTripleArgs(for: target.target)
519+
moduleWrapArgs += try self.buildParameters.buildTripleArgs(for: target.target)
520520
self.manifest.addShellCmd(
521521
name: target.wrappedModuleOutputPath.pathString,
522522
description: "Wrapping AST for \(target.target.name) for debugging",

Sources/Build/BuildPlan/BuildPlan+Clang.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ extension BuildPlan {
4242
clangTarget.additionalFlags += try pkgConfig(for: target).cFlags
4343
case let target as BinaryTarget:
4444
if case .xcframework = target.kind {
45-
let libraries = try self.parseXCFramework(for: target)
45+
let libraries = try self.parseXCFramework(for: target, target: clangTarget.target)
4646
for library in libraries {
4747
library.headersPaths.forEach {
4848
clangTarget.additionalFlags += ["-I", $0.pathString]

Sources/Build/BuildPlan/BuildPlan+Product.swift

+14-7
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ extension BuildPlan {
5252
// Note: This will come from build settings in future.
5353
for target in dependencies.staticTargets {
5454
if case let target as ClangTarget = target.underlyingTarget, target.isCXX {
55-
if buildParameters.targetTriple.isDarwin() {
55+
let buildTriple = buildProduct.buildTriple
56+
if buildTriple.isDarwin() {
5657
buildProduct.additionalFlags += ["-lc++"]
57-
} else if buildParameters.targetTriple.isWindows() {
58+
} else if buildTriple.isWindows() {
5859
// Don't link any C++ library.
5960
} else {
6061
buildProduct.additionalFlags += ["-lstdc++"]
@@ -221,12 +222,12 @@ extension BuildPlan {
221222
}
222223
switch binaryTarget.kind {
223224
case .xcframework:
224-
let libraries = try self.parseXCFramework(for: binaryTarget)
225+
let libraries = try self.parseXCFramework(for: binaryTarget, target: target)
225226
for library in libraries {
226227
libraryBinaryPaths.insert(library.libraryPath)
227228
}
228229
case .artifactsArchive:
229-
let tools = try self.parseArtifactsArchive(for: binaryTarget)
230+
let tools = try self.parseArtifactsArchive(for: binaryTarget, target: target)
230231
tools.forEach { availableTools[$0.name] = $0.executablePath }
231232
case.unknown:
232233
throw InternalError("unknown binary target '\(target.name)' type")
@@ -254,9 +255,15 @@ extension BuildPlan {
254255
}
255256

256257
/// Extracts the artifacts from an artifactsArchive
257-
private func parseArtifactsArchive(for target: BinaryTarget) throws -> [ExecutableInfo] {
258-
try self.externalExecutablesCache.memoize(key: target) {
259-
let execInfos = try target.parseArtifactArchives(for: self.buildParameters.targetTriple, fileSystem: self.fileSystem)
258+
private func parseArtifactsArchive(
259+
for binaryTarget: BinaryTarget,
260+
target: ResolvedTarget
261+
) throws -> [ExecutableInfo] {
262+
try self.externalExecutablesCache.memoize(key: binaryTarget) {
263+
let execInfos = try binaryTarget.parseArtifactArchives(
264+
for: self.buildParameters.buildTriple(for: target),
265+
fileSystem: self.fileSystem
266+
)
260267
return execInfos.filter{!$0.supportedTriples.isEmpty}
261268
}
262269
}

Sources/Build/BuildPlan/BuildPlan+Swift.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extension BuildPlan {
3939
swiftTarget.additionalFlags += try pkgConfig(for: target).cFlags
4040
case let target as BinaryTarget:
4141
if case .xcframework = target.kind {
42-
let libraries = try self.parseXCFramework(for: target)
42+
let libraries = try self.parseXCFramework(for: target, target: swiftTarget.target)
4343
for library in libraries {
4444
library.headersPaths.forEach {
4545
swiftTarget.additionalFlags += ["-I", $0.pathString, "-Xcc", "-I", "-Xcc", $0.pathString]

0 commit comments

Comments
 (0)