Which C/C++ compiler is preferred on Windows in mixed projects?

In a mixed C/C++/Swift CMake project on Windows, which C/C++ compiler should I use: clang, clang-cl, or MSVC?

I want to drive this setting through a CMakePresets.json:

"configurePresets": [
    {
      "name": "debug",
      "displayName": "CMake Configure (Debug)",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/debug",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug",
        "CMAKE_C_COMPILER": "clang-cl", 
        "CMAKE_CXX_COMPILER": "clang-cl",

Specifying clang-cl gives me:

>cmake --preset debug
-- The C compiler identification is Clang 19.1.5 with MSVC-like command-line
-- The CXX compiler identification is Clang 19.1.5 with MSVC-like command-line
-- The Swift compiler identification is Apple 6.3

Using clang and clang++ from the Swift toolchain

"configurePresets": [
    {
      "name": "debug",
      "displayName": "CMake Configure (Debug)",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/debug",
      "cacheVariables": {
        "CMAKE_C_COMPILER": "$env{SWIFT_TOOLCHAIN_PATH}/bin/clang.exe",
        "CMAKE_CXX_COMPILER": "$env{SWIFT_TOOLCHAIN_PATH}/bin/clang++.exe",
        "SWIFT_TOOLCHAIN_PATH": "$env{SWIFT_TOOLCHAIN_PATH}",
        "CMAKE_Swift_COMPILER": "$env{SWIFT_COMPILER}",

gives me

>cmake --preset debug
-- The C compiler identification is Clang 19.1.5 with GNU-like command-line
-- The CXX compiler identification is Clang 19.1.5 with GNU-like command-line
-- The Swift compiler identification is Apple 6.3

Edit: I guess this is what I want.

Not specifying a CMAKE_C(XX)_COMPILER results in MSVC:

E:\sandbox\ktraunmueller\compositor\Sources\Win\Compositor-Win>cmake --preset debug
-- The C compiler identification is MSVC 19.42.34435.0
-- The CXX compiler identification is MSVC 19.42.34435.0
-- The Swift compiler identification is Apple 6.3

I think that it depends on what your goals are.

For many projects, you will be forced to use clang or clang-cl to ensure that you are able to handle Swift's calling conventions. However, it comes at the cost of quality of debug information generation (clang is not as good as MSVC). Ultimately, the issue is that using clang is more complicated due to the various flags that need to be piped through, particularly if you are using the Windows SDK. clang-cl simplifies some of that, but introduces a penalty when trying to get code to build across platforms.

1 Like

Since I’m making use of Swift/C++ interop in my project, I guess that implies using either clang++ or clang-cl.

If you're using C++ interop then yes, you'll need to use clang. If you just want to link against a C++ DLL, you can link against one that was built with either clang or MSVC++. You can also link against a library built with MSVC++, use headers from that library, and augment them with API notes as was described in this recent blog post.

1 Like