-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Use vswhere to find MSVC tools
#6120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
db8ee97
4d42948
e377bcb
66a0523
7bc9aee
23bf36b
3b839c8
b7a6340
7867ea8
185b652
d217a63
325bd79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,7 +56,7 @@ public final class UserToolchain: Toolchain { | |
| /// Search paths from the PATH environment variable. | ||
| let envSearchPaths: [AbsolutePath] | ||
|
|
||
| /// Only use search paths, do not fall back to `xcrun`. | ||
| /// Only use search paths, do not fall back to `xcrun` or `vswhere`. | ||
| let useXcrun: Bool | ||
|
|
||
| private var _clangCompiler: AbsolutePath? | ||
|
|
@@ -100,7 +100,7 @@ public final class UserToolchain: Toolchain { | |
| return toolPath | ||
| } | ||
|
|
||
| private static func findTool(_ name: String, envSearchPaths: [AbsolutePath], useXcrun: Bool) | ||
| private static func findTool(_ name: String, destination: Destination, envSearchPaths: [AbsolutePath], swiftCompilerPath: AbsolutePath?, useXcrun: Bool) | ||
| throws -> AbsolutePath | ||
| { | ||
| if useXcrun { | ||
|
|
@@ -117,15 +117,60 @@ public final class UserToolchain: Toolchain { | |
| return toolPath | ||
| } | ||
| } | ||
|
|
||
| if useXcrun { | ||
|
||
| #if os(Windows) | ||
|
||
| func getHostTriple(from destination: Destination, swiftCompilerPath: AbsolutePath?) -> Triple? { | ||
| if let triple = destination.hostTriple { | ||
| return triple | ||
| } else if let swiftCompilerPath = swiftCompilerPath { | ||
| return .getHostTriple(usingSwiftCompiler: swiftCompilerPath) | ||
| } else { | ||
| return nil | ||
| } | ||
| } | ||
| if let hostTriple = getHostTriple(from: destination, swiftCompilerPath: swiftCompilerPath), | ||
| case let targetTriple = destination.targetTriple ?? hostTriple, targetTriple.isWindows() { | ||
| func vcArchNames(triple: Triple) -> (product: String, host: String, target: String)? { | ||
| switch triple.arch { | ||
| case .x86_64: | ||
| return ("Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "HostX64", "x64") | ||
| case .i686: | ||
| return ("Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "HostX86", "x86") | ||
| case .arm64, .arm64e, .aarch64: | ||
| return ("Microsoft.VisualStudio.Component.VC.Tools.ARM64", "HostARM64", "arm64") | ||
| case .arm, .armv5, .armv6, .armv7: | ||
| return ("Microsoft.VisualStudio.Component.VC.Tools.ARM", "HostARM", "arm") | ||
| default: return nil | ||
| } | ||
| } | ||
| if let (_, vcHost, _) = vcArchNames(triple: hostTriple), | ||
| let (vcTools, _, vcTarget) = vcArchNames(triple: targetTriple), | ||
| let programFiles = TSCBasic.ProcessEnv.vars["ProgramFiles(x86)"] { | ||
| if let visualStudio = try? TSCBasic.Process.checkNonZeroExit(arguments: [ | ||
| "\(programFiles)\\Microsoft Visual Studio\\Installer\\vswhere.exe", | ||
| "-latest", "-products", "*", "-requires", vcTools, "-property", "installationPath" | ||
| ]).spm_chomp(), | ||
| let vcToolsVersion = try? String(contentsOfFile: "\(visualStudio)\\VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt").spm_chomp(), | ||
| let vcToolsDir = try? AbsolutePath(validating: "\(visualStudio)\\VC\\Tools\\MSVC\\\(vcToolsVersion)\\bin\\\(vcHost)\\\(vcTarget)"), | ||
| let toolPath = try? getTool(name, binDir: vcToolsDir) { | ||
| return toolPath | ||
| } | ||
| } | ||
| } | ||
| #endif | ||
| } | ||
|
||
|
|
||
| throw InvalidToolchainDiagnostic("could not find \(name)") | ||
| } | ||
|
|
||
| // MARK: - public API | ||
|
|
||
| public static func determineLibrarian( | ||
| triple: Triple, binDir: AbsolutePath, | ||
| triple: Triple, destination: Destination, binDir: AbsolutePath, | ||
| useXcrun: Bool, | ||
| environment: EnvironmentVariables, | ||
| swiftCompilerPath: AbsolutePath, | ||
| searchPaths: [AbsolutePath] | ||
| ) throws | ||
| -> AbsolutePath | ||
|
|
@@ -163,12 +208,12 @@ public final class UserToolchain: Toolchain { | |
| if let librarian = try? UserToolchain.getTool(tool, binDir: binDir) { | ||
| return librarian | ||
| } | ||
| return try UserToolchain.findTool(tool, envSearchPaths: searchPaths, useXcrun: useXcrun) | ||
| return try UserToolchain.findTool(tool, destination: destination, envSearchPaths: searchPaths, swiftCompilerPath: swiftCompilerPath, useXcrun: useXcrun) | ||
| } | ||
|
|
||
| /// Determines the Swift compiler paths for compilation and manifest parsing. | ||
| public static func determineSwiftCompilers( | ||
| binDir: AbsolutePath, useXcrun: Bool, environment: EnvironmentVariables, | ||
| binDir: AbsolutePath, destination: Destination, useXcrun: Bool, environment: EnvironmentVariables, | ||
| searchPaths: [AbsolutePath] | ||
| ) throws -> SwiftCompilers { | ||
| func validateCompiler(at path: AbsolutePath?) throws { | ||
|
|
@@ -201,7 +246,7 @@ public final class UserToolchain: Toolchain { | |
| // Try to lookup swift compiler on the system which is possible when | ||
| // we're built outside of the Swift toolchain. | ||
| resolvedBinDirCompiler = try UserToolchain.findTool( | ||
| "swiftc", envSearchPaths: searchPaths, useXcrun: useXcrun) | ||
| "swiftc", destination: destination, envSearchPaths: searchPaths, swiftCompilerPath: nil, useXcrun: useXcrun) | ||
| } | ||
|
|
||
| // The compiler for compilation tasks is SWIFT_EXEC or the bin dir compiler. | ||
|
|
@@ -236,7 +281,7 @@ public final class UserToolchain: Toolchain { | |
|
|
||
| // Otherwise, lookup it up on the system. | ||
| let toolPath = try UserToolchain.findTool( | ||
| "clang", envSearchPaths: self.envSearchPaths, useXcrun: useXcrun) | ||
| "clang", destination: destination, envSearchPaths: self.envSearchPaths, swiftCompilerPath: swiftCompilerPath, useXcrun: useXcrun) | ||
| self._clangCompiler = toolPath | ||
| return toolPath | ||
| } | ||
|
|
@@ -261,7 +306,7 @@ public final class UserToolchain: Toolchain { | |
| } | ||
| // If that fails, fall back to xcrun, PATH, etc. | ||
| return try UserToolchain.findTool( | ||
| "lldb", envSearchPaths: self.envSearchPaths, useXcrun: useXcrun) | ||
| "lldb", destination: destination, envSearchPaths: self.envSearchPaths, swiftCompilerPath: swiftCompilerPath, useXcrun: useXcrun) | ||
| } | ||
|
|
||
| /// Returns the path to llvm-cov tool. | ||
|
|
@@ -430,7 +475,7 @@ public final class UserToolchain: Toolchain { | |
| let binDir = destination.toolchainBinDir | ||
|
|
||
| let swiftCompilers = try UserToolchain.determineSwiftCompilers( | ||
| binDir: binDir, useXcrun: useXcrun, environment: environment, searchPaths: envSearchPaths) | ||
| binDir: binDir, destination: destination, useXcrun: useXcrun, environment: environment, searchPaths: envSearchPaths) | ||
| self.swiftCompilerPath = swiftCompilers.compile | ||
| self.architectures = destination.architectures | ||
|
|
||
|
|
@@ -439,7 +484,8 @@ public final class UserToolchain: Toolchain { | |
| destination.targetTriple ?? Triple.getHostTriple(usingSwiftCompiler: swiftCompilers.compile) | ||
|
|
||
| self.librarianPath = try UserToolchain.determineLibrarian( | ||
| triple: triple, binDir: binDir, useXcrun: useXcrun, environment: environment, | ||
| triple: triple, destination: destination, binDir: binDir, | ||
| useXcrun: useXcrun, environment: environment, swiftCompilerPath: swiftCompilerPath, | ||
| searchPaths: envSearchPaths) | ||
|
|
||
| // Change the triple to the specified arch if there's exactly one of them. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still undecided if we want to rename the variable. I didn't do this at the point because neither have I got a short and clear name (
useExternalToolsounds verbose and confusing), nor am I going to makevswherethe default likexcrunis now. It can be prioritized in later pitches.