在同一项目中混合使用 cl、clang-cl 和 clang

Mixing cl, clang-cl and clang in the same project

上下文

我正在开发一个依赖于对性能高度敏感的开源库的跨平台项目。该库支持多种不同的编译器,但性能最高的版本是通过 clang 编译的,因为 MSVC 编译器 (cl) 不支持内联汇编。这向我强调了 clang 能够在 Windows 上编译代码,并发出高性能的 dll 库,但我对 MSVC 工具链和 clang 生态系统的互操作性的理解也存在缺陷。

问题

使用 clang 编译的代码在多大程度上可与 MSVC 工具链互操作?

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

是的。我有一个相当大的 Windows (MFC-based) 项目,我在其中使用本机 MSVC 编译器来构建实际上 使用 任何 MFC(或其他 WinAPI)的所有组件代码,但对一个特定的“核心”模块(构建为静态库)使用 clang-cl。该核心模块中的所有代码都是 strictly Standard-compliant(C++17,目前,但 vide infra)。我已经使用这种 MSVC+clang 组合多年,但尚未遇到与 ABI 不兼容相关的任何问题。 (但请注意 Windows 上的静态库具有“.lib”扩展名,而不是“.a”。)

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

是的——但你需要 VS 2022 来支持 C++20 或更高版本:VS 2019 附带的 clang-cl 编译器 (V11) 最多只能识别(包括)C++17;但是,clang-cl V13(由 VS 2022 安装)可以设置为使用 C++20 或 C++23。 (另请注意,我上面提到的库 大量 使用“STL”容器,例如 std::vector。)

Can clang emit 32-bit binaries?

是的。在 VS IDE 中在 64 位和 32 位目标体系结构之间切换对于 MSVC 和 clang-cl 项目同样有效。这也 似乎 在切换到 ARM64 目标时工作(假设您已经安装了所需的工具),但我无法验证最终输出,因为我无法访问 ARM64 -基于Windows系统。

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?

我已经尝试使用 clang-cl 工具来构建我的 整个 项目,但是 - 到目前为止 - 没有成功。这 可能 是由于我使用的是 MFC(我在 link 时得到一整块重复的 and/or 缺失符号)。但是,使用 clang-cl 为 Windows 构建简单的 console-mode 程序就可以了。

还有一点要注意:在使用 clang-cl 编译核心库时,我的最终程序的 run-time 性能 显着提高 (即更快) ,与使用 MSVC 编译的相同代码相比。