Skip to content

Commit

Permalink
Add 'replace_needed_multiple' to reduce total number of calls to 'pat…
Browse files Browse the repository at this point in the history
…chelf'.
  • Loading branch information
Ashley Anderson committed May 2, 2022
1 parent 756580b commit 141b568
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
20 changes: 20 additions & 0 deletions src/auditwheel/patcher.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import re
from distutils.spawn import find_executable
from itertools import chain
from subprocess import CalledProcessError, check_call, check_output
from typing import Iterable, Tuple


class ElfPatcher:
def replace_needed(self, file_name: str, so_name: str, new_so_name: str) -> None:
raise NotImplementedError

def replace_needed_multiple(
self, file_name: str, so_name_pairs: Iterable[Tuple[str, str]]
) -> None:
raise NotImplementedError

def set_soname(self, file_name: str, new_so_name: str) -> None:
raise NotImplementedError

Expand Down Expand Up @@ -44,6 +51,19 @@ def __init__(self) -> None:
def replace_needed(self, file_name: str, so_name: str, new_so_name: str) -> None:
check_call(["patchelf", "--replace-needed", so_name, new_so_name, file_name])

def replace_needed_multiple(
self, file_name: str, so_name_pairs: Iterable[Tuple[str, str]]
) -> None:
check_call(
[
"patchelf",
*chain.from_iterable(
("--replace-needed", *pair) for pair in so_name_pairs
),
file_name,
]
)

def set_soname(self, file_name: str, new_so_name: str) -> None:
check_call(["patchelf", "--set-soname", new_so_name, file_name])

Expand Down
11 changes: 8 additions & 3 deletions src/auditwheel/repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ def repair_wheel(
# 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]
replacements = [] # type: List[Tuple[str, str]]
for soname, src_path in ext_libs.items():
if src_path is None:
raise ValueError(
Expand All @@ -81,7 +81,9 @@ def repair_wheel(

new_soname, new_path = copylib(src_path, dest_dir, patcher)
soname_map[soname] = (new_soname, new_path)
patcher.replace_needed(fn, soname, new_soname)
replacements.append((soname, new_soname))
if replacements:
patcher.replace_needed_multiple(fn, replacements)

if len(ext_libs) > 0:
new_rpath = os.path.relpath(dest_dir, os.path.dirname(fn))
Expand All @@ -94,9 +96,12 @@ def repair_wheel(
# name of the other.
for old_soname, (new_soname, path) in soname_map.items():
needed = elf_read_dt_needed(path)
replacements = []
for n in needed:
if n in soname_map:
patcher.replace_needed(path, n, soname_map[n][0])
replacements.append((n, soname_map[n][0]))
if replacements:
patcher.replace_needed_multiple(path, replacements)

if update_tags:
ctx.out_wheel = add_platforms(ctx, abis, get_replace_platforms(abis[0]))
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test_elfpatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ def test_replace_needed(self, check_call, _0, _1):
["patchelf", "--replace-needed", soname_old, soname_new, filename]
)

def test_replace_needed_multiple(self, check_call, _0, _1):
patcher = Patchelf()
filename = "test.so"
replacements = [
("TEST_OLD1", "TEST_NEW1"),
("TEST_OLD2", "TEST_NEW2"),
]
patcher.replace_needed_multiple(filename, replacements)
check_call.assert_called_once_with(
[
"patchelf",
"--replace-needed",
*replacements[0],
"--replace-needed",
*replacements[1],
filename,
]
)

def test_set_soname(self, check_call, _0, _1):
patcher = Patchelf()
filename = "test.so"
Expand Down

0 comments on commit 141b568

Please sign in to comment.