diff --git a/README.md b/README.md index 40df6a4737871..724bc36ecc6fb 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ then you may need to force rustbuild to use an older version. This can be done by manually calling the appropriate vcvars file before running the bootstrap. ```batch -> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat" +> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" > python x.py build ``` diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 3f6a1a72ea61e..3a0d5261d0c86 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -32,6 +32,7 @@ use std::path::{Path, PathBuf}; use std::process::{Output, Stdio, ExitStatus}; use std::str; use std::env; +use std::ffi::OsString; pub use rustc_codegen_utils::link::*; @@ -158,6 +159,36 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB } }; + // UWP apps have API restrictions enforced during Store submissions. + // To comply with the Windows App Certification Kit, + // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). + let t = &sess.target.target; + if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" { + if let Some(ref tool) = msvc_tool { + let original_path = tool.path(); + if let Some(ref root_lib_path) = original_path.ancestors().skip(4).next() { + let arch = match t.arch.as_str() { + "x86_64" => Some("x64".to_string()), + "x86" => Some("x86".to_string()), + "aarch64" => Some("arm64".to_string()), + _ => None, + }; + if let Some(ref a) = arch { + let mut arg = OsString::from("/LIBPATH:"); + arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a.to_string())); + cmd.arg(&arg); + } + else { + warn!("arch is not supported"); + } + } else { + warn!("MSVC root path lib location not found"); + } + } else { + warn!("link.exe not found"); + } + } + // The compiler's sysroot often has some bundled tools, so add it to the // PATH for the child. let mut new_path = sess.host_filesearch(PathKind::All) @@ -1027,6 +1058,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, let t = &sess.target.target; cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path)); + for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) { cmd.add_object(obj); } diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs new file mode 100644 index 0000000000000..5d8b829f2ab71 --- /dev/null +++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy}; + +pub fn target() -> TargetResult { + let mut base = super::windows_uwp_msvc_base::opts(); + base.max_atomic_width = Some(64); + base.has_elf_tls = true; + + // FIXME: this shouldn't be panic=abort, it should be panic=unwind + base.panic_strategy = PanicStrategy::Abort; + + Ok(Target { + llvm_target: "aarch64-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(), + arch: "aarch64".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "uwp".to_string(), + linker_flavor: LinkerFlavor::Msvc, + options: base, + }) +} diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs new file mode 100644 index 0000000000000..5e8e8c2a4149c --- /dev/null +++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs @@ -0,0 +1,22 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::windows_uwp_msvc_base::opts(); + base.cpu = "pentium4".to_string(); + base.max_atomic_width = Some(64); + base.has_elf_tls = true; + + Ok(Target { + llvm_target: "i686-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(), + arch: "x86".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "uwp".to_string(), + linker_flavor: LinkerFlavor::Msvc, + options: base, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 54e3cad6a6149..dbb29c595038a 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -61,6 +61,7 @@ mod uefi_base; mod windows_base; mod windows_msvc_base; mod windows_uwp_base; +mod windows_uwp_msvc_base; mod thumb_base; mod l4re_base; mod fuchsia_base; @@ -439,8 +440,11 @@ supported_targets! { ("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu), ("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc), + ("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc), ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc), + ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc), ("i686-pc-windows-msvc", i686_pc_windows_msvc), + ("i686-uwp-windows-msvc", i686_uwp_windows_msvc), ("i586-pc-windows-msvc", i586_pc_windows_msvc), ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc), diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs new file mode 100644 index 0000000000000..1121916e68f51 --- /dev/null +++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs @@ -0,0 +1,33 @@ +use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use std::default::Default; + +pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Msvc, + vec!["/NOLOGO".to_string(), + "/NXCOMPAT".to_string(), + "/APPCONTAINER".to_string(), + "mincore.lib".to_string()]); + + TargetOptions { + function_sections: true, + dynamic_linking: true, + executables: true, + dll_prefix: String::new(), + dll_suffix: ".dll".to_string(), + exe_suffix: ".exe".to_string(), + staticlib_prefix: String::new(), + staticlib_suffix: ".lib".to_string(), + target_family: Some("windows".to_string()), + is_like_windows: true, + is_like_msvc: true, + pre_link_args: args, + crt_static_allows_dylibs: true, + crt_static_respected: true, + abi_return_struct_as_int: true, + emit_debug_gdb_scripts: false, + requires_uwtable: true, + + .. Default::default() + } +} diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs new file mode 100644 index 0000000000000..40dd52c159151 --- /dev/null +++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs @@ -0,0 +1,22 @@ +use crate::spec::{LinkerFlavor, Target, TargetResult}; + +pub fn target() -> TargetResult { + let mut base = super::windows_uwp_msvc_base::opts(); + base.cpu = "x86-64".to_string(); + base.max_atomic_width = Some(64); + base.has_elf_tls = true; + + Ok(Target { + llvm_target: "x86_64-pc-windows-msvc".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(), + arch: "x86_64".to_string(), + target_os: "windows".to_string(), + target_env: "msvc".to_string(), + target_vendor: "uwp".to_string(), + linker_flavor: LinkerFlavor::Msvc, + options: base, + }) +} diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index f706709c9ccf4..b1f9d9766f705 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -714,7 +714,7 @@ if #[cfg(target_vendor = "uwp")] { pub struct FILE_STANDARD_INFO { pub AllocationSize: LARGE_INTEGER, pub EndOfFile: LARGE_INTEGER, - pub NumberOfLink: DWORD, + pub NumberOfLinks: DWORD, pub DeletePending: BOOLEAN, pub Directory: BOOLEAN, } diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 5bae6ba4749bd..204f6af5fc1a0 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -357,7 +357,7 @@ impl File { size as c::DWORD))?; attr.file_size = info.AllocationSize as u64; attr.number_of_links = Some(info.NumberOfLinks); - if attr.is_reparse_point() { + if attr.file_type().is_reparse_point() { let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; if let Ok((_, buf)) = self.reparse_point(&mut b) { attr.reparse_tag = buf.ReparseTag;