Skip to content

[cmake] Add runpath for libBlocksRuntime.so #2246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

drodriguez
Copy link
Contributor

@drodriguez drodriguez commented May 9, 2019

Dispatch build leaves artifacts in both the root directory and the src
directory, but only the src directory was being added to the runpath, so
the libBlocksRuntime.so library might not have been found.

Additionally, remove the rpath flags from libdispatch_ldflags, which are
used to compile Foundation, but will point to the build directory
results. Add those flags instead to a list used for the test binaries.

In the end Foundation ends up with a path of $ORIGIN; TestFoundation
has paths to Foundation, to Dispatch and BlocksRuntime, and to XCTest;
while xdgTestHelper points to Foundation, and Dispatch and
BlocksRuntime.

Extract a small function for adding rpaths to a list, to make the rpath
easier to read.

Also, remove Android from the rpath flags, since Android will not work
with the build tree rpaths, and will need its own solution. For the time
being, do not set any rpath.

@drodriguez drodriguez requested a review from spevans May 9, 2019 22:00
@spevans
Copy link
Contributor

spevans commented May 9, 2019

Which binary is this setting the RPATH for ?

I don't think its needed because its covered by the existing LD_LIBRARY_PATH?

@drodriguez
Copy link
Contributor Author

In my machine xdgTestHelper ended up with:

$ readelf -d xdgTestHelper
…
0x000000000000001d RUNPATH              /data/users/danielrodriguez/scratch/swift/build/my_linux/swift-linux-x86_64/lib/swift/linux:/data/users/danielrodriguez/scratch/swift/build/my_linux/libdispatch-linux-x86_64/src:/home/danielrodriguez/scratch/swift/build/my_linux/foundation-linux-x86_64
…

When I tried to run the TestProcess tests, the ones that remove all the environment were failing because they couldn’t find libBlocksRuntime.so, which sits in /data/users/danielrodriguez/scratch/swift/build/my_linux/libdispatch-linux-x86_64 (without the src/).

The change allows xdgTestHelper to find libBlocksRuntime.so while running those tests without environment.

(This is unrelated to Android, this is a Linux machine)

@spevans
Copy link
Contributor

spevans commented May 9, 2019

Oh I see, it works normally on Linux because it is using the system installed libBlocksRuntime

$ ldd  build/buildbot_linux/foundation-linux-x86_64/TestFoundation/xdgTestHelper |grep Blocks
	libBlocksRuntime.so => /usr/lib/x86_64-linux-gnu/libBlocksRuntime.so (0x00007f851fdc6000)
$ dpkg -l |grep libblocks
ii  libblocksruntime-dev                  0.4.1-1.1                              amd64        Blocks Runtime (development files)
ii  libblocksruntime0                     0.4.1-1.1                              amd64        Blocks Runtime library

I guess it depends if we always want to use the one built as part of libdispatch and ignore the system one.

@drodriguez
Copy link
Contributor Author

Your choice to merge or not. It was something I found in my setup. The Android runpath problem is more convoluted.

@compnerd
Copy link
Member

compnerd commented May 9, 2019

This really is going down the wrong path. We should be reducing RPATH dependencies, not increasing them. They are a security concern and increase difficulty in debugging. I think that relying more on $ORIGIN/../lib is the right approach with all the libraries being co-located.

@spevans
Copy link
Contributor

spevans commented May 10, 2019

If this PR is just adjusting the rpath for the test programs, arent those paths already set in the LD_LIBRARY_PATH environment variable? Maybe one thing we should do is adjust the libdispatch build to put all of the .so files into the same build directory so we can prune one more directory from library paths.

@kevints
Copy link
Contributor

kevints commented May 10, 2019

