Support for 32-bit CPUs

We've unfortunately decided to skip Windows 10 32-bit support for now. Windows 10 64-bit, Ubuntu, macOS, iOS, Android are a pretty good list to start I suppose. If anyone does choose to take up the Windows 10 32-bit effort, please let us all know!

I would like to revive this issue, as the only person seemingly distributing a 32-bit Swift toolchain now, with my 5.6.1 build for Android armv7. I had to apply a commit from trunk to get the compiler to build and it appears to work well now, other than a runtime regression and a few prior bugs.

Given the upcoming embedded push and focus on performance, we should set up a CI for some 32-bit platform, to make sure it keeps building. I had to apply three patches to include/swift/ to get the Apr. 17 snapshot of the 5.7 branch to build for Android armv7 but the resulting compiler segfaults, haven't looked into why. I also recently reported some trunk regressions when building the stdlib for armv7 on my Android CI.

@futurejones, I don't know how well AArch32 support works on linux AArch64, would you be willing to set up 32-bit builds as part of your upcoming ARM CI? @ColemanCDA, you may be interested in getting a proper 32-bit CI going too, considering your recent 32-bit pulls.

I'm not interested in a 32-bit toolchain for Windows, but definitely care about the 32-bit runtime (for x86 and ARMv7).

1 Like

We definitely want to maintain the ability to host the toolchain in a 32-bit environment, but I'm not surprised that portability bugs have crept in, given how much we use PointerUnion and given that prevalence of 64-bit on developer machines these days. Having a 32-bit host CI would be a great start.

4 Likes

@Buttaface
Yes, definitely looking at adding 32-bit builds to the new Swift Arm Community CI
I am currently experimenting with docker and qemu to emulate armv7l on aarch64. If anyone has experience in this or other VM emulation options I would love to hear from you.

1 Like

I haven't used docker or qemu for this, but on linux x86_64, I've seen distros add a 32-bit compat mode, where you can install a bunch of i686 packages and build and run software for 32-bit linux i686 without a problem.

Given that most AArch64 CPUs can similarly run AArch32 software without a problem, I was hoping there would be a similar armv7 compat mode in the packaging system of whatever linux distro you are running on your CI. That would be the easiest way to set this up on 64-bit ARM, and I've been manually doing something similar to test my Android armv7 Swift toolchain on my Android AArch64 phone.

If you'd like to discuss further, feel free to PM or email me instead and maybe we can get a 32-bit CI easily set up on your 64-bit server.

I am making good progress with docker emulation of arm32v7 on the 64-bit server.
It turns out there are already official 32 bit docker images for both Debian and Ubuntu.
Ubuntu - Docker Hub
Debian - Docker Hub
These can be run using the --platform linux/arm/v7 option to give 32-bit armv7 build environment.

~$ docker run --platform linux/arm/v7 -it arm32v7/ubuntu
root@07e0cbfdc06d:/# uname -a
Linux 07e0cbfdc06d 5.4.0-107-generic #121-Ubuntu SMP Thu Mar 24 16:07:22 UTC 2022 armv7l armv7l armv7l GNU/Linux

I am running some test armv7 builds of swift on Debian and Ubuntu at the moment. Hopefully will have the 32-bit CI set up by the end of the week.

3 Likes

I am making good progress with docker emulation of arm32v7 on the 64-bit server.

Great, but does Docker run armv7 natively on AArch64 or run it through QEMU emulation first, as it would on x86_64? The latter is going to be much slower, which is why I suggested the 32-bit packaging compat mode instead, if it exists for armv7. I have almost no experience with Docker, so just asking how it works.

Docker runs armv7 through QEMU emulation so there is a big performance drop compared to native aarch64.

The build environment needs to docker contained so it can coexist with the other Jenkins build jobs running on the server. There will be multiple build jobs for many different Debian and Ubuntu versions running.

Swift toolchain builds are usually taking around 50mins in native aarch64. The test armv7 builds I have run are taking around 2 hours. (builds are failing but near completion)
So even though this is a lot longer I still think this is a very good and usable build time.

Docker runs armv7 through QEMU emulation so there is a big performance drop compared to native aarch64.

I just looked it up and Debian/Ubuntu both claim to support armv7 in a Multiarch mode, with some people saying it worked for them. You could always get that set up in an AArch64 Docker, if you need the isolation from other build jobs, but get much faster builds and test runs by running the armv7 binaries natively by using this Multiarch mode.

As for the failing builds, check out the patches I linked above. I'm about to try out an Android armv7 build of the Apr. 20 trunk snapshot source on my Android AArch64 phone, will let you know what I find. Edit: The trunk snapshot crashes too when built for armv7.

