This post is intended to be some supplemental documentation for getting Swift and its components running on OpenBSD and describe context on the state of the port. This is done here on the forums in order to more dynamically and rapidly augment "more official" in-tree documentation, which requires pull requests and reviews to update.
Getting the compiler and stdlib built
Follow the in-tree documentation (docs/OpenBSD.md).
Take special care to the symlinks section -- don't just blindly copy and paste these, because you need to make sure these apply to the current OpenBSD version.
This is because LLVM doesn't recognize the OpenBSD platform version scheme, and mix up static and dynamic libraries. There is a manual change that can be made to LLVM that alleviates the need for making changes to the base system, which I will link in a future edit, but probably will not be upstreamed because of comments about OpenBSD potentially adopting adding symlinks anyway.
Known issues/deficiencies:
The REPL doesn't work (i.e., calling swift without arguments) and will give a scary backtrace, however the "inbuilt JIT" mode does (swift foo.swift).
AIUI, this needs more comprehensive lldb work on the platform. This is unlikely to happen any time soon.
Necessary cherrypicks:
As of 2022-03-10, the Swift compiler should build at HEAD.
Foundation and Dispatch
Necessary cherrypicks:
As of 2022-02-10, you will need to cherrypick pr #559 in Dispatch and #3004 in Foundation.
The Foundation pr is primarily to get CFRunLoop implemented
Among other things, this pr uses kevent, which the BSDs all implement. So does xnu, for that matter. It would be a fun experiment to cross-check whether the kevent implementation in that pr works on Darwin...
The Dispatch pr implements a few gaps in functionality
Specifically, it uses pipe2 and packed file descriptors for runloop implementation, which has inherent tradeoffs for portability.
This implementation may still require some additional testing but generally works well and the associated runloop Foundation tests pass. The caveat here, however, is that the Foundation and Dispatch testing coverage may not be as thorough.
You will notice that existing in-tree documentation carefully counsels disabling Dispatch in the Swift compiler/stdlib. This is because the Dispatch pr has not landed.
If you go the route of cherrypicking these prs, you can go back and compile with Dispatch enabled.
The road to SwiftPM
llbuild requires some manual changes to the in-tree support library, but they are minimal.
More TK.
swift-crypto works well enough if you make the obvious changes such as changing all the defined(__linux__) to defined(__linux__) || defined(__OpenBSD__). However, I don't know if this is advisable to upstream: OpenBSD has libressl and may be somewhat opinionated about security primitives, but an explicit goal of swift-crypto is to be bit-compatible across platforms and therefore may require specific implementations. More thinking and research may be required here.
yams needs the usual amd64 naming change and substituting of complex macro DBL_DECIMAL_DIG. Not difficult, just have not done this yet.
With these changes SPM seems to build OK.
This is no guarantee that other packages that use SPM will build OK, however!
Just so I understand, how much more needs to be done for OpenBSD to be a first class platform on which one could use Swift? I am a FreeBSD user, and I hope to be able to deploy my Vapor sites there, as well as building my Publish there.
I hope that your OpenBSD work will help in that direction. :-)
"first-class platform" isn't something that is well-defined right now. What level of support are you expecting? I have no idea if Vapor will work, and especially won't work if it depends on Swift packages like swift-nio or what have you -- more portability work needs to be done there.
Regardless, the Swift compiler should build cleanly out of the box. I need to update the docs a little, but essentially, check out cmark, llvm-project, swift, swift-syntax, and run build-script with --bootstrapping=off. Dispatch and corelibs should also build cleanly when picking Dispatch pr #559 as per above.
My definition of a First-class Platform is one on which all the server-side swift code should run - essentially one with support approximately as good as Linux. I think that means it needs to support Swift Package Manager, all the *NIO libraries, Foundation, and any library I personally use. (Just kidding about the last.)
Again, my real interest is in support for FreeBSD, but I prefer OpenBSD to Linux, so that would be a step in the right direction.
It installed fine but seems super slow, compiling ninja from source takes 20X the time it does on the macOS arm64 host, implying it's still running under some QEMU interpreter or other impediment. Is there a way to get close to native speed from OpenBSD arm64 when running under UTM? I think that would get a lot more people trying OpenBSD on macOS and your Swift work too.
UTM invokes qemu on the backend and I don't know whether it's doing so correctly. I've noticed qemu does support macOS's virtualization framework so you could try that directly and see if you get better results.
If I find some reliable performance mechanism for virtualization on arm64 I'll let you know.
I've never had much interest in invoking QEMU directly, was hoping UTM would handle that for me. I previously installed Fedora 43 AArch64 with Virtualization enabled using UTM, and I now see I get around 80% of native speed building ninja in that linux VM, ie you can actually use it.
As you say, maybe it's a config issue, maybe it's some underlying tech that's missing in OpenBSD, would be good to get that working. I'd like to try building Swift for OpenBSD arm64, that would be an ideal environment to do so.