alexmurray / emacs-snap

GNU Emacs in a snap
https://snapcraft.io/emacs
74 stars 13 forks source link

`GLIBC_2.33` errors when installing `jinx` module #71

Open michaelmhoffman opened 1 year ago

michaelmhoffman commented 1 year ago

I tried to install the jinx module for Emacs, snap r2249, on Ubuntu 22.04.3 LTS. I have the libenchant2-2 and libenchant-2-dev apt packages installed, both version 2.3.2-1ubuntu2.

I started emacs -q and then executed the following form, adapting from the instructions from #66:

(let* ((emacs-snap-dir (file-name-as-directory (getenv "EMACS_SNAP_DIR")))
       (process-environment (append process-environment `(,(concat "CC=" emacs-snap-dir "usr/bin/gcc-10" )
                                                          ,(concat "CXX=" emacs-snap-dir "usr/bin/g++-10")
                                                          ,(concat "CFLAGS=--sysroot=" emacs-snap-dir)
                              ,(concat "CPPFLAGS=--sysroot=" emacs-snap-dir)
                              ,(concat "LDFLAGS=--sysroot=" emacs-snap-dir " -L" emacs-snap-dir "/usr/lib")))))

  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'jinx)
  (require 'jinx)
  (global-jinx-mode))

I get the following backtrace:

Debugger entered--Lisp error: (module-open-failed "/home/mhoffman/.emacs.d/elpa/jinx-20231001.2308/jinx-mod.so" "/snap/emacs/2249/usr/bin/../../lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libenchant-2.so.2)")
  module-load("/home/mhoffman/.emacs.d/elpa/jinx-20231001.2308/jinx-mod.so")
  jinx--load-module()
  jinx-mode(1)
  jinx--on()
  global-jinx-mode()
  (let* ((emacs-snap-dir (file-name-as-directory (getenv "EMACS_SNAP_DIR"))) (process-environment (append process-environment (list (concat "CC=" emacs-snap-dir "usr/bin/gcc-10") (concat "CXX=" emacs-snap-dir "usr/bin/g++-10") (concat "CFLAGS=--sysroot=" emacs-snap-dir) (concat "CPPFLAGS=--sysroot=" emacs-snap-dir) (concat "LDFLAGS=--sysroot=" emacs-snap-dir " -L" emacs-snap-dir "/usr/lib"))))) (require 'package) (if (member '("melpa" . "https://melpa.org/packages/") package-archives) package-archives (setq package-archives (cons '("melpa" . "https://melpa.org/packages/") package-archives))) (package-refresh-contents) (package-install 'jinx) (require 'jinx) (global-jinx-mode))
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  command-execute(eval-last-sexp)

I assume this is because the system /lib/x86_64-linux-gnu/libenchant-2.so.2 is not compatible with the version of glibc in the snap.

Do you have any suggestions on how to work around this?

michaelmhoffman commented 1 year ago

Further investigation shows that function jinx--load-module compiles the dynamic module, assembling its command from pkg-config --cflags --libs enchant-2. On my system this leads to a compilation command of

gcc -I. -O2 -Wall -Wextra -fPIC -shared -o jinx-mod.so jinx-mod.c -pthread -I/usr/include/enchant-2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lenchant-2

Manually changing to

/snap/emacs/2249/usr/bin/gcc-10 -I. -O2 -Wall -Wextra -fPIC -shared -o jinx-mod.so jinx-mod.c --sysroot=/snap/emacs/2249 -pthread -I/usr/include/enchant-2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lenchant-2

leads to

/usr/bin/ld: cannot find -lenchant-2: No such file or directory
collect2: error: ld returned 1 exit status

Not including the --sysroot results in successful compilation but the GLIBC error. It should be equivalent to the original compilation form, so that's not a surprise.

alexmurray commented 1 year ago

Hmmmm I think the only option here would be to ship enchant within the emacs snap (if we don't already) and ensure this gets used when compiling and running the module. I'm currently on leave for a couple weeks so won't get time to look at this properly until I get back but will keep an eye on this issue in the meantime.

michaelmhoffman commented 1 year ago

Looks like you ship the shared object but not the corresponding .a file.

Enjoy your leave!

alexmurray commented 1 year ago

So I just had another look at this - I don't think ubuntu provides any libenchant-2.a (although as you say it does provide the .so):

[amurray:~] 1 $ apt-file search libenchant-2.so
libenchant-2-2: /usr/lib/x86_64-linux-gnu/libenchant-2.so.2
libenchant-2-2: /usr/lib/x86_64-linux-gnu/libenchant-2.so.2.3.3
libenchant-2-dev: /usr/lib/x86_64-linux-gnu/libenchant-2.so
[amurray:~] $ apt-file list libenchant-2-2
libenchant-2-2: /usr/lib/x86_64-linux-gnu/enchant-2/enchant_aspell.so
libenchant-2-2: /usr/lib/x86_64-linux-gnu/enchant-2/enchant_hspell.so
libenchant-2-2: /usr/lib/x86_64-linux-gnu/enchant-2/enchant_hunspell.so
libenchant-2-2: /usr/lib/x86_64-linux-gnu/libenchant-2.so.2
libenchant-2-2: /usr/lib/x86_64-linux-gnu/libenchant-2.so.2.3.3
libenchant-2-2: /usr/share/doc/libenchant-2-2/README
libenchant-2-2: /usr/share/doc/libenchant-2-2/changelog.Debian.gz
libenchant-2-2: /usr/share/doc/libenchant-2-2/copyright
libenchant-2-2: /usr/share/enchant-2/enchant.ordering
[amurray:~] $ apt-file list libenchant-2-dev
libenchant-2-dev: /usr/include/enchant-2/enchant++.h
libenchant-2-dev: /usr/include/enchant-2/enchant-provider.h
libenchant-2-dev: /usr/include/enchant-2/enchant.h
libenchant-2-dev: /usr/lib/x86_64-linux-gnu/libenchant-2.so
libenchant-2-dev: /usr/lib/x86_64-linux-gnu/pkgconfig/enchant-2.pc
libenchant-2-dev: /usr/share/doc/libenchant-2-dev/HACKING
libenchant-2-dev: /usr/share/doc/libenchant-2-dev/NEWS.gz
libenchant-2-dev: /usr/share/doc/libenchant-2-dev/README
libenchant-2-dev: /usr/share/doc/libenchant-2-dev/changelog.Debian.gz
libenchant-2-dev: /usr/share/doc/libenchant-2-dev/copyright

So I am not sure this can easily be solved - would the .so be sufficient?

connormclaud commented 8 months ago

same for me: Emacs -Q

  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'jinx)
  (require 'jinx)
  (global-jinx-mode))
Package ‘jinx’ installed.
Jinx: jinx-mod.so compiled successfully
jinx--load-module: Module could not be opened: "/home/connormclaud/.emacs.d/elpa/jinx-20240305.1632/jinx-mod.so", "/snap/emacs/2418/usr/bin/../../lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /lib/x86_64-linux-gnu/libenchant-2.so.2)"
$ find /snap/emacs/current/ -name "*libc*.so"
/snap/emacs/current/lib/x86_64-linux-gnu/libc-2.31.so
alexmurray commented 8 months ago

I've added a couple changes which hopefully will allow jinx to be compiled - however I haven't had a chance to finish testing it completely, but once new builds land in beta in a couple hours, with any luck you may be able to get it to compile via:

(let* ((emacs-snap-dir (file-name-as-directory (getenv "EMACS_SNAP_DIR")))
       (process-environment (append process-environment `(,(concat "CC=" emacs-snap-dir "usr/bin/gcc-10" )
                                                          ,(concat "CXX=" emacs-snap-dir "usr/bin/g++-10")
                                                          ,(concat "CFLAGS=--sysroot=" emacs-snap-dir)
                              ,(concat "CPPFLAGS=--sysroot=" emacs-snap-dir)
                              ,(concat "LDFLAGS=--sysroot=" emacs-snap-dir " -L" emacs-snap-dir "/usr/lib")
                                                          ,(concat "PKG_CONFIG_PATH=" emacs-snap-dir (car (file-expand-wildcards "/usr/lib/*/pkgconfig")))))))

  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'jinx)
  (require 'jinx)
  (global-jinx-mode))
connormclaud commented 8 months ago
/snap/emacs/2421/usr/bin/gcc-10 -I. -O2 -Wall -Wextra -fPIC -shared -o jinx-mod.so jinx-mod.c -I/usr/include/enchant-2 -lenchant-2
jinx-mod.c:19:10: fatal error: enchant.h: No such file or directory
   19 | #include <enchant.h>
      |          ^~~~~~~~~~~
compilation terminated.
Jinx: Compilation of jinx-mod.so failed

For some reason absolute path is passed to GCC and providing headers with snap don't help:

find /snap/emacs/current/ -name "*enchant.h"
/snap/emacs/current/usr/include/enchant-2/enchant.h
connormclaud commented 8 months ago

It looks like after installing system wide header it compiled and loaded. It couldn't find dictionaries but probably it is unrelated to this issue.

alexmurray commented 8 months ago

Apologies, I realise there was an error in the example code above - I just corrected it and was also able to reproduce the failure:

/snap/emacs/2421/usr/bin/gcc-10 -I. -O2 -Wall -Wextra -fPIC -shared -o jinx-mod.so jinx-mod.c -I/build/emacs/stage/usr/include/enchant-2 -I/build/emacs/stage/usr/include/glib-2.0 -I/build/emacs/stage/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/build/emacs/stage/usr/include -pthread -L/build/emacs/stage/usr/lib/x86_64-linux-gnu -lenchant-2
jinx-mod.c:19:10: fatal error: enchant.h: No such file or directory
   19 | #include <enchant.h>
      |          ^~~~~~~~~~~
compilation terminated.
Jinx: Compilation of jinx-mod.so failed

I think I know what the issue is - let me see if I can fix it...

alexmurray commented 8 months ago

With the additional fix (in ...) we get a bit closer but it still fails to compile:

/snap/emacs/2430/usr/bin/gcc-10 -I. -O2 -Wall -Wextra -fPIC -shared -o jinx-mod.so jinx-mod.c -I/snap/emacs/current/usr/include/enchant-2 -I/snap/emacs/current/usr/include/glib-2.0 -I/snap/emacs/current/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/snap/emacs/current/usr/include -pthread -L/snap/emacs/current/usr/lib/x86_64-linux-gnu -lenchant-2
In file included from jinx-mod.c:20:
/snap/emacs/current/usr/include/stdio.h:781:10: fatal error: bits/sys_errlist.h: No such file or directory
  781 | #include <bits/sys_errlist.h>
      |          ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
Jinx: Compilation of jinx-mod.so failed

But we can work around this by setting CPATH in the environment as follows:

(let* ((emacs-snap-dir (file-name-as-directory (getenv "EMACS_SNAP_DIR")))
       (process-environment (append `(,(concat "CC=" emacs-snap-dir "usr/bin/gcc-10" )
                                      ,(concat "CXX=" emacs-snap-dir "usr/bin/g++-10")
                                      ,(concat "CFLAGS=--sysroot=" emacs-snap-dir " -B" emacs-snap-dir "usr/lib/gcc")
                                      ,(concat "CPATH=" (file-name-directory (car (file-expand-wildcards (concat emacs-snap-dir "usr/include/*/bits")))))
                      ,(concat "CPPFLAGS=--sysroot=" emacs-snap-dir)
                      ,(concat "LDFLAGS=--sysroot=" emacs-snap-dir " -L" emacs-snap-dir "usr/lib")
                                      ,(concat "PKG_CONFIG_PATH=" (car (file-expand-wildcards (concat emacs-snap-dir "usr/lib/*/pkgconfig")))))
                                    process-environment)))
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'jinx)
  (require 'jinx)
  (global-jinx-mode))

With the above snippet I can get jinx to compile and install correctly for the emacs snap which is currently in the stable channel (r2430 on amd64).

You can test by removing any existing module and using the above for to reinstall it: rm .emacs.d/elpa/jinx-1.4/jinx-mod.so

connormclaud commented 8 months ago

On my Fedora 39 jinx was successfully compiled and run after

$ snap install --beta --classic emacs

using following configuration:

(use-package jinx
  :ensure t
  :hook (emacs-startup . global-jinx-mode)
  :bind (("M-$" . jinx-correct))
  :custom
  (jinx-languages "en_US de_DE ru_RU")
  )

Unfortunately, it couldn't find dictionaries and unusable for me :(

Jinx: No dictionaries available for "en_US de_DE ru_RU" [5 times]

I will try on my Ubuntu over weekend.

connormclaud commented 8 months ago

On my Ubuntu it 22.04.4 LTS it works like a charm. Compiles without a problem and fetches installed dictionaries

alexmurray commented 8 months ago

Thanks for confirming @connormclaud

alexmurray commented 8 months ago

I'll leave this issue open for now so that others can find if need be.