libvips / pyvips

python binding for libvips using cffi
MIT License
629 stars 49 forks source link

Cannot locate libvips.so.42, now on Red Hat Linux 9 (or RHEL 9) #356

Open nakigoe opened 1 year ago

nakigoe commented 1 year ago

I'm using the following set of instructions to install all the dependencies for Red Hat Linux 9 (or RHEL 9):

-------------------------------------- Install PyVips ----------------------------------------
$ su root
# dnf install python-requests
# dnf install python-pip
# dnf install python-wheel
# subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms
# exit

$ pip install pyvips

----------------------------------------- Install LibVips -------------------------------------
$ su root

# subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
# dnf upgrade
# dnf install snapd
# systemctl enable --now snapd.socket
# ln -s /var/lib/snapd/snap /snap

logout/reboot RHEL9

$ su root
# snap wait system seed.loaded
# snap install libvips

--------------------------------- Run the wind.py app -------------------------------
Go to the app folder first, then

$ python wind.py

My Python app runs perfectly under Windows: https://github.com/nakigoe/sea/tree/main/graph_wind_create But under RHEL 9 (Red Hat Linux 9) an infamous error pops up: Cannot locate libvips.so.42

jcupitt commented 1 year ago

Hi @nakigoe,

I would install libvips-devel. pyvips setup.py can generate and compile a binding to your libvips binary at install time, and it needs the libvips headers to do this. It'll still work if it can't find the headers, but it'll fall back to ABI mode where it generates the calls into libvips at runtime. This is noticably slower.

I'd verify that you have the libvips library in the usual place, and that it's called libvips.so.42.

You can also enable logging to get some insight into what's going wrong at runtime. Try:

#!/usr/bin/python3

import logging
logging.basicConfig(level=logging.DEBUG)
import sys

import pyvips

print('test Image')
image = pyvips.Image.new_from_file(sys.argv[1])
print('image =', image)
print('image.width =', image.width)
print('\n''')

I see:

$ ./try1.py ~/pics/k2.jpg
DEBUG:pyvips:Loaded binary module _libvips
DEBUG:pyvips:Module generated for libvips 8.14
DEBUG:pyvips:Linked to libvips 8.14
DEBUG:pyvips:Inited libvips
test Image
DEBUG:pyvips.voperation:VipsOperation.call: operation_name = VipsForeignLoadJpegFile
DEBUG:pyvips.voperation:VipsOperation.call: match_image = None
DEBUG:pyvips.vobject:VipsObject.set: name = filename, value = /home/john/pics/k2.jpg
...
nakigoe commented 1 year ago

@jcupitt, Thank you for the fast reply! You must be very busy there in London (It is my dream to move there). Thank you for your time!

With the list of instructions from the official website https://snapcraft.io/install/libvips/rhel Libvips is installed here: /var/lib/snapd/snap/libvips/11/libvips/libvips/.libs/libvips.so.42 I located it via standard FILE SEARCH

The python test code you've kindly provided produced this output:

DEBUG:pyvips:Binary module load failed: No module named '_libvips'
DEBUG:pyvips:Falling back to ABI mode
Traceback (most recent call last):
  File "/home/nakigoe/.local/lib/python3.9/site-packages/pyvips/__init__.py", line 19, in <module>
    import _libvips
ModuleNotFoundError: No module named '_libvips'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/nakigoe/Downloads/test.py", line 5, in <module>
    import pyvips
  File "/home/nakigoe/.local/lib/python3.9/site-packages/pyvips/__init__.py", line 71, in <module>
    vips_lib = ffi.dlopen(_vips_libname)
  File "/usr/local/lib64/python3.9/site-packages/cffi/api.py", line 150, in dlopen
    lib, function_cache = _make_ffi_library(self, name, flags)
  File "/usr/local/lib64/python3.9/site-packages/cffi/api.py", line 832, in _make_ffi_library
    backendlib = _load_backend_lib(backend, libname, flags)
  File "/usr/local/lib64/python3.9/site-packages/cffi/api.py", line 827, in _load_backend_lib
    raise OSError(msg)
OSError: cannot load library 'libvips.so.42': libvips.so.42: cannot open shared object file: No such file or directory.  Additionally, ctypes.util.find_library() did not manage to locate a library called 'libvips.so.42'
jcupitt commented 1 year ago

I don't think it'll work easily as a snap. That's a sandbox install and only for the use of other sandbox applications. You'll have difficulty using it from regular python.

Unfortunately I can't help directly since rhel is not free and I don't have a copy. I used to use centos to help people out, but that has mostly vanished too, sadly.

I would use remi collet's RPM repo:

https://rpms.remirepo.net/

Add that to your system and you ought to be able to yum install libvips-devel (or maybe use dnf?).

Another alternative would be to switch to something like Ubuntu or Debian. They are free, and they have libvips built in.

jcupitt commented 1 year ago

(and yes London is crazy right now, our government is ... struggling)

nakigoe commented 1 year ago

