Xcode 15 Beta Swift/C++ Interop with C++20

I have a C++ project that produces a lot of libraries that require C++20.

I have tried to set the requirement for that in the module.modulemap like so (for example):

module cxx_library {
  requires cplusplus20
  header "library.h"
  link "CXXLibrary"
}

This seems to be correct per the clang documentation: https://clang.llvm.org/docs/Modules.html#requires-declaration

However I cannot figure out how to get cmd+click on the imported module in my sample swift file to work with this. For one, Xcode seems to refuse to even import my module when it requires C++20.

How do I tell Xcode that all of my C++/ObjectiveC++ requires C++20? The compiler default is C++14, but it's not clear how to properly change that so that I can import a C++20-enabled clang module into some sample swift projects to try out the new interior features.

If I remove the 20 from my requires statement, and just use my code as-is, It always complains in the UI that:

Couldn't Generate Swift Representation

Error (from SourceKit): "Could not load module: cxx_library (could not build Objective-C module 'cxx_library', unknown type name 'char8_t')"

Which is very frustrating. When I compile with CMake, I can just set this:

add_executable(E
  E.swift)
target_compile_options(E PRIVATE
  -cxx-interoperability-mode=default
  SHELL:-Xcc SHELL:-std=c++20)
target_link_libraries(E PRIVATE
  cxx_library)

And swiftc compiles the code with no issue.

I have uploaded a minimized version of my code as a fork of a project by compnerd on GitHub here: https://github.com/ADKaster/swift-cmake-examples/tree/main/Interop

The project builds just fine with

cmake -S Interop -B build -GNinja
cmake --build build

But by creating an Xcode project from it:

cmake -S Interop -B build-xcode -GXcode

and then opening build-xcode/P.xcodeproj in Xcode 15 Beta, and trying to cmd-click on import cxx_library in E.swift does not work.

Have you changed the compiler flags in the project settings/targets? If std=c++20 doesn’t work, try 2b.

Also, check the feature support pages. char8_t requires Xcode 15.

Yeah, I'm using Xcode 15.0 beta 5 (15A5209g). I set the C++ Language Dialect on the Project, on the C++ library target, and on the Swift executable target, and the GUI still complains about the C++-20 feature I'm using. If I make sure they're all C++2b, the error still shows up in the Xcode GUI when trying to parse the auto-generated swift bindings. Asking Xcode to build the project says it succeeds too.

CMake also generates the 'Swift Compiler - Custom Flags' for each debug/release mode, and they all look like so:

'-cxx-interoperability-mode=default' -Xcc '-std=c++20' $(inherited)

(modulo the -O options for size/none/etc).

So I'm confused what flags Xcode 15 Beta is using when showing me the bindings it generates per the WWDC 2023 talk I tagged.

@AndrewKaster Wait are we sure Apple clang supports C++ modules? If I recall, there is only partial support, meaning I wouldn‘t expect it to work so well now. I suspect your solution is not to use modules.

@KTRosenberg I am not using C++20 standard modules. Those are not complete in any version of Clang, and their documentation is here https://clang.llvm.org/docs/StandardCPlusPlusModules.html. The module information I linked is about Clang modules, which is a pre-C++20 feature that Swift/Objective-C use to import modules into Swift projects. As noted on the Clang modules documentation, they are very different https://clang.llvm.org/docs/Modules.html#standard-c-modules

I’m not familiar enough to help with the problem, I suppose. I agree, it’s weird.

Xcode 15 Beta Swift/C++ Interop with C++20
 
 
Q