I'm trying to get started with Swift/C++ interoperability by generating C++ headers for my Swift code. The official instructions say Xcode can do it, but I'm working cross-platform so I don't want to go that route. Another page shows how to make swiftc generate headers:
It gets farther, but fails because it can't find the other modules in my project:
error: emit-module command failed with exit code 1 (use -v to see invocation)
Sources/Redacted/Database.swift:8:15: error: no such module '_Common'
6 | //
7 |
8 | public import _Common
| `- error: no such module '_Common'
Do I need to pass every single file in my project on the command line?
I'm just a simple guy who types swift build and it builds my code. This is a bit over my head.
I see there are .swiftmodule files being generated down inside .build/arm64-apple-macosx/debug/ModuleCache ... are those the ones you mean?
It sounds like basic C++ interop is requiring me to construct my own enormous build commands like the ones shown in Xcode build logs. There's no support for this in SwiftPM?
Thus far I've been using Xcode with my SwiftPM package without having to have an xcodeproj file. It's generally very nice (I don't miss messing with huge lists of build settings) but using Xcode to create interop headers requires having a project file, which appears to mean I have to set everything up by hand again, creating targets and adding all my source files manually. I wish there were an upgrade process, i.e. generate an xcodeproj from my existing Package.swift file.
ModuleCache isn't what you want; it has implicitly compiled modules from the system frameworks (which will be generated automatically for you in a temporary directory if needed, when running swiftc yourself). I think the Modules directory in the same location has what you need.
Rather than trying to piece together an invocation from scratch, I wonder if you could just wedge the -emit-clang-header-path flag into the unsafe settings of the target you're interested in. You wouldn't be able to do anything else with that header in a SwiftPM sense AFAIK, but if you're just looking to inspect it, that ought to spit it out.
Meanwhile I'm reading this extremely depressing series of blog posts by Davide DeRosa about cross-platform Swift, in which he says:
The first advice I can give if you want to build consistently across platforms is to avoid SwiftPM, except for Swift Testing. It’s just not fit for the role yet. XCFrameworks only work on Apple, and binary artifact bundles are on their way, but haven’t been released yet. If you need something that works today, get familiar with swiftc and clang, and switch to CMake with ninja.
... At this point, you may come to realize how SwiftPM could lead you to a complex source hierarchy. The highly granular dependency model encouraged by the manifest is a neat abstraction, and works very well for modular Swift-only systems. But when you have to account for C/C++ targets, modulemaps, DocC, and external non-Swift libraries, it makes you want to jump off the nearest cliff without even a goodbye letter.
I've been very happy to have left CMake behind, but now it's returning from the grave...