Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
MarijnS95 committed Jan 10, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent d2e401f commit 3fac180
Showing 3 changed files with 25 additions and 4 deletions.
4 changes: 3 additions & 1 deletion BUILDING.md
Original file line number Diff line number Diff line change
@@ -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"
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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" }
20 changes: 17 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
@@ -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,9 +548,22 @@ 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");
// 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
// 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).
&& matches!(
compiler.family(),
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()
} else {
compiler

0 comments on commit 3fac180

Please sign in to comment.