@@ -206,7 +206,7 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
206206 return max_key
207207 }
208208
209- fn get_windows_sdk_path ( ) -> Option < ( PathBuf , usize ) > {
209+ fn get_windows_sdk_path ( ) -> Option < ( PathBuf , usize , Option < OsString > ) > {
210210 let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows" ;
211211 let key = LOCAL_MACHINE . open ( key. as_ref ( ) ) ;
212212 let ( n, k) = match key. ok ( ) . as_ref ( ) . and_then ( max_version) {
@@ -217,28 +217,29 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
217217 let major = parts. next ( ) . unwrap ( ) . parse :: < usize > ( ) . unwrap ( ) ;
218218 let _minor = parts. next ( ) . unwrap ( ) . parse :: < usize > ( ) . unwrap ( ) ;
219219 k. query_str ( "InstallationFolder" ) . ok ( ) . map ( |folder| {
220- ( PathBuf :: from ( folder) , major)
220+ let ver = k. query_str ( "ProductVersion" ) ;
221+ ( PathBuf :: from ( folder) , major, ver. ok ( ) )
221222 } )
222223 }
223224
224225 fn get_windows_sdk_lib_path ( sess : & Session ) -> Option < PathBuf > {
225- let ( mut path, major) = match get_windows_sdk_path ( ) {
226+ let ( mut path, major, ver ) = match get_windows_sdk_path ( ) {
226227 Some ( p) => p,
227228 None => return None ,
228229 } ;
229230 path. push ( "Lib" ) ;
230231 if major <= 7 {
231232 // In Windows SDK 7.x, x86 libraries are directly in the Lib folder,
232- // x64 libraries are inside, and it's not necessary to link agains
233+ // x64 libraries are inside, and it's not necessary to link against
233234 // the SDK 7.x when targeting ARM or other architectures.
234235 let x86 = match & sess. target . target . arch [ ..] {
235236 "x86" => true ,
236237 "x86_64" => false ,
237238 _ => return None ,
238239 } ;
239240 Some ( if x86 { path} else { path. join ( "x64" ) } )
240- } else {
241- // Windows SDK 8.x installes libraries in a folder whose names
241+ } else if major <= 8 {
242+ // Windows SDK 8.x installs libraries in a folder whose names
242243 // depend on the version of the OS you're targeting. By default
243244 // choose the newest, which usually corresponds to the version of
244245 // the OS you've installed the SDK on.
@@ -251,7 +252,25 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
251252 } ) . map ( |path| {
252253 path. join ( "um" ) . join ( extra)
253254 } )
254- }
255+ } else if let Some ( mut ver) = ver {
256+ // Windows SDK 10 splits the libraries into architectures the same
257+ // as Windows SDK 8.x, except for the addition of arm64.
258+ // Additionally, the SDK 10 is split by Windows 10 build numbers
259+ // rather than the OS version like the SDK 8.x does.
260+ let extra = match windows_sdk_v10_subdir ( sess) {
261+ Some ( e) => e,
262+ None => return None ,
263+ } ;
264+ // To get the correct directory we need to get the Windows SDK 10
265+ // version, and so far it looks like the "ProductVersion" of the SDK
266+ // corresponds to the folder name that the libraries are located in
267+ // except that the folder contains an extra ".0". For now just
268+ // append a ".0" to look for find the directory we're in. This logic
269+ // will likely want to be refactored one day.
270+ ver. push ( ".0" ) ;
271+ let p = path. join ( ver) . join ( "um" ) . join ( extra) ;
272+ fs:: metadata ( & p) . ok ( ) . map ( |_| p)
273+ } else { None }
255274 }
256275
257276 fn windows_sdk_v8_subdir ( sess : & Session ) -> Option < & ' static str > {
@@ -263,6 +282,16 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
263282 }
264283 }
265284
285+ fn windows_sdk_v10_subdir ( sess : & Session ) -> Option < & ' static str > {
286+ match & sess. target . target . arch [ ..] {
287+ "x86" => Some ( "x86" ) ,
288+ "x86_64" => Some ( "x64" ) ,
289+ "arm" => Some ( "arm" ) ,
290+ "aarch64" => Some ( "arm64" ) , // FIXME - Check if aarch64 is correct
291+ _ => return None ,
292+ }
293+ }
294+
266295 fn ucrt_install_dir ( vs_install_dir : & Path ) -> Option < ( PathBuf , String ) > {
267296 let is_vs_14 = vs_install_dir. iter ( ) . filter_map ( |p| p. to_str ( ) ) . any ( |s| {
268297 s == "Microsoft Visual Studio 14.0"
0 commit comments