Why, RHEL 9 is absolutely free for developers! I've installed it just yesterday inside VitualBox from the official Red Hat Linux website: https://developers.redhat.com/products/rhel/download

I have to demonstrate my app will work under Red Hat Enterprise Linux 9 x86_64

jcupitt commented 1 year ago

I tried in docker:

 docker run --rm -it redhat/ubi9
Unable to find image 'redhat/ubi9:latest' locally
latest: Pulling from redhat/ubi9
6e93aa5bb632: Pull complete 
deeb168f5044: Pull complete 
Digest: sha256:a5c120f83beb00653c544c7b1d240140a3bf47705be50cb1cfb86a4dd587c2f2
Status: Downloaded newer image for redhat/ubi9:latest
[root@1f7836447644 /]# yum update -y
Updating Subscription Management repositories.
Unable to read consumer identity
Subscription Manager is operating in container mode.

This system is not registered with an entitlement server. You can use subscription-manager to register.
...

You have to register to use it, so I can't script it.

nakigoe commented 1 year ago

enter an email and an alias on the official website to register, that's it.

After installation enter the alias and the password There is an option to register somewhere during and after install, you must be registered at the official website first. RHEL 9 is absolutely free for developers. https://developers.redhat.com/products/rhel/download

kleisauke commented 1 year ago

Here are some instructions to install libvips on RHEL 9 (and its derivatives) via Remi's RPM repository.

# Install the EPEL repository configuration package
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

# Enable the CodeReady Builder repository since EPEL packages may depend on packages from it
crb enable
# or:
# subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms

# Install the Remi repository configuration package
dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm

# Enable Remi's RPM repository
dnf config-manager --set-enabled remi

# Install libvips (+ development files and command-line tools)
dnf install vips vips-devel vips-tools
Optional modules ```shell ## Install optional modules ## See: https://github.com/remicollet/remirepo/issues/171 # HEIC / AVIF support via libheif dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-9.noarch.rpm dnf install vips-heif # JPEG-XL support via libjxl dnf install vips-jxl # *Magick support via GraphicsMagick dnf install vips-magick-gm # *Magick support via ImageMagick 6 dnf install vips-magick-im6 # *Magick support via ImageMagick 7 dnf install vips-magick-im7 # OpenSlide support dnf install vips-openslide # PDF load support via Poppler dnf install vips-poppler ```

See https://github.com/libvips/libvips/issues/1184#issuecomment-447973135 for reasons why libvips isn't included in EPEL. Personally, I would use AlmaLinux or Rocky Linux because I don't like subscription-managed distributions.

nakigoe commented 1 year ago

My app is finally working on Red Hat Enterprise Linux 9 !!!

The list of instructions I'm using now to install Libvips into VirtualBox with RHEL 9:

-------------------------------------- Setup Python ----------------------------------------
$ su root
# dnf install python-requests
# dnf install python-pip
# dnf install python-wheel

-------------------------------------- Install Libvips ----------------------------------------
# subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms
# subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
# dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
# dnf config-manager --set-enabled remi
# dnf install vips vips-devel vips-tools
# dnf upgrade
jcupitt commented 1 year ago

After installation enter the alias and the password There is an option to register somewhere during and after install, you must be registered at the official website first.

Right, but that means I can't make a dockerfile that automates the process and can be run anonymously, so I can't use it.

jcupitt commented 1 year ago

DEBUG:pyvips:Binary module load failed: No module named '_libvips' DEBUG:pyvips:Falling back to ABI mode

This probably means that the libvips headers were not available when setup.py was run. I would check your install and make sure the libvips headers are available. Try:

$ pkg-config vips --modversion
8.13.2

And verify that it prints the correct version number for your libvips install.

Traceback (most recent call last): File "/home/nakigoe/Downloads/test.py", line 8, in image = pyvips.Image.new_from_file(sys.argv[1]) IndexError: list index out of range

You need to supply the path to a sample file as an argument, eg.:

$ ./try1.py ~/pics/k2.jpg
nakigoe commented 1 year ago

@jcupitt, thank You for Your patience (invite me to UK!) Confirmed:

$ pkg-config vips --modversion
8.13.2

Python output:

DEBUG:pyvips:Binary module load failed: No module named '_libvips'
DEBUG:pyvips:Falling back to ABI mode
DEBUG:pyvips:Loaded lib <cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x7f57d73f2790>
DEBUG:pyvips:Loaded lib <cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x7f57d73f25b0>
DEBUG:pyvips:Inited libvips
test Image
DEBUG:pyvips.voperation:VipsOperation.call: operation_name = VipsForeignLoadJpegFile
DEBUG:pyvips.voperation:VipsOperation.call: match_image = None
DEBUG:pyvips.vobject:VipsObject.set: name = filename, value = k2.jpg
DEBUG:pyvips.vobject:VipsObject.get: name = out
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.vobject:VipsObject.get: name = width
DEBUG:pyvips.vobject:VipsObject.get: name = height
DEBUG:pyvips.vobject:VipsObject.get: name = format
DEBUG:pyvips.vobject:VipsObject.get: name = bands
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.voperation:VipsOperation.call: result = <pyvips.Image 3008x2000 uchar, 3 bands, srgb>
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.vobject:VipsObject.get: name = width
DEBUG:pyvips.vobject:VipsObject.get: name = height
DEBUG:pyvips.vobject:VipsObject.get: name = format
DEBUG:pyvips.vobject:VipsObject.get: name = bands
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
image = <pyvips.Image 3008x2000 uchar, 3 bands, srgb>
DEBUG:pyvips.vobject:VipsObject.get: name = width
image.width = 3008
jcupitt commented 1 year ago

