Monday, April 20, 2020

libreadline.so.6: cannot open shared object file: No such file or directory

Readline Share Library Missing

When I run a script that calls rlwrap, I got this error on Ubuntu 18.04


rlwrap: error while loading shared libraries: libreadline.so.6: cannot open shared object file: No such file or directory




Looks like it is missing the readline library. Searching Ubuntu package repositories


$ apt search libreadline

libreadline-dev/bionic 7.0-3 amd64
  GNU readline and history libraries, development files

libreadline-gplv2-dev/bionic 5.2+dfsg-3build1 amd64
  GNU readline and history libraries, development files

libreadline-java/bionic 0.8.0.1+dfsg-6 amd64
  GNU readline and BSD editline wrappers for Java

libreadline-java-doc/bionic,bionic 0.8.0.1+dfsg-6 all
  API docs for readline/editline wrappers for Java

libreadline5/bionic,now 5.2+dfsg-3build1 amd64 [installed]
  GNU readline and history libraries, run-time libraries

libreadline5-dbg/bionic 5.2+dfsg-3build1 amd64
  GNU readline and history libraries, debugging libraries

libreadline7/bionic,now 7.0-3 amd64 [installed]
  GNU readline and history libraries, run-time libraries

libreadline7-dbg/bionic 7.0-3 amd64
  GNU readline and history libraries, debugging libraries




Checking on the libreadline6 library, it was deleted on 2017-12-06 from this Debian bug. The reason for deletion being

(From Debian) ROM; obsolete version of readline;

What is Readline

Readline is the library that allows you to
  • move the text cursor in command line
  • search history
  • copy and paste
  • tab completion
  • and so on
In short, any useful command line utility using C will need Readline or an equivalent library. 


Using Readline 5 and Readline 7

Let's see if the other versions of Readline has been installed on the system

$ sudo apt install libreadline5
Reading package lists... Done
Building dependency tree
Reading state information... Done
libreadline5 is already the newest version (5.2+dfsg-3build1).
0 upgraded, 0 newly installed, 0 to remove and 15 not upgraded.


$ sudo apt install libreadline7
Reading package lists... Done
Building dependency tree
Reading state information... Done
libreadline7 is already the newest version (7.0-3).
0 upgraded, 0 newly installed, 0 to remove and 15 not upgraded.



Unfortunately the script still requires the Readline version 6

rlwrap: error while loading shared libraries: libreadline.so.6: cannot open shared object file: No such file or directory



libreadline-dev

From my understanding of the error message, I thought Readline 6 is required. I am going to try installing libreadline-dev anyway, to see if it has the pkg-config files and recompile rlwrap with libreadline7.


$ sudo apt install libreadline-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  readline-doc
The following NEW packages will be installed:
  libreadline-dev
