m.css icon indicating copy to clipboard operation
m.css copied to clipboard

libgs cannot be found on python 3.8 alpine and slim images

Open rommeswi opened this issue 1 year ago • 11 comments

No matter whether I use python:3.8-slim or python:3.8-alpine, I keep running into issues with libgs not being found.

on slim:

CRITICAL RuntimeError: libgs found by linker magic,   __init__.py:683
                    but is not in /usr/lib or /usr/lib64

on alpine latex2svg simply complains that it cannot find libgs.

Surprisingly, in alpine it is actually installed in a standard directory /usr/lib but python3 -c "from ctypes.util import find_library; print(find_library('gs'))" returns None.

I am not sure how to proceed about this. Is this a configuration error? It seems using an alpine image for something like github/gitlab pages seems like something that should be working.

rommeswi avatar Dec 09 '24 09:12 rommeswi

Oh no, this is a source of constant pain. Can you help me debug it so I can add more workarounds and hints to the code?

  1. If you run dvisvgm --version on slim, what do you get? Where is libgs.so located on that system? Is there a file without a suffix or only for example libgs.so.10?

  2. What's the full path to libgs on alpine? Is it /usr/lib/libgs.so or again some suffix like /usr/lib/libgs.so.10?

  3. The find_library thing is, to me, unpenetrable dark magic relying on very-platform-specific hardcoded paths. It's possible that on alpine it just doesn't have enough paths hardcoded or something. The following patch could, I think, help?

diff --git a/plugins/latex2svg.py b/plugins/latex2svg.py
index c2919efd..085be7f7 100755
--- a/plugins/latex2svg.py
+++ b/plugins/latex2svg.py
@@ -71,8 +71,15 @@ if not hasattr(os.environ, 'LIBGS') and not libgs:
         homebrew_libgs = '/usr/local/opt/ghostscript/lib/libgs.dylib'
         if os.path.exists(homebrew_libgs):
             default_params['libgs'] = homebrew_libgs
+    if sys.platform == 'linux':
+        # On Alpine Linux, find_library() may not work even though the library
+        # is in usual paths. Try some candidates before failing hard.
+        for linux_libgs in ['/usr/lib/libgs.so', '/usr/lib/libgs.so.10']:
+            if os.path.exists(linux_libgs):
+                default_params['libgs'] = linux_libgs
+                break
     if not default_params['libgs']:

  1. In any case, the path can be supplied via the LIBGS env var, so for example export LIBGS=/usr/lib/libgs.so. I'm going to update the messages to suggest this as a workaround.

Thanks in advance!

mosra avatar Dec 10 '24 10:12 mosra

On the Alpine image:

$ find / -name "libgs*"
/usr/lib/libgssrpc.so.4
/usr/lib/libgssrpc.so.4.2
/usr/lib/libgssapi_krb5.so.2.2
/usr/lib/libgssapi_krb5.so.2

On the slim image:

$ find / -name "libgs*"
/usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2.2
/usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2
/usr/share/doc/libgssapi-krb5-2
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.postinst
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.md5sums
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.shlibs
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.triggers
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.postrm
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.symbols
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.list

rommeswi avatar Dec 12 '24 04:12 rommeswi

Hm, neither of them is really GhostScript tho :) So the error was, in fact, correct.

It's usually a part of a LaTeX installation, i.e. unlikely to be present in the image by default. Here's the package in Alpine and here in Debian.

If you install it explicitly, I think it could maybe work even without the patch above. Let me know if the patch is ultimately needed or not -- thanks!

mosra avatar Dec 12 '24 07:12 mosra

Now after proper installation on the slim image the following are installed:

/usr/lib/x86_64-linux-gnu/libgs.so.10
/usr/lib/x86_64-linux-gnu/libgs.so.10.00
/usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2.2
/usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2
/usr/share/doc/libgs10-common
/usr/share/doc/libgs10
/usr/share/doc/libgs-common
/usr/share/doc/libgssapi-krb5-2
/var/lib/dpkg/info/libgs-common.md5sums
/var/lib/dpkg/info/libgs10:amd64.symbols
/var/lib/dpkg/info/libgs10:amd64.md5sums
/var/lib/dpkg/info/libgs10:amd64.triggers
/var/lib/dpkg/info/libgs-common.list
/var/lib/dpkg/info/libgs10-common.list
/var/lib/dpkg/info/libgs10-common.md5sums
/var/lib/dpkg/info/libgs10:amd64.shlibs
/var/lib/dpkg/info/libgs10:amd64.list
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.postinst
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.md5sums
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.shlibs
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.triggers
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.postrm
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.symbols
/var/lib/dpkg/info/libgssapi-krb5-2:amd64.list

It still fails. Rather annoying that the python slim image puts everything in a weird folder.

rommeswi avatar Dec 16 '24 09:12 rommeswi

For alpine:

$ find / -name "libgs*"
/usr/lib/libgs.so.10
/usr/lib/libgs.so.10.04
/usr/lib/libgssrpc.so.4
/usr/lib/libgssrpc.so.4.2
/usr/lib/libgssapi_krb5.so.2.2
/usr/lib/libgssapi_krb5.so.2

Here it is properly installed in /usr/lib but I still get an error "Warning: libgs not found" while loading m.math

rommeswi avatar Dec 16 '24 09:12 rommeswi

Great, can you try with the above patch now?

mosra avatar Dec 16 '24 10:12 mosra

Sorry, missed your other message above. Yeah, the weird /usr/lib/ subdirectory Debian-based distros use is only making things more complicated for some abstract reason.

This is I think what could cover both cases:

diff --git a/plugins/latex2svg.py b/plugins/latex2svg.py
index c2919efd..085be7f7 100755
--- a/plugins/latex2svg.py
+++ b/plugins/latex2svg.py
@@ -71,8 +71,15 @@ if not hasattr(os.environ, 'LIBGS') and not libgs:
         homebrew_libgs = '/usr/local/opt/ghostscript/lib/libgs.dylib'
         if os.path.exists(homebrew_libgs):
             default_params['libgs'] = homebrew_libgs
+    if sys.platform == 'linux':
+        # On certain Linux distros find_library() may not work even though the
+        # library is in usual paths. Try some candidates before failing hard.
+        for linux_libgs in [
+            '/usr/lib/libgs.so.10',
+            '/usr/lib/{}-linux-gnu/libgs.so.10'.format(os.uname().machine)
+        ]:
+            if os.path.exists(linux_libgs):
+                default_params['libgs'] = linux_libgs
+                break
     if not default_params['libgs']:

Let me know if this finally makes it stop complaining. Thank you! :)

mosra avatar Dec 17 '24 11:12 mosra

Thanks!

rommeswi avatar Jan 07 '25 02:01 rommeswi

So, just to avoid confusion .. the above patch worked for you? In case it did, I'll commit it.

mosra avatar Jan 07 '25 11:01 mosra

The fix in https://github.com/mosra/m.css/issues/260#issuecomment-2548182506 worked for me when I started getting errors finding GhostScript on the latest GitHub Actions Ubuntu runners.

SRGDamia1 avatar Mar 04 '25 15:03 SRGDamia1

Yes, it worked for me. Sorry for the late reply!

rommeswi avatar Mar 31 '25 08:03 rommeswi