C++ interoperability is broken (Windows platform)

static_assert(false) is a new feature in C++23. paper: P2593R1
However, Microsoft-STL simply used it without language version checking.
This is causing problems.

EDIT: This has been reported as a defect and retroactively applied to existing C++. (not MS's fault)
It seems to be unavailable until the Clang compiler for Swift is upgraded.

2 Likes

Thanks for the insight!

Is there a possibility that one of the Swift 6 versions may see a clang upgrade (at least for windows)? It's beginning to look more and more necessary for Windows Swift/C++ interop to work at all.

From that well-written linked paper above, :laughing: it's important to have a good laugh, as infuriating as things may seem at times:

Thanks to all the people over the years to whom I’ve had to explain why static_assert(false); doesn’t work and what they have to write instead for not immediately destroying their computers and switching to Rust.

Thanks again. :smile:

How do I do that? Or is it already clear that this won't help?
Tried adding -Xcc -std=c++20 without success.

Support for static_assert(false) is not available in the older clang. We have backported this to the 5.10 release and I put up a change for the current stable branch at [Clang] Implement CWG2518 - static_assert(false) by compnerd ¡ Pull Request #9200 ¡ swiftlang/llvm-project ¡ GitHub. The change should be part of the next rebranch already. Once PR9200 is merged and a stable toolchain following that is released, this issue should be resolved.

4 Likes

I love everything you’ve been doing for Swift on Windows, you’ve been such an asset to the Swift community.

I just wanted to ask, is there a way to use your fixed Swift version in GitHub actions via compnerd/gha-setup-swift@main?

1 Like

Thank you! :blue_heart:

I'm not sure I understand the question. That action should be usable already, is something broken? If you are simply enquiring if the action is maintained, then, yes, that action is maintained (and patches to improve it are welcome!) and we do also use it at The Browser Company, so there is more than just a single person invested in it.

Sorry, I was not clear on my question, what I had meant to ask --

Is there a specific branch and tag we can use in the interim, until your revision to support static_assert(false) is backported into the Swift 5.10 release?

Since the following fails at static_assert(false) on windows-latest until your revision is backported:

steps:
  - uses: compnerd/gha-setup-swift@main
    with:
      branch: swift-5.10-release
      tag: 5.10-RELEASE

Thanks again!

Oh, I see. I don't think that there is a build that has it available. The extension does support use of a GH release as well though, so if/when a build is available from the TBC CI, you would be able to use that I suppose, but otherwise, we would need to wait for an official release from swift.org.

1 Like

@compnerd Sorry to bother you with yet another potential Windows bug.

SwiftPM: If the cxxLanguageStandard is set to .cxx20 (note, this is not an issue when using .cxx17) on Windows, then all includes of same package C++ target dependencies fail to #include in the other C++ targets within that same package, with the following error:

Sources/MyCxxTarget/include/MyCxxTarget/api.h:
fatal error: module 'MyOtherCxxTarget' is needed but has not been provided,
and implicit use of module files is disabled
#include "MyOtherCxxTarget/someApi.h"
         ^

Potentially this is also just due to using too old of a Clang version in Swift 5.10.1, and this issue should also be resolved once the version of Clang in which Swift embeds is upgraded?


Update
Actually, I believe I have found a workaround, which is to manually create a module.modulemap in each of the target's public headers search paths with any module dependencies.

With a directory layout structure like this:

MyCxxTarget 
  include/
    MyCxxTarget/
      MyCxxTarget.h
    module.modulemap (add this)

With the contents of the module.modulemap file like so:

module MyCxxTarget {
  header "MyCxxTarget/MyCxxTarget.h"
  requires MyOtherCxxTarget
  export *
}

Though perhaps as a feature request, these requires fields should be propagated with each of its SwiftPM specified (.target(), and .product()) dependencies as part of the auto-generated module.modulemap files?

This does seem like a configuration issue to me. The module is missing, and it would be on the user to provide the module definitions I believe. The update that you posted seems like a reasonable workaround, though I wonder why the MyOtherCxxTarget is not defined (did you create the module definition?).

The update that you posted seems like a reasonable workaround, though I wonder why the MyOtherCxxTarget is not defined (did you create the module definition?).

Up until now, I've been leaving it up to Swift/SwiftPM to autogenerate all of the module.modulemap files (which it does by default), so I've been able to get away with creating zero module.modulemap files for all/any targets.

However, after running into the error above when building with .cxx20 on Windows, it appears to only work if I explicitly set requires [TargetDependency], regardless if the module definition exists or not.

This is made obvious by the fact that Swift/SwiftPM's automatically generated module.modulemap module definitions did nothing to sort out the error, due to the notable lacking requires [TargetDependency] in its generated module.modulemap files, which now appears to be required for any target dependency headers to successfully include at all (I've just gone through and added ~100 or so module.modulemap files to every single one of my SwiftPM targets specifically ensuring that all target dependencies have a respective requires [TargetDependency] field specified across all of my libraries :sweat_smile:).


