Swift 5 binaries are linked against libs in build folder

I regularly build Swift 5 snapshots myself on my Arch Linux based system. I recently found that in certain cases binaries are linked against libs in build folder by referring them with full path. So if I cleanup or delete build folder it will kill my Swift deployment as well.
I expect a fully built package should be self-contained apart from dynamically linked system libraries.

I checked binaries under <swiftenv versions root/swift5>/usr/bin and the followings are still are back referring to libs under build folder.

## usr/bin/plutil
libswiftGlibc.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so (0x00007f5bcf8aa000)
libswiftCore.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so (0x00007f5bcf37c000)
libswiftDispatch.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/libdispatch-linux-x86_64/src/libswiftDispatch.so (0x00007f5bce86a000)
libdispatch.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/libdispatch-linux-x86_64/src/libdispatch.so (0x00007f5bce807000)
libicui18nswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicui18nswift.so.61 (0x00007f5bce172000)
libicuucswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicuucswift.so.61 (0x00007f5bcdf77000)
libicudataswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicudataswift.so.61 (0x00007f5bcc5d0000)

## usr/bin/swift-build
libswiftCore.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so (0x00007f187df19000)
libswiftGlibc.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so (0x00007f187df0d000)
libicuucswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicuucswift.so.61 (0x00007f187d4de000)
libicui18nswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicui18nswift.so.61 (0x00007f187d1c7000)
libicudataswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicudataswift.so.61 (0x00007f187b6ac000)

## usr/bin/swift-package
libswiftCore.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so (0x00007ff2b445b000)
libswiftGlibc.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so (0x00007ff2b444f000)
libicuucswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicuucswift.so.61 (0x00007ff2b3a20000)
libicui18nswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicui18nswift.so.61 (0x00007ff2b3709000)
libicudataswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicudataswift.so.61 (0x00007ff2b1bee000)

## usr/bin/swift-run
libswiftCore.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so (0x00007fb1fc909000)
libswiftGlibc.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so (0x00007fb1fc8fd000)
libicuucswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicuucswift.so.61 (0x00007fb1fbece000)
libicui18nswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicui18nswift.so.61 (0x00007fb1fbbb7000)
libicudataswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicudataswift.so.61 (0x00007fb1fa09c000)

## usr/bin/swift-test
libswiftCore.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so (0x00007fe4749bd000)
libswiftGlibc.so => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftGlibc.so (0x00007fe4749b1000)
libicuucswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicuucswift.so.61 (0x00007fe473f82000)
libicui18nswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicui18nswift.so.61 (0x00007fe473c6b000)
libicudataswift.so.61 => /home/segabor/Workspace/swift-dev/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libicudataswift.so.61 (0x00007fe472150000)

The following command is used for building snapshots:

./swift/utils/build-script \
  --preset=buildbot_linux,no_test \
  installable_package=~/swift.tar.gz \
  install_destdir=~/.swiftenv/versions/${SNAPSHOT}

How can this be fixed?

I did open a bug about this, [SR-9315] Linux shared libraries contain unnecessary RUNPATH entries · Issue #51785 · apple/swift · GitHub but it was closed as a dupe (wrongly in my opinion). The Jira does contain a possible solution, using chrpath to rewrite the RUNPATH which you could use.

However Im surprised that deleting your build directory stops things from running if you are installing after building as the RUNPATH should contain multiple entries including paths relative to $ORIGIN.

1 Like

You're right, deployment does not depend on build folder. It turned out I had a different problem (swift binary missed a symbol in a linked library and I falsely identified it as it was due to changed build folder).

We haven't really come up with a good answer to this because there's no standard install path for Swift on Linux. The Apple platform behavior for this is changing with Swift 5 though (expect a GitHub PR in the coming weeks) so maybe we can consider following that (no rpath by default, but can opt in; SwiftPM always opts in), or at least adding an opt-out option.

The problem is that the some of the libraries shipped in the Linux distributions have hardcoded RUNPATHs pointing back to the jenkins build directory. This has 2 problems

  1. When running post install integration tests, the installed swift will work even if a library hasn't been copied because a version can be found in the build directory of some libs.

  2. If Swift is installed and there happens to be a jenkins home directory with the a library of the right name in the right subdirectory then it will be loaded instead of the Swift installed version, as the build directories are the first entries in the RUNPATH.

Probably best to not use RUNPATHs but that would require setting up a long LD_LIBRARY_PATH in the environment as part of the build, easier to just clean up the RUNPATH as part of the post-build install.

1 Like