Skip to content

Commit fe45465

Browse files
authored
Merge pull request #376 from aganders3/aa/batch-patch
Update 'replace_needed' to reduce total calls to 'patchelf'
2 parents 756580b + fac01db commit fe45465

File tree

3 files changed

+42
-8
lines changed

3 files changed

+42
-8
lines changed

Diff for: src/auditwheel/patcher.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
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 Tuple
46

57

68
class ElfPatcher:
7-
def replace_needed(self, file_name: str, so_name: str, new_so_name: str) -> None:
9+
def replace_needed(self, file_name: str, *old_new_pairs: Tuple[str, str]) -> None:
810
raise NotImplementedError
911

1012
def set_soname(self, file_name: str, new_so_name: str) -> None:
@@ -41,8 +43,16 @@ class Patchelf(ElfPatcher):
4143
def __init__(self) -> None:
4244
_verify_patchelf()
4345

44-
def replace_needed(self, file_name: str, so_name: str, new_so_name: str) -> None:
45-
check_call(["patchelf", "--replace-needed", so_name, new_so_name, file_name])
46+
def replace_needed(self, file_name: str, *old_new_pairs: Tuple[str, str]) -> None:
47+
check_call(
48+
[
49+
"patchelf",
50+
*chain.from_iterable(
51+
("--replace-needed", *pair) for pair in old_new_pairs
52+
),
53+
file_name,
54+
]
55+
)
4656

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

Diff for: src/auditwheel/repair.py

+8-3
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(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(path, *replacements)
100105

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

Diff for: tests/unit/test_elfpatcher.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,35 @@ def test_patchelf_version_check_fail(check_output, version):
4141
class TestPatchElf:
4242
""" "Validate that patchelf is invoked with the correct arguments."""
4343

44-
def test_replace_needed(self, check_call, _0, _1):
44+
def test_replace_needed_one(self, check_call, _0, _1):
4545
patcher = Patchelf()
4646
filename = "test.so"
4747
soname_old = "TEST_OLD"
4848
soname_new = "TEST_NEW"
49-
patcher.replace_needed(filename, soname_old, soname_new)
49+
patcher.replace_needed(filename, (soname_old, soname_new))
5050
check_call.assert_called_once_with(
5151
["patchelf", "--replace-needed", soname_old, soname_new, filename]
5252
)
5353

54+
def test_replace_needed_multple(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(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)