Additional Linux Distributions

Yes:

/usr/lib/x86_64-linux-gnu/Scrt1.o

It seems swift is invoking ld.gold like this:

execve("/usr/bin/ld.gold", ["/usr/bin/ld.gold", "--sysroot=/Library/Developer/Pla"..., "-pie", "-z", "relro", "--hash-style=gnu", "--eh-frame-hdr", "-m", "elf_x86_64", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "bla", "Scrt1.o",  ...

whereas e.g. clang++ gives absolute paths:

"/usr/bin/ld" -pie -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o bla /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o ...

I tried some -Xlinker -L options but nothing worked.

Invoking ld.gold on the command line gives me the same result: Absolute paths work, filenames with -L don't.

The path to the object file should be fully resolved not be left to the linker to search for. The library search path only applies to libraries, not to object files.

Exactly. The thing is, swift 5.2.1 from the download page works flawlessly whereas your provided deb package doesn't work at all. I'm trying to find out why. The -sdk, -I and -L flags got me one step further, now I am investigating the next error which is:

/usr/bin/ld.gold: error: cannot open Scrt1.o: No such file or directory

An strace of the swiftc from the deb package gives me the following (strace + grep Scrt):

[pid 51503] access("/Library/Developer/Toolchains/unknown-Asserts-development.xctoolchain/usr/lib/clang/10.0.0/Scrt1.o", F_OK) = -1 ENOENT (No such file or directory)
[pid 51503] access("/Library/Developer/Toolchains/unknown-Asserts-development.xctoolchain/usr/lib/clang/10.0.0/lib/linux/Scrt1.o", F_OK) = -1 ENOENT (No such file or directory)
[pid 51503] access("/Library/Developer/Toolchains/unknown-Asserts-development.xctoolchain/usr/bin/../Scrt1.o", F_OK) = -1 ENOENT (No such file or directory)
[pid 51503] access("/Library/Developer/Platforms/Linux.platform/Developer/SDKs/Linux.sdk/usr/lib/Scrt1.o", F_OK) = -1 ENOENT (No such file or directory)
[pid 51504] execve("/usr/bin/ld.gold", ["/usr/bin/ld.gold", "--sysroot=/Library/Developer/Pla"..., "-pie", "-z", "relro", "--hash-style=gnu", "--eh-frame-hdr", "-m", "elf_x86_64", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "bla", "Scrt1.o", "crti.o", "crtbeginS.o", "-L/Library/Developer/Platforms/L"..., "-L/Library/Developer/Platforms/L"..., "-L/Library/Developer/Platforms/L"..., "-L/Library/Developer/Platforms/L"..., "-rpath", "/Library/Developer/Platforms/Lin"..., "-rpath", "/Library/Developer/Platforms/Lin"..., "/Library/Developer/Platforms/Lin"..., "/tmp/bla-fb5b35.o", "-lswiftSwiftOnoneSupport", "-lswiftCore", "-lswiftCore", "-lgcc", "--as-needed", "-lgcc_s", ...], 0x7ffcc77bd070 /* 56 vars */ <unfinished ...>
[pid 51504] openat(AT_FDCWD, "Scrt1.o", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid 51504] write(2, "cannot open Scrt1.o: No such fil"..., 46 <unfinished ...>
[pid 51499] read(3, "cannot open Scrt1.o: No such fil"..., 1024) = 47
write(2, "/usr/bin/ld.gold: error: cannot "..., 664/usr/bin/ld.gold: error: cannot open Scrt1.o: No such file or directory

Which makes me think swiftc is looking for Scrt1.o in the wrong places and then hands the filename without an absolute path to ld.gold (unlike the working clang does).

Right?

Upon closer examination of the logs, I think it is the -sdk parameter which is translated into --sysroot=. I had a patch that changed the behaviour of -sdk slightly which is why I keep mixing up things. You should be able to use -resource-dir instead as:

-resource-dir /Library/Developer/Platforms/Linux.platform/Developer/SDKs/Linux.sdk/usr/lib/swift 

to avoid that issue I believe.

That works. Thanks! :slight_smile:

Running the program gives

error while loading shared libraries: libicuuc64.so: cannot open shared object file: No such file or directory

which is resolved by prepending with LD_LIBRARY_PATH:

LD_LIBRARY_PATH=/Library/Library/icu-64/usr/lib ./bla

Thanks very much!

As mentioned above, since one week spm has a dependency on Yams:

https://github.com/apple/swift-package-manager/commit/705c1fff374dbb5070ff570ba685771faa4a788b

I also checked the last building deb and found out thats swift-build-tool and libllbuild.so are included, swift-build and swift-package however were missing.

I might try fixing the Yams error. You pointed me to two scripts. How can I edit them and test the build?

Regards
g

I've been testing out building packages for enterprise linuxes, currently I'm splitting them up into swift (all the dev tooling), swift-foundation, swift-libdispatch, swift-libicu, and swift-xctest. Packages are all versioned to match the Swift release with a package revision, so something like swift-foundation-5.2.3-1.el7.rpm. The foundation, libdispatch, and libicu package are the runtime, and what should happen is that binaries built with Swift should be packaged up as RPMs with explicit version dependencies for the runtime packages that match up.

That's also coming from the perspective of having spent a lot of years as a systems engineer, and the strong standard that if it goes on a production system it has to be properly packaged with dependencies, YMMV.

@Max_Desiatov I am also looking forward to official support from Swift on Alpine Linux. In my company, we set up services under Vapor 2 then Vapor 3 which we have just migrated under Vapor 4. We started with Swift on Ubuntu 16.04 and currently we are on Swift on Ubuntu 18.04. At Swift level we started with Swift 4 and now with Swift 5.2. The services work well but we can't call them microservices. What bothers us is that each time the services are updated to a new version of Ubuntu or Swift (without change the service or update Vapor), the services have larger docker images and require more memory. This moves us further and further away from a microservice architecture. If Swift could be officially supported on Alpine Linux I am sure that we could significantly reduce the size of the docker images and the memory used.

I've attempted to get this working, but it looks like upstream LLVM and Clang don't support musl and Alpine Linux without certain patches that are currenly applied by Alpine maintainers. I personally think that these patches should be merged upstream and then propagated to the Apple's Swift LLVM branches, which would simplify a lot of porting efforts. After that, there's a question whether we need to create a separate Musl Swift module in addition to the available Glibc module to indicate the difference in behavior of those libraries. In that case, this will require Swift developers to replace (or make conditional) import Glibc with import Musl if those are present in their source code. We also need to make sure that the Swift compiler, runtime, ICU and Foundation work well with musl by setting up CI with relevant test suites enabled. All of that is a substantial amount of effort, and I don't think I'll be able to pull it off myself anytime soon, given the amount of other projects I'm currently working on.

@Tof if you're concerned with size, this distroless option described above is something you should try. If your Docker images aren't small enough with distroless, they are unlikely to become much smaller with Alpine. If you're concerned with the amount of space that Swift binaries and libraries that you link with take, you should also consider static linking and then applying WMO/LTO on top of that. There may still be some unused code in the resulting binary, but there's ongoing work on making LTO more effective with the latest update on that avialable here: "[GSoC] LTO support progress report".

I personally would focus my efforts on getting improved LTO into Swift, since that would benefit all platforms in terms of resulting binary size, not just Linux. Only after all those efforts combined with distroless don't lead to good results, I'd continue the work on making LLVM/Clang/Swift work well with musl/Alpine.

2 Likes

Apologies for resurrecting an old thread but this looked like the most appropriate place for my question.

The swift-ci directory now includes a file for Debian, albeit version 9 (a PR has been submitted that would add a Dockerfile for version 10).

Is there anything additional that needs to be done to offer an official toolchain for Debian?

1 Like

cc @mishal_shah

We are currently seeing this build failure on Debian 10:

/usr/bin/ld: lib/hwasan/CMakeFiles/RTHwasan_dynamic.x86_64.dir/hwasan.cpp.o: relocation R_X86_64_PC32 against undefined symbol `__ehdr_start' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: nonrepresentable section on output
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)

https://ci.swift.org/job/oss-swift-package-debian-10/2/console

1 Like

This specific error was filed as a bug in llvm's compiler-rt library (bug report) but it looks like this is really a bug in v2.31.1-16 of binutils, the version in Debian 10's repository (bug report).

The bug was fixed in v2.32 of binutils (patch) and the patch was backported to the v2.31.1 branch of binutils (commit) but the updated version isn't in Debian 10 repository. Unfortunately, there's no backport for Debian 10. The version of binutils in Debian 11 is v2.35.2-2 (listing) and so presumably this is not a problem in that version but that's not much help for Debian 10.

In terms of how to resolve this, I confess after searching around for an hour or so I'm at a loss. It seems strange to me that you'd just be unable to compile something like the compiler-rt library on the stable release of Debian but maybe that's just the reality.

At the time of writing, Debian 11 is the testing release. Debian 11 doesn't have a release date but its 'freeze' has begun (announcement). Maybe targeting Debian 11 is the best option?

Debian 11 has been released. I think building against it should avoid the problems referred to in the previous post.

1 Like

Fix for binutils on Debian 10

I have been testing a work around for the bug in Debian 10 binutils version. While there is no backport for the Debian 11 version it is possible to install this version on Debian 10 without any issues or conflicts.
This is the method I have been using.

# add the bullseye source to sources list
echo "deb http://deb.debian.org/debian bullseye main" | tee -a /etc/apt/sources.list

# update and install binutils
apt-get update && apt-get --no-install-recommends install -y binutils

# remove bullseye source
sed -i '$ d' /etc/apt/sources.list

Make sure you immediately remove the bullseye source.

I have done several full Swift toolchain builds for 5.4.2-release and main branch developer snapshots without any problems or errors.

Building for Debian 11

Debian 11 doesn't have any of the binutils issues that version 10 had but it does have some python3 issues causing a couple of test failures.
You will need to add the following patches to build 5.4.2 -

The main branch is building without any issues.

Debian 10 and Debian 11 Apt Install Packages

Both Debian 10 and 11 are now available with apt install swiftlang on the new community Swift repository.
More info on the repository here - New Swift Package Repository for Ubuntu/Debian Linux Distributions

6 Likes

Thanks so much for this! I'd missed the announcement when you originally posted about the repository back in July. Just installed Swift 5.4.2 on my Debian system and it's working great :D

3 Likes