Skip to content

Commit ac6451a

Browse files
committed
build: Only replace cl.exe with clang-cl for ARM64 Windows builds
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.
1 parent d2e401f commit ac6451a

File tree

3 files changed

+27
-5
lines changed

3 files changed

+27
-5
lines changed

BUILDING.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ edition of Visual Studio, like Community, Standard, or Enterprise). The
2222
“Desktop development with C++” workflow must be installed. Visual Studio
2323
2022 Version 17.5 is supported; earlier versions of Visual Studio may work.
2424

25+
### (Cross-)compiling to Windows ARM64
26+
2527
For Windows ARM64 targets (aarch64-pc-windows-msvc), the Visual Studio Build
2628
Tools “VS 2022 C++ ARM64 build tools” and "clang" components must be installed.
27-
Add Microsoft's provided version of `clang` to `%PATH%`, which will allow the
29+
Add Microsoft's provided version of `clang-cl` to `%PATH%`, which will allow the
2830
build to work in GitHub Actions without installing anything:
2931
```
3032
$env:Path += ";C:\Program Files (x86)\Microsoft Visual Studio\2022\Enterprise\VC\Tools\Llvm\x64\bin"

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,8 @@ default-members = [
227227
".",
228228
"cavp"
229229
]
230+
231+
[patch.crates-io]
232+
# https://github.com/rust-lang/cc-rs/pull/1357
233+
# https://github.com/rust-lang/cc-rs/pull/1358
234+
cc = { git = "https://github.com/rust-lang/cc-rs", rev = "e551e8b" }

build.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ fn cpp_flags(compiler: &cc::Tool) -> &'static [&'static str] {
147147
NON_MSVC_FLAGS
148148
} else {
149149
static MSVC_FLAGS: &[&str] = &[
150+
"/std:c11",
150151
"/Gy", // Enable function-level linking.
151152
"/Zc:wchar_t",
152153
"/Zc:forScope",
@@ -547,10 +548,24 @@ fn obj_path(out_dir: &Path, src: &Path) -> PathBuf {
547548

548549
fn configure_cc(c: &mut cc::Build, target: &Target, c_root_dir: &Path, include_dir: &Path) {
549550
let compiler = c.get_compiler();
550-
// FIXME: On Windows AArch64 we currently must use Clang to compile C code
551-
let compiler = if target.os == WINDOWS && target.arch == AARCH64 && !compiler.is_like_clang() {
552-
let _ = c.compiler("clang");
553-
c.get_compiler()
551+
// FIXME: On Windows AArch64, ring C code cannot be compiled using cl.exe, but must be compiled
552+
// using the LLVM toolchain.
553+
let compiler = if target.os == WINDOWS && target.arch == AARCH64 {
554+
match compiler.family() {
555+
// If the user is already using clang or clang-cl, nothing needs to be replaced
556+
cc::ToolFamily::Clang { .. } | cc::ToolFamily::Msvc { clang_cl: true, .. } => compiler,
557+
// If cl.exe is used, replace that with clang-cl which is most likely to be compatible
558+
// with flags that are already in place (i.e. custom CFLAGS that the user provided to cc).
559+
cc::ToolFamily::Msvc {
560+
clang_cl: false, ..
561+
} => {
562+
// FIXME: This requires clang-cl to be available in PATH, regardless of any explicit
563+
// or custom path that the user might have provided to cc via the CC flag.
564+
c.compiler("clang-cl");
565+
c.get_compiler()
566+
}
567+
t => panic!("Unsupported tool `{t:?}` for ARM64 Windows compilation"),
568+
}
554569
} else {
555570
compiler
556571
};

0 commit comments

Comments
 (0)