diff --git a/src/auditwheel/lddtree.py b/src/auditwheel/lddtree.py index 86fcb6de..eadf7d9f 100644 --- a/src/auditwheel/lddtree.py +++ b/src/auditwheel/lddtree.py @@ -318,7 +318,7 @@ def load_ld_paths( ) -> dict[str, list[str]]: """Load linker paths from common locations - This parses the ld.so.conf and LD_LIBRARY_PATH env var. + This parses the ld.so.conf and AUDITWHEEL_LD_LIBRARY_PATH / LD_LIBRARY_PATH env vars. Parameters ---------- @@ -334,15 +334,22 @@ def load_ld_paths( """ ldpaths: dict[str, list[str]] = {"conf": [], "env": [], "interp": []} - # Load up $LD_LIBRARY_PATH. - env_ldpath = os.environ.get("LD_LIBRARY_PATH") - if env_ldpath is not None: - if root != "/": - log.warning("ignoring LD_LIBRARY_PATH due to ROOT usage") - else: - # TODO: If this contains $ORIGIN, we probably have to parse this - # on a per-ELF basis so it can get turned into the right thing. - ldpaths["env"] = parse_ld_paths(env_ldpath, path="") + ld_library_path = os.environ.get("LD_LIBRARY_PATH") + if root != "/" and ld_library_path is not None: + log.warning("ignoring LD_LIBRARY_PATH due to ROOT usage") + ld_library_path = None + + # Load up $AUDITWHEEL_LD_LIBRARY_PATH and $LD_LIBRARY_PATH + env_ldpath = ":".join( + filter(None, (os.environ.get("AUDITWHEEL_LD_LIBRARY_PATH"), ld_library_path)), + ) + + if env_ldpath: + # TODO: If this contains $ORIGIN, we probably have to parse this + # on a per-ELF basis so it can get turned into the right thing. + # don't pass root: in case root != "/", only AUDITWHEEL_LD_LIBRARY_PATH is checked + # it shall already contain fully resolved paths + ldpaths["env"] = parse_ld_paths(env_ldpath, path="") if libc == Libc.MUSL: # from https://git.musl-libc.org/cgit/musl/tree/ldso diff --git a/tests/integration/test_bundled_wheels.py b/tests/integration/test_bundled_wheels.py index e7bb52f7..0fb48214 100644 --- a/tests/integration/test_bundled_wheels.py +++ b/tests/integration/test_bundled_wheels.py @@ -1,19 +1,18 @@ from __future__ import annotations -import importlib import json import os import sys import zipfile from argparse import Namespace from datetime import datetime, timezone -from os.path import isabs from pathlib import Path from typing import Any from unittest.mock import Mock import pytest +import auditwheel.wheel_abi from auditwheel import lddtree, main_repair from auditwheel.architecture import Architecture from auditwheel.libc import Libc @@ -24,60 +23,83 @@ @pytest.mark.parametrize( - ("file", "external_libs", "exclude"), + ("file", "external_libs", "exclude", "env"), [ ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libffi.so.5", "libpython2.7.so.1.0"}, frozenset(), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["libffi.so.5", "libpython2.7.so.1.0"]), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libffi.so.5", "libpython2.7.so.1.0"}, frozenset(["libffi.so.noexist", "libnoexist.so.*"]), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libpython2.7.so.1.0"}, frozenset(["libffi.so.[4,5]"]), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libffi.so.5", "libpython2.7.so.1.0"}, frozenset(["libffi.so.[6,7]"]), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libpython2.7.so.1.0"}, frozenset([f"{HERE}/*"]), + "LD_LIBRARY_PATH", + ), + ( + "cffi-1.5.0-cp27-none-linux_x86_64.whl", + {"libpython2.7.so.1.0"}, + frozenset([f"{HERE}/*"]), + "AUDITWHEEL_LD_LIBRARY_PATH", + ), + ( + "cffi-1.5.0-cp27-none-linux_x86_64.whl", + {"libffi.so.5", "libpython2.7.so.1.0"}, + frozenset([f"{HERE}/*"]), + None, ), ( "cffi-1.5.0-cp27-none-linux_x86_64.whl", {"libpython2.7.so.1.0"}, frozenset(["libffi.so.*"]), + None, ), - ("cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["*"])), + ("cffi-1.5.0-cp27-none-linux_x86_64.whl", set(), frozenset(["*"]), None), ( "python_snappy-0.5.2-pp260-pypy_41-linux_x86_64.whl", {"libsnappy.so.1"}, frozenset(), + None, ), ], ) -def test_analyze_wheel_abi(file, external_libs, exclude): - # If exclude libs contain path, LD_LIBRARY_PATH need to be modified to find the libs - # `lddtree.load_ld_paths` needs to be reloaded for it's `lru_cache`-ed. - modify_ld_library_path = any(isabs(e) for e in exclude) +def test_analyze_wheel_abi(file, external_libs, exclude, env): + # If exclude libs contain path, the parametrized environment variable "env" needs to be + # modified to find the libs + + lddtree.load_ld_paths.cache_clear() + auditwheel.wheel_abi.get_wheel_elfdata.cache_clear() with pytest.MonkeyPatch.context() as cp: - if modify_ld_library_path: - cp.setenv("LD_LIBRARY_PATH", f"{HERE}") - importlib.reload(lddtree) + cp.delenv("AUDITWHEEL_LD_LIBRARY_PATH", raising=False) + cp.delenv("LD_LIBRARY_PATH", raising=False) + if env: + cp.setenv(env, f"{HERE}") winfo = analyze_wheel_abi( Libc.GLIBC, @@ -91,8 +113,8 @@ def test_analyze_wheel_abi(file, external_libs, exclude): f"{HERE}, {exclude}, {os.environ}" ) - if modify_ld_library_path: - importlib.reload(lddtree) + lddtree.load_ld_paths.cache_clear() + auditwheel.wheel_abi.get_wheel_elfdata.cache_clear() def test_analyze_wheel_abi_pyfpe():