Hello again Swift developers,
Welcome back to another round of warts in the Linux support. I've been working on the driver a bit recently, trying to wrestle with some of the layout assumptions that are baked into the driver. The motivation behind this is to help separate the standard library development and the compiler development as well as cross-compilation.
Starting off with the original state of the world, the standard library and the compiler builds were intertwined completely, the swift (SDK) content being placed into the compiler resource directory and this path to relative to the compiler.
With additional architectures being added, the swift content gained an additional level of indirection - the architecture. This made the resource directory change from 'usr/lib/swift//...to a split of the content across
usr/lib/swift// which contained the swift content (
.swiftmodule,
.swiftdoc) and
usr/lib/swift/` which contained the architecture dependent runtime components. This means that a single build can only target a single architecture of the platform. It also pretty much meant that everything was built as a single unit (or you would have to copy and paste content across machines to build on a different build machine).
The reasonable approach to deal with this was to split up the runtime compilation and the compiler builds. This is the work that I finished a little while ago, permitting building just the toolchain or building just the standard library. With this work complete, it was possible to build just the standard library for a different target than the compiler allowing building the compiler for Windows, macOS, or Linux with the standard library for android (or Windows, Linux).
With that in place, the separation of the content of the SDK (standard library, libdispatch/swiftDispatch, Foundation) was now possible. However, the behaviour of -sdk
was odd in that it was treated as a sysroot and did not actually cascade the search for the runtime support (swiftrt.o
/swiftrt.obj
), glibc.modulemap
, or the swift runtime bits for linking. That brings me to the set of changes that I am currently working on - allowing cascading of the searches. This unfortunately also brings to light that we need a separation of Swift SDK search and the system content (i.e. sysroot). The reason for this is that repackaging another vendor's SDK may be more involved than what I would like to get into (e.g. can I bundle in the content of MacOSX.sdk
?) Additionally, swift's build system currently builds the content as a sysroot more than a SDK (the platform is referenced again in the SDK where it should not since the SDK is platform dependent by definition).
I assume that the problem of the generated layout is possible to solve (just some work which needs to be done on the build system). But, that brings me to the point of future work that I am not entirely certain on how to best address. This work would solve the issue of the architecture dependent bits in the architecture independent location, as that is the last piece necessary to complete the SDK layout support. However, there is another wrinkle here - the current layout really does not provide sufficient granularity to be able to solve the problem. For concreteness, let us consider a specific case: "Linux ARM". Let us restrict ourselves to the 32-bit variant of ARMv7 (is anyone actually working with ARMv6 hardware? Anything less than ARMv5TE in LLVM is pretty suspect I imagine). Well, the problem is that ARMv7 is immensely fragmented, largely incompatible, and all the same architecture: armv7. That is, 'usr/lib/linux/armv7` does not work to home the platform. The platform may be any of the following:
-
-target armv7-unknown-linux-gnueabi -mfloat-abi=softfp
(okay, I doubt that anyone actually uses this anymore, but I'm not particularly right in the head I've been told) -
-target armv7-unknown-linux-gnu -mfloat-abi=soft
(this is deprecated and shouldn't be used for modern targets) -
-target armv7-unknown-linux-gnu -mfloat-abi=hard
(lets just engorge ourselves in hatred for ourselves) -
-target armv7-unknown-linux-gnueabi -mfloat-abi=soft
(this is extremely common still) -
-target armv7-unknown-linux-gnueabi -mfloat-abi=hard
or-target armv7-unknown-linux-gnueabihf
(many distributions are starting to support this, yes, they are subtly different, lets just ignore that and be friends?) -
-target armv7-unknown-linux-eabi -mfloat-abi=soft
(embedded environment, non-glibc or no libc) -
-target armv7-unknown-linux-eabi -mfloat-abi=hard
or-target armv7-unknown-linux-eabihf
(embedded environment, non-glibc or no libc, hard float) -
-target armv7-unknown-linux-musleabi
(musl libc instead of glibc) -
-target armv7-unknown-linux-musleabihf
(musl libc instead of glibc, hard float)
They are all ARMv7 variants, all of which should be part of the same SDK, but we have no possible way to organise these currently. There are at least four options that I can come up with:
- make the SDK more of a
swiftroot
- organised like a sysroot with a layout likeusr/<target>/lib
- make the SDK more like a SDK and expand the
<arch>
directory to<arch>-<environ>
- make the SDK more like a SDK and add an
<environ>
component under the<arch>
- make the SDK target/environment dependent and require different SDKs for each of the architecture/environment combination (at the cost of the combinatorial explosion of SDKs)
My personal preference would be the third of changing the layout to support this with multiple architecture/environment variables for each platform in a single SDK. This would make cross-compilation to different architectures extremely easy and convenient with only needing a single SDK per platform. At that point, I believe that we will have enough flexibility to address the multitude of Linux environments as well as android environments and we would be easily able to cross-compile swift code for a variety of targets.
This still leaves the fact that we need two separate roots - one for the Swift SDK and one for the system SDK which is needed for the C library, math library, threading library, etc. I think that we should cascade the search for the system libraries through the SDK enabling someone to create a SDK for a distribution which contains the system libraries, but does not require it so that it is possible to be able to target systems which may not be fully under our control.
Saleem