alexmurray / emacs-snap

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

GLIBC_2.33 errors when trying to install zmq package #66

Open dmusican opened 1 year ago

dmusican commented 1 year ago

I'm trying to install package zmq, which is used within jupyter. Then when issuing (require 'zmq), I am prompted to build it, for which I respond yes.

I keep getting this error:

Debugger entered--Lisp error: (module-open-failed "/home/<username>/.config/emacs-doom-chemacs/.local/elpa/zmq-20230608.1856/emacs-zmq.so" "/snap/emacs/2157/usr/bin/../../lib/x86_64-linux-gnu/libc.so.6: version 'GLIBC_2.33' not found (required by /home/<username>/.config/emacs-doom-chemacs/.local/elpa/zmq-20230608.1856/emacs-zmq.so)")

I'm running on Ubuntu 22.04, running in this snap.

I understand that this has something to do with the version of glibc being different between the system version and the snap version, but I'm not sure what to do about it. I see that there are other issues relating to glibc on other packages, but I'm not sure what to do about it in this particular case. Any advice?

alexmurray commented 1 year ago

Thanks for reporting this issue - basically this boils down to (as you suggested) the host glibc version from Ubuntu 22.04 being different (newer in this case) than the one shipped in the emacs snap. When compiling the emacs-zmq.so module, it looks like it has used the host installed gcc and hence linked this against the host glibc. Then when emacs goes to load the module, there is a version mismatch as emacs itself was compiled against the glibc in the snap (which comes from Ubuntu 20.04).

There is no good way around this from the emacs snap side - but you might be able to instead have zmq use the gcc that is shipped within the emacs snap and hence then have the module get linked against the glibc from the emacs snap. We take this approach for tree-sitter in the emacs snap - basically I patch the tree-sitter code to use the gcc from the snap instead via https://github.com/alexmurray/emacs-snap/blob/88538f290f140e896545ebd5497e7c9be6a0b7a4/treesit.patch

It is a shame there is no support in emacs itself to say something like, whenever compiling any module, use this gcc / compiler arguments - instead it seems every package that wants to use a native module has to implement support for compiling the module itself (as tree-sitter does) and hence each then requires a bespoke solution from the emacs snap side.