DEBUG:pyvips:Binary module load failed: No module named '_libvips' DEBUG:pyvips:Falling back to ABI mode

That's better, but you're still in ABI mode. Try uninstalling and reinstalling pyvips, without using the wheel from last time.

I see:

$ pip3 uninstall pyvips
Found existing installation: pyvips 2.2.1
Uninstalling pyvips-2.2.1:
  Would remove:
    /home/john/.local/lib/python3.10/site-packages/pyvips.egg-link
Proceed (Y/n)? y
  Successfully uninstalled pyvips-2.2.1
$ pip3 install --no-cache-dir pyvips
Defaulting to user installation because normal site-packages is not writeable
Collecting pyvips
  Downloading pyvips-2.2.1.tar.gz (633 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 633.6/633.6 KB 5.4 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Requirement already satisfied: cffi>=1.0.0 in /home/john/.local/lib/python3.10/site-packages (from pyvips) (1.15.0)
Requirement already satisfied: pkgconfig in /home/john/.local/lib/python3.10/site-packages (from pyvips) (1.5.5)
Requirement already satisfied: pycparser in /home/john/.local/lib/python3.10/site-packages (from cffi>=1.0.0->pyvips) (2.21)
Building wheels for collected packages: pyvips
  Building wheel for pyvips (setup.py) ... done
  Created wheel for pyvips: filename=pyvips-2.2.1-cp310-cp310-linux_x86_64.whl size=153389 sha256=4e95837f392a040b1ce3edadbd251ec4ef6add6fbab2885e60601785b66aad39
  Stored in directory: /tmp/pip-ephem-wheel-cache-4k7e9r9f/wheels/53/a1/9e/895a8ca1f7881a879a8841047d32250e03f3ec7444539c7ce3
Successfully built pyvips
Installing collected packages: pyvips
Successfully installed pyvips-2.2.1
nakigoe commented 1 year ago

• Removing pyvips both from the normal user $ pip uninstall pyvips and the root user # pip uninstall pyvips • manually clearing the pip cache by finding it with pip cache dir • installing pyvips from the usual user $ pip install pyvips solved the issue. The output of $ python test.py k2.jpg:

DEBUG:pyvips:Loaded binary module _libvips
DEBUG:pyvips:Module generated for libvips 8.13
DEBUG:pyvips:Linked to libvips 8.13
DEBUG:pyvips:Inited libvips
test Image
DEBUG:pyvips.voperation:VipsOperation.call: operation_name = VipsForeignLoadJpegFile
DEBUG:pyvips.voperation:VipsOperation.call: match_image = None
DEBUG:pyvips.vobject:VipsObject.set: name = filename, value = k2.jpg
DEBUG:pyvips.vobject:VipsObject.get: name = out
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.vobject:VipsObject.get: name = width
DEBUG:pyvips.vobject:VipsObject.get: name = height
DEBUG:pyvips.vobject:VipsObject.get: name = format
DEBUG:pyvips.vobject:VipsObject.get: name = bands
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.voperation:VipsOperation.call: result = <pyvips.Image 3008x2000 uchar, 3 bands, srgb>
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
DEBUG:pyvips.vobject:VipsObject.get: name = width
DEBUG:pyvips.vobject:VipsObject.get: name = height
DEBUG:pyvips.vobject:VipsObject.get: name = format
DEBUG:pyvips.vobject:VipsObject.get: name = bands
DEBUG:pyvips.vobject:VipsObject.get: name = interpretation
image = <pyvips.Image 3008x2000 uchar, 3 bands, srgb>
DEBUG:pyvips.vobject:VipsObject.get: name = width
image.width = 3008

A huge thank you to @jcupitt and @kleisauke for the fast-paced help and patience!!!

akostadinov commented 4 months ago

FYI to build a docker image that requires a subscription, you can register the host machine using subscription-manager and then starting a build with podman or buildah should insert that subscription automatically. I expect this to only work with RHEL and Fedora host machines. If you use another distro, I guess a virtual machine will be the easiest workaround.

Also a good alternative is to use CentOS streams base image. It will not require bothering with subscriptions. It is supposed to ride just slightly ahead of RHEL, basically RHEL with a few patches that are expected to be included in upcoming updates.

While on it, you could request including libvips into RHEL on bugzilla.redhat.com so that external repos are not needed. I'd vote to such an issue.