def osx_ch_link(path, link): assert path.startswith(config.build_prefix + '/') link_loc = find_lib(link) if not link_loc: return lib_to_link = relpath(dirname(link_loc), 'lib') path_to_lib = utils.relative(path[len(config.build_prefix) + 1:]) # e.g., if # path = '/build_prefix/lib/some/stuff/libstuff.dylib' # link_loc = 'lib/things/libthings.dylib' # then # lib_to_link = 'things' # path_to_lib = '../..' # @rpath always means 'lib', link will be at # @rpath/lib_to_link/basename(link), like @rpath/things/libthings.dylib. # For when we can't use @rpath, @loader_path means the path to the library # ('path'), so from path to link is # @loader_path/path_to_lib/lib_to_link/basename(link), like # @loader_path/../../things/libthings.dylib. ret = '@rpath/%s/%s' % (lib_to_link, basename(link)) # XXX: IF the above fails for whatever reason, the below can be used # TODO: This might contain redundant ..'s if link and path are both in # some subdirectory of lib. # ret = '@loader_path/%s/%s/%s' % (path_to_lib, lib_to_link, basename(link)) ret = ret.replace('/./', '/') return ret
def mk_relative_linux(f, rpaths=('lib',)): path = join(config.build_prefix, f) rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) if not d.startswith('/') else d for d in rpaths) patchelf = external.find_executable('patchelf') print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) utils.execute([patchelf, '--force-rpath', '--set-rpath', rpath, path])
def mk_relative_linux(f, rpaths=('lib',)): path = join(config.build_prefix, f) rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) if not d.startswith('/') else d for d in rpaths) patchelf = external.find_executable('patchelf') print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) call([patchelf, '--force-rpath', '--set-rpath', rpath, path])
def test_relative_subdir(self): for f, r in [ ('lib/libhdf5.so', './sub'), ('lib/sub/libhdf5.so', '.'), ('bin/python', '../lib/sub'), ('bin/somedir/cmd', '../../lib/sub'), ]: self.assertEqual(utils.relative(f, 'lib/sub'), r)
def test_relative_subdir(): for f, r in [ ('lib/libhdf5.so', './sub'), ('lib/sub/libhdf5.so', '.'), ('bin/python', '../lib/sub'), ('bin/somedir/cmd', '../../lib/sub'), ]: assert utils.relative(f, 'lib/sub') == r
def test_relative_4(self): for f, r in [ ('a/b/c/d/libhdf5.so', '.'), ('a/b/c/x/libhdf5.so', '../d'), ('a/b/x/x/libhdf5.so', '../../c/d'), ('a/x/x/x/libhdf5.so', '../../../b/c/d'), ('x/x/x/x/libhdf5.so', '../../../../a/b/c/d'), ]: self.assertEqual(utils.relative(f, 'a/b/c/d'), r)
def test_relative_prefix(self): for f, r in [ ('xyz', '.'), ('a/xyz', '..'), ('a/b/xyz', '../..'), ('a/b/c/xyz', '../../..'), ('a/b/c/d/xyz', '../../../..'), ]: self.assertEqual(utils.relative(f, '.'), r)
def test_relative_4(): for f, r in [ ('a/b/c/d/libhdf5.so', '.'), ('a/b/c/x/libhdf5.so', '../d'), ('a/b/x/x/libhdf5.so', '../../c/d'), ('a/x/x/x/libhdf5.so', '../../../b/c/d'), ('x/x/x/x/libhdf5.so', '../../../../a/b/c/d'), ]: assert utils.relative(f, 'a/b/c/d') == r
def test_relative_prefix(): for f, r in [ ('xyz', '.'), ('a/xyz', '..'), ('a/b/xyz', '../..'), ('a/b/c/xyz', '../../..'), ('a/b/c/d/xyz', '../../../..'), ]: assert utils.relative(f, '.') == r
def mk_relative_linux(f, prefix, build_prefix=None, rpaths=('lib',)): path = join(prefix, f) if build_prefix is None: assert path.startswith(prefix + '/') else: prefix = build_prefix rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) if not d.startswith('/') else d for d in rpaths) patchelf = external.find_executable('patchelf', prefix) print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) call([patchelf, '--force-rpath', '--set-rpath', rpath, path])
def test_relative_default(self): for f, r in [ ('bin/python', '../lib'), ('lib/libhdf5.so', '.'), ('lib/python2.6/foobar.so', '..'), ('lib/python2.6/lib-dynload/zlib.so', '../..'), ('lib/python2.6/site-packages/pyodbc.so', '../..'), ('lib/python2.6/site-packages/bsdiff4/core.so', '../../..'), ('xyz', './lib'), ('bin/somedir/cmd', '../../lib'), ]: self.assertEqual(utils.relative(f), r)
def test_relative_2(): for f, r in [ ('a/b/c/d/libhdf5.so', '../..'), ('a/b/c/libhdf5.so', '..'), ('a/b/libhdf5.so', '.'), ('a/libhdf5.so', './b'), ('x/x/libhdf5.so', '../../a/b'), ('x/b/libhdf5.so', '../../a/b'), ('x/libhdf5.so', '../a/b'), ('libhdf5.so', './a/b'), ]: assert utils.relative(f, 'a/b') == r
def mk_relative_linux(f, prefix, build_prefix=None, rpaths=('lib', )): path = join(prefix, f) if build_prefix is None: assert path.startswith(prefix + '/') else: prefix = build_prefix rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) if not d.startswith('/') else d for d in rpaths) patchelf = external.find_executable('patchelf', prefix) print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) call([patchelf, '--force-rpath', '--set-rpath', rpath, path])
def osx_ch_link(path, link): assert path.startswith(config.build_prefix + "/") reldir = utils.relative(path[len(config.build_prefix) + 1 :]) prefix_lib = config.build_prefix + "/lib" if link.startswith(prefix_lib): return "@loader_path/%s/%s" % (reldir, link[len(prefix_lib) + 1 :]) if link.startswith(("lib", "@executable_path/")): return "@loader_path/%s/%s" % (reldir, basename(link)) if link == "/usr/local/lib/libgcc_s.1.dylib": return "/usr/lib/libgcc_s.1.dylib"
def test_relative_lib(): for f, r in [ ('bin/python', '../lib'), ('lib/libhdf5.so', '.'), ('lib/python2.6/foobar.so', '..'), ('lib/python2.6/lib-dynload/zlib.so', '../..'), ('lib/python2.6/site-packages/pyodbc.so', '../..'), ('lib/python2.6/site-packages/bsdiff3/core.so', '../../..'), ('xyz', './lib'), ('bin/somedir/cmd', '../../lib'), ('bin/somedir/somedir2/cmd', '../../../lib'), ]: assert utils.relative(f, 'lib') == r
def osx_ch_link(path, link): assert path.startswith(config.build_prefix + '/') reldir = utils.relative(path[len(config.build_prefix) + 1:]) prefix_lib = config.build_prefix + '/lib' if link.startswith(prefix_lib): return '@loader_path/%s/%s' % (reldir, link[len(prefix_lib) + 1:]) if link.startswith(('lib', '@executable_path/')): return '@loader_path/%s/%s' % (reldir, basename(link)) if link == '/usr/local/lib/libgcc_s.1.dylib': return '/usr/lib/libgcc_s.1.dylib'
def mk_relative(m, f): assert sys.platform != 'win32' path = join(config.build_prefix, f) if not is_obj(path): return if sys.platform.startswith('linux'): rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) for d in m.get_value('build/rpaths', ['lib'])) patchelf = external.find_executable('patchelf') print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) call([patchelf, '--set-rpath', rpath, path]) elif sys.platform == 'darwin': mk_relative_osx(path)
def mk_relative_linux(f, prefix, rpaths=('lib', )): 'Respects the original values and converts abs to $ORIGIN-relative' elf = os.path.join(prefix, f) origin = os.path.dirname(elf) patchelf = external.find_executable('patchelf', prefix) try: existing = check_output([patchelf, '--print-rpath', elf]).decode('utf-8').splitlines()[0] except: print('patchelf: --print-rpath failed for %s\n' % (elf)) return existing = existing.split(os.pathsep) new = [] for old in existing: if old.startswith('$ORIGIN'): new.append(old) elif old.startswith('/'): # Test if this absolute path is outside of prefix. That is fatal. relpath = os.path.relpath(old, prefix) if relpath.startswith('..' + os.sep): print('Warning: rpath {0} is outside prefix {1} (removing it)'. format(old, prefix)) else: relpath = '$ORIGIN/' + os.path.relpath(old, origin) if relpath not in new: new.append(relpath) # Ensure that the asked-for paths are also in new. for rpath in rpaths: if not rpath.startswith('/'): # IMHO utils.relative shouldn't exist, but I am too paranoid to remove # it, so instead, make sure that what I think it should be replaced by # gives the same result and assert if not. Yeah, I am a chicken. rel_ours = os.path.normpath(utils.relative(f, rpath)) rel_stdlib = os.path.normpath( os.path.relpath(rpath, os.path.dirname(f))) assert rel_ours == rel_stdlib, \ 'utils.relative {0} and relpath {1} disagree for {2}, {3}'.format( rel_ours, rel_stdlib, f, rpath) rpath = '$ORIGIN/' + rel_stdlib if rpath not in new: new.append(rpath) rpath = ':'.join(new) print('patchelf: file: %s\n setting rpath to: %s' % (elf, rpath)) call([patchelf, '--force-rpath', '--set-rpath', rpath, elf])
def mk_relative_linux(f, prefix, rpaths=('lib',)): 'Respects the original values and converts abs to $ORIGIN-relative' elf = os.path.join(prefix, f) origin = os.path.dirname(elf) patchelf = external.find_executable('patchelf', prefix) try: existing = check_output([patchelf, '--print-rpath', elf]).decode('utf-8').splitlines()[0] except: print('patchelf: --print-rpath failed for %s\n' % (elf)) return existing = existing.split(os.pathsep) new = [] for old in existing: if old.startswith('$ORIGIN'): new.append(old) elif old.startswith('/'): # Test if this absolute path is outside of prefix. That is fatal. relpath = os.path.relpath(old, prefix) if relpath.startswith('..' + os.sep): print('Warning: rpath {0} is outside prefix {1} (removing it)'.format(old, prefix)) else: relpath = '$ORIGIN/' + os.path.relpath(old, origin) if relpath not in new: new.append(relpath) # Ensure that the asked-for paths are also in new. for rpath in rpaths: if not rpath.startswith('/'): # IMHO utils.relative shouldn't exist, but I am too paranoid to remove # it, so instead, make sure that what I think it should be replaced by # gives the same result and assert if not. Yeah, I am a chicken. rel_ours = os.path.normpath(utils.relative(f, rpath)) rel_stdlib = os.path.normpath(os.path.relpath(rpath, os.path.dirname(f))) assert rel_ours == rel_stdlib, \ 'utils.relative {0} and relpath {1} disagree for {2}, {3}'.format( rel_ours, rel_stdlib, f, rpath) rpath = '$ORIGIN/' + rel_stdlib if rpath not in new: new.append(rpath) rpath = ':'.join(new) print('patchelf: file: %s\n setting rpath to: %s' % (elf, rpath)) call([patchelf, '--force-rpath', '--set-rpath', rpath, elf])
def mk_relative_linux(f, rpaths=('lib',)): path = join(config.build_prefix, f) rpath = ':'.join('$ORIGIN/' + utils.relative(f, d) for d in rpaths) patchelf = external.find_executable('patchelf') print('patchelf: file: %s\n setting rpath to: %s' % (path, rpath)) call([patchelf, '--set-rpath', rpath, path])
def mk_relative_linux(f, rpaths=("lib",)): path = join(config.build_prefix, f) rpath = ":".join("$ORIGIN/" + utils.relative(f, d) for d in rpaths) patchelf = external.find_executable("patchelf") print("patchelf: file: %s\n setting rpath to: %s" % (path, rpath)) call([patchelf, "--set-rpath", rpath, path])