Why is my shared library not found? - gcc

I'm trying to compile an example program that links to the shared library produced by Sundown. I'm compiling the program like so.
$ gcc -o sd sundown.c -L. -lsundown
Yet, when I run it I get the following error.
./sd: error while loading shared libraries: libsundown.so: cannot open shared object
file: No such file or directory
The output of ls is.
$ ls
libsundown.so libsundown.so.1 sundown.c sd
Why is the shared library not found by ld?

Short solution:
add . (or whatever it is from your -L flag) to your LD_LIBRARY_PATH. When you run sd, it'll look for libraries in the standard places and the LD_LIBRARY_PATH. Note that since you've added ., this will only work if you run sd from the same directory libsundown.so is in.
I plan on distributing the compiled binary. How can I do so that the library can be distributed without forcing people to edit their LD_LIBRARY_PATH?
You should install libsundown.so in one of the standard places, like /usr/lib or /usr/local/lib. You can do that with an installer or a make file, or something as simple as a INSTALL or README that tells the user to stick the libraries there and ensure the permissions are set to something sensible.

On Centos systems with /usr/lib and /usr/lib64, if you install 64-bit libs manually into /usr/lib then at runtime, the library may not be visible even though at build time it is visible (I used autotools and it was able to find my zopfli library from /usr/lib without any problem). When I execute the my_binary that links to /usr/lib/libzopfli.so.1 I got
libzopfli.so.1 => not found
After moving libzopfly.so.1 from /usr/lib to /usr/lib64, then everything works fine.

Related

Linking against static Lua libraries on macOS

I'm trying to compile and link a program (using CMake) that uses Lua 5.3's C interface on Mac OS X 10.15.7. However I have these problems:
brew install lua#5.3 only installs dynamic libraries
I cannot copy static libraries built from source to /usr/local due to System Integrity Protection (?)
I don't know how to make CMake find the libraries if I put them anywhere else (using find_package(Lua 5.3 REQUIRED)
What's the easiest way to solve this?
If I correctly understand your question, you are trying to use Lua's C API, which means that you need access to the principal header files lua.h, lualib.h, and lauxlib.h, as well the static library liblua.a that is created when the interpreter is built.
I would recommend downloading lua-5.3.5.tar.gz from lua.org and then building from source.
This can be done easily from the Terminal:
$ wget http://www.lua.org/ftp/lua-5.3.5.tar.gz
$ tar xzf lua-5.3.5.tar.gz
$ cd lua-5.3.5
$ make macosx
After that you should be able to do make install as well, which copies the Lua interpreter to /usr/local/bin, I believe.
If you do not want the key Lua header files put into your include path, build your program with -I and -L flags. Also, don't forget the -llua -ldl -lm flags when linking your program.

caffe can't find libboost_system.so.166.0

