libcheck / check

A unit testing framework for C
GNU Lesser General Public License v2.1
1.06k stars 206 forks source link

Unable to load shared library (libcheck.so.0). #155

Closed quytelda closed 6 years ago

quytelda commented 6 years ago

I've installed check 0.12.0 from git on Debian Testing. I used the following commands:

$ git clone https://github.com/libcheck/check.git && cd check && git checkout 0.12.0
$ autoreconf --install
$ make
$ make check
$ sudo make install

However, when I try to run the unit tests in my project I get the following output:

$ make check
make -C test
make[1]: Entering directory '/home/myhome/myproject/test'
gcc -c -I ../include -g  -o list/testproj.o list/testproj.c
gcc -o testproject list/testproj.o -I ../include -g -lcheck -L .. -lmyprojectlib
make[1]: Leaving directory '/home/myhome/myproject/test'
make -C test check
make[1]: Entering directory '/home/myhome/myproject/test'
./testproject: error while loading shared libraries: libcheck.so.0: cannot open shared object file: No such file or directory
Makefile:18: recipe for target 'check' failed
make[1]: *** [check] Error 127
make[1]: Leaving directory '/home/myhome/myproject/test'
Makefile:35: recipe for target 'check' failed
make: *** [check] Error 2

When I run make check in this repository on Arch Linux (where I installed the package check via pacman), the unit tests all run successfully. I also tried installing from the prepackaged tarball release, but I got the same result.

I also ran make installcheck, which fails:

Making installcheck in lib
make[1]: Entering directory '/home/myhome/check/lib'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/lib'
Making installcheck in src
make[1]: Entering directory '/home/myhome/check/src'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/src'
Making installcheck in doc
make[1]: Entering directory '/home/myhome/check/doc'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/doc'
Making installcheck in .
make[1]: Entering directory '/home/myhome/check'
make[1]: Nothing to be done for 'installcheck-am'.
make[1]: Leaving directory '/home/myhome/check'
Making installcheck in checkmk
make[1]: Entering directory '/home/myhome/check/checkmk'
bad=0; pid=$$; list="checkmk"; for p in $list; do \
  case '  ' in \
   *" $p "* | *" ./$p "*) continue;; \
  esac; \
  f=`echo "$p" | sed 's,^.*/,,;s,x,x,'`; \
  for opt in --help --version; do \
    if "/usr/local/bin/$f" $opt >c${pid}_.out \
         2>c${pid}_.err </dev/null \
     && test -n "`cat c${pid}_.out`" \
     && test -z "`cat c${pid}_.err`"; then :; \
    else echo "$f does not support $opt" 1>&2; bad=1; fi; \
  done; \
done; rm -f c${pid}_.???; exit $bad
checkmk does not support --help
checkmk does not support --version
Makefile:559: recipe for target 'installcheck-binSCRIPTS' failed
make[1]: *** [installcheck-binSCRIPTS] Error 1
make[1]: Leaving directory '/home/myhome/check/checkmk'
Makefile:561: recipe for target 'installcheck-recursive' failed
make: *** [installcheck-recursive] Error 1
brarcher commented 6 years ago

It might be that by default libcheck is being installed to /usr/local/lib instead of /usr/lib when built from source. Is your project also trying to find the library in /usr/local/lib ? Or, can you install Check into /usr/lib ?

On Wed, Apr 25, 2018 at 4:03 AM, Quytelda Kahja notifications@github.com wrote:

I've installed check 0.12.0 from git on Debian Testing. I used the following commands:

$ git clone https://github.com/libcheck/check.git && cd check && git checkout 0.12.0 $ autoreconf --install $ make $ make check $ sudo make install

However, when I try to run the unit tests in my project I get the following output:

$ make check make -C test make[1]: Entering directory '/home/myhome/myproject/test' make[1]: Nothing to be done for 'all'. make[1]: Leaving directory '/home/myhome/myproject/test' make -C test check make[1]: Entering directory '/home/myhome/myproject/test' ./linklist: error while loading shared libraries: libcheck.so.0: cannot open shared object file: No such file or directory Makefile:18: recipe for target 'check' failed make[1]: [check] Error 127 make[1]: Leaving directory '/home/myhome/myproject/test' Makefile:35: recipe for target 'check' failed make: [check] Error 2

When I run make check in this repository on Arch Linux (where I installed the package via pacman), the unit tests all run successfully. I also tried installing from the prepackaged tarball release, but I got the same result.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/libcheck/check/issues/155, or mute the thread https://github.com/notifications/unsubscribe-auth/AFBUl38uIWNg24ikcvwK84tyiwE5Zrgqks5tsC3ogaJpZM4Ti9Jz .

quytelda commented 6 years ago

I successfully ran the following:

$ autoreconf --install
$ ./configure --prefix=/usr
$ make check
$ make && sudo make install

Perfect; now the unit tests work in my project. However, it is worth noting that make installcheck is still failing:

