def repair_wheel(wheel_path: str, abi: str, lib_sdir: str, out_dir: str, update_tags: bool, patcher: ElfPatcher) -> Optional[str]: external_refs_by_fn = get_wheel_elfdata(wheel_path)[1] # Do not repair a pure wheel, i.e. has no external refs if not external_refs_by_fn: return soname_map = {} # type: Dict[str, str] if not isabs(out_dir): out_dir = abspath(out_dir) wheel_fname = basename(wheel_path) with InWheelCtx(wheel_path) as ctx: ctx.out_wheel = pjoin(out_dir, wheel_fname) dest_dir = WHEEL_INFO_RE(wheel_fname).group('name') + lib_sdir if not exists(dest_dir): os.mkdir(dest_dir) # here, fn is a path to a python extension library in # the wheel, and v['libs'] contains its required libs for fn, v in external_refs_by_fn.items(): ext_libs = v[abi]['libs'] # type: Dict[str, str] for soname, src_path in ext_libs.items(): if src_path is None: raise ValueError(('Cannot repair wheel, because required ' 'library "%s" could not be located') % soname) new_soname, new_path = copylib(src_path, dest_dir, patcher) soname_map[soname] = (new_soname, new_path) patcher.replace_needed(fn, soname, new_soname) if len(ext_libs) > 0: new_rpath = os.path.relpath(dest_dir, os.path.dirname(fn)) new_rpath = os.path.join('$ORIGIN', new_rpath) patcher.set_rpath(fn, new_rpath) # we grafted in a bunch of libraries and modified their sonames, but # they may have internal dependencies (DT_NEEDED) on one another, so # we need to update those records so each now knows about the new # name of the other. for old_soname, (new_soname, path) in soname_map.items(): needed = elf_read_dt_needed(path) for n in needed: if n in soname_map: patcher.replace_needed(path, n, soname_map[n][0]) if update_tags: ctx.out_wheel = add_platforms(ctx, [abi], get_replace_platforms(abi)) return ctx.out_wheel
def repair_wheel( wheel_path: str, abis: List[str], lib_sdir: str, out_dir: str, update_tags: bool, patcher: ElfPatcher, strip: bool = False, ) -> Optional[str]: external_refs_by_fn = get_wheel_elfdata(wheel_path)[1] # Do not repair a pure wheel, i.e. has no external refs if not external_refs_by_fn: return None soname_map = {} # type: Dict[str, Tuple[str, str]] if not isabs(out_dir): out_dir = abspath(out_dir) wheel_fname = basename(wheel_path) with InWheelCtx(wheel_path) as ctx: ctx.out_wheel = pjoin(out_dir, wheel_fname) match = WHEEL_INFO_RE(wheel_fname) if not match: raise ValueError("Failed to parse wheel file name: %s", wheel_fname) dest_dir = match.group("name") + lib_sdir if not exists(dest_dir): os.mkdir(dest_dir) # here, fn is a path to a python extension library in # the wheel, and v['libs'] contains its required libs for fn, v in external_refs_by_fn.items(): ext_libs = v[abis[0]]["libs"] # type: Dict[str, str] for soname, src_path in ext_libs.items(): if src_path is None: raise ValueError( ("Cannot repair wheel, because required " 'library "%s" could not be located') % soname) new_soname, new_path = copylib(src_path, dest_dir, patcher) soname_map[soname] = (new_soname, new_path) patcher.replace_needed(fn, soname, new_soname) if len(ext_libs) > 0: new_rpath = os.path.relpath(dest_dir, os.path.dirname(fn)) new_rpath = os.path.join("$ORIGIN", new_rpath) append_rpath_within_wheel(fn, new_rpath, ctx.name, patcher) # we grafted in a bunch of libraries and modified their sonames, but # they may have internal dependencies (DT_NEEDED) on one another, so # we need to update those records so each now knows about the new # name of the other. for old_soname, (new_soname, path) in soname_map.items(): needed = elf_read_dt_needed(path) for n in needed: if n in soname_map: patcher.replace_needed(path, n, soname_map[n][0]) if update_tags: ctx.out_wheel = add_platforms(ctx, abis, get_replace_platforms(abis[0])) if strip: libs_to_strip = [path for (_, path) in soname_map.values()] extensions = external_refs_by_fn.keys() strip_symbols(itertools.chain(libs_to_strip, extensions)) return ctx.out_wheel