I'm installing caffe on an Ubuntu 17.04 system using boost 1.66. I am able to execute make all and make test without problems:
me#icvr1:~/PackageDownloads/caffe$ make all
make: Nothing to be done for 'all'.
me#icvr1:~/PackageDownloads/caffe$ make test
make: Nothing to be done for 'test'.
However, when I try make runtest, I get the following error:
me#icvr1:~/PackageDownloads/caffe$ make runtest
.build_release/tools/caffe
.build_release/tools/caffe: error while loading shared libraries: libboost_system.so.1.66.0: cannot open shared object file: No such file or directory
Makefile:532: recipe for target 'runtest' failed
make: *** [runtest] Error 127
Now, I know that libboost_system.so.1.66.0 exists in /usr/local/lib, which (I believe) is a fairly standard location:
me#icvr1:~/PackageDownloads/caffe$ ls /usr/local/lib/libboost_system*
/usr/local/lib/libboost_system.a /usr/local/lib/libboost_system.so /usr/local/lib/libboost_system.so.1.66.0
and, in caffe's Makefile.config, /usr/local/lib is on the library path:
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/hdf5/serial
So, what am I missing here? How can I ensure caffe will know where to find libboost_system.so.1.66.0 ?
Your /usr/local/lib/libboost_system.so.1.66.0 is evidently one you built
yourself and want the loader to find at runtime without special measures.
But having built it, you didn't update the ldconfig cache
(because you didn't know you had to); so the runtime loader is not yet aware that this
library exists and can't find it.
When the loader is looking for the shared libraries needed to assemble a new process,
it does not search all of the linker's default search directories. That would be slow.
By default it searches a cached database /etc/ld.so.cache, of libraries that were
found by ldconfig, last time it was run.
By default, ldconfig caches libraries that it finds in /lib, /usr/lib and in the directrories
listed in the file /etc/ld.so.conf, and/or any similar *.conf files that are recursively include-ed in /etc/ld.so.conf.
For example:
$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
$ cat /etc/ld.so.conf.d/*.conf
/usr/lib/x86_64-linux-gnu/libfakeroot
# libc default configuration
/usr/local/lib
# Multiarch support
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/lib/nvidia-384
/usr/lib32/nvidia-384
/usr/lib/nvidia-384
/usr/lib32/nvidia-384
# Legacy biarch compatibility support
/lib32
/usr/lib32
You see that /usr/local/lib is listed there. So, to make the loader aware
of your new /usr/local/lib/libboost_system.so.1.66.0, just run:
ldconfig
as root. You need to do likewise anytime you install a new locally built
shared library in /usr/local/lib.
If you want the loader to find a shared library /a/b/libfoo.so that isn't in the ldconfig
cache, you can get it to do so by the special measure of appending /a/b/libfoo.so to the value of the
environment variable LD_LIBRARY_PATH (which by default is empty) in the environment in which you launch
the process that needs to load that library. The loader will search the LD_LIBRARY_PATH
directories, if any, before the ldconfig cache. However, not adding a shared library
to the ldconfig cache should be an informed choice and setting LD_LIBRARY_PATH
is, of course, not well motivated merely by ignorance of the ldconfig apparatus or of the linker's -rpath option

g++: link to non-standard /usr/local

I have an OSX 10.7 computer with a non-administrator account, and was attempting to install the pre-compiled versions of gcc and g++ found here. I've attempted to use the answers presented in these questions (three different links) to compile some code with g++, to confusing avail. I have a folder structure like this:
~/code/:
usr/:
local/:
bin/ (3.6MB)
include/ (8.6MB)
lib/ (51MB)
libexec/ (49MB)
share/ (16MB)
c++/:
source/ (contains .cpp files)
g++ -v returns this:
code USER$ usr/local/bin/g++ -v
Using built-in specs.
COLLECT_GCC=usr/local/bin/g++
COLLECT_LTO_WRAPPER=/Users/USERNAME/code/usr/local/bin/../libexec/gcc/ x86_64-apple-darwin11.4.0/4.7.1/lto-wrapper
Target: x86_64-apple-darwin11.4.0
Configured with: ../gcc-4.7.1/configure --enable-languages=fortran
Thread model: posix
gcc version 4.7.1 (GCC)
An attempt at compiling a file that "#include"s only iostream:
$ usr/local/bin/g++ c++/source/test.cpp -o ex6
In file included from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/bits/postypes.h:42:0,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iosfwd:42,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ios:39,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ostream:40,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iostream:40,
from c++/source/ex6.cpp:1:
/Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cwchar:46:19: fatal error: wchar.h: No such file or directory
compilation terminated.
I tried compiling with some flags recommended in one of the links mentioned, like this: (with all combinations of "usr/" to "usr/local/include/" and "usr/" to "/usr/local/lib" giving the same result (which is also the same as using no flags).
$ /Users/USERNAME/code/usr/local/bin/g++ source/ex6.cpp -I/Users/USERNAME/code/usr/local/include/ -L/Users/USERNAME/code/usr/local/lib/In file included from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/bits/postypes.h:42:0,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iosfwd:42,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ios:39,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/ostream:40,
from /Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/iostream:40,
from source/ex6.cpp:1:
/Users/USERNAME/code/usr/local/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cwchar:46:19: fatal error: wchar.h: No such file or directory
compilation terminated.
In short, I'm having trouble understanding what the answers in the links provided are saying to do. I saw reference to a specs file, which I could find no specific information for, and "-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)", for which I couldn't figure out what I was supposed to substitute for "DEFAULT_LIB_INSTALL_PATH".
What should I do to point the downloaded g++ compiler to its own files without placing them in their default location, as I do not have administrative capabilities on this account?
I will provide any information as necessary.
It looks like you don't have required header files. You need to install Command Line Tools from Apple Developers site (free registration needed). The problem is that you don't have administrator account. I suggest that you ask the administrator to install the tools for you. If it is not possible you could try to extract the contents of downloaded package (DevSDK.pkg) to your local directory (Pacifist can do that) and pass the path with the missing headers to your compiler. I haven't tried that though.

Trying to use boost filesystem. cannot find -lboost_system

I have looked through the file library for boost and it does have filesystem but it doesn't have anything for system. However, when I run the code without including system, I get an error saying filesystem needs the boost system to run properly. I am running Code::Blocks 10.05 with a GNU GCC compiler. I have tried including -lboost_system in the links for my project but it couldn't find system either. How can this be fixed?

How to specify non-default shared-library path in GCC Linux? Getting "error while loading shared libraries" when running

There is a laptop on which I have no root privilege.
onto the machine I have a library installed using configure --prefix=$HOME/.usr .
after that, I got these files in ~/.usr/lib :
libXX.so.16.0.0
libXX.so.16
libXX.so
libXX.la
libXX.a
when I compile a program that invokes one of function provided by the library with this command :
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX
xxx.out was generated without warning, but when I run it error like this was thrown:
./xxx.out: error while loading shared libraries: libXX.so.16: cannot open shared object file: No such file or directory , though libXX.so.16 resides there.
my clue-less assumption is that ~/.usr/lib wasn't searched when xxx.out is invoked.
but what can I do to specify path of .so , in order that xxx.out can look there for .so file?
An addition is when I feed -static to gcc, another error happens like this:
undefined reference to `function_proviced_by_the_very_librar'
It seems .so does not matter even though -L and -l are given to gcc.
what should I do to build a usable exe with that library?
For other people who has the same question as I did
I found a useful article at tldp about this.
It introduces static/shared/dynamic loaded library, as well as some example code to use them.
There are two ways to achieve that:
Use -rpath linker option:
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX -Wl,-rpath=/home/user/.usr/lib
Use LD_LIBRARY_PATH environment variable - put this line in your ~/.bashrc file:
export LD_LIBRARY_PATH=/home/user/.usr/lib
This will work even for a pre-generated binaries, so you can for example download some packages from the debian.org, unpack the binaries and shared libraries into your home directory, and launch them without recompiling.
For a quick test, you can also do (in bash at least):
LD_LIBRARY_PATH=/home/user/.usr/lib ./xxx.out
which has the advantage of not changing your library path for everything else.
Should it be LIBRARY_PATH instead of LD_LIBRARY_PATH.
gcc checks for LIBRARY_PATH which can be seen with -v option

Resources