Source code for rez.utils.elf

# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the Rez Project


"""
Functions that wrap readelf/patchelf utils on linux.
"""
import os
import pipes
import subprocess

from rez.utils.filesystem import make_path_writable


[docs]def get_rpaths(elfpath): """Get rpaths/runpaths from header. """ # stdout lines look like: # 0x000000000000000f (RPATH) Library rpath: [/xxx:/yyy] # out = _run("readelf", "-d", elfpath) # parse out rpath/runpath for line in out.split('\n'): parts = line.strip().split() if "(RPATH)" in parts or "(RUNPATH)" in parts: txt = parts[-1] txt = txt[1:-1] # strip [ and ] rpaths = txt.split(':') return rpaths or [] return []
[docs]def patch_rpaths(elfpath, rpaths): """Replace an elf's rpath header with those provided. """ # this is a hack to get around https://github.com/nerdvegas/rez/issues/1074 # I actually hit a case where patchelf was installed as a rez suite tool, # causing '$ORIGIN' to be expanded early (to empty string). # TODO remove this hack when bug is fixed # env = os.environ.copy() env["ORIGIN"] = "$ORIGIN" with make_path_writable(elfpath): if rpaths: _run("patchelf", "--set-rpath", ':'.join(rpaths), elfpath, env=env) else: _run("patchelf", "--remove-rpath")
def _run(*nargs, **popen_kwargs): proc = subprocess.Popen( nargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **popen_kwargs ) out, err = proc.communicate() if proc.returncode: cmd_ = ' '.join(pipes.quote(x) for x in nargs) raise RuntimeError( "Command %s - failed with exitcode %d: %s" % (cmd_, proc.returncode, err.strip().replace('\n', "\\n")) ) return out