libgs cannot be found on python 3.8 alpine and slim images
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.
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?
-
If you run
dvisvgm --versiononslim, what do you get? Where islibgs.solocated on that system? Is there a file without a suffix or only for examplelibgs.so.10? -
What's the full path to
libgsonalpine? Is it/usr/lib/libgs.soor again some suffix like/usr/lib/libgs.so.10? -
The
find_librarything is, to me, unpenetrable dark magic relying on very-platform-specific hardcoded paths. It's possible that onalpineit 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']:
- In any case, the path can be supplied via the
LIBGSenv var, so for exampleexport LIBGS=/usr/lib/libgs.so. I'm going to update the messages to suggest this as a workaround.
Thanks in advance!
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
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!
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.
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
Great, can you try with the above patch now?
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! :)
Thanks!
So, just to avoid confusion .. the above patch worked for you? In case it did, I'll commit it.
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.
Yes, it worked for me. Sorry for the late reply!