diff --git a/BUILDING.md b/BUILDING.md index 9143841cf..eaacef053 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -22,9 +22,11 @@ edition of Visual Studio, like Community, Standard, or Enterprise). The “Desktop development with C++” workflow must be installed. Visual Studio 2022 Version 17.5 is supported; earlier versions of Visual Studio may work. +### (Cross-)compiling to Windows ARM64 + For Windows ARM64 targets (aarch64-pc-windows-msvc), the Visual Studio Build Tools “VS 2022 C++ ARM64 build tools” and "clang" components must be installed. -Add Microsoft's provided version of `clang` to `%PATH%`, which will allow the +Add Microsoft's provided version of `clang-cl` to `%PATH%`, which will allow the build to work in GitHub Actions without installing anything: ``` $env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin" diff --git a/Cargo.toml b/Cargo.toml index 494b708a8..be9f4f061 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -227,3 +227,8 @@ default-members = [ ".", "cavp" ] + +[patch.crates-io] +# https://github.com/rust-lang/cc-rs/pull/1357 +# https://github.com/rust-lang/cc-rs/pull/1358 +cc = { git = "https://github.com/rust-lang/cc-rs", rev = "e551e8b" } diff --git a/build.rs b/build.rs index 740bc27fa..12cfac52c 100644 --- a/build.rs +++ b/build.rs @@ -147,6 +147,7 @@ fn cpp_flags(compiler: &cc::Tool) -> &'static [&'static str] { NON_MSVC_FLAGS } else { static MSVC_FLAGS: &[&str] = &[ + "/std:c11", "/Gy", // Enable function-level linking. "/Zc:wchar_t", "/Zc:forScope", @@ -547,10 +548,24 @@ fn obj_path(out_dir: &Path, src: &Path) -> PathBuf { fn configure_cc(c: &mut cc::Build, target: &Target, c_root_dir: &Path, include_dir: &Path) { let compiler = c.get_compiler(); - // FIXME: On Windows AArch64 we currently must use Clang to compile C code - let compiler = if target.os == WINDOWS && target.arch == AARCH64 && !compiler.is_like_clang() { - let _ = c.compiler("clang"); - c.get_compiler() + // FIXME: On Windows AArch64, ring C code cannot be compiled using cl.exe, but must be compiled + // using the LLVM toolchain. + let compiler = if target.os == WINDOWS && target.arch == AARCH64 { + match compiler.family() { + // If the user is already using clang or clang-cl, nothing needs to be replaced + cc::ToolFamily::Clang { .. } | cc::ToolFamily::Msvc { clang_cl: true, .. } => compiler, + // If cl.exe is used, replace that with clang-cl which is most likely to be compatible + // with flags that are already in place (i.e. custom CFLAGS that the user provided to cc). + cc::ToolFamily::Msvc { + clang_cl: false, .. + } => { + // FIXME: This requires clang-cl to be available in PATH, regardless of any explicit + // or custom path that the user might have provided to cc via the CC flag. + c.compiler("clang-cl"); + c.get_compiler() + } + t => panic!("Unsupported tool `{t:?}` for ARM64 Windows compilation"), + } } else { compiler };