But given this is a third-party package I am not sure there is a lot I can do - I can provide a workaround though - with the following I was able to get zmq installed and the module correctly loaded in a fresh emacs -q environment - so just change the section at ;; load zmq module to whereever you currently call (require 'zmq) or similar:

(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")))))
  ;; load zmq package
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'zmq)
  (require 'zmq)
  (zmq-load))
dmusican commented 1 year ago

Thanks so much for trying this. I just tried your sample code in a fresh install, and I'm still not being successful with it. The code you provided ran, and it did the compile etc, but it must still have linked to the wrong glibc for me. I've posted the errors below, but I recognize that this is third-party code that isn't your responsibility to figure out. As you say, it's too bad that emacs doesn't provide a better approach for combining these approaches together.

Debugger entered--Lisp error: (module-open-failed "/home/<username>/.emacs.d/elpa/zmq-20230608.1856/emacs-zmq.so" "/snap/emacs/2157/usr/bin/../../lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /home/<username>/.emacs.d/elpa/zmq-20230608.1856/emacs-zmq.so)")
  zmq-load()
  #f(compiled-function (buf status) #<bytecode -0x780d411bd01378e>)(#<buffer *compilation*> "finished\n")
  compilation-handle-exit(exit 0 "finished\n")
  compilation-sentinel(#<process compilation> "finished\n")
  recursive-edit()
  zmq-load()
  byte-code("\300 \210\301\302!\207" [zmq-load provide zmq] 2)
  require(zmq)
  (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 'zmq) (require 'zmq) (zmq-load))
  (progn (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 'zmq) (require 'zmq) (zmq-load)))
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  command-execute(eval-last-sexp)
alexmurray commented 1 year ago

Did you remove the old emacs-zmq.so first?

dmusican commented 1 year ago

Wow, I guess that was it. I was completely convinced that I had nuked my .emacs.d and started from scratch, but I just did it again to prove it, and now it's working. :) Thank you! I'll now have to see if I can integrate the above into the rest of my workflow, but that's the nudge I needed. Much appreciated.

alexmurray commented 1 year ago

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

martibosch commented 1 year ago

Hello!

unluckily this workaround did not work for me... Here is my minimal configuration with a single file, and I there is not a single other file/folder in my configuration directory (actully I use chemacs):

(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")))))
  ;; load zmq package
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'zmq)
  (require 'zmq)
  (zmq-load))

and here is the traceback of the error:

Debugger entered--Lisp error: (module-open-failed "/home/martibosch/emacs-zmq/elpa/zmq-20230608.1856/..." "/snap/emacs/2163/usr/bin/../../lib/x86_64-linux-gn...")
  load("/home/martibosch/emacs-zmq/elpa/zmq-20230608.1856/..." t)
  zmq-load()
  zmq-load()
  byte-code("\300 \210\301\302!\207" [zmq-load provide zmq] 2)
  require(zmq)
  (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 'zmq) (require 'zmq) (zmq-load))
  load-with-code-conversion("/home/martibosch/emacs-zmq/init.el" "/home/martibosch/emacs-zmq/init.el" t t)
  load("/home/martibosch/emacs-zmq/init.el" t t)
  (let ((init-file (expand-file-name "init.el" user-emacs-directory))) (setq package-user-dir (expand-file-name "elpa" user-emacs-directory)) (load init-file t t) (let ((chemacs-custom-file (chemacs-profile-get 'custom-file init-file))) (if (not custom-file) (progn (setq custom-file chemacs-custom-file) (if (equal custom-file init-file) nil (if (file-exists-p custom-file) nil (let (...) (save-current-buffer ... ...))) (load custom-file))))))
  chemacs-load-user-init()
  load-with-code-conversion("/home/martibosch/.emacs.d/init.el" "/home/martibosch/.emacs.d/init.el" t t)
  load("/home/martibosch/.emacs.d/init" noerror nomessage)
  startup--load-user-init-file(#f(compiled-function () #<bytecode 0x1f3d938e70c8d2c1>) #f(compiled-function () #<bytecode -0x1f3c61addc0b8a75>) t)
  command-line()
  normal-top-level()

any clues of why this happens?

Thank you, Martí

alexmurray commented 1 year ago

I notice it is loading zmq.al from the path /home/martibosch/emacs-zmq/init.el - are you sure there is not already a emacs-zmq.so somewhere within this directory (it would likely be at /home/martibosch/emacs-zmq/elpa/zmq-20230608.1856/emacs-zmq.so but the backtrace is eliding long strings so I can't be certain) - if so, please remove this and try again.

martibosch commented 1 year ago

I think I figured out my issue (it was completely my mistake, but I write it here in case it is useful for anyone else): when running emacs in the fresh environment, you need to answer "n" (No) to Check for compatible module binary to download? so that the module is compiled using the customized settings from your snippet above, i.e., answering "y" to ZMQ module not found. Build it?.

Tokubara commented 1 year ago

Thanks for reporting this issue - basically this boils down to (as you suggested) the host glibc version from Ubuntu 22.04 being different (newer in this case) than the one shipped in the emacs snap. When compiling the emacs-zmq.so module, it looks like it has used the host installed gcc and hence linked this against the host glibc. Then when emacs goes to load the module, there is a version mismatch as emacs itself was compiled against the glibc in the snap (which comes from Ubuntu 20.04).

There is no good way around this from the emacs snap side - but you might be able to instead have zmq use the gcc that is shipped within the emacs snap and hence then have the module get linked against the glibc from the emacs snap. We take this approach for tree-sitter in the emacs snap - basically I patch the tree-sitter code to use the gcc from the snap instead via https://github.com/alexmurray/emacs-snap/blob/88538f290f140e896545ebd5497e7c9be6a0b7a4/treesit.patch

It is a shame there is no support in emacs itself to say something like, whenever compiling any module, use this gcc / compiler arguments - instead it seems every package that wants to use a native module has to implement support for compiling the module itself (as tree-sitter does) and hence each then requires a bespoke solution from the emacs snap side.

But given this is a third-party package I am not sure there is a lot I can do - I can provide a workaround though - with the following I was able to get zmq installed and the module correctly loaded in a fresh emacs -q environment - so just change the section at ;; load zmq module to whereever you currently call (require 'zmq) or similar:

(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")))))
  ;; load zmq package
  (require 'package)
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
  (package-refresh-contents)
  (package-install 'zmq)
  (require 'zmq)
  (zmq-load))

With this I still meet the same error:

apply: Module could not be opened: "/home/quebec/.emacs.d/elpa/29.1/develop/zmq-20230608.1856/emacs-zmq.so", "/snap/emacs/2249/usr/bin/../../lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by /home/quebec/.emacs.d/elpa/29.1/develop/zmq-20230608.1856/emacs-zmq.so)"