Generating C++ interop Clang headers on Windows

[Update 11 Sep 2024: A solution has been found]

Hi everyone - My objective is to generate a C++ header file such that a dynamic library built with SPM can be used inside a C++ codebase. Thank you everyone that is contributing so much effort to advancing Swift for multiplatform use and C++ interoperability, it is wonderful that Swift is to the point where I am asking this question at all!

On Mac, this process works as follows. We install:

  1. Specify swiftSettings: [.interoperabilityMode(.Cxx)] in our Package.swift target.
  2. Build, with swift build.
  3. Generate the header(s) with swiftc -frontend -typecheck Sources/[PackageName]/Foo.swift -module-name [PackageName] -cxx-interoperability-mode=default -emit-clang-header-path [HeaderName].h [See note 1]

Voila, we have our header file and dynamic library and it feels magical to call Swift code inside C++.

On Windows, I have:

  1. Installed swift.org Windows release/6.0 snapshot August 7 2024, yielding Swift version 6.0-dev. [See note 2]
  2. Built the package, with target swiftSettings: [.interoperabilityMode(.Cxx)] via swift build, yielding a [PackageName].dll.
  3. Attempted to run the same swiftc -frontend -typecheck Sources/[PackageName]/Foo.swift -module-name [PackageName] -cxx-interoperability-mode=default -emit-clang-header-path [HeaderName].h.

Step 3 fails with error: <unknown>:0: error: unable to load standard library for target 'x86_64-unknown-windows-msvc

Does anyone have any ideas about how this might be resolved?

More notes:

  1. The Windows machine is running Windows 11 Version 23H2 (OS Build 22631.4149).
  2. The Windows machine has Visual Studio 2022 installed, with Windows 11 SDK and Windows 10 SDK both installed via "Individual Components".
  3. echo %SDKROOT% returns C:\Users\[USER]\AppData\Local\Programs\Swift\Platforms\[VERSION]\Windows.platform\Developer\SDKs\Windows.sdk\
  4. Specifying -sdk [SDKROOT from (3)] with the swiftc invocation does not solve the issue.
  5. The Windows machine has had previous versions of Swift installed, as far back as 5.4. These were removed before installing 6.0-dev.
  6. echo %SWIFTFLAGS% returns nothing.

Note 1: Mac Step (3) fails with a "<unknown>:0: error: unable to load standard library for target 'arm64-apple-macosx14.0" if you use the default Swift toolchain on macOS 14.6.1 with Xcode 15.4. It succeeds using the swift.org toolchain package installer, and in this case, I was using development snapshot 2024-09-06-a yielding Swift version Apple Swift version 6.1-dev to successfully build a C++ compatible .dylib and header.

Note 2: Windows steps also repeated swift.org package installer "Latest Release (Swift 5.10.1" with yielding Swift version 5.10.1. An attempt was made to install Windows main snapshot August 28, 2024, however the installer failed.

Update: I feel a bit goofy. After posting, I continued attempting to resolve the problem, and I appear to have found a resolution only a few minutes late.

Removing typechecking from the swiftc call yields a header file. That is, I now call swiftc:

swiftc Sources/[PackageName]/Foo.swift -module-name [PackageName] -cxx-interoperability-mode=default -emit-clang-header-path [HeaderName].h

... And the header is generated. I hope this post is useful to someone, regardless.

1 Like