-
Notifications
You must be signed in to change notification settings - Fork 450
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
fix llvm-ar as archiver for msvc targets; fix clang-cl detection; fix assembler output flag detection; add clang/clang-cl windows CI #1015
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.
i'm definitely open to a more robust way to get the archiver "Family" (maybe something similar to how we detect compiler family? idk) if that would be better
I don't know any better way than checking name, or its output of --version
.
Perhaps we can try link something and check its output for signature of linker?
With this and the other PR, I can now cross-compile to windows using clang from window
Is it possible to add testing for this in CI?
src/lib.rs
Outdated
@@ -2398,7 +2398,8 @@ impl Build { | |||
} | |||
|
|||
let target = self.get_target()?; | |||
if target.contains("msvc") { | |||
let (mut ar, cmd, _any_flags) = self.get_ar()?; | |||
if target.contains("msvc") && !cmd.to_str().unwrap().contains("llvm-") { |
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.
if target.contains("msvc") && !cmd.to_str().unwrap().contains("llvm-") { | |
if target.contains("msvc") && !cmd.to_str_lossy().contains("llvm-") { |
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.
Applied, except to_str_lossy of course doesn't exist as the lossy conversion requires a (conditional) allocation
src/lib.rs
Outdated
if target.contains("msvc") { | ||
let (mut cmd, program, any_flags) = self.get_ar()?; | ||
let (mut cmd, program, any_flags) = self.get_ar()?; | ||
if target.contains("msvc") && !program.to_str().unwrap().contains("llvm-") { |
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.
if target.contains("msvc") && !program.to_str().unwrap().contains("llvm-") { | |
if target.contains("msvc") && !program.to_str_lossy().contains("llvm-") { |
this is somewhat a nasty hack here, but it does work. when (cross) compiling for msvc and you use llvm-ar as the archiver, then you need to use gnu-style flags. currently it attemps to run llvm-ar like: ``` running: "/usr/bin/llvm-ar" "-out:/workspaces/ars/build_windows_clang_x86_64_relnoopt/./cargo/build/x86_64-pc-windows-msvc/release/build/link-cplusplus-b04e59fc086748c2/out/liblink-cplusplus.a" "-nologo" "/workspaces/ars/build_windows_clang_x86_64_relnoopt/./cargo/build/x86_64-pc-windows-msvc/release/build/link-cplusplus-b04e59fc086748c2/out/0466faf07398e270-dummy.o" ``` which doesn't work, as llvm-ar takes in GNU-style ar flags. i'm definitely open to a more robust way to get the archiver "Family" (maybe something similar to how we detect compiler family? idk) if that would be better
While working on that CI pass, I found that the clang-cl detection doesn't work at all.... Clang defines _MSC_VER when target is *msvc, and actually has no relation to the frontend variant. That combined with us not passing C[XX]FLAGS to the -E invocation just means that all it detects is if the host system is windows, lol.... |
While I'm working on clang cross compilation for linux->windows, I was going to add the CI pass to windows so I don't have to worry about getting windows SDK/msvc installed in Linux. But since the host is windows it ends up thinking clang is clang-cl! |
I know you're waiting on this to release--I think it's still a good change of course, but that CI is not going to work yet. Want me to rip out CI and open a new PR with hopefully some way to fix clang-cl detection, that can be merged after the release? |
I would prefer the clang-cl to be fixed as well before cutting a new release to avoid regression. |
BTW, can you please update the PR title and description? Thanks!! |
Okay, this seems to work now 😅 It ended up being more changes than I thought! Do you want me to split into mutiple PRs? Im also happy to rebase it into a cleaner incremental history for future bisecting |
Hmm it's hard to be sure that the env vars are actually being set.... |
Ah, I don't think it's possible to emit multiple env vars from GITHUB_ENV? At least I can't figure it out. which is kinda wild |
Ok, not quite ready I guess. Will look tomorrow |
The doc says just put them in multiple lines, i.e. |
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
Updated CI and code, still doesn't work |
Ok, phew, there was some more cases to handle here, but it seems to be working. |
I'm not sure if you want to keep the changes you made, notably the CI formatting changes. I'm happy to simplify that diff if you want. |
That'd be ok for me, thanks for yhe fix! |
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.
Thank you, in LGTM, however since I'm not very familiar with cc test-suite, I'd like another approval from another maintainer @thomcc
Opened llvm/llvm-project#87209 to address clang-cl not taking |
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.
Thanks, the changes look good. That said, it's a big change, and I don't think we have great test coverage here, so it does make me worry a little. We should land it anyway though.
That said, maybe we should squash-land this so that we can revert more easily if it causes problems. WDYT @NobodyXu?
# Some packages were removed, and this is causing the g++multilib | ||
# install to fail. Similar issue: | ||
# https://github.com/scikit-learn/scikit-learn/issues/13928. | ||
sudo add-apt-repository --remove ppa:ubuntu-toolchain-r/test |
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.
Well, if it works...
is_arm: bool, | ||
) { | ||
if msvc && !clang && !gnu && !cuda && !(is_asm && is_arm) { | ||
pub(crate) struct CmdAddOutputFileArgs { |
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.
Thanks for this.
if target.contains("msvc") { | ||
let (mut cmd, program, any_flags) = self.get_ar()?; | ||
let (mut cmd, program, any_flags) = self.get_ar()?; | ||
if target.contains("msvc") && !program.to_string_lossy().contains("llvm-") { |
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.
This will probably need adjusting but for now is fine.
@@ -3939,7 +3959,7 @@ fn which(tool: &Path, path_entries: Option<OsString>) -> Option<PathBuf> { | |||
} | |||
|
|||
// search for |prog| on 'programs' path in '|cc| -print-search-dirs' output | |||
fn search_programs(cc: &mut Command, prog: &str, cargo_output: &CargoOutput) -> Option<PathBuf> { | |||
fn search_programs(cc: &mut Command, prog: &Path, cargo_output: &CargoOutput) -> Option<PathBuf> { |
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.
Ideally the change to use &Path would be in a different pr. But I'm not about to hold this up for that, since it is a good change.
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271 | ||
let accepts_cl_style_flags = | ||
run(Command::new(path).arg("-?").stdout(Stdio::null()), path, &{ | ||
// the errors are not errors! |
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.
🙃
Yeah, cc-rs defaults to squash merge so it should be pretty easy to revert. |
This PR contains several clang on windows improvements:
-?
, instead of checking for_MSC_VER
. This is what cmake does, and_MSC_VER
is always defined for msvc ABI targets, regardless of the frontend variant usedOriginal description:
this is somewhat a nasty hack here, but it does work. when (cross) compiling for msvc and you use llvm-ar as the archiver, then you need to use gnu-style flags.
currently it attemps to run llvm-ar like:
which doesn't work, as llvm-ar takes in GNU-style ar flags.
i'm definitely open to a more robust way to get the archiver "Family" (maybe something similar to how we detect compiler family? idk) if that would be better
I also moved some APIs to to use Path as it avoided a string->path conversion. Let me know if that's not of interest.
With this and the other PR, I can now cross-compile to windows using clang from linux :)
EDIT: also fixes the path to the archiver not being set on when env_tool finds it