0 upgraded, 1 newly installed, 0 to remove and 15 not upgraded.
Need to get 133 kB of archives.
After this operation, 728 kB of additional disk space will be used.
Get:1 http://xco-engapt.xilinx.com/ubuntu180401 bionic/main amd64 libreadline-de
v amd64 7.0-3 [133 kB]
Fetched 133 kB in 1s (90.8 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libreadline-dev:amd64.
(Reading database ... 328880 files and directories currently installed.)
Preparing to unpack .../libreadline-dev_7.0-3_amd64.deb ...
Unpacking libreadline-dev:amd64 (7.0-3) ...
Processing triggers for install-info (6.5.0.dfsg.1-2) ...
Setting up libreadline-dev:amd64 (7.0-3) ...



Let's take a look at the content

$ dpkg -L libreadline-de
v
/.
/usr
/usr/include
/usr/include/readline
/usr/include/readline
/usr/include/readline/chardefs.h
/usr/include/readline/history.h
/usr/include/readline/keymaps.h
/usr/include/readline/readline.h
/usr/include/readline/rlconf.h
/usr/include/readline/rlstdc.h
/usr/include/readline/rltypedefs.h
/usr/include/readline/tilde.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libhistory.a
/usr/lib/x86_64-linux-gnu/libreadline.a
/usr/share
/usr/share/doc
/usr/share/info
/usr/lib/x86_64-linux-gnu/libhistory.so
/usr/lib/x86_64-linux-gnu/libreadline.so
/usr/share/doc/libreadline-dev





Hmmm... there's a /usr/lib/x86_64-linux-gnu/libreadline.so . Let's try to recompile and see if it works

$ ./configure
...
...
...
checking readline/readline.h usability... yes
checking readline/readline.h presence... yes
checking for readline/readline.h... yes
checking whether your readline headers and library know about rl_set_screen_size
... yes
checking whether your readline headers and library know about rl_basic_quote_cha
racters... yes
checking whether your readline headers and library know about rl_variable_value.
.. yes
checking whether your readline headers and library know about rl_readline_versio
n... yes
checking whether your readline headers and library know about rl_executing_keyse
q... yes
checking whether the private symbol _rl_horizontal_scroll_mode is visble in your
 readline libs... yes
Will rlwrap find command's working directory under /proc/commands pid=""/cwd? let
's see...
checking for /proc/5269/cwd/configure.ac... yes
checking whether we can find command line under opt_proc_mountpoint/pid/cmdl
ine and mirror it by overwriting our own *argv... yes
checking that generated files are newer than configure... done
checking that generated files are newer than configure... done
configure: creating ./config.status/pid/opt_proc_mountpoint/commands




And now build the binary

$ make
make  all-recursive
make[1]: Entering directory '/Github/rlwrap'
Making all in doc
make[2]: Entering directory '/Github/rlwrap/doc'
sed -e 's#@DATADIR@#/usr/local/share#'  rlwrap.man > rlwrap.1
make[2]: Leaving directory '/Github/rlwrap/doc'
Making all in src
make[2]: Entering directory '/Github/rlwrap/src'
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT main.
o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT signa
ls.o -MD -MP -MF .deps/signals.Tpo -c -o signals.o signals.c
mv -f .deps/signals.Tpo .deps/signals.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT readlmv -f .deps/signals.Tpo .deps/signals.Po                               [84/1892]
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT readl
ine.o -MD -MP -MF .deps/readline.Tpo -c -o readline.o readline.c
mv -f .deps/readline.Tpo .deps/readline.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT pty.o
 -MD -MP -MF .deps/pty.Tpo -c -o pty.o pty.c
mv -f .deps/pty.Tpo .deps/pty.Po
rbgen completion.rb completion.c || echo "You don't seem to have rbgen (http://l
ibredblack.sourceforge.net/). If you didn't change any .rb files, this is not a
problem"
/bin/sh: rbgen: command not found
You don't seem to have rbgen (http://libredblack.sourceforge.net/). If you didn'
t change any .rb files, this is not a problem
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT compl
etion.o -MD -MP -MF .deps/completion.Tpo -c -o completion.o completion.c
mv -f .deps/completion.Tpo .deps/completion.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT term.
o -MD -MP -MF .deps/term.Tpo -c -o term.o term.c
mv -f .deps/term.Tpo .deps/term.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT ptytt
y.o -MD -MP -MF .deps/ptytty.Tpo -c -o ptytty.o ptytty.c
mv -f .deps/ptytty.Tpo .deps/ptytty.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT utils
.o -MD -MP -MF .deps/utils.Tpo -c -o utils.o utils.c
mv -f .deps/utils.Tpo .deps/utils.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT strin
g_utils.o -MD -MP -MF .deps/string_utils.Tpo -c -o string_utils.o string_utils.c
mv -f .deps/string_utils.Tpo .deps/string_utils.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT mallo
mv -f .deps/string_utils.Tpo .deps/string_utils.Po                     [57/1892]
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT mallo
c_debug.o -MD -MP -MF .deps/malloc_debug.Tpo -c -o malloc_debug.o malloc_debug.c
mv -f .deps/malloc_debug.Tpo .deps/malloc_debug.Po
gcc -DHAVE_CONFIG_H -I. -I..    -DDATADIR=\"/usr/local/share\"  -g -O2 -MT filte
r.o -MD -MP -MF .deps/filter.Tpo -c -o filter.o filter.c
mv -f .deps/filter.Tpo .deps/filter.Po
gcc -DDATADIR=\"/usr/local/share\"  -g -O2   -o rlwrap main.o signals.o readline
.o pty.o completion.o term.o ptytty.o utils.o string_utils.o malloc_debug.o filt
er.o  -lutil   -lreadline -ltinfo
make[2]: Leaving directory '/Github/rlwrap/src'
Making all in filters
make[2]: Entering directory '/Github/rlwrap/filters'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/Github/rlwrap/filters'
make[2]: Entering directory '/Github/rlwrap'
make[2]: Leaving directory '/Github/rlwrap'
make[1]: Leaving directory '/Github/rlwrap' 





And let's try the script that calls rlwrap again

$ ggv macos src
grep: src: Is a directory
grep: src: Is a directory
============================ grep results ===============================
     1  ./tools/config.sub:1396:              | -macos* | -mpw* | -magic* | -mmi
xware* | -mon960* | -lnews*)
     2  ./tools/config.sub:1399:                os=`echo $os | sed -e 's|mac|mac
os|'`
     3  ./tools/config.sub:1695:                os=-macos
     4  ./tools/config.sub:1766:                        -mpw* | -macos*)
============================ grep results ===============================
Enter a number between 1 and 4 or anything else to quit:  2




Looks great!


In short, libreadline-dev is needed to run rlwrap - although during compilation it is not needed. Not intuitive to me, as I expect libreadline-dev to be used during compilation, instead of containing the shared library that is used during runtime.

No comments:

Post a Comment