@spevans we should never be using the system libBlocksRuntime (see the discussion on https://bugs.swift.org/browse/SR-9347) so anything still relying on it is a bug. Whether we use RPATHs or LD_LIBRARY_PATH to do that doesn't matter too much for a test program, but for binaries that are installed onto the system we should prefer to use RPATH.

We should also not be including build tree RPATHs in the installed binaries. In cmake that should be possible with https://cmake.org/cmake/help/v3.4/variable/CMAKE_INSTALL_RPATH.html, which will cause the cmake install or package step to update the RPATH field of the binary before copying it.

@millenomi
Copy link
Contributor

@kevints I'm okay with RPATHs in this instance because these are test binaries which won't be distributed.

@drodriguez
Copy link
Contributor Author

The variable is also used while compiling Foundation, and indeed points to the build directory. It works because during testing the build directory is still there (it happens before installing).

I can (gladly) abandon this PR, but the rest of the RPATHs are still pointing to similar paths.

@spevans
Copy link
Contributor

spevans commented May 10, 2019

@drodriguez Which binaries are affected by this PR, is it just TestFoundation and xdgTestHelper or libraries as well?

@drodriguez
Copy link
Contributor Author

This PR modified libdispatch_ldflags, because that variable was the one used for setting the RPATH pointing to libdispatch.so/libswiftdispatch.so (in the build directory).

That variable is used while building libFoundation.so, plutil, xdgTestHelper and TestFoundation.

One can move this change to another variable, but that doesn’t change the fact that the variable was applying the RPATH to all the artifacts and pointing to the build directory.

@millenomi
Copy link
Contributor

Hmm. @spevans is correct that we shouldn't ship with build machine paths for at least some of the products — libFoundation.so and plutil should not carry them. They're fine to a point in TestFoundation and the helper tool.

@spevans
Copy link
Contributor

spevans commented May 16, 2019

You could just add the extra directory into XDG_TEST_HELPER_RPATH which is used by xdgTestHelper to set its rpath. This could also be used by TestFoundation (you may want to rename this variable to TEST_BINARY_HELPER_RPATH or something as well). This would fix the test binaries and leave the libs alone.
In fact this is probably better than what we currently have as on Ubuntu CI we currently run the tests against the system libBlocksRuntime.so and not the one that is built as part of libdispatch so this should improve the testing.

Would this change allow the removal of the LD_LIBRARY_PATH set in TestProcess explicitly for Android?

@drodriguez
Copy link
Contributor Author

I can change this PR to work for Linux at least. Android is a special creature. Maybe '$ORIGIN' works there, but I have to check.

@drodriguez
Copy link
Contributor Author

I think this should work in anybody Linux installation. Only the test binaries have extra rpaths. Also, Android is left without them for the time being. I will do it in another commit.

@swift-ci please test

@drodriguez
Copy link
Contributor Author

@swift-ci please test linux

@finagolfin
Copy link
Member

We should also not be including build tree RPATHs in the installed binaries.

They are still being included in the official releases for linux, as I noted to @drodriguez in the comments for a different pull a couple months ago. I see that it's still the case for libXCTest.so and other shared libraries in the 5.0 release, along with binaries like plutil, swift-build, or swift-package:

> readelf -d swift-5.0-RELEASE-ubuntu18.04/usr/bin/{plutil,swift-build,swift-package}|grep -E "File:|RUNPATH"
File: swift-5.0-RELEASE-ubuntu18.04/usr/bin/plutil
 0x000000000000001d (RUNPATH)            Library runpath: [/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux:/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/libdispatch-linux-x86_64/src:$ORIGIN/../lib/swift/linux]
File: swift-5.0-RELEASE-ubuntu18.04/usr/bin/swift-build
 0x000000000000001d (RUNPATH)            Library runpath: [/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux:$ORIGIN:$ORIGIN/../lib/swift/linux:/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/swiftpm-linux-x86_64/.bootstrap/lib/swift/linux:$ORIGIN/../lib/swift/pm/llbuild:/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/llbuild-linux-x86_64/lib]
File: swift-5.0-RELEASE-ubuntu18.04/usr/bin/swift-package
 0x000000000000001d (RUNPATH)            Library runpath: [/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux:$ORIGIN:$ORIGIN/../lib/swift/linux:/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/swiftpm-linux-x86_64/.bootstrap/lib/swift/linux:$ORIGIN/../lib/swift/pm/llbuild:/home/buildnode/jenkins/workspace/oss-swift-5.0-package-linux-ubuntu-18_04/build/buildbot_linux/llbuild-linux-x86_64/lib]

@drodriguez
Copy link
Contributor Author

Yes. That discussion points to the source of all those invalid runpaths, which come from the compiler itself embedding a full path of the build machine. Very nice when you are running those binaries in the build machine, useless for other cases.

This PR only deals with the test binaries, when run against the non-installed libraries. libFoundation.so still has $ORIGIN (which is not helpful while not installed, but it is when installed), and plutil still points to $ORIGIN (which is not correct in either case, and I don’t know in the installed result where it gets $ORIGIN/../lib/swift/linux, which is correct).

The new commit just fixes some conflicts, but doesn’t try to do anything more. I think this PR might still be interesting by itself, specially since it deals with testing the right setup.

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@spevans
Copy link
Contributor

spevans commented May 20, 2019

@drodriguez So does this PR fix the RUNPATH for only TestFoundation and xdgTestHelper to include the build directories and doesnt touch anything else ? If that is the case Im fine with the PR.

Note that currently plutil in the snapshot release is broken. It should have a RUNPATH of $ORIGIN/../lib/swift/linux (or whatever os) and was originally fixed in #1789 but has since been broken by updates to the CMakeLists.txt.

$ chrpath -l ~/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/bin/plutil 
/home/spse/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/bin/plutil: RUNPATH=/home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-18_04/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux:/home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-18_04/build/buildbot_linux/libdispatch-linux-x86_64/src:$ORIGIN
$ ~/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/bin/plutil 
/home/spse/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/bin/plutil: error while loading shared libraries: libswiftGlibc.so: cannot open shared object file: No such file or directory

So that also needs fixing.

libFoundation.so should only have $ORIGIN but has the build paths as well:

$ chrpath -l ~/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/lib/swift/linux/libFoundation.so 
/home/spse/swift-DEVELOPMENT-SNAPSHOT-2019-05-18-a-ubuntu18.04/usr/lib/swift/linux/libFoundation.so: RUNPATH=/home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-18_04/build/buildbot_linux/swift-linux-x86_64/lib/swift/linux:/home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-18_04/build/buildbot_linux/libdispatch-linux-x86_64/src:$ORIGIN

So we need to scrub those as well.

We should really add a test into the swift-intergration-tests repo to check these RUNPATHs after install to stop extra directories getting into the shipped binaries.

I did open https://bugs.swift.org/browse/SR-9315 about the RUNPATHs but it was closed (incorrectly in my opinion).

@drodriguez
Copy link
Contributor Author

@drodriguez So does this PR fix the RUNPATH for only TestFoundation and xdgTestHelper to include the build directories and doesnt touch anything else ? If that is the case Im fine with the PR.

Correct. It removes the dispatch paths from Foundation and plutil, but adds them to TestFoundation and xdgTestHelper, since those are the only targets that need a clue where dispatch is before being installed.

Note that currently plutil in the snapshot release is broken. It should have a RUNPATH of $ORIGIN/../lib/swift/linux (or whatever os) and was originally fixed in #1789 but has since been broken by updates to the CMakeLists.txt.

That explain why I’m seeing different results from @buttaface above. If you want to create that PR, I will be happy to accept it. Notice that right now, I think plutil uses ${Foundation_RPATH}, which I think it is incorrect.

libFoundation.so should only have $ORIGIN but has the build paths as well:

I think that path is added by the compiler itself, and only in Linux. https://github.com/apple/swift/blob/ad79bbaf860a3281b72d9f775b7cbfde57e30639/lib/Driver/UnixToolChains.cpp#L199-L205. It has an obvious TODO about the standard library moving around, which is what's happening here. In Android, this piece of code is disabled (because when cross-compiling, whatever absolute rpath you add is wrong). That part of the code might be right once the compiler is installed in some machine, but it is not helpful when the compiler is not in the final location. Darwin has a similar piece of code. 🤷‍♂️

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@drodriguez
Copy link
Contributor Author

@swift-ci please test linux

@spevans
Copy link
Contributor

spevans commented May 24, 2019

I was just having a re-read through this PR and noticed 2 other changes that need to be made:

For platforms where the RPATH is being set inTestFoundation:
The following should be removed when runnng TestFoundation:

  ENVIRONMENT
 LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}:${FOUNDATION_PATH_TO_XCTEST_BUILD}:${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}:${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src

Also, ${FOUNDATION_PATH_TO_XCTEST_BUILD} needs to be added to the RPATH for TestFoundation

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@drodriguez
Copy link
Contributor Author

I hope I captured all the feedback with the last version (environment variables removed, complete the rpaths with XCTest where needed).

And since we are here, I don’t think plutil should use Foundation_RPATH (which is just $ORIGIN), since plutil ends up in the bindir. I think we could remove the rpath from plutil, but that will make it difficult to use in the build tree.

(Additionally it has the rpath to the build tree even after installing, but as I have said above, that's something the compiler does).

@spevans
Copy link
Contributor

spevans commented May 29, 2019

Ive done a fix for plutil in #2307 which I will rebase on top of this once it has gone in.

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@drodriguez
Copy link
Contributor Author

@spevans so I think removing -rpath;-Xlinker;${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src from libdispatch_ldflags have the secondary effect of not allowing the LLDB test to load Foundation. Seems that LLDB links against the build tree again, which breaks the loading (I imagine that TestFoundation doesn’t fail to load dispatch because the executable itself has the right rpath).

I don’t know if it is worth it to copy the libraries to a temporal directory for testing LLDB or that will become untenable over time.

@spevans
Copy link
Contributor

spevans commented May 31, 2019

I wouldnt bother about copying the libraries I would just leave the path in for now. In future we might be able to set an LD_LIBRARY_CACHE path when running lldb but let's leave that for now and try and get this PR in.

@drodriguez
Copy link
Contributor Author

@swift-ci please test

@spevans
Copy link
Contributor

spevans commented Jun 26, 2019

@drodriguez Do you want to rebase this and get it merged?

@drodriguez
Copy link
Contributor Author

@swift-ci please test Linux platform

@spevans
Copy link
Contributor

spevans commented Jun 26, 2019

@swift-ci test linux

Dispatch build leaves artifacts in both the root directory and the src
directory, but only the src directory was being added to the runpath, so
the libBlocksRuntime.so library might not have been found.

Additionally, remove the rpath flags from libdispatch_ldflags, which are
used to compile Foundation, but will point to the build directory
results. Add those flags instead to a list used for the test binaries.

In the end Foundation ends up with a path of `$ORIGIN`; TestFoundation
has paths to Foundation, to Dispatch and BlocksRuntime, and to XCTest;
while xdgTestHelper points to Foundation, and Dispatch and
BlocksRuntime.

Extract a small function for adding rpaths to a list, to make the rpath
easier to read.

Also, remove Android from the rpath flags, since Android will not work
with the build tree rpaths, and will need its own solution. For the time
being, do not set any rpath.
@drodriguez
Copy link
Contributor Author

Rebased to avoid conflicts with master. Ready for review.

@swift-ci please test Linux platform

file(TO_CMAKE_PATH "${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}" FOUNDATION_PATH_TO_LIBDISPATCH_BUILD)
# NOTE: the following two are for testing LLDB and others, but should be removed
append_linker_rpath(Foundation_RPATH ${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD}/src)
append_linker_rpath(Foundation_RPATH ${FOUNDATION_PATH_TO_LIBDISPATCH_BUILD})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be adding build paths to libFoundation.so we should fix lldb instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That NOTE is the result of our conversation on May 31st: #2246 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spevans: Some decision around this? I can try to fix it in LLDB, but I would l love to not have to modify it in there before merging this. Thanks!

@drodriguez
Copy link
Contributor Author

For some reason https://ci.swift.org/view/Pull%20Request/job/swift-corelibs-foundation-PR-Linux/3426 haven't reported back here. Firing it up again.

@swift-ci please test Linux platform

@finagolfin
Copy link
Member

Any interest in getting this in? I made a similar change to remove the libdispatch build directory runpath when packaging up the Swift toolchain for Android.

@finagolfin
Copy link
Member

This CMake config has changed so much over the past year that this pull doesn't apply anymore. It will have to be redone, either here or in a separate pull.

@shahmishal shahmishal closed this Oct 6, 2020
@shahmishal
Copy link
Member

The Swift project moved the default branch to main and deleted master branch, so GitHub automatically closed the PR. Please re-create pull request with main branch.

More detail about the branch update - https://forums.swift.org/t/updating-branch-names/40412

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants