jim-easterbrook / python-gphoto2

Python interface to libgphoto2
GNU Lesser General Public License v3.0
357 stars 59 forks source link

symbol lookup error: /dist-packages/gphoto2/camlibs/ptp2.so: undefined symbol: static_assert #133

Closed eechhx closed 2 years ago

eechhx commented 2 years ago

Your system What version of Python are you using?

python3 --version
Python 3.8.10

What version of libgphoto2 have you installed?

gphoto2 -v
gphoto2 2.5.28

Copyright (c) 2000-2021 Marcus Meissner and others

gphoto2 comes with NO WARRANTY, to the extent permitted by law. You may
redistribute copies of gphoto2 under the terms of the GNU General Public
License. For more information about these matters, see the files named COPYING.

This version of gphoto2 is using the following software versions and options:
gphoto2         2.5.28         gcc, popt(m), exif, no cdk, no aa, jpeg, no readline
libgphoto2      2.5.28         standard camlibs (SKIPPING docupen), gcc, no ltdl, EXIF
libgphoto2_port 0.12.0         iolibs: disk ptpip serial usb1 usbdiskdirect usbscsi, gcc, no ltdl, EXIF, USB, serial without locking

How have you installed (or attempted to install) python-gphoto2?

sudo pip3 install gphoto2 --only-binary :all:

Your problem I recently updated my version of libgphoto2 to 2.5.28. When running examples/camera-summary, I get the following:

python3: symbol lookup error: /usr/local/lib/python3.8/dist-packages/gphoto2/camlibs/ptp2.so: undefined symbol: static_assert

Downgrading python-gphoto2 to version 2.3.0 fixes the issue and I am able to get the appropriate camera summary.

sudo pip3 install gphoto2==2.3.0 --only-binary :all:

Thank you for your time.

jim-easterbrook commented 2 years ago

If you install with --only-binary :all: the separately installed version of libgphoto2 (and gphoto2) is irrelevant. The "binary wheel" includes its own copy of libgphoto2. The gphoto2_version.py example will show you what version of libgphoto2 is being used by python-gphoto2.

jim-easterbrook commented 2 years ago

I've just tried the camera-summary.py example with my Canon 100D and I'm getting the same undefined symbol error (using python-gphoto2 2.3.1 and libgphoto2 2.5.28). Running ldd on python-gphoto2's copy of ptp2.so doesn't show anything unusual.

I'll investigate further tomorrow.

eechhx commented 2 years ago

If you install with --only-binary :all: the separately installed version of libgphoto2 (and gphoto2) is irrelevant. The "binary wheel" includes its own copy of libgphoto2. The gphoto2_version.py example will show you what version of libgphoto2 is being used by python-gphoto2.

Ah, that makes sense. Thank you for the clarification.

gphoto2_version.py for the --only-binary variant of 2.3.0:

python: 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0]
libgphoto2: ['2.5.27', 'standard camlib set SKIPPING SOME (ax203 canon digigr8 dimagev directory docupen jl2005a jl2005c kodak_dc240 mars pentax ptp2 ricoh_g3 sierra sonix sq905 st2205 topfield tp6801 SKIPPING lumix)', 'gcc (C compiler used)', 'ltdl (for portable loading of camlibs)', 'EXIF (for special handling of EXIF files)']
libgphoto2_port: ['0.12.0', 'iolibs: disk ptpip serial usb usbdiskdirect usbscsi', 'gcc (C compiler used)', 'ltdl (for portable loading of iolibs)', 'EXIF (for vusb)', 'USB (libusb0, for USB cameras)', 'serial (for serial cameras)', 'no resmgr (serial port access and locking)', 'no ttylock (serial port locking)', 'no lockdev (serial port locking)']
python-gphoto2: 2.3.0

photo2_version.py for the --only-binary variant of 2.3.1:

python: 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0]
libgphoto2: ['2.5.28', 'standard camlib set SKIPPING SOME (ax203 canon digigr8 dimagev directory docupen jl2005a jl2005c kodak_dc240 mars pentax ptp2 ricoh_g3 sierra sonix sq905 st2205 topfield tp6801 SKIPPING lumix)', 'gcc (C compiler used)', 'no ltdl (for portable loading of camlibs)', 'EXIF (for special handling of EXIF files)']
libgphoto2_port: ['0.12.0', 'iolibs: disk ptpip serial usb usbdiskdirect usbscsi', 'gcc (C compiler used)', 'no ltdl (for portable loading of iolibs)', 'EXIF (for vusb)', 'USB (libusb0, for USB cameras)', 'serial (for serial cameras)', 'no resmgr (serial port access and locking)', 'no ttylock (serial port locking)', 'no lockdev (serial port locking)']
python-gphoto2: 2.3.1

