Cross-Compilation on Mac to Ubuntu Fails

Dear Swift Community,

I'm trying to cross-compile a binary on my Mac for Ubuntu 20.04, but I'm facing some issues.

After building the Ubuntu SDK with this command:

/path/to/swift-package-manager/Utilities/build_ubuntu_cross_compilation_toolchain ~/toolchains swift-5.3.3-RELEASE-osx.pkg swift-5.3.3-RELEASE-ubuntu20.04.tar.gz

I tried to compile a simple hello-world package:

$ swift package init --type executable
$ swift build --destination ~/toolchains/cross-toolchain/ubuntu-xenial-destination.json
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open Scrt1.o: No such file or directory
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crti.o: No such file or directory
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtbeginS.o: No such file or directory
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc_s
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lc
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc_s
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtendS.o: No such file or directory
/Users/user/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtn.o: No such file or directory
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
[0/1] Linking test

Passing -sdk to swiftc doesn't work either:

$ swift build --destination ~/toolchains/cross-toolchain/ubuntu-xenial-destination.json -Xswiftc -sdk -Xswiftc ~/toolchains/cross-toolchain/ubuntu-xenial.sdk
[1/1] Planning build

clang-10: error: no such file or directory: '/Users/jefflebrun/toolchains/cross-toolchain/ubuntu-xenial.sdk/usr/lib/swift/linux/x86_64/swiftrt.o'
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
[3/4] Linking test

Nor does passing ~/toolchains/cross-toolchain/swift.xctoolchain to -sdk:

$ swift build --destination ~/toolchains/cross-toolchain/ubuntu-xenial-destination.json -Xswiftc -sdk -Xswiftc ~/toolchains/cross-toolchain/swift.xctoolchain

[1/1] Planning build

/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open Scrt1.o: No such file or directory
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crti.o: No such file or directory
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtbeginS.o: No such file or directory
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc_s
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lc
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: unable to find library -lgcc_s
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtendS.o: No such file or directory
/Users/jefflebrun/toolchains/cross-toolchain/swift.xctoolchain/usr/bin/ld.lld: error: cannot open crtn.o: No such file or directory
clang-10: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
[3/4] Linking test

Jeff

@LebJe the script (without telling you, sorry) builds a cross compilation toolchain for Ubuntu Xenial which is 16.04 but you're trying to use it with Swift for Ubuntu 20.04. I'm not 100% sure this is the issue but that's definitely not quite right.

To be honest, that cross compilation toolchain builder script is more an example what needs to be done to build a cross-compilation toolchain rather than being a real solution. The folks over at the SwiftCrossCompilers project have done more work improving on that script. Unfortunately, the newest configuration they have is Swift 5.1.1 for Ubuntu 18.04.

CC @Helge_Hess1 / @rvsrvs to see if they've built any newer cross-compilation toolchains.

I've gotten 5.3 working on 64 -bit platforms. Haven't caught up with 5.4 yet. I need to spend some time to create a new release. @Helge_Hess1 has his stuff up-to-date. The big issue for me is that 32-bit hasn't worked since 5.1 so if you are targeting the Pi Zero (for example) or 32-bit on Pi 2,3, 4 there's really nothing we can do. @uraimo had posted radars on the problems there, but as far as I know they have not been addressed.

1 Like

@johannesweiss I tried cross-compiling using the latest Ubuntu Zenial toolchain and the build failed with the same errors. Thankfully the solution provided by @Helge_Hess1 works.

@Helge_Hess1 Thank you for SPMDestinations, what's even better is that the 16.04 toolchain works on 20.04 if you statically link the standard library:

$ brew install SPMDestinations/tap/spm-dest-5.3-x86_64-ubuntu16.04
$ swift build --static-swift-stdlib --destination /usr/local/lib/swift/dst/x86_64-unknown-linux/swift-5.3-ubuntu16.04.xtoolchain/destination.json

$ docker run --rm -v $(pwd):/src -w /src -it ubuntu:latest
root@c12a1cb3622e:/src# ./.build/debug/test
Hello, World!
root@c12a1cb3622e:/src#

@rvsrvs Thanks for the insight! Thankfully the solution provided by @Helge_Hess1 worked for me, just like you said.

1 Like