Skip to content

Commit af668d0

Browse files
committed
PackageModel: adjust toolchain layout for Windows
Add in a migration path for adjusting the layout of the toolchain. This is required in order to support more than one architecture SDK to be installed simultaneously. The problem is primarily on the XCTest side, where the binary is not slotted to an architecture. Having multiple variants of XCTest is difficult with the toolchain layout. The XCTest installation is located at `%DEVELOPER_DIR%\Platforms\<Platform>.platform\Library\XCTest-<version>`. The runtime component is located under, and the DLL is always named `XCTest.dll`. The following options were considered: 1. renaming `XCTest.dll` to: - `XCTest32.dll` (x86) - `XCTest64.dll` (x64) - `XCTest32a.dll` (ARMv7) - `XCTest64a.dll` (ARM64) 2. renaming `bin` to: - `bin32` (x86) - `bin64` (x64) - `bin32a` (ARMv7) - `bin64a` (ARM64) 3. adding a subdirectory to `bin` Option 2 was deemed to be the best of the terrible options. It would allow a migration path (as the DLL name is embedded into the import library and subsequently the executable). We simultaneously update the location for the import library. Although it is possible to build a multi-architecture import library, we would need generate that manually before the installer package is built and then only install the runtime. It seems that moving the directory would be easier and ensure that we can keep them somewhat independent.
1 parent e6ffbb2 commit af668d0

File tree

1 file changed

+75
-6
lines changed

1 file changed

+75
-6
lines changed

Sources/PackageModel/UserToolchain.swift

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,28 @@ public final class UserToolchain: Toolchain {
255255
root.appending(component: "Developer")
256256
.appending(component: "Library")
257257
.appending(component: "XCTest-\(info.defaults.xctestVersion)")
258+
258259
xctest = [
259260
"-I", AbsolutePath("usr/lib/swift/windows/\(triple.arch)", relativeTo: path).pathString,
260-
"-L", AbsolutePath("usr/lib/swift/windows", relativeTo: path).pathString,
261+
"-L", AbsolutePath("usr/lib/swift/windows/\(triple.arch)", relativeTo: path).pathString,
261262
]
262263

264+
// Migration Path
265+
//
266+
// In order to support multiple parallel
267+
// installations of an SDK, we need to ensure that
268+
// we can have all the architecture variant
269+
// libraries available. Prior to this getting
270+
// enabled (~5.7), we always had a singular
271+
// installed SDK. Prefer the new variant which has
272+
// an architecture subdirectory in `bin` if
273+
// available.
274+
let implib: AbsolutePath =
275+
AbsolutePath("usr/lib/swift/windows/XCTest.lib", relativeTo: path)
276+
if localFileSystem.exists(implib) {
277+
xctest.append(contentsOf: ["-L", implib.parentDirectory.pathString])
278+
}
279+
263280
extraSwiftCFlags = info.defaults.extraSwiftCFlags ?? []
264281
}
265282
}
@@ -460,11 +477,63 @@ public final class UserToolchain: Toolchain {
460477
if let info = WindowsPlatformInfo(reading: root.appending(component: "Info.plist"),
461478
diagnostics: nil,
462479
filesystem: localFileSystem) {
463-
return root.appending(component: "Developer")
464-
.appending(component: "Library")
465-
.appending(component: "XCTest-\(info.defaults.xctestVersion)")
466-
.appending(component: "usr")
467-
.appending(component: "bin")
480+
481+
let installation: AbsolutePath =
482+
root.appending(component: "Developer")
483+
.appending(component: "Library")
484+
.appending(component: "XCTest-\(info.defaults.xctestVersion)")
485+
486+
// Migration Path
487+
//
488+
// In order to support multiple parallel installations of an
489+
// SDK, we need to ensure that we can have all the
490+
// architecture variant libraries available. Prior to this
491+
// getting enabled (~5.7), we always had a singular
492+
// installed SDK. Prefer the new variant which has an
493+
// architecture subdirectory in `bin` if available.
494+
switch triple.arch {
495+
case .x86_64, .x86_64h:
496+
let path: AbsolutePath =
497+
installation.appending(component: "usr")
498+
.appending(component: "bin64")
499+
if localFileSystem.exists(path) {
500+
return path
501+
}
502+
503+
case .i686:
504+
let path: AbsolutePath =
505+
installation.appending(component: "usr")
506+
.appending(component: "bin32")
507+
if localFileSystem.exists(path) {
508+
return path
509+
}
510+
511+
case .armv7:
512+
let path: AbsolutePath =
513+
installation.appending(component: "usr")
514+
.appending(component: "bin32a")
515+
if localFileSystem.exists(path) {
516+
return path
517+
}
518+
519+
case .arm64:
520+
let path: AbsolutePath =
521+
installation.appending(component: "usr")
522+
.appending(component: "bin64a")
523+
if localFileSystem.exists(path) {
524+
return path
525+
}
526+
527+
default:
528+
// Fallback to the old-style layout. We should really
529+
// report an error in this case - this architecture is
530+
// unavailable.
531+
break
532+
}
533+
534+
// Assume that we are in the old-style layout.
535+
return installation.appending(component: "usr")
536+
.appending(component: "bin")
468537
}
469538
}
470539
}

0 commit comments

Comments
 (0)