Skip to content

Commit 141b568

Browse files
author
Ashley Anderson
committed
Add 'replace_needed_multiple' to reduce total number of calls to 'patchelf'.
1 parent 756580b commit 141b568

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

src/auditwheel/patcher.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
import re
22
from distutils.spawn import find_executable
3+
from itertools import chain
34
from subprocess import CalledProcessError, check_call, check_output
5+
from typing import Iterable, Tuple
46

57

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

12+
def replace_needed_multiple(
13+
self, file_name: str, so_name_pairs: Iterable[Tuple[str, str]]
14+
) -> None:
15+
raise NotImplementedError
16+
1017
def set_soname(self, file_name: str, new_so_name: str) -> None:
1118
raise NotImplementedError
1219

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

54+
def replace_needed_multiple(
55+
self, file_name: str, so_name_pairs: Iterable[Tuple[str, str]]
56+
) -> None:
57+
check_call(
58+
[
59+
"patchelf",
60+
*chain.from_iterable(
61+
("--replace-needed", *pair) for pair in so_name_pairs
62+
),
63+
file_name,
64+
]
65+
)
66+
4767
def set_soname(self, file_name: str, new_so_name: str) -> None:
4868
check_call(["patchelf", "--set-soname", new_so_name, file_name])
4969

src/auditwheel/repair.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ def repair_wheel(
6767
# here, fn is a path to a python extension library in
6868
# the wheel, and v['libs'] contains its required libs
6969
for fn, v in external_refs_by_fn.items():
70-
7170
ext_libs = v[abis[0]]["libs"] # type: Dict[str, str]
71+
replacements = [] # type: List[Tuple[str, str]]
7272
for soname, src_path in ext_libs.items():
7373
if src_path is None:
7474
raise ValueError(
@@ -81,7 +81,9 @@ def repair_wheel(
8181

8282
new_soname, new_path = copylib(src_path, dest_dir, patcher)
8383
soname_map[soname] = (new_soname, new_path)
84-
patcher.replace_needed(fn, soname, new_soname)
84+
replacements.append((soname, new_soname))
85+
if replacements:
86+
patcher.replace_needed_multiple(fn, replacements)
8587

8688
if len(ext_libs) > 0:
8789
new_rpath = os.path.relpath(dest_dir, os.path.dirname(fn))
@@ -94,9 +96,12 @@ def repair_wheel(
9496
# name of the other.
9597
for old_soname, (new_soname, path) in soname_map.items():
9698
needed = elf_read_dt_needed(path)
99+
replacements = []
97100
for n in needed:
98101
if n in soname_map:
99-
patcher.replace_needed(path, n, soname_map[n][0])
102+
replacements.append((n, soname_map[n][0]))
103+
if replacements:
104+
patcher.replace_needed_multiple(path, replacements)
100105

101106
if update_tags:
102107
ctx.out_wheel = add_platforms(ctx, abis, get_replace_platforms(abis[0]))

tests/unit/test_elfpatcher.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ def test_replace_needed(self, check_call, _0, _1):
5151
["patchelf", "--replace-needed", soname_old, soname_new, filename]
5252
)
5353

54+
def test_replace_needed_multiple(self, check_call, _0, _1):
55+
patcher = Patchelf()
56+
filename = "test.so"
57+
replacements = [
58+
("TEST_OLD1", "TEST_NEW1"),
59+
("TEST_OLD2", "TEST_NEW2"),
60+
]
61+
patcher.replace_needed_multiple(filename, replacements)
62+
check_call.assert_called_once_with(
63+
[
64+
"patchelf",
65+
"--replace-needed",
66+
*replacements[0],
67+
"--replace-needed",
68+
*replacements[1],
69+
filename,
70+
]
71+
)
72+
5473
def test_set_soname(self, check_call, _0, _1):
5574
patcher = Patchelf()
5675
filename = "test.so"

0 commit comments

Comments
 (0)