You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Swift-bridge basically generates four files presently:
A "stdlib" C header (SwiftBridgeCore.h)
A crate-specific C header for the generated rust code (my-cool-crate.h)
A "stdlib" Swift file (SwiftBridgeCore.swift)
A carte-specific Swift file (my-cool-crate.swift).
With the following implicit dependencies between the files:
my-cool-crate.h uses names from SwiftBridgeCore.h
SwiftBridgeCore.swift uses names from SwiftBridgeCore.h
my-cool-crate.swift uses names from SwiftBridgeCore.swift, SwiftBridgeCore.h, and my-cool-crate.h.
In contrast to xcframeworks, which can mix C headers and Swift code, Swift Package Manager (SPM) requires you to separate them into different targets, with explicit imports. That means that the static lib + C headers generated by swift-bridge have to be a different target from the Swift code, and imports (using the target names from Package.swift) need to be added to the files to make it all work.
(Just to underline this last point: I need to name the Package.swift target wrapping the right code, and if I name it FooBar, then import FooBar needs to be added to the beginning of the generated code, which is a leaky abstraction. For an example of this working, see #307)
Additionally, SPM is pretty picky about which files go where. Source files (such as the generated C headers) have to be "below" Package.swift in the directory hierarchy. This means that the rust build.rs has to be told where to spit out the generated files, or they have to be copied into place as part of the swift build.
Finally, SPM needs extra instructions to the linker to be added to Package.swift telling it where to find the static lib file (libfoo_crate.a). This can escape the package root, but it's another path that needs to be correct.
All of these issues mean that there's lots to get wrong.
Suggestion: produce a complete, working SPM package with cargo build
How great would it be if we just dumped a full SPM package source tree into target or wherever the user specifies with cargo's upcoming --artifact-dirbuild flag?
Swift packages are very versatile - unlike XCFrameworks, they can be used in other SPM packages on all platforms (including by path), but they can also be added to an Xcode project without any hassle.
The idea would be to generate a Package.swift with a total of four targets for a crate my-cool-crate:
RustSwiftBridge, a binary target with the "stdlib" C header and rust
RustMyCoolCrate, a binary target with the generated C headers and generated rust
SwiftBridge, a library with the swift "stdlib" code, depending on RustSwiftBridge
MyCoolCrate, a library with the generated swift code, dependending on the three other targets
Because we control the generation of Package.swift, we can get all the fiddly paths correct in the generation phase, as well as add the necessary imports to each file.
A user could import this Package.swift from another Swift package:
dependencies: [
.package(url: "../crates/my-cool-crate/target/debug/MyCoolCrate")
// ... other dependencies
]
Or they could add it directly to Xcode, also by path.
The text was updated successfully, but these errors were encountered:
It seems like there are bits and pieces that could be adapted for this already in the repo (some of which I didn't see before). For example, swift_bridge_build::create_package wraps an xcframework in an SPM package.
Possible duplicate of #280.
Swift-bridge basically generates four files presently:
SwiftBridgeCore.h
)my-cool-crate.h
)SwiftBridgeCore.swift
)my-cool-crate.swift
).With the following implicit dependencies between the files:
my-cool-crate.h
uses names fromSwiftBridgeCore.h
SwiftBridgeCore.swift
uses names fromSwiftBridgeCore.h
my-cool-crate.swift
uses names fromSwiftBridgeCore.swift
,SwiftBridgeCore.h
, andmy-cool-crate.h
.In contrast to xcframeworks, which can mix C headers and Swift code, Swift Package Manager (SPM) requires you to separate them into different targets, with explicit imports. That means that the static lib + C headers generated by swift-bridge have to be a different target from the Swift code, and imports (using the target names from
Package.swift
) need to be added to the files to make it all work.(Just to underline this last point: I need to name the
Package.swift
target wrapping the right code, and if I name itFooBar
, thenimport FooBar
needs to be added to the beginning of the generated code, which is a leaky abstraction. For an example of this working, see #307)Additionally, SPM is pretty picky about which files go where. Source files (such as the generated C headers) have to be "below"
Package.swift
in the directory hierarchy. This means that the rustbuild.rs
has to be told where to spit out the generated files, or they have to be copied into place as part of the swift build.Finally, SPM needs extra instructions to the linker to be added to
Package.swift
telling it where to find the static lib file (libfoo_crate.a
). This can escape the package root, but it's another path that needs to be correct.All of these issues mean that there's lots to get wrong.
Suggestion: produce a complete, working SPM package with
cargo build
How great would it be if we just dumped a full SPM package source tree into
target
or wherever the user specifies with cargo's upcoming--artifact-dir
build flag?Swift packages are very versatile - unlike XCFrameworks, they can be used in other SPM packages on all platforms (including by path), but they can also be added to an Xcode project without any hassle.
The idea would be to generate a
Package.swift
with a total of four targets for a cratemy-cool-crate
:RustSwiftBridge
, a binary target with the "stdlib" C header and rustRustMyCoolCrate
, a binary target with the generated C headers and generated rustSwiftBridge
, a library with the swift "stdlib" code, depending onRustSwiftBridge
MyCoolCrate
, a library with the generated swift code, dependending on the three other targetsBecause we control the generation of
Package.swift
, we can get all the fiddly paths correct in the generation phase, as well as add the necessary imports to each file.A user could import this
Package.swift
from another Swift package:Or they could add it directly to Xcode, also by path.
The text was updated successfully, but these errors were encountered: