-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Compiling assembly with gcc-style args broken using clang-cl on Windows #24152
Comments
@michaelsiegrist Can you take a look at this issue? |
@bazel-io fork 7.4.1 |
@bazel-io fork 8.0.0 |
@meteorcloudy sure, I can try to take a look here. @fhanau, can you verify the behavior in your environment without #23406 when the .code
PUBLIC decrement
decrement PROC x:WORD
xchg rcx,rax
dec rax
ret
decrement EndP
END If you're able to compile that code with Here's what I see in my environment when I compile that code with PS C:\Users\micha\source\repos\test> & 'C:\Program Files\LLVM\bin\clang-cl.exe' dec.S
dec.S:1:1: error: unknown directive .code
.code
^
dec.S:2:1: error: invalid instruction mnemonic 'public'
PUBLIC decrement
^~~~~~
dec.S:3:16: error: unexpected token in argument list
decrement PROC x:WORD
^
dec.S:4:3: error: unknown use of instruction mnemonic without a size suffix
xchg rcx,rax
^
dec.S:5:3: error: ambiguous instructions require an explicit suffix (could be 'decb', 'decw', 'decl', or 'decq')
dec rax
^
dec.S:7:1: error: invalid instruction mnemonic 'decrement'
decrement EndP
^~~~~~~~~
dec.S:8:1: error: invalid instruction mnemonic 'end'
END
^~~ Whereas when I use PS C:\Users\micha\source\repos\test> & 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx64\x64\ml64.exe' dec.S
Microsoft (R) Macro Assembler (x64) Version 14.33.31629.0
Copyright (C) Microsoft Corporation. All rights reserved. Assembling: dec.S
Microsoft (R) Incremental Linker Version 14.33.31629.0
Copyright (C) Microsoft Corporation. All rights reserved.
/OUT:dec.exe
dec.obj
LINK : fatal error LNK1561: entry point must be defined If you get the same behavior, then I think the right thing to do is to not pass the C/C++ compiler arguments to the assembler, at least for |
@michaelsiegrist I agree that the code in your example is likely to fail with clang-cl, regardless of what my build environment looks like. This is due to it using MASM-style syntax, which I assume is not supported by clang-cl (just how clang on Linux does not support MASM syntax) The way I see it there's two things going on here that cause problems:
As I explained in the issue description, there is no perfect solution here: Some asm files can be compiled only with MASM and some can only be compiled with clang-cl. This is a more fundamental issue than (2), which can be worked around by modifying copts. But if we have to choose one assembler to be used for the clang-cl toolchain, it is more consistent to use clang-cl.exe, as we use clang-cl for everything else (as mentioned, this will make some ASM files work and some files not work). As a side effect, this also solves (2) – we would want to not have C/C++ flags be passed to the assembler, but this seems difficult to fix and with clang-cl it is not harmful to do so. |
@fhanau just to be sure I'm clear, it sounds like in your environment, you have some assembly files in AT&T format that are meant to be ingested by If that is the case, and if as you say there is no great way to support both AT&T and MASM style assembly as input to the same assembler, I feel personally like it would make the most sense for MASM support to be the primary goal of Windows toolchains, just as AT&T support should be the primary goal of Linux toolchains. At least if we have to make a choice, it seems reasonable to me to prefer the "most native" option. To give a bit more of my own context, we depend on both LLVM and Boost, which both have I think it is still worth a stab at getting the C/C++ options detached from assembly options if we can, though I still need to look more at the toolchain code to see if it's possible to really do that. Also, if you would like to use GCC-style arguments, would it be possible to use the I did also find that there's an llvm-ml tool that could possibly be an alternative to |
Yup, I think having Unix-style AT&T asm files describes our situation well. My concern is that clang-cl driver is fundamentally intended to make the clang interface compatible with Windows – it makes it possible to compile the same code across platforms using a shared set of compiler flags (some exceptions apply, of course) in accordance with the MSVC ABI so that it is possible to use clang to compile code across platforms and still depend on libraries using the MSVC ABI and support Windows-specific APIs. For applications developed primarily for Windows, the MSVC toolchain is a good choice.
Compiling such
Absolutely – I suspect this may require a lot of work since there's nothing like
I'm afraid that there is no such thing as a plain clang bazel toolchain for Windows. The clang-cl toolchain takes that role. Either way, I think we've both described our perspectives in detail here, the bazel maintainers should weigh in at this point. |
The cc toolchain configuration code has actually been moved from Bazel to rules_cc for Bazel@HEAD and Bazel 8, see https://github.com/bazelbuild/rules_cc/blob/main/cc/private/toolchain/windows_cc_configure.bzl#L830-L831. This means we can actually fix the problem in rules_cc without a new bazel release. I want to propose the following:
@michaelsiegrist @fhanau Does this sounds good? |
Maybe the fix would be to remove assemble actions from the |
Thank you, that sounds like a path forward! Modifying |
The right path forward may very well be to add |
Sure, that sounds good to me. We can use I do think it would be worth investigating further what the right thing to do for selecting an assembler. Perhaps the ClangCL toolset used by CMake would be informative here. If I understand correctly, the ClangCL toolset uses Here's what I see when I use CMake to compile Boost on Windows with MSVC and the ClangCL toolset. Set up the CMake project:
Build with verbose output, and note that
That said, I know this is a single data point, and it could be that Boost in particular (or CMake or MSVC) has some special knowledge that chooses All that to say, it does seem like having a separate That will still probably not help @fhanau, though, since instead of getting errors about unsupported options, Some references: |
This essentially reverts bazelbuild/bazel#23337 now that the toolchain configuration has been moved here. clang-cl does support assembly just like other clang variants and unlike MASM supports assembly using native AT&T syntax as with regular clang. MSVC-style assembly requires using MASM, which continues to be available in the MSVC toolchain. This has previously been discussed in bazelbuild/bazel#24152 and reverted for Bazel 7.4.1 in bazelbuild/bazel#24211. Ideally, we'd want to have some mechanism to make assembler selection configurable and support several kinds of asm syntax in the future.
Description of the bug:
As of Bazel 7.3.1, the standard clang-cl Windows toolchain supports compiling assembly code using clang-cl.exe (as it does with C and C++ code). As of 7.4.0, the clang-cl toolchain uses MASM instead of clang-cl itself to compile assembly code. This breaks our build configuration as we use gcc-style compiler flags (e.g.
-Wno-macro-redefined
) which are not supported by MASM.The most straightforward way to fix this would be to revert #23406 so that clang-cl.exe is used again for assembly, contrary to what is stated there it is capable of compiling assembly code. This resolves the inconsistency of using MSVC tools for assembly and clang-cl for everything else in the clang-cl toolchain; having the tools be consistent is crucial for being able to compile the same files with the same compiler flags on both Unix and Windows using clang/clang-cl. Of course, this would break developers who depend on using MASM for some assembly files (as reported in the original issue motivating the change, #23128). Ideally, there would be some way to configure what assembler is being used without having to define a custom toolchain; and a means to not have C/C++ compiler flags apply to compiling assembly (we need
-Wno-macro-redefined
to avoid excessive warnings for C++ code on Windows, but don't actually need it when compiling assembly).Which category does this issue belong to?
C++ Rules
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
We assume that Windows and the clang-cl toolchain are being used. Create an empty
dummy.S
file alongside a basic assembly target:Then compile the target with a gcc-style compiler flag, e.g.
bazel build --copt=-Wno-macro-redefined //:dummy
. This works with Bazel 7.3.1, but fails with Bazel 7.4.0 with the following error.//:x64_windows-clang-cl
refers to a simple platform definition for clang-cl setting the@bazel_tools//tools/cpp:clang-cl
constraint. The output reflects this being executed in a CI environment for our project.The params file
dummy.obj.params
suggests that this failed with the first argument with a leading dash, which leads to the A1013 error.Since the action failed due to MASM not accepting gcc-style arguments like
-Wno-macro-redefined
, the switch to MASM in 7.4.0 is likely responsible here.Which operating system are you running Bazel on?
Windows Server 2022
What is the output of
bazel info release
?release 7.4.0
If
bazel info release
returnsdevelopment version
or(@non-git)
, tell us how you built Bazel.No response
What's the output of
git remote get-url origin; git rev-parse HEAD
?If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.
I did not bisect since I only observed this on Windows CI, but believe that this is being caused by #23406 where the clang-cl toolchain starts using MASM to compile assembly instead of clang-cl which is used for other compile actions.
The PR asserts that "clang-cl is not intended to handle assembly", but we have been compiling assembly code on Windows with Bazel 7.3.1 and thus clang-cl without any issues; using MASM instead breaks compilation.
Have you found anything relevant by searching the web?
No response
Any other information, logs, or outputs that you want to share?
No response
The text was updated successfully, but these errors were encountered: