Skip to content

Commit

Permalink
build: Only replace cl.exe with clang-cl for ARM64 Windows builds
Browse files Browse the repository at this point in the history
When cross-compiling to Windows from Linux or similar, it's common to
use the `clang-cl` driver from the LLVM toolchain which supports parsing
`cl.exe`-like arguments.

Ring however doesn't seem to compile for ARM64 Windows using `cl.exe`,
and contains a `// FIXME`-style workaround to use `clang` to compile its
C files instead.

The command-line interface for `clang` isn't always compatible with that
of `cl.exe` and `clang-cl`.  There didn't seem to be any trouble with
this yet, but when cross-compiling from Linux it's common to explicitly
provide "sysroots" via `-vctoolsdir` and `-winsdkdir` in `CFLAGS`.
In such a setup this workaround in `ring` would pass those arguments
to `clang`, resulting in "unknown argument" errors.

`cc-rs` can tell us exactly what compiler it found, and we can use this
information to decide how to fill in this workaround.  If the user was
already compiling their code with `clang`, nothing has to be replaced.
In the end, all this entails is changing the workaround to not compile
with `clang`, but with `clang-cl` instead.
  • Loading branch information
MarijnS95 committed Jan 10, 2025
1 parent d2e401f commit 9608023
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 5 deletions.
4 changes: 3 additions & 1 deletion BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
17 changes: 13 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -547,10 +548,18 @@ 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 we currently must use LLVM (clang-cl) to compile C code
let compiler = if target.os == WINDOWS && target.arch == AARCH64 {
match compiler.family() {
cc::ToolFamily::Clang { .. } | cc::ToolFamily::Msvc { clang_cl: true, .. } => compiler,
cc::ToolFamily::Msvc {
clang_cl: false, ..
} => {
c.compiler("clang-cl");
c.get_compiler()
}
t => panic!("Unsupported tool `{t:?}` for ARM64 Windows compilation"),
}
} else {
compiler
};
Expand Down

0 comments on commit 9608023

Please sign in to comment.