$ make installcheck
Making installcheck in lib
make[1]: Entering directory '/home/myhome/check/lib'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/lib'
Making installcheck in src
make[1]: Entering directory '/home/myhome/check/src'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/src'
Making installcheck in doc
make[1]: Entering directory '/home/myhome/check/doc'
make[1]: Nothing to be done for 'installcheck'.
make[1]: Leaving directory '/home/myhome/check/doc'
Making installcheck in .
make[1]: Entering directory '/home/myhome/check'
make[1]: Nothing to be done for 'installcheck-am'.
make[1]: Leaving directory '/home/myhome/check'
Making installcheck in checkmk
make[1]: Entering directory '/home/myhome/check/checkmk'
bad=0; pid=$$; list="checkmk"; for p in $list; do \
  case '  ' in \
   *" $p "* | *" ./$p "*) continue;; \
  esac; \
  f=`echo "$p" | sed 's,^.*/,,;s,x,x,'`; \
  for opt in --help --version; do \
    if "/usr/bin/$f" $opt >c${pid}_.out \
         2>c${pid}_.err </dev/null \
     && test -n "`cat c${pid}_.out`" \
     && test -z "`cat c${pid}_.err`"; then :; \
    else echo "$f does not support $opt" 1>&2; bad=1; fi; \
  done; \
done; rm -f c${pid}_.???; exit $bad
checkmk does not support --help
checkmk does not support --version
Makefile:559: recipe for target 'installcheck-binSCRIPTS' failed
make[1]: *** [installcheck-binSCRIPTS] Error 1
make[1]: Leaving directory '/home/myhome/check/checkmk'
Makefile:561: recipe for target 'installcheck-recursive' failed
make: *** [installcheck-recursive] Error 1

This may be a bug; I'm not sure. Either way, it feels like installing to /usr/lib should be the default behavior of the install script. I believe /usr/lib is the first path checked by GCC, or at least before /usr/local/lib, and it would make sense to install there if some setups don't check /usr/local/lib at all by default.

My system doesn't have any unusual build configuration or anything; it's just a vanilla Debian VM I spun up to do testing in. The details of the system are as follows:

$ cat /etc/issue
Debian GNU/Linux buster/sid \n \l

$ uname -a
Linux debian 4.15.0-3-amd64 #1 SMP Debian 4.15.17-1 (2018-04-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 7.3.0-16) 7.3.0
...
$ make --version
GNU Make 4.1
Built for x86_64-pc-linux-gnu
...
$ automake --version
automake (GNU automake) 1.15.1
....
$ autoconf --version
autoconf (GNU Autoconf) 2.69
...
$ dpkg -l | grep libtool
ii  libltdl-dev:amd64                2.4.6-2.1                      amd64        System independent dlopen wrapper for GNU libtool
ii  libltdl7:amd64                   2.4.6-2.1                      amd64        System independent dlopen wrapper for GNU libtool
ii  libtool                          2.4.6-2.1                      all          Generic library support script
$ pkg-config --version
0.29
$ dpkg -l | grep texinfo
ii  texinfo                          6.5.0.dfsg.1-2                 amd64        Documentation system for on-line information and printed output
$ sed --version
sed (GNU sed) 4.4
brarcher commented 6 years ago

I think the installcheck issue is a bug; I've not tried that target myself and I do not think it is part of the automated tests. As it is failing in checkmk I suspect it never worked. The automake documentation says it is typically not used. Probably it should be a no-op instead of fail, though.

As for installing to /usr/local instead of /usr, I think this is expected behavior and is common among the various configure scripts I've interacted with. Here is a discussion about it.

quytelda commented 6 years ago

I see; well, hopefully this issue will help out anyone trying to install from source on a similar systems. I don't think the problem was that GCC didn't check /usr/local/lib though, since I tried manually adding that to the linker path and the linker still fails when building the unit tests. I checked the permissions on the files, and they are alright, so I doubt that is the problem. I haven't tried building with --prefix=/usr/local though; perhaps that will yield some sort of interesting insight.

ozars commented 6 years ago

I had a similar issue with Ubuntu 16.04, with check 0.12.0 compiled from source code. Creating sym link solved the issue for me for now:

sudo ln -s /usr/local/lib/libcheck.so.0 /usr/lib/libcheck.so.0
ozars commented 6 years ago

I found the solution for my case: Running ldconfig to regenerate linker cache. Apparently, it wasn't called, as I didn't install check through aptitude,

Below command didn't produce any output before I ran ldconfig. Its output after running ldconfig:

$ ldconfig -p | grep libcheck    
        libcheck.so.0 (libc6,x86-64) => /usr/local/lib/libcheck.so.0
        libcheck.so (libc6,x86-64) => /usr/local/lib/libcheck.so

Also I made sure /usr/local/lib is included by /etc/ld.so.conf (or by other conf files it includes) before running ldconfig.

quytelda commented 6 years ago

I think it's kind of surprising that libtool doesn't handle that automatically, but evidently it is normal. See: https://lists.gnu.org/archive/html/libtool/2014-05/msg00021.html

That said, I do think it would be helpful and worthwhile to add a reminder to update the library cache somewhere during the install or maybe even in the docs/README; it seems some other libraries do that, and it would clear up confusion for those who don't install from tarballs very often - pre-built packages tend to handle this type of stuff automatically.

brarcher commented 6 years ago

May you propose an addition to README.md which may be helpful fo other users? Maybe something at the end of the autoconf section. If you can create a pull request (editing the file on GitHub should take care of that) I can merge it in. If not, you can mention what verbiage would be helpful here.

brarcher commented 6 years ago

I've merged in your README changes. Thanks