I want to compile moongose with static library of libssl .
I have given .a file with -L option.
But still it is loading .so file.
why ?
how can I force it to use static lib ?
Run compilation under strace, to look where .a file is being searched and why .so is loaded instead.
EDIT
By default moongose loads SSL dynamically. To change this compile it with NO_SSL_DL macro. Add -DNO_SSL_DL to compilation command line. See this link.
Related
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
I am trying to write a simple application with GLFW on Linux. Right now the main file (the only file) is basically just a few lines of code to make sure the dynamic library linked correctly. Here it is:
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
glfwInit();
std::cout << "It works this far!" << std::endl;
glfwTerminate();
}
The include files are stored in a directory labelled "include" and the library files are stored in a directory labelled "lib". As of right now, I am compiling the program with the following line:
g++ -Wl,-Rlib -Iinclude -Llib test.cpp -o test -lglfw.3.2
It compiles and links just fine, but when I try to execute it, I get the following error:
./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
Now, before you rush to downvote this question into oblivion and mark it as a duplicate, at least allow me to explain why I believe my question is different enough to not be a duplicate. I already attempted the solutions that the other questions presented, but it was unsuccessful. As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib tag. I also tried setting LD_LIBRARY_PATH to point to the location of my libraries (the 'lib' folder), but it still threw the same error. (It didn't matter if the path was relative or absolute.)
So, the next thing I tried was running the ldd command on the executable. I got some other dependencies that were working just fine, but importantly, I got this:
libglfw.so.3 => not found
For some reason, it insists on looking for libglfw.so.3. It will not have it any other way. Upon renaming the library from libglfw.3.2.so to libglfw.so.3, the program executed just fine and printed It works this far! as if there were no problems at all.
Why would this happen?
For some reason, it insists on looking for libglfw.so.3. ... Upon renaming the library from libglfw.3.2.so to libglfw.so.3 ...
The ELF executables contain the exact name of the dynamic libraries used.
If the executable contains the library name "libglfw.so.3" the file must be named exactly like this.
The file naming scheme is intentionally done in a way that not the "full" version is coded into the file name: This way a later version ("libglfw.so.3.15") will work with the executable.
Normally there should be a symbolic link to the latest version of the library installed:
libglfw.so.3 -> libglfw.so.3.2
This symbolic link seems to be missing on your computer. I would say that this is an installation problem!
EDIT
The question could be: Why is the file name stored in the executable file not libglfw.3.2.so but libglfw.so.3?
The answer has to do with the backward compatibility when a new version of a library is installed:
Normally you would use the switch -lglfw and a symbolic link named libglfw.so is looked up.
If you stored the file name libglfw.so in the executable file and a new, incompatible version if this library (libglfw.so.4) is installed you would have no chance to get the program running by having both versions of the library installed.
To enable backward compatibility by having both versions of the library installed the "real" symbolic link name of the library (libglfw.so.3) must be stored in the executable file.
Therefore the "expected" file name of a library is stored in the library itself: Inside the file libglfw.so.3.2 you'll find some information that the file expects itself to be stored as libglfw.so.3.
The linker will use this information about the file name because it assumes that the library name given in the linker switch (-lglfw) is less "precise" than the name stored in the library itself.
For some reason, it insists on looking for libglfw.so.3. It will not have it any other way.
This is the Linux convention for shared libraries which is described here among other places. For Linux libfoo.so.x.y.z is considered to have the same ABI as libfoo.so.x. Usually when shared libraries are installed (e.g. via rpm, dpkg, etc.) there's an invocation of ldconfig that happens so that the just installed libraries have a symlink following the convention installed that references the library. Also these libs (if installed to a "trusted location"), are added to a linker cache for performance reasons.
It compiles and links just fine, but when I try to execute it, I get the following error:
./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
libglfw.so.3 isn't on ld-linux.so's path.
As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib
Still won't find it -- libglfw.so.3 isn't on ld-linux.so's path. You can add it by doing something like:
ldconfig -n /path/to/lib
Which should output the requisite libglfw.so.3 symlink for your lib.
IIRC setting the rpath might require a full path.
I also tried setting LD_LIBRARY_PATH to point to the location of my libraries
Again, libglfw.so.3 isn't on ld-linux.so's path.
I am trying to use the NBIS library from NIST:
http://www.nist.gov/itl/iad/ig/nbis.cfm
NBIS is composed of several different related libraries that they compile into multiple archive files. They give you an option when installing it to install either all of the individual .a files or to bundle them into a single, monolithic .a file. I had been using the multiple library files but decided to try to use the single, monolithic file to make things easier. But I am getting an error when trying to link against it when using -lnbis in my link step (using g++, which uses ld):
libnbis.a: error adding symbols: Archive has no index; run ranlib to add one
Looking at the archive, it contains the other individual .a files:
$ ar t libnbis.a
liban2k.a
libbozorth3.a
libcblas.a
... and so forth
The line in the Makefile that generates the archive is: $(AR) -ru libnbis.a *.a
I have tried running ranlib libnbis.a and that does not modify it.
So, my question is: How can I link to the NBIS library? I know which individual libraries inside the libnbis.a file I need to link to if I need that. Will it work this way? Or are NIST doing something wrong trying to merge their individual libraries into one archive file?
I have tried searching around to find similar problems and it seems like the answer to the above is that they are doing it wrong. For instance, answers to this question suggest unpacking the individual .a files and repacking the .o files into the conglomerate archive:
How to merge two "ar" static libraries into one
There is also a comment suggesting using libtool:
https://stackoverflow.com/a/8170851/196561
So it looks like I have a couple options if I want to build the libnbis.a file myself. I just wanted to make sure there was not some way to use the .a files in the archive as-is before I do that.
I am trying to compile one of the projects found here
USB-I2C/SPI/GPIO Interface Adapter.
I downloaded the i2c_bridge-0.0.1-rc2.tgz package. I installed libusb and that seemed to go well with no issues. I go into the i2c_bridge-0.0.1-rc2/ directory and make. That compiles. I move into the i2c_bridge-0.0.1-rc2/i2c folder and make. It compiles and gives me ./i2c. However, when I run it, it says error while loading shared libraries: libi2cbrdg.so: cannot open shared object file: No such file or directory
The makefile in i2c_bridge-0.0.1-rc2/i2c has the library directory as ../. The libi2cbrdg.so is in this directory (i2c_bridge-0.0.1-rc2). I also copied the file to /usr/local/lib. An ls of the i2c_bridge-0.0.1-rc2/ directory is
i2c i2cbrdg.d i2cbrdg.o libi2cbrdg.a Makefile tests
i2cbrdg.c i2cbrdg.h INSTALL libi2cbrdg.so README u2c4all.sh
(That i2c is a directory)
If I sudo ./i2c, it still gives me the problem.
I had to take away the -Werror and -noWdecrepated (spelling?) options in all the makefiles to get them to compile, but that shouldn't affect this should it?
What else is necessary for it to find the .so file? If anyone can help me find out what is wrong I would be very grateful. If more information is needed I can post it.
You have to distinguish between finding so's at compile-time and at run-time. The -L flag you give at compile-time has nothing to do with localizing the library at run-time. This is rather done via a number of variables and some paths embedded in the library.
The best hot-fix for this problem is often setting LD_LIBRARY_PATH to the directory with the .so file, e.g.:
$ LD_LIBRARY_PATH=.. ./i2c
For a long-term solution, you need to either have a close look at the whole LD system with rpath and runpath, or use libtool (which solves these issues for your portably).
Copying a file to /usr/local/lib is often insufficient because ld caches the available libraries, so you need to re-run ldconfig (as root) after you copied a library to /usr/local/lib.
If you are building the code from source that needs the the library, you can put the path that the library is in in the environment variable LD_RUN_PATH before building, and the linker will save that path into the binary, so that it will automatically be looked for in the right place at runtime.
Linux specific: Alternately, put the library in /lib, /usr/lib, or some other path referenced in your /etc/ld.so.conf or its imported config fragments, and then all you need to do is run /sbin/ldconfig to refresh ld.so (the dynamic linker)'s cache of libraries.
This works for my issue,hope will help anyone.
gcc test.c -Wl,-rpath /usr/local/lib -lfcgi -o test.fcg
And -Wl,-rpath option is the key trick.
I have compiled this library successfully. It generates a libcds2.la file that I am trying to link into my own project. I have all files (including the .h file) in the same directory as my project file. When I try to link and use the functions of said library, using:
g++ -o test -I/opt/include/ -L/opt/lib/ -lcds2 libcdsNoptrs.cpp util.cpp
comes back with
./test: error while loading shared libraries: libcds2.so.2:
cannot open shared object file: No such file or directory
whatever that is. But the point is that most of the time it just doesn't recognize the library. I assume I'm doing something wrong with the file paths, but can't figure it out. My test file is a C++ file including #include "libcds2/array.h" and everything is installed in opt/lib, opt/include, ugly, I know, but that's what the Makefile generated.
Any pointers?
The libtool .la is a 'meta data' file. After building the cds2 library, it's expected that libtool will also be used in 'link' mode to build any of the package's tests, etc.
Typically, the in the directory you find the .la file, you will find the .a and .so under the .libs subdirectory. The .libs/libcds2.a file will be found there, provided configure was given the --enable-static option (or it is enabled by default). But, my understanding is that you've installed the package in /opt :
g++ -I/opt/include/ libcdsNoptrs.cpp util.cpp -o test /opt/lib/libcds2.a
Otherwise, if libcds2 isn't installed, just supply a path to: .../libcds2/lib/.libs/libcds2.a
Unless you want to use libtool in --link mode with -static to handle everything. But learning the advantages of libtool is usually an exercise for a rainy day:)