- General evaluation: Overall this seems like a good thing for SwiftPM to be able to do.
- Effort: Glanced through most of it, but focused on the
Modeling a mixed language target and its build process
and Building a mixed language target
sections.
I had a few questions that came to mind:
- CMake mixed targets:
CMake can handle add_library(foo foo.c foo.swift foo.cpp)
to generate mixed targets today. One of the challenges was on the linking side. To match the model that CMake was already using, we decided to generate the object files for the C and C++ sources first, and then pass those to the swiftc
invocation so that swiftc
would handle scheduling building the Swift files since the , linking the C/C++ objects with the Swift objects as appropriate, and providing the linker with the additional swift-specific search paths and linking swiftrt.o
. I haven't set up the header generation yet, so folks have to use a custom command at the moment unfortunately.
As you noted with respect to bridging headers, this has the drawback that you have to run the Swift compiler twice, once to generate a header, and then again to build the Swift files. My question is, since you're running the Swift compiler first, what does the link phase look like?
- C++ interop
Additionally, when present, each non-Objective-C/C header (e.g. a C++ header) is excluded from the module. This avoids build errors that arise when exposing, for example, a C++ header to Swift
From the proposal, C++ headers are left out of the module. What is the plan for adding C++ interop support to this?
- Specifying flags to clang build job vs Swift build job vs Link step
I think I got a little confused by this portion:
Build flags for the Swift part of the target
The following flags are used when compiling the Swift part of the target:
-import-underlying-module
This flag triggers a partial build of the underlying C language sources when building the Swift module. This critical flag enables the Swift sources to use C language types defined in the Clang part of the target.
-I /path/to/overlay_directory
The above -import-underlying-module
flag will look for a module map in the given header search path. The overlay directory chosen when creating the above VFS overlay files is used here.
-ivfsoverlay /path/to/Intermediates/all-product-headers.yaml
This enables the overlay to take effect during the compilation. Specifically, it will be used during the partial build of the C language sources that is triggered by the -import-underlying-module
flag.
-ivfsoverlay /path/to/Intermediates/unextended-module-overlay.yaml
This enables the overlay to take effect during the compilation. Specifically, it will be used when compiling the Swift sources.
-I $(target’s path)
Adding the target's path allows for importing headers using paths relative to the root of the target. Because passing -import-underlying-module
triggers a partial build of the C language sources, this is needed for resolving possible header imports.
Build flags for the Clang part of the target
The following flags are used when compiling the Clang part of the target:
-I $(target’s path)
Adding the target's path allows for importing headers using paths relative to the root of the target.
-ivfsoverlay /path/to/Intermediates/all-product-headers.yaml
This enables the overlay to take effect during the compilation.
-I /path/to/Intermediates/
The above overlay virtually adds the generated Swift header to the overlay directory. Adding it as a search path enables it to then be imported with #import “$(TargetName)-Swift.h”
.
Does setting swiftSettings
, cSettings
, cxxSettings
, and linkerSettings
separately still pass the flags to the appropriate sub-target?
e.g.
let settings = [.unsafeFlags(["-Xfrontend", "-super-cool-swift-only-flag"], .when(configuration: .debug))]
...
let package = Package(
...
.target(
name: "MyMixedTarget",
dependencies: [],
swiftSettings: settings
Thanks