0

Context

I am developing a cross-platform project that depends on a highly performance sensitive open-source library. This library supports a number of different compilers, but the most performant version is compiled via clang, due to inline assembly which isn't supported by the MSVC compiler (cl). This has highlighted to me that clang is capable of compiling code on Windows, and emitting highly performant dll libraries, but that there is also a deficit in my understanding of the interoperability of the MSVC toolchain and the clang ecosystem.

Question

To what extent is code compiled with clang, interoperable with the MSVC toolchain?

  • Are binaries emitted by clang ABI compatible with binaries emitted by cl, up to and including the latest language standard?
  • Specifically, can a static library (.a) compiled with clang be consumed by the MSVC toolchain? (ie. symbol definitions are not dllexport/imported).
  • Can clang emit 32-bit binaries?
  • I recognise clang-cl is simply a driver for clang, but are there any practical limitations or other reasons not to favour clang-cl over cl for new projects?
blockchaindev
  • 3,134
  • 3
  • 22
  • 30
  • Maybe this: [https://clang.llvm.org/docs/MSVCCompatibility.html](https://clang.llvm.org/docs/MSVCCompatibility.html) – drescherjm Apr 25 '22 at 16:11
  • I had not noted it in my original question, but I had already taken stock of the contents of that link. It provides valuable technical information and contributes to the answer in a meaningful way, so thank you for contributing that. – blockchaindev Apr 25 '22 at 19:53

2 Answers2

2

Specifically, can a static library (.a) compiled with clang be consumed by the MSVC toolchain? (ie. symbol definitions are not dllexport/imported).

Yes. I have a fairly large Windows (MFC-based) project in which I use the native MSVC compiler to build all components that actually use any MFC (or other WinAPI) code, but use clang-cl for one particular "core" module (built as a static library). All code in that core module is strictly Standard-compliant (C++17, currently, but vide infra). I have been using this MSVC+clang combination for some years and have yet to experience any issues related to ABI incompatibility. (But note that static libraries on Windows have the ".lib" extension, not ".a".)

Are binaries emitted by clang ABI compatible with binaries emitted by cl, up to and including the latest language standard?

Yes – but you'll need VS 2022 for C++20 or later: The clang-cl compiler (V11) that comes with VS 2019 only recognizes up to (and including) C++17; however, clang-cl V13 (as installed by VS 2022) can be set to use C++20 or C++23. (Also note that the library I mentioned above makes heavy use of the "STL" containers, like std::vector.)

Can clang emit 32-bit binaries?

Yes. Switching between 64-bit and 32-bit target architectures within the VS IDE works equally well for both MSVC and clang-cl projects. This also seems to work when switching to ARM64 targets (assuming you have installed the required tools), but I can't verify the final output, as I don't have access to an ARM64-based Windows system.

I recognise clang-cl is simply a driver for clang, but are there any practical limitations or other reasons not to favour clang-cl over cl for new projects?

I have tried building my entire project with the clang-cl tools but – so far – without success. This may be due to the fact that I am using MFC (I get a whole chunk of duplicate and/or missing symbols at link time). However, building simple, console-mode programs for Windows with clang-cl works just fine.

And, one further note: The run-time performance of my final program is considerably greater (i.e. faster) when compiling that core library with clang-cl, compared to the same code compiled with MSVC.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • This is exactly the level of insight and precision I was looking for. I am going to leave the question open for a little while longer to allow any further comments / discussion, but I am very grateful for the benefit of your insight. Further to your answer, are you able to comment on the status of the runtime sanitizers, and OpenMP support? Finally, is there any reason to favour the clang-cl that ships with the MSVC toolkit, as opposed to a (newer?) Windows distribution of clang? – blockchaindev Apr 25 '22 at 20:01
  • @blockchaindev On the OpenMP issue: Dunno, don't use it. On the clang-cl *versus* clang ('native'): **always** go with clang-cl, because that gives you (in theory) the ABI compatibility. I think. On *why* I don't use OpenMP: well, since C++17, we have *native* parallel processing. – Adrian Mole Apr 25 '22 at 20:38
  • Can't speak much for the *run-time* sanitizers but, FWIW, I have a configuration (for my whole project) that uses the clang-cl *compile-time* (static) code analyzer: that catches quite a few issues that the native MSVC analyzer doesn't catch; and I'm grateful to the clang developers, for that. – Adrian Mole Apr 25 '22 at 20:42
0

It was very misinterpretative that you called the compiler clang. Your ment clang-cl.exe, not clang, because clang demangle g++ cpmpatible, clang-cl.exe demangle msvc compatible. If you had put into a compile example, maybe : cmake -G Ninja -DCMAKE_C_COMPILER="clang-cl.exe" -DCMAKE_CXX_COMPILER="clang-cl.exe" -DCMAKE_BUILD_TYPE=Release -DCMAKE_LINKER="llvm-link.exe" . everyone would have understoodd it immediately (so do I now). In Inforamtion theory one example explains more than text only (I'm a mathematician and in math the theory is the meat in informations theory the examples - code snipped - are the meat). The compiler options from clang-cl.exe are exactly the options from msvc, but the option from clang are totally different (g++ options). Hopefully it helps the next reader to understand immediately, that clang-cl.exe is ment, not clang.