Hi.
I am working on a Swift package for implementing platforms for the Roc Programming Language. The language works in an unusual way, where by itself it is a functional language without any IO, and depends on a domain specific runtime/framework that is linked together with the binary.
The Swift package would provide Roc primitives like numbers and strings, and generate safe ffi bindings. This should allow almost seamless interoperability between the two and make Swift very convenient for developing Roc platforms.
It wasn't hard to get a proof of concept working using just swiftc
, but where it gets quite tricky is integrating it with the Swift Package Manager as a dependency, for a few reasons:
- A platform consists of object files for various architectures and some Roc code which implements the Roc api on top of Swift FFI. This means I must use the Swift Embedded mode to emit static object files that don't introduce any additional dynamic dependencies. Especially for targets like
wasm
. - At the same time there would need to be an option to use full Swift, in case a platform would like to integrate Roc with an Apple framework that requires it, like SwiftUI.
- I need to use unsafe flags which if I remember correctly makes the package unusable in the first place.
- I need to have a custom build step that generates bindings based on what is exported from the Roc side of the platform, to hide the unsafe
@_extern
and pointer types — and the product would be an archive of the platform, not a standard Swift binary.
In a way, the package would need to provide a custom Target
that handles this, correct? Is this something that can be done?
I could very easily implement this process with a more flexible build system, like Zig, but a standard Swift package would of course be much more convenient to just import and start implementing a platform.