diff --git a/src/auditwheel/main_repair.py b/src/auditwheel/main_repair.py index 4374f208..07faca87 100644 --- a/src/auditwheel/main_repair.py +++ b/src/auditwheel/main_repair.py @@ -109,7 +109,11 @@ def execute(args, p): from .repair import repair_wheel from .wheel_abi import NonPlatformWheel, analyze_wheel_abi - exclude = frozenset(args.EXCLUDE) + # Split comma separated values and flatten it + exclude = frozenset( + item.strip() for sublist in args.EXCLUDE for item in sublist.split(",") + ) + wheel_policy = WheelPolicies() for wheel_file in args.WHEEL_FILE: diff --git a/tests/integration/test_manylinux.py b/tests/integration/test_manylinux.py index acd7b1ab..80fb0b81 100644 --- a/tests/integration/test_manylinux.py +++ b/tests/integration/test_manylinux.py @@ -329,27 +329,57 @@ def test_repair_exclude(self, any_manylinux_container, io_folder): orig_wheel = filenames[0] assert "manylinux" not in orig_wheel - repair_command = [ - f"LD_LIBRARY_PATH={test_path}/a:$LD_LIBRARY_PATH", - "auditwheel", - "repair", - f"--plat={policy}", - "--only-plat", - "-w", - "/io", - "--exclude=liba.so", - f"/io/{orig_wheel}", - ] - output = docker_exec(manylinux_ctr, ["bash", "-c", " ".join(repair_command)]) - assert "Excluding liba.so" in output - filenames = os.listdir(io_folder) - assert len(filenames) == 2 - repaired_wheel = f"testrpath-0.0.1-{PYTHON_ABI}-{tag}.whl" - assert repaired_wheel in filenames + def run_repair_test(exclude_args, expected_exclusions): + repair_command = ( + [ + f"LD_LIBRARY_PATH={test_path}/a:$LD_LIBRARY_PATH", + "auditwheel", + "repair", + f"--plat={policy}", + "--only-plat", + "-w", + "/io", + ] + + exclude_args + + [ + f"/io/{orig_wheel}", + ] + ) + output = docker_exec( + manylinux_ctr, ["bash", "-c", " ".join(repair_command)] + ) - # Make sure we don't have liba.so & libb.so in the result - contents = zipfile.ZipFile(os.path.join(io_folder, repaired_wheel)).namelist() - assert not any(x for x in contents if "/liba" in x or "/libb" in x) + # Check for exclusions in the output + for arg in exclude_args: + if "," in arg: + libs = arg.split("=")[1].split(",") + for lib in libs: + assert f"Excluding {lib}" in output + else: + lib = arg.split("=")[1] + assert f"Excluding {lib}" in output + + filenames = os.listdir(io_folder) + assert len(filenames) == 2 + repaired_wheel = f"testrpath-0.0.1-{PYTHON_ABI}-{tag}.whl" + assert repaired_wheel in filenames + + # Make sure we don't have the excluded libraries in the result + contents = zipfile.ZipFile( + os.path.join(io_folder, repaired_wheel) + ).namelist() + for lib in expected_exclusions: + assert not any(x for x in contents if f"/{lib}" in x) + + # Test case 1: Exclude liba.so and libx.so using 2 --exclude parameters + run_repair_test( + ["--exclude=liba.so", "--exclude=libx.so"], + ["liba.so", "libb.so", "libx.so"], + ) + # Test case 2: Exclude liba.so and libx.so using comma separated + run_repair_test( + ["--exclude=liba.so,libx.so"], ["liba.so", "libb.so", "libx.so"] + ) def test_build_wheel_with_binary_executable( self, any_manylinux_container, docker_python, io_folder @@ -410,9 +440,21 @@ def test_build_wheel_with_binary_executable( ) # testprogram should be a Python shim since we had to rewrite its RPATH. + python_version = docker_exec( + docker_python, + [ + "python", + "-c", + ( + "import sys; " + "print(f'python{sys.version_info.major}." + "{sys.version_info.minor}')" + ), + ], + ).strip() assert ( docker_exec(docker_python, ["head", "-n1", "/usr/local/bin/testprogram"]) - == "#!/usr/local/bin/python\n" + == f"#!/usr/local/bin/{python_version}\n" ) # testprogram_nodeps should be the unmodified ELF binary. @@ -492,8 +534,12 @@ def test_build_wheel_depending_on_library_with_rpath( [ "bash", "-c", - "LD_LIBRARY_PATH=" - "/auditwheel_src/tests/integration/testrpath/a:$LD_LIBRARY_PATH " + ( + "LD_LIBRARY_PATH=" + "/auditwheel_src/tests/integration/testrpath/a:" + "/auditwheel_src/tests/integration/testrpath/x:" + "$LD_LIBRARY_PATH " + ) + repair_command, ], ) @@ -512,13 +558,15 @@ def test_build_wheel_depending_on_library_with_rpath( "from testrpath import testrpath; print(testrpath.func())", ], ) - assert output.strip() == "11" + # output = fa + fx = (1+10) + 20 = 31 + assert output.strip() == "31" with zipfile.ZipFile(os.path.join(io_folder, repaired_wheel)) as w: libraries = tuple( name for name in w.namelist() if "testrpath.libs/lib" in name ) - assert len(libraries) == 2 + assert len(libraries) == 3 assert any(".libs/liba" in name for name in libraries) + assert any(".libs/libx" in name for name in libraries) for name in libraries: with w.open(name) as f: elf = ELFFile(io.BytesIO(f.read())) diff --git a/tests/integration/testrpath/setup.py b/tests/integration/testrpath/setup.py index 75b92674..7264fc6e 100644 --- a/tests/integration/testrpath/setup.py +++ b/tests/integration/testrpath/setup.py @@ -11,6 +11,10 @@ class BuildExt(build_ext): def run(self) -> None: cmd = "gcc -fPIC -shared -o b/libb.so b/b.c" subprocess.check_call(cmd.split()) + + cmd = "gcc -fPIC -shared -o x/libx.so x/x.c" + subprocess.check_call(cmd.split()) + cmd = ( "gcc -fPIC -shared -o a/liba.so " "-Wl,{dtags_flag} -Wl,-rpath=$ORIGIN/../b " @@ -36,9 +40,10 @@ def run(self) -> None: Extension( "testrpath/testrpath", sources=["src/testrpath/testrpath.c"], - include_dirs=["a"], - libraries=["a"], - library_dirs=["a"], + include_dirs=["a", "x"], + libraries=["a", "x"], + library_dirs=["a", "x"], + extra_link_args=["-Wl,-rpath,$ORIGIN/../a", "-Wl,-rpath,$ORIGIN/../x"], ) ], ) diff --git a/tests/integration/testrpath/src/testrpath/testrpath.c b/tests/integration/testrpath/src/testrpath/testrpath.c index 32731129..e406a92e 100644 --- a/tests/integration/testrpath/src/testrpath/testrpath.c +++ b/tests/integration/testrpath/src/testrpath/testrpath.c @@ -1,5 +1,6 @@ #include #include "a.h" +#include "x.h" static PyObject * func(PyObject *self, PyObject *args) @@ -9,7 +10,7 @@ func(PyObject *self, PyObject *args) (void)self; (void)args; - res = fa(); + res = fa() + fx(); return PyLong_FromLong(res); } diff --git a/tests/integration/testrpath/x/x.c b/tests/integration/testrpath/x/x.c new file mode 100644 index 00000000..2f6eaed7 --- /dev/null +++ b/tests/integration/testrpath/x/x.c @@ -0,0 +1,3 @@ +int fx(void) { + return 20; +} diff --git a/tests/integration/testrpath/x/x.h b/tests/integration/testrpath/x/x.h new file mode 100644 index 00000000..1c443e7a --- /dev/null +++ b/tests/integration/testrpath/x/x.h @@ -0,0 +1 @@ +int fx(void);