I want to write a SwiftUI app for personal use, which can be run on my iPhone and iPad. Writing Swift code on macOS is simple, but my main desktop machine with dual monitors is on Linux. I want to edit code on it too.
Therefore, I would like to install the Swift Toolchains on Linux. I am running Artix Linux, which is not officially supported by Apple. It currently only supports Ubuntu and CentOS.
The power of Arch-based Linux is the AUR. Normally, a package like this can be installed via AUR.
There are mainly three versions of Swift in the AUR, the swift-bin, the swift-language and the swift-language-git.
From the pinned comment in the swift-language package.
soloturn commented on 2020-09-06 22:25 (UTC) (edited on 2021-06-12 17:51 (UTC) by soloturn) options to install a binary swift are currently two flavors of swift-5.4.1, and one latest from git: swift-bin, which repackages tachoknights official released centos8 build: https://aur.archlinux.org/packages/swift-bin/. the install is quick, no hours of waiting until everything is compiled. this build. native arch. fanjiang built binaries on GCE: https://github.com/ProfFan/swift-aur/releases latest from git: use swift-language-git, builds native on arch. as it takes long to build, there is a binary built with github actions. the version number is taken out of the official tag on apple/swift main branch: e.g. swift-language-git-swift.DEVELOPMENT.SNAPSHOT.2020.09.28.a.r208.g6651f6e55d4-1-x86_64.pkg.tar.zst. so this one is the development tag from sep 28 + 208 commits, the commit hash is g6651f: aur - https://aur.archlinux.org/packages/swift-language-git. gh-actions: https://github.com/soloturn/swift-aur/releases/tag/latest
First, I would like to compile myself. Since I use paru as my AUR helper, installing from the AUR is very simple.
paru -S swift-language
But it failed to compile. It gave an error of "ninja subcommand
failed". I used
dmesg to investigate what happened. It turned out to
be no permission to read the kernel buffer. After a few attempts to
solve this, I gave up. Also, it takes a long time to compile.
Then, I manually clone the swift repo from github and build it myself. It did not work either.
As a result, I looked into the swift-bin package, which is a pre-built binary.
I have to patch it myself.
First, clone the git repo.
git clone https://aur.archlinux.org/swift-bin.git
Or you may use paru, but do not proceed to install.
paru -S swift-bin
PKGBUILD. Edit the package version.
The official swift website used to target centos8, but it later changed into centos7. If you are have an old script, make sure every centos entry is centos7 instead of centos8. In Emacs, you may just use M-x query-replace.
Generate a new checksum. //wiki.archlinux.org/title/Makepkg#Signature_checking
Manually update the checksum in PKGBUILD.
==> Retrieving sources... -> Found swift-5.7-RELEASE-centos7.tar.gz ==> Generating checksums for source files... sha256sums=('96d9b6686aa79cb88061187d90464fe85f9f421bb6cff10b1053234c0b2ad98e')
After installing the package, we should be able to find the Swift
Swift relies on an old version of python3.6. We can install it via AUR.
But Swift will not run and give this error.
swift: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory
[stderr] /usr/bin/sourcekit-lsp: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory
These are because that the latest version of ncurses is at version 6. But Swift expects to have a version 5. We have to install a compatible library, which is in the AUR also, ncurses5-compat-libs.
For all the dependencies.
paru -S ncurses5-compat-libs python36
Now we can use Swift on Linux.
Although we are able to write Swift code and run on Linux. We cannot develop SwiftUI directly on Linux other than editing code. Since SwiftUI relies on the Cocoa library on macOS. Moreover, the header files for iOS and iPadOS is not available outside of macOS, whenever we call some iOS specific function, sourcekit-lsp will give an error.
This may be solved by copying the header files from macOS to Linux manually, I may try it later.