Reinstalling non --only-binary variant of python-gphoto2 2.3.1 with pip:

➜  examples git:(master) ✗ python3 -m pip cache purge
Files removed: 475
➜  examples git:(master) ✗ sudo pip3 uninstall gphoto2
Found existing installation: gphoto2 2.3.1
Uninstalling gphoto2-2.3.1:
  Would remove:
    /usr/local/lib/python3.8/dist-packages/gphoto2-2.3.1.dist-info/*
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libXpm-99013f46.so.4.11.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libexif-8d1b563f.so.12.3.3
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libfontconfig-63352676.so.1.4.4
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libfreetype-20bfc0cd.so.6.3.22
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libgd-dd257cdd.so.2.0.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libgphoto2-dc66b31d.so.6.2.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libgphoto2_port-298e2eb7.so.12.0.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libjpeg-7feae879.so.62.0.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libltdl-f7aa2269.so.7.3.1
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libpng12-640ca796.so.0.49.0
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libusb-0-c68a7334.1.so.4.4.4
    /usr/local/lib/python3.8/dist-packages/gphoto2.libs/libz-eb09ad1d.so.1.2.3
    /usr/local/lib/python3.8/dist-packages/gphoto2/*
Proceed (y/n)? y
  Successfully uninstalled gphoto2-2.3.1
➜  examples git:(master) ✗ sudo pip3 install gphoto2 --no-cache-dir
Collecting gphoto2
  Downloading gphoto2-2.3.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (4.9 MB)
     |████████████████████████████████| 4.9 MB 5.1 MB/s 
Installing collected packages: gphoto2
Successfully installed gphoto2-2.3.1
➜  examples git:(master) ✗ python3 camera-summary.py 
WARNING: gphoto2: (gp_port_usb_close [libusb.c:309]) Invalid parameters: 'port && port->pl->dh' is NULL/FALSE.
python3: symbol lookup error: /usr/local/lib/python3.8/dist-packages/gphoto2/camlibs/ptp2.so: undefined symbol: static_assert

Not sure why I'm getting a WARNING: gphoto2: (gp_port_usb_close [libusb.c:309]) Invalid parameters: 'port && port->pl->dh' is NULL/FALSE.. Running gphoto2 --summary outputs summary successfully without the libusb warning..

Downgrading back to non --only-binary variant of python-gphoto2 2.3.0 with pip also gives the libusb warning, but with a successful output that matches gphoto2 --summary (and again, without the libusb warning):

➜  examples git:(master) ✗ sudo pip3 install gphoto2==2.3.0 --no-cache-dir
Collecting gphoto2==2.3.0
  Downloading gphoto2-2.3.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl (4.9 MB)
     |████████████████████████████████| 4.9 MB 5.1 MB/s 
Installing collected packages: gphoto2
Successfully installed gphoto2-2.3.0
➜  examples git:(master) ✗ python3 camera-summary.py 
WARNING: gphoto2: (gp_port_usb_close [libusb.c:325]) Invalid parameters: 'port && port->pl->dh' is NULL/FALSE.
Summary
=======
Manufacturer: Sony Corporation
Model: ILCE-6500

... 

Also not sure if I'm not installing python-gphoto2 properly, but after downgrading to 2.3.0 without the --only-binary flag, the versions of libgphoto2 doesn't match, so might be an error on my part, not too sure.

➜  examples git:(master) ✗ python3 gphoto2_version.py 
python: 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0]
libgphoto2: ['2.5.27', 'standard camlib set SKIPPING SOME (ax203 canon digigr8 dimagev directory docupen jl2005a jl2005c kodak_dc240 mars pentax ptp2 ricoh_g3 sierra sonix sq905 st2205 topfield tp6801 SKIPPING lumix)', 'gcc (C compiler used)', 'ltdl (for portable loading of camlibs)', 'EXIF (for special handling of EXIF files)']
libgphoto2_port: ['0.12.0', 'iolibs: disk ptpip serial usb usbdiskdirect usbscsi', 'gcc (C compiler used)', 'ltdl (for portable loading of iolibs)', 'EXIF (for vusb)', 'USB (libusb0, for USB cameras)', 'serial (for serial cameras)', 'no resmgr (serial port access and locking)', 'no ttylock (serial port locking)', 'no lockdev (serial port locking)']
python-gphoto2: 2.3.0
➜  examples git:(master) ✗ gphoto2 --version 
gphoto2 2.5.28

Copyright (c) 2000-2021 Marcus Meissner and others

gphoto2 comes with NO WARRANTY, to the extent permitted by law. You may
redistribute copies of gphoto2 under the terms of the GNU General Public
License. For more information about these matters, see the files named COPYING.

This version of gphoto2 is using the following software versions and options:
gphoto2         2.5.28         gcc, popt(m), exif, no cdk, no aa, jpeg, no readline
libgphoto2      2.5.28         standard camlibs (SKIPPING docupen), gcc, no ltdl, EXIF
libgphoto2_port 0.12.0         iolibs: disk ptpip serial usb1 usbdiskdirect usbscsi, gcc, no ltdl, EXIF, USB, serial without locking
jim-easterbrook commented 2 years ago

That last 'mismatch' is expected. The gphoto2 command is using the installed libgphoto2 version 2.5.28, the python-gphoto2 package is using its private copy of libgphoto2 which is version 2.5.27. The only significant difference between python-gphoto2 2.3.0 and 2.3.1 is the version of libgphoto2.

The port NULL/false message is probably nothing to worry about.

jim-easterbrook commented 2 years ago

I've found this in the GitHub Actions build log for the "manylinux" binary wheel:

In file included from ptp2/ptp.c:44:
  ptp2/ptp.c: In function ‘ptp_init_container’:
  ../libgphoto2_port/libgphoto2_port/compiletime-assert.h:40:2: warning: implicit declaration of function ‘static_assert’ [-Wimplicit-function-declaration]
    static_assert((CONDITION), #CONDITION)
    ^~~~~~~~~~~~~
  ptp2/ptp.c:78:2: note: in expansion of macro ‘COMPILETIME_ASSERT’
    COMPILETIME_ASSERT(INT_MAX >= UINT16_MAX);

This suggests the compiler doesn't know about the static_assert function. I think this is a difference between the C99 and C11 standards - I'm not sure which the manylinux build is supposed to use, or if I can force it to use the other. (The libgphoto2_port/compiletime-assert.h file defines a macro COMPILETIME_ASSERT that uses static_assert if it's being compiled with C11 or later.)

jim-easterbrook commented 2 years ago

And libgphoto2_port/compiletime-assert.h was added to libgphoto2 2 months ago, i.e. between 2.5.27 and 2.5.28.

jim-easterbrook commented 2 years ago

I've just uploaded release 2.3.2 to PyPI which I hope fixes the problem. It does for me, but every Linux system is different.

eechhx commented 2 years ago

I've just uploaded release 2.3.2 to PyPI which I hope fixes the problem. It does for me, but every Linux system is different.

Everything looks good on my end.

➜  examples git:(master) ✗ python3 gphoto2_version.py 
python: 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0]
libgphoto2: ['2.5.28', 'standard camlib set SKIPPING SOME (ax203 canon digigr8 dimagev directory docupen jl2005a jl2005c kodak_dc240 mars pentax ptp2 ricoh_g3 sierra sonix sq905 st2205 topfield tp6801 SKIPPING lumix)', 'gcc (C compiler used)', 'no ltdl (for portable loading of camlibs)', 'EXIF (for special handling of EXIF files)']
libgphoto2_port: ['0.12.0', 'iolibs: disk ptpip serial usb usbdiskdirect usbscsi', 'gcc (C compiler used)', 'no ltdl (for portable loading of iolibs)', 'EXIF (for vusb)', 'USB (libusb0, for USB cameras)', 'serial (for serial cameras)', 'no resmgr (serial port access and locking)', 'no ttylock (serial port locking)', 'no lockdev (serial port locking)']
python-gphoto2: 2.3.2

Thanks for the timely response and patch of the bug! I'll close the issue now. For posterity, my system setup is as follows: Ubuntu 20.04 LTS (x86_64); Python 3.8.10; pip 21.3.1.

jim-easterbrook commented 2 years ago

Thanks for reporting the bug. I really should have found it in my own testing.