Skip to content
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

fix linking within bundles #1072

Closed
nerdvegas opened this issue May 8, 2021 · 1 comment · Fixed by #1075
Closed

fix linking within bundles #1072

nerdvegas opened this issue May 8, 2021 · 1 comment · Fixed by #1075

Comments

@nerdvegas
Copy link
Contributor

nerdvegas commented May 8, 2021

Compiled binaries and libraries within rez packages that get bundled, may still link to libs outside of the bundle due to runpath/rpath headers.

Unfortunately it doesn't appear possible to fix this simply by patching (eg) rpath headers to $ORIGIN/.... There's no guarantee that patched paths are shorter in length than the existing paths, and it's not possible to patch with longer paths.

A lib within a bundle linking to a lib outside the bundle may still work, but isn't really standalone. We have a case where we're copying bundles into containers that are missing the mount where our central package repos are, so in this case the bundle fails completely because the dynamic linker cannot find the files at all.

A proposed solution is (pseudocode):

libpaths = []

for pkg in reverse_dep_order(bundle_context):
    for elfpath in find_elfs(pkg):
        for libpath in iter_rpaths(elfpath):
            for pkg2 in iter_pkgs(bundle_context):
                rel_libpath = os.path.relpath(libpath, get_pre_bundled_root(pkg2)):
                    if not rel_libpath.startswith("../"):
                        libpaths.append("{%s.root}/%s" % (pkg.name, rel_libpath))
                        break

with open("post_commands.py", 'w') as f:
    for libpath in libpaths:
        f.write("env.LD_LIBRARY_PATH.append(%r)\n" % libpath)

The resulting file will be sourced after the bundle context, via #1071.

Note that this will only work on linux/(mac?). Another solution will have to be found for windows, and it's possible that post_commands.py requires some extra code to switch based on platform.

Note:
We should also investigate whether it's feasible to use patchelf to clear the existing rpath, so the linker never attempts to link to anything outside of the bundle.

@nerdvegas
Copy link
Contributor Author

Note: It seems patchelf is actually fine with replacing rpath with a longer searchpath, so I've gone with that (it's simpler and less prone to differing behaviour)

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

Successfully merging a pull request may close this issue.

1 participant