diff --git a/src/auditwheel/lddtree.py b/src/auditwheel/lddtree.py index 18064d87..cd529609 100644 --- a/src/auditwheel/lddtree.py +++ b/src/auditwheel/lddtree.py @@ -19,6 +19,7 @@ import glob import logging import os +from fnmatch import fnmatch from pathlib import Path from typing import Any @@ -405,7 +406,7 @@ def lddtree( elif t.entry.d_tag == "DT_RUNPATH": runpaths = parse_ld_paths(t.runpath, path=path, root=root) elif t.entry.d_tag == "DT_NEEDED": - if t.needed in exclude: + if any(fnmatch(t.needed, e) for e in exclude): log.info(f"Excluding {t.needed}") else: libs.append(t.needed) diff --git a/src/auditwheel/main_repair.py b/src/auditwheel/main_repair.py index 4374f208..47ad8be0 100644 --- a/src/auditwheel/main_repair.py +++ b/src/auditwheel/main_repair.py @@ -89,7 +89,8 @@ def configure_parser(sub_parsers): "--exclude", dest="EXCLUDE", help="Exclude SONAME from grafting into the resulting wheel " - "(can be specified multiple times)", + "(can be specified multiple times) " + "(can contain wildcards, for example libfoo.so.*)", action="append", default=[], ) diff --git a/src/auditwheel/repair.py b/src/auditwheel/repair.py index 220f5404..2a162cc8 100644 --- a/src/auditwheel/repair.py +++ b/src/auditwheel/repair.py @@ -8,6 +8,7 @@ import shutil import stat from collections.abc import Iterable +from fnmatch import fnmatch from os.path import abspath, basename, dirname, exists, isabs from os.path import join as pjoin from pathlib import Path @@ -70,7 +71,7 @@ def repair_wheel( ext_libs: dict[str, str] = v[abis[0]]["libs"] replacements: list[tuple[str, str]] = [] for soname, src_path in ext_libs.items(): - assert soname not in exclude + assert not any(fnmatch(soname, e) for e in exclude) if src_path is None: raise ValueError( diff --git a/tests/integration/test_bundled_wheels.py b/tests/integration/test_bundled_wheels.py index e83535b7..a63305a3 100644 --- a/tests/integration/test_bundled_wheels.py +++ b/tests/integration/test_bundled_wheels.py @@ -25,6 +25,23 @@ [ ("cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libffi.so.5"}, frozenset()), ("cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["libffi.so.5"])), + ( + "cffi-1.5.0-cp27-none-linux_x86_64.whl", + {"libffi.so.5"}, + frozenset(["libffi.so.noexist", "libnoexist.so.*"]), + ), + ( + "cffi-1.5.0-cp27-none-linux_x86_64.whl", + set(), + frozenset(["libffi.so.[4,5]"]), + ), + ( + "cffi-1.5.0-cp27-none-linux_x86_64.whl", + {"libffi.so.5"}, + frozenset(["libffi.so.[6,7]"]), + ), + ("cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["libffi.so.*"])), + ("cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["*"])), ( "python_snappy-0.5.2-pp260-pypy_41-linux_x86_64.whl", {"libsnappy.so.1"},