コード例 #1
0
ファイル: repair.py プロジェクト: fbrennen/auditwheel
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
コード例 #2
0
ファイル: repair.py プロジェクト: pypa/auditwheel
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