Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auditwheel not finding libraries already inside wheel #285

Closed
psavery opened this issue Feb 15, 2021 · 3 comments
Closed

Auditwheel not finding libraries already inside wheel #285

psavery opened this issue Feb 15, 2021 · 3 comments

Comments

@psavery
Copy link

psavery commented Feb 15, 2021

Hi there,

I'm using cibuildwheel to build some wheels for one of my projects. This builds some python bindings for C++ using pybind11. When auditwheel repair runs on Linux, I get this error:

# auditwheel repair avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl 
INFO:auditwheel.main_repair:Repairing avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl
Traceback (most recent call last):
  File "/usr/local/bin/auditwheel", line 8, in <module>
    sys.exit(main())
  File "/opt/_internal/tools/lib/python3.7/site-packages/auditwheel/main.py", line 50, in main
    rval = args.func(args, p)
  File "/opt/_internal/tools/lib/python3.7/site-packages/auditwheel/main_repair.py", line 95, in execute
    strip=args.STRIP)
  File "/opt/_internal/tools/lib/python3.7/site-packages/auditwheel/repair.py", line 69, in repair_wheel
    soname)
ValueError: Cannot repair wheel, because required library "libAvogadroCore.so.1" could not be located

However, the library is actually already inside the wheel. If I run these commands:

unzip avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl 
export LD_LIBRARY_PATH=$PWD/avogadro:$LD_LIBRARY_PATH 
auditwheel repair avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl

It succeeds. I'm also able to successfully run tests after the wheel is audited. Any idea what could be going on?

The wheel is attached below with a .zip extension instead of .whl (since GitHub insists on a .zip extension). You can repeat this behavior by running auditwheel repair on the wheel from the quay.io/pypa/manylinux2010_x86_64 docker image.

The auditwheel -v show output is attached here.

avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.zip

Looks like auditwheel 3.3.1 via python 3.7 is being used.

@psavery
Copy link
Author

psavery commented Feb 23, 2021

I guess I can turn this issue into a feature request.

That wheel linked above is in fact a valid wheel already. You can pip install it and use it. If you unzip it, and run ldd on one of the python modules, you can see that it can already find the library that is causing the error in auditwheel repair:

$ ldd avogadro/core.cpython-38-x86_64-linux-gnu.so 
        ...
	libAvogadroCore.so.1 => $PWD/avogadro/libAvogadroCore.so.1 (0x00007fb2cabfd000)
        ...

(note I replaced the path to $PWD with $PWD)

That is because the RPATH is set to $ORIGIN in those python modules. So they can find the libraries since the libraries
are in the directory with it already.

So I guess the feature request would be to check if the RPATH is set, and if it is, and
the linked library is in the RPATH and already inside the wheel, just ignore it.

Otherwise, if I have other libraries I need auditwheel to find, I have to come up with work-arounds
to prevent this error, such as making the linked library find-able by auditwheel by unzipping it like:

unzip avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl 
export LD_LIBRARY_PATH=$PWD/avogadro:$LD_LIBRARY_PATH
auditwheel repair avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl

@mayeut
Copy link
Member

mayeut commented Mar 7, 2021

Thanks for the reproducer.
The issue does not come from the python modules. As you mentioned, the wheel can be installed and loaded without being repaired.
The issue comes from the extra ELF files present in the wheel.
auditwheel assumes libAvogadroQuantumIO.so.1.93.0 will be used on its own, let's say via ctypes for example since the file is not present in the elf tree of the python modules.

(cp38) [root@5aca54fce21d ~]# pip install avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl 
Processing ./avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl
Installing collected packages: avogadro
Successfully installed avogadro-1.93.1.dev134+g71afbae
(cp38) [root@5aca54fce21d ~]# python
Python 3.8.8 (default, Mar  3 2021, 07:55:59) 
[GCC 9.3.1 20200408 (Red Hat 9.3.1-2)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> ctypes.CDLL('/root/cp38/lib/python3.8/site-packages/avogadro/libAvogadroQuantumIO.so.1.93.0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/python/cp38-cp38/lib/python3.8/ctypes/__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libAvogadroIO.so.1: cannot open shared object file: No such file or directory
>>> ctypes.CDLL('/root/cp38/lib/python3.8/site-packages/avogadro/libAvogadroIO.so.1.93.0')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/python/cp38-cp38/lib/python3.8/ctypes/__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: libAvogadroCore.so.1: cannot open shared object file: No such file or directory
(cp38) [root@5aca54fce21d ~]# unzip avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl 
Archive:  avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl
  inflating: avogadro-1.93.1.dev134+g71afbae.dist-info/top_level.txt  
  inflating: avogadro-1.93.1.dev134+g71afbae.dist-info/RECORD  
  inflating: avogadro-1.93.1.dev134+g71afbae.dist-info/WHEEL  
  inflating: avogadro-1.93.1.dev134+g71afbae.dist-info/LICENSE  
  inflating: avogadro-1.93.1.dev134+g71afbae.dist-info/METADATA  
  inflating: avogadro/libAvogadroQuantumIO.so  
  inflating: avogadro/io.cpython-38-x86_64-linux-gnu.so  
  inflating: avogadro/libAvogadroIO.so.1  
  inflating: avogadro/libAvogadroIO.so.1.93.0  
  inflating: avogadro/libAvogadroQuantumIO.so.1  
  inflating: avogadro/libAvogadroCore.so.1  
  inflating: avogadro/__init__.py    
  inflating: avogadro/core.cpython-38-x86_64-linux-gnu.so  
  inflating: avogadro/libAvogadroCore.so  
  inflating: avogadro/libAvogadroQuantumIO.so.1.93.0  
  inflating: avogadro/libAvogadroIO.so  
  inflating: avogadro/libAvogadroCore.so.1.93.0  
(cp38) [root@5aca54fce21d ~]# ldd avogadro/libAvogadroQuantumIO.so.1.93.0
	linux-vdso.so.1 =>  (0x00007ffd16913000)
	libAvogadroIO.so.1 => not found
	libAvogadroCore.so.1 => not found
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fb7b919e000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fb7b8e9c000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fb7b8ace000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb7b88b8000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb7b96f0000)

You can fix libAvogadro*.so* RPATH so they can be loaded on their own (not tested).
You're best bet (and in fact I checked that it works) is to remove all libAvogadro*.so & libAvogadro*.so.1.93.0 and adjust avogadro-1.93.1.dev134+g71afbae.dist-info/RECORD.
This will also save some space on PyPI and end-users:

-rw-r--r-- 1 root root 2302787 Mar  7 07:54 avogadro-1.93.1.dev134+g71afbae-cp38-cp38-linux_x86_64.whl
-rw-r--r-- 1 root root  850469 Mar  7 07:58 avogadro-1.93.1.dev134+mine-cp38-cp38-linux_x86_64.whl
-rw-r--r-- 1 root root  854074 Mar  7 07:58 avogadro-1.93.1.dev134+mine-cp38-cp38-manylinux2010_x86_64.whl
-rw-r--r-- 1 root root  854075 Mar  7 07:58 avogadro-1.93.1.dev134+mine-cp38-cp38-manylinux2014_x86_64.whl

@psavery
Copy link
Author

psavery commented Mar 8, 2021

Thank you very much for looking through this, @mayeut. This information is very helpful.

I haven't tested this yet, but I'll assume it's correct and close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants