C++ interoperability is broken (Windows platform)

The -cxx-interoperability-mode command line option for the swiftc compiler used to work, but then (seemingly after an update to MS Visual Studio 2022) it stopped. How to reproduce:

Create a dynamicLibrary.swift file:

public func foo() -> Int {
    return 42
}

Try to compile it with the following command:
swiftc dynamicLibrary.swift -emit-library -cxx-interoperability-mode=default

Expected result: dynamic library is created.
Actual result: The following console output:

e[1m<module-includes>:1:10: e[0me[0;1;30mnote: e[0me[1min file included from <module-includes>:1:
e[0m#include "ccomplex"
e[0;1;32m         ^
e[0me[1mC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include/ccomplex:8:10: e[0me[0;1;30mnote: e[0me[1min file included from C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include/ccomplex:8:
e[0m#include <yvals_core.h>
e[0;1;32m         ^
e[0me[1mC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include\yvals_core.h:898:1: e[0me[0;1;31merror: e[0me[1mstatic assertion failed: error STL1000: Unexpected compiler version, expected Clang 17.0.0 or newer.
e[0m_EMIT_STL_ERROR(STL1000, "Unexpected compiler version, expected Clang 17.0.0 or newer.");
e[0;1;32m^
e[0me[1mC:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include\yvals_core.h:519:44: e[0me[0;1;30mnote: e[0me[1mexpanded from macro '_EMIT_STL_ERROR'
e[0m#define _EMIT_STL_ERROR(NUMBER, MESSAGE)   static_assert(false, "error " #NUMBER ": " MESSAGE)
e[0;1;32m                                           ^
e[0me[1m<unknown>:0: e[0me[0;1;31merror: e[0me[1mcould not build C module 'std'
e[0merror: fatalError
1 Like

Yes, Microsoft updated the minimum required version of Clang to Clang 17. The clang that is embedded in the Swift compiler for importing C and C++ APIs is aligned with the Clang 16 release. For the time being, you will need to use an older Windows SDK that is compatible with Clang 16 (or older).

Edit: At least according to the WinGet installation documentation, Microsoft.VisualStudio.Component.Windows11SDK.22000 should work.

2 Likes

Nope. Just did a clean install of Microsoft.VisualStudio.Component.Windows11SDK.22000 (no later SDKs installed). Same error message.

I believe this can be avoided by adding the following compiler flags to the command

-Xcc -D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH

Alternatively, you can add them to the cxxSettings of Package.swift, like this

cxxSettings: [
  .define("_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH", .when(platforms: [.windows]))
]
1 Like

It works, thank you. What are the implications of ignoring the version mismatch? Is generated binary technically correct?

Visual C++ STL is packaged along with MSVC tools, and has nothing to do with the Windows SDK. This is a breaking change introduced within VS 17.x release cycle, and the valid workaround should be to manually install an older MSVC toolchain and specify it manually with -visualc-tools-root.

1 Like

It means that the Microsoft STL is the version that has been tested with Clang. (this article).
It is expected to typically work unless you are using the latest features (perhaps C++23 or 26?).

If you encounter problems, try installing a different version of the STL (download), or you can find information about it here.

1 Like

I think we need a table to clarify the version of Clang packed within the Swift toolchain, and match it with STL requirements (if such version bump is still going to happen).

I use C++ interoperability to just emit a C/C++ header file with the -emit-clang-header-path option of the swiftc compiler. No C++ code actually involved, just Swift.

Shouldn't Swift compiler rely on Windows SDK only, and not a closed-source commercial product from Microsoft? Next time Microsoft may break the entire compiler, not just one feature.

It’s not Swift depending on VC++, it is Clang that really depends on it (by default, on Windows).

In theory you can use another C ABI with Swift, but in that way you’re no longer able to build directly against MSVC ABI, eg. with a hypothetical Swift SDK for Cygwin or msys2.

1 Like