-
Notifications
You must be signed in to change notification settings - Fork 715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
build: Only replace cl.exe
with clang-cl
for ARM64 Windows builds
#2216
base: main
Are you sure you want to change the base?
build: Only replace cl.exe
with clang-cl
for ARM64 Windows builds
#2216
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In ci.yml
, we have (twice):
- if: ${{ matrix.target == 'aarch64-pc-windows-msvc' }}
run: |
echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH
When using clang-cl, is this still necessary, or is clang-cl already in the path in GitHub actions?
If clang-cl is more common and clang-cl is already in the path, then we should remove this from ci.yml.
We should also update BUILDING.md "For Windows ARM64 targets..." to describe the updated situation.
build.rs
Outdated
&& !compiler.is_like_clang() | ||
&& !compiler.is_like_clang_cl() | ||
{ | ||
c.compiler("clang"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we start defaulting to clang-cl instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps. If users are more commonly compiling for Windows MSVC than Windows GNU, arbitrarily replacing their requested compiler with clang-cl
whose arguments are compatible with cl.exe
seems a lot less error-prone than giving them the clang
interface. Any cl.exe
-specific argument in their CFLAGS
(my issue: #2215) and this fails to compile.
Either way, overwriting compilers - which might have been carefully set up via CC
environment flags etc (to not have to rely on PATH
!) - seems very painful. As said below, having ring
compile natively with cl.exe
would be awesome. At least it's isolated to ARM64 Windows though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the time, cl.exe didn't have uint128_t
and probably there were other issues too. Maybe BoringSSL actually made some changes upstream to avoid requiring uint128_t for the ECC code? If so, then we can probably start supporting cl.exe. Definitely, I would love it, and I think there's already an issue for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool - I'll try to cross-compile with cl.exe
from my Windows X64 machine to find out and document what specifically is holding it back if at all.
At the same time I'm inquiring to get access to an ARM64 Windows machine soon, to test what happens when natively compiling on that machine.
In the commit message:
here and elsewhere you use the word "overwrite" when I think "override" is the better word.
I suggest instead we say "When this is done,".
Most likely, we need to modify our compiler flag handling in build.rs to pass the correct flags to clang-cl.
IIRC, when I tried it, clang-cl couldn't compile the assembly source files, which is why we hard-code clang. We need to modify ci.yml to add the clang-cl-based configuration. I also think that, assuming it works "equally well," we should default to the clang-cl-based build (instead of clang) when we detect the C compiler is MSVC and the target is aarch64. |
clang-cl
with clang
for ARM64 Windows buildsclang-cl
with clang
for ARM64 Windows builds
This PR is solely about supporting a cross-compile from Linux (for #2215), and I have no clue about a "native" cross-compile from Windows->Windows (barring the architecture). If you want to know this for sure, I'd have to boot into a Windows machine for some experimentation. It seems very unlikely that
I don't think much is changing, or supposed to be changed here. All this PR really is about, is making the constraints for this As above, if we're "blindly" replacing the compiler command with The best course of action would be if this project could natively compile for |
Agreed. It doesn't overwrite the compiler, but it does "overwrite" or "overrule" a
NAK. I didn't introduce the idea of "overwrite the compiler with
As above, if we assume that user flags are more likely compatible with I do think we can be more strict here. We're going to expose the match compiler.family() {
// The workaround
ToolFamily::Msvc { clang_cl: false } => c.compiler("clang-cl"),
ToolFamily::Msvc { clang_cl: true } | ToolFamily::Clang { .. } => {},
ToolFamily::Gnu { .. } => todo!("Test this"),
}
Curious what that entails. For me it failed only because of warnings forced as errors in the Line 314 in d2e401f
Sure let's always use |
In the issue, you mentioned:
Of course, we require C99 at least, so we need to change build.rs to tell clang-cl to use the right version of C. You can see here we have:
So, when the compiler is clang-cl, we need to pass the clang-cl equivalent of In the issue, you also mentioned:
Obviously, this is pretty concerning and I'd like to prioritize addressing it. The reason we have all of these warnings enabled in the .git build is precisely to ensure compatibility with the compilers we support. If we're adding support for a new compiler, as we are here with clang-cl, then we need to have CI test this configuration. Which means doing the |
It is introduced by the subject line "Don't override clang-cl with clang for ARM64 Windows builds." |
59f3144
to
9608023
Compare
The format for this seems to be
I hope it shows up in CI, or that you can reproduce it locally when cross-compiling for Windows ARM64 using |
clang-cl
with clang
for ARM64 Windows buildscl.exe
with clang-cl
for ARM64 Windows builds
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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this where clang-cl lives?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's part of the LLVM toolchain. On Linux machines, yes. On Windows: probably?
build.rs
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should say "clang or clang-cl" instead of "clang-cl" here. I think we should add a comment "If the compiler is MSVC, switch to clang-cl so that CFLAGS
, etc., are more likely to be compatible."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had that at first, but considered that the weight is mostly on the file being compiled via an LLVM
toolchain. Whether the compiler/argument "driver" is clang
or clang-cl
doesn't matter, but you're right that I could comment this better in the match
arms.
I've rewritten the patch and description:
Note that this means we have the following targets to add to CI:
|
9608023
to
ac6451a
Compare
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2216 +/- ##
==========================================
+ Coverage 97.02% 97.16% +0.13%
==========================================
Files 160 158 -2
Lines 20391 20330 -61
Branches 458 455 -3
==========================================
- Hits 19785 19754 -31
+ Misses 498 471 -27
+ Partials 108 105 -3 ☔ View full report in Codecov by Sentry. |
ac6451a
to
3fac180
Compare
Going all the way back to this, I'm confused by the CI setup: For the For the "twice" case you mentioned, in |
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.
3fac180
to
d44f9d1
Compare
Fixes #2215
Caution
This change depends on rust-lang/cc-rs#1357.
When cross-compiling to Windows from Linux or similar, it's common to use the
clang-cl
driver from the LLVM toolchain which supports parsingcl.exe
-like arguments.Ring however doesn't seem to compile for ARM64 Windows using
cl.exe
, and contains a// FIXME
-style workaround to useclang
to compile its C files instead.The command-line interface for
clang
isn't always compatible with that ofcl.exe
andclang-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
inCFLAGS
. In such a setup this workaround inring
would pass those arguments toclang
, 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 withclang
, nothing has to be replaced. In the end, all this entails is changing the workaround to not compile withclang
, but withclang-cl
instead.