I have managed to improve 32-bit build performance greatly by using combination of docker platform (linux/arm/v7) and a custom arch32v7 docker image with a patched uname. This gives us near native performance and what was taking 2 hours is now only taking 15 mins.

The server is up and running at https://ci.swiftlang.xyz/
Debian Bullseye Armv7 build job - swift-5.6.1-debian-bullseye-armv7 [Jenkins]
The Docker images are available here - Docker Hub

I have also setup a Github repository ci-swiftlang for the build jobs and will have more details on how to contribute patches and fixes soon, once I get PR testing setup.

4 Likes

@Buttaface I have finished all the setup for the server and we should be ready to go.
Just posted details about the project here - Swift Arm Community CI Server

I have setup a project for Swift on Armv7 and it is ready for PR's and patch testing.

1 Like

Thanks for setting that up and letting us know. I'll take a look at the current stdlib build failure and I've let others know who use Swift on 32-bit ARM, so hopefully we can get that working well.

I haven't run into this issue with my Android armv7 builds, maybe because I cross-compile the toolchain from linux x86_64 while you are natively compiling it on armv7.

Since this was thread was originally about targeting 32-bit systems, and it’s now about hosting the toolchain on 32-bit systems, I think we should probably start a new thread over in Compiler Development. I could move all the recent posts over if people are okay with that.

3 Likes

I agree, I think too much importance is being put into hosting the Swift compiler on 32 bit platforms (like Armv7) instead of having distributable builds for the runtime and cross compiling. I have projects to build Swift 5.6.1 and its runtimes libraries for Debian 11 and Buildroot. Currently working on Yocto as well. I've been testing and maintaining this port since last year, staring with only Buildroot.

1 Like

I don't want to say that hosting on 32-bit systems is unimportant, just that hosting and targeting are pretty different projects with different needs, and this thread was originally focused on just one of them.

1 Like

I think it's great to have that, but realistically it should be a higher priority to get Swift supported on as many platforms as possible targeting cross compilation first. I think it's counterproductive to focus first on hosting the compiler because it will be a lot of work, and once all that is merged is done, you still need to patch the runtime to get a usable product. It would be extremely beneficial for the adoption of Swift to verify 32 bit support is solid (ideally Armv7 since that is a huge commercial and hobby platform) before each release with a platform champion as is the case with Windows currently. The company where I work at relies on Swift for Linux Armv7 for multiple IoT products and it's pretty much broken every release in one way or another and we are always catching up. Another benefit to focusing on the runtime is that we can use existing x86 infrastructure for cross compilation and try to get that officially supported, compared to compiler ports like Linux Armv7 and PPC 64 that have been pretty much abandoned and need to be compiled and testing on dedicated hardware.

I've started another thread specifically for Swift on Linux Armv7

fwiw, x-compile tooling was a major topic in the first embedded systems call two weeks ago. I mentioned the great work you and @futurejones do :)

1 Like

it should be a higher priority to get Swift supported on as many platforms as possible targeting cross compilation first.

Agreed, cross-compilation is easier.

I think it's counterproductive to focus first on hosting the compiler because it will be a lot of work

Not really, the Swift compiler is mostly written in C++, so if you're happy with C++ compilation for your platform, building the compiler should just work. Of course, building the compiler generally for 32-bit platforms has regressed a couple times, so issues do come up with C++ too, but I currently distribute a working Swift 5.6.1 toolchain that runs natively on Android armv7 devices, AFAIK the only up-to-date 32-bit Swift toolchain.

The current issue with linux armv7 is actually building the Swift stdlib with the native bootstrap compiler causing a compiler crash, not any C++ errors when building the Swift compiler itself.

It would be extremely beneficial for the adoption of Swift to verify 32 bit support is solid (ideally Armv7 since that is a huge commercial and hobby platform) before each release with a platform champion as is the case with Windows currently. The company where I work at relies on Swift for Linux Armv7 for multiple IoT products

You may be the ideal champion then. :wink:

While everyone agrees that porting the Swift runtime should come before porting the compiler, @oof actually started this thread asking about the latter and it is more general and a superset of just getting the runtime working. For example, once you have the Swift compiler and other testing tools working natively, you can run the entire compiler validation suite, including the 1k executable tests, and really exercise platform support.

I just ran the compiler validation suite for the first time on the 32-bit Android armv7 compiler (not including the tests that require tools like swift-ide-test) on my Android AArch64 phone, and found less than 200 tests with different results when running the Android Aarch64 compiler similarly, out of around 13k tests in the suite. That is not easy to do when just cross-compiling the runtime, though the Android armv7 CI does run around 12k of those tests on linux x86_64, ie excluding the 1k tests that require running a cross-compiled executable natively.

4 Likes