Personally, I don't have a preference either way if we must now manually create module.modulemap files for all SwiftPM targets with explicit requires [TargetDependency] entries for each SwiftPM target's respective dependencies, but if this is the case, I believe it would probably be best if SwiftPM stopped attempting to generate each of the module.modulemap files and this gets documented in the Swift/C++ Interop Documentation.

However, with edge cases such as these:

dependencies: [
  .target(name: "PyBind11", condition: .when(platforms: Arch.OS.nix.platform))
]

There is no way to conditionally requires [TargetDependency] in the module.modulemap files (at least that I'm aware of), so I think it may be best if SwiftPM's auto-generation of the module.modulemap files handles this internally.


I'm not yet sure if this is Windows specific or if macOS and Linux experience this issue as well, this is my first time flipping the C++ standard to anything beyond .cxx17.

@compnerd yikes! Well the workaround above compiled all the C/C++ just fine, but when it eventually got to the Swift imports of those modules:

$ swift build -c debug --target UsdView
Building for debugging...
error: emit-module command failed with exit code 1 (use -v to see invocation)
...\x86_64-unknown-windows-msvc\debug\Arch.build\module.modulemap:2:21:

error: umbrella for module 'Arch' already covers this directory
    umbrella header "...\\Sources\\Arch\\include\\Arch\\Arch.h"

...\Sources\PixarUSD\Base\Arch\Align.swift:13:8:
error: could not build C module 'Arch'
import Arch

So, I reckon I'm not quite sure what to do here, since I'm not even able to create any module.modulemap files to override the incorrectly auto-generated ones :thinking:.


For those of you experiencing similar issues on Windows, this is what worked the best for me, use the .cxx17 language standard (anything higher will not work), and define this for every single C++ target:

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

And create a new Swift target specifically to replace the Microsoft STL <version> header with something similar to this target, then replace every instance of #include <version> with #include <MicrosoftSTL/STLVersion.h> in your own C++ libraries (only if this is relevant for your project), and lastly be sure to use MSVC v14.40 or earlier and not 14.41 or above.

It's not pretty, but it'll work for now.

The issue here is the STL update really. That is best controlled by using a professional licensed VS to downgrade to the appropriate version as the clang version upgrade is not so easy. MS STL quickly adopts new features, sometimes far ahead of clang's implementation. Due to the changes required to support Swift, there is a lag in the clang version that is bundled and compatible with the toolchain releases.

1 Like

I wouldn't suppose there could be any chance that Microsoft would be in any way interested offering the Swift toolchain "out of the box", such as offered in the Visual Studio Installer? I'm unsure if that's something one could "apply for" or negotiate with them, but it seems to me that would ensure that MSVC releases could align with Swift releases, providing a pretty solid stability layer.

As an example, if you open the Visual Studio Installer and select Modify there is a list of available Workloads and Individual Components, some of which include:

  • Python
  • Node.js
  • Game Development with Unity
  • OpenJDK

I think it would be wonderful if Swift was something that could be offered here, though, I'm unsure if these are all internally maintained by Microsoft themselves, or if this is offset to those official projects, just a thought! Thanks.

That is entirely under the control of Microsoft, and I do not know how to influence that. If you are aware of how to get Microsoft to add Swift into that list, I think that would be great!

1 Like

It's worth a shot! Here's what I submitted to them:


Hello Microsoft Visual Studio team!

There's been a tremendous amount of work done on bringing proper support for Microsoft Windows with the Swift Programming Language. This is an inquiry to see if there's any possibility that Swift can be offered "out of the box" from within the Visual Studio Installer (from within the Modify > Workloads or Individual Components tab), and what the steps would entail to make that a reality?

The main reasoning, is that Swift developers on the Microsoft Windows platform have been experiencing a good deal of "whiplash" between MSVC updates, and the Swift on Windows community could really benefit from some stability between MSVC releases, due to the changes required to support Swift, there is a lag in the Clang version that is bundled and compatible with the toolchain releases.

If there's anyone on the Microsoft and/or Swift programming language team that I can direct a line of communication to, we'd love to make this possible.

A good reference for an engineer on the Swift team that has been instrumental to supporting Microsoft Windows is @compnerd, who has also expressed interest in making this happen.

Thank you!


The ticket reference is #10745547 (though I'm not sure if that's a publicly available link or not). Hopeful it gains some traction!

1 Like

The link is publicly available. Nice try :face_holding_back_tears:

2 Likes

That ticket had received a (probably auto-generated) response:

Thank you for taking the time to provide your suggestion. We will do some preliminary checks to make sure we can proceed further. You will hear from us in about a week on our next steps.

So looks like ~ a week before we get an update on that. I don't necessarily have high hopes they will do much of anything, but anything is possible.

@compnerd Your high proficiency in Windows, LLVM, Swift and more surely makes you someone whose communications would be received with interest at Microsoft. You also have colleagues at TBC, if I understand correctly, who have worked at Microsoft in recent years and could help you increase this influence. It would be great if Microsoft added Swift to the languages ​​offered by Visual Studio.

Thanks for all the great work!

2 Likes

The goal should always be that the VS community edition is sufficient. Where Microsoft's STL implementation runs ahead of the Clang bundled with Swift in the use of C++ features, we'll try to pull in the corresponding Clang changes for point releases.

Doug

4 Likes