Sweep-module.so undefined symbol: PL_version_info

cmake -k -G Ninja  -DCMAKE_INSTALL_PREFIX=$HOME/.local -DINSTALL_DOCUMENTATION=ON -DBUILD_PDF_DOCUMENTATION=OFF -DTEST_PROTOBUFS_PROTOC=OFF -DSWIPL_PACKAGES_ARCHIVE=OFF -DLibArchive_LIBRARIES=/home/peter/src/libarchive/libarchive/libarchive.so -DLibArchive_INCLUDE_DIRS=/home/peter/src/libarchive/libarchive ..
$ echo $PATH
/home/peter/gems/bin:/home/peter/.local/gcc-12/bin:/home/peter/.local/bin:/home/peter/gems/bin:/home/peter/.local/gcc-12/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/snap/bin
$ type swipl
swipl is /home/peter/.local/bin/swipl
$ find ~/.local -name '*sweep*' | xargs file
/home/peter/.local/lib/swipl/lib/x86_64-linux/sweep-module.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=d022ac1fc5a82b7a40ad8ec378ffccf5faa14911, with debug_info, not stripped

(I don’t think the “archive” library flags are important; they’re because I’ve been (slowly) working on fixing some issues with library(archive))

I did a clean build of emacs and of swipl - also did rm -r ~/.local/lib/swipl ~/.local/bin/swipl before doing ninja install.

?- current_prolog_flag(libswipl, X).
X = '/home/peter/.local/lib/swipl/lib/x86_64-linux/libswipl.so'.

When I rebuilt swipl and emacs, I also got the crash. I needed to also do package-refresh-contents (plus package-update, etc.) to get to the next problem. :wink:

1 Like

Thanks, I can reproduce the issue locally now.
Seems the problem surfaces because in your configuration, library(help) is not available. This causes some warning and error messages to be printed where we expect to find the path to sweep-module, so we try to load a bogus path instead, and naturally fail.

I’m not sure why library(help) isn’t available (maybe -DBUILD_PDF_DOCUMENTATION=OFF disables it?), but you can probably work around this issue right away by changing some cmake flags. I’ll update the routine for finding sweep-module to be more robust so we don’t fail in such cases anyway.

I removed the -DBUILD_PDF_DOCUMENTATION=OFF and -DSWIPL_PACKAGES_ARCHIVE=OFF, installed pdflatex (in package texlive-latex-base), rebuilt and it seems to be working fine now. Thank-you!

Indeed, library(help) is not around if there is no documentation. In sweep you can do

:- if(exists_source(library(help))).
...
:- endif.

This does not depend on -DBUILD_PDF_DOCUMENTATION but on -DINSTALL_DOCUMENTATION=OFF. Installing the HTML docs is by default on, but may be disabled. Notably the docs typically do not build if you omit some of the packages. A lacking archive package is one issue. The only stuff you can safely omit are xpce, odbc and jpl. Those are also the most practical to omit as they all pull in a lot of dependencies.

Using the default setup, all should be fine. sweep needs to be aware that the docs may be missing.

Another issue is emacs-module.h. Ideally we get that from the installed Emacs. For generating binaries though this means making emacs a build dependency. That is a rather big step. I’m still wondering what to do. For Windows I merely installed a copy of emacs-module.h in the Docker container. That is not going to work for e.g. the Linux packages. Could you ask the Emacs community for best practices or see how other projects that support an Emacs plugin handle this?

I’m already quite surprised that this approach seems to run with few problems on all our major platforms :slight_smile:

Sure, I’ll ask and try to find a project with a similar setup. If anyone has an idea for a useful reference I’d appreciate it. Most Emacs packages that I use that rely on a native module, build it themselves on the user’s machine (e.g. the vterm and pdf-tools packages). We opted to avoid that and instead include sweep-module with swipl such that sweep-module benefits from the standard SWI-Prolog build process.

I wonder if it would be possible to include a sparse checkout of emacs as a submodule, just for emacs-module.h. Given that swipl already uses submodules, that might work decently, without adding another dependency…but I suspect that sparse-checkouts + submodules might be a bit of an unpleasant interaction.

You mean a depth=1 checkout? Might be an idea. Would still demand adding this to the source archive though as (AFAIK) several of the build daemons have no internet access. Alternatively, I guess, we can simply (re-)add emacs-module.h to the sweep package and make CMake first search for a public one and as fallback use the local copy. It is ugly. Wonder what the Emacs folks consider good practice.

I was thinking of depth=1 plus git-sparse-checkout to only get that one file, but I have found it somewhat janky in the past (I was using it with worktrees and it had some weird things that didn’t work properly). In any case though, just adding emacs-module.h is probably the simplest way…As @oskardrums has said, it seems like both emacs libraries with modules don’t distribute the module & instead have the package build it on demand, but surely there should be a better way.

Ah, never knew you could checkout part of the git repo. Good to know :slight_smile: Building on the fly was also @oskardrums first approach. It would not work well on Windows and also on Mac it is not without troubles. We use building binary support tools for IDEs also for the PDT Eclipse plugin. I think we are pretty close to an out of the box solution for most people :slight_smile:

1 Like

What’s the status of this issue?
While I could manually tweak LD_PRELOAD, this is made a bit inconvenient by the fact that I’m using emacs as a window manager, on NixOS. Is there something that I can do during installation that would alleviate this problem?

EDIT: no problem, I switched to emacs 29 and all seems to be fine now! Yay!

2 Likes