how to use my own dynamic library in linux (Makefile) - linux

I have a c++ project (g++/raw Makefile) designed for linux, I used to statically link everything which worked fine for ages. Now I want to build binaries both statically and dynamically linked. The following command is used in my Makefile to build the dynamic library (say libtest):
$(CXX) -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0.0 $(LIBTEST_OBJS)
The output is libtest.so.1.0.0 which has the so name libtest.so.1
I found at least a symbolic link libtest.so --> libtest.so.1.0.0 is required to link my client program that actually use the above generated libtest.so.1.0.0 library.
Here my question is if I want to build my software, what is the standard way of managing the above symbolic link? Clearly I don't want this extra stuff in my source directory, but it is required to build my client binary, shall I create it as a temp link for building the client then just remove it when done? or shall I create a directory to host the generate .so library and its links and leave everything there until I do "make install" to install them into other specified directories? Will be cool to now what is the standard way of doing this.
Or maybe the way how I generate libraries is incorrect? shall I just generate libtest.so (as actual library, not a link) to link my executable, then rename the library and create those links when doing ``make install''?
any input will be appreciated. :)

Certainly don't generate libtest.so as an actual link. Typically installing the shared library development files installs the .h files and creates a symbolic link libtest.so as part of some install script you have to write.
If you're not installing the development files, but only using the library in your build process of your binary, you just create the symbolik link from your makefile.
There's not that much of a standard here, some prefer to build artifacts to a separate build directory,
some don't care if it's built in the source directory. I'd build to a separate directory though, and keep the source directory clean of any .o/.so/executable files.
You might find useful information here

My suggestion is to use libtool which handles situations like this.

Related

Shared Library on Linux is not found

I have built some shared libraries on Ubuntu Linux 16.0.2 from source.
They are 64-bit libs.
I manually copied them to /usr/local/lib.
I verified that the /usr/local/lib path is indeed in one of the .conf files that ld.so.conf includes.
I then ran: sudo ldconfig to update the cache.
But then when I try to run my executable which tries to dynamically load one of the .so files that I previously copied into /usr/local/lib using dlopen, it fails.
In my code, I have:
dlopen ("foobar.so", RTLD_LAZY);
Can anybody tell me what I am doing wrong?
The dynamic linker normally doesn't access the paths recursively included from /etc/ld.so.conf directly, but it uses a cache.
You can update the cache with
sudo ldconfig
See ldconfig(8) for more details.
for dlopen to work, there's no directory list of places to find the shared object. So doing dlopen("somefile", ...); probably won't work.
You don't need to use any path or to put the shared object (or to comply with naming conventions) to use a shared object via dlopen(3). That's only a requirement of the dynamic linker that loads and links all the shared libraries at launch time: linux-vdso.so.1 (in 64bit)
To test, just put the shared in your local dir and try to open it with it's basename, like you post.
For a system library, there are more requirements, like defining a soname for the library, which is used by the loader to load the library and to construct the cache database index, so if you have no idea of what I'm talking about, you will not be able to use automatic loading procedure. If you want to see if an executable file has all the libraries it needs and where the loader finds them out, just run ldd(1) with the executable as argument, and you'll se the dependencies for automatic loading and how the dynamic linker resolves the paths.

Bash command: export BLAS_LIBS="-L$LAPACKHOME/lib -lblas"

Can any body explain to me what does the whole sentence mean?
I know this is to set Macro BLAS_LIBS as another string.
But I'm not sure what's the "-lblas" mean and I don't know how to use it.
Similar as the following code. "-llapack"
export LAPACK_LIBS="-L$LAPACKHOME/lib -llapack"
How can the program find out the BLAS and LAPACK libraries just by "-lblas" and "-llapack" ?
Thanks for advance.
I'm not sure why you say "just by -llapack" because that's not what is happening here. Specifically, the -L option just before it specifies a directory path to add to the library resolution path. This works roughly like PATH in the shell.
For example, with the command line fragment gcc -Lfoodir -Lbardir -lfoo -lbar, you basically instruct the linker to search the directories foodir and bardir for the library files libfoo.a and libbar.a.
The -l option is described in GCC: Options for Linking and -L and friends in the following section GCC: Options for Directory Search.
This build arrangement -- configure the build to show where the required files are before compiling -- is common for libraries, where if a user has already downloaded and compiled a required library for some other project, they don't need to rebuild it; they can just point the compiler to wherever they already have the stuff needed for this project.
Building your own libraries is becoming increasingly unnecessary anyway, as prepackaged binaries of most common libraries are available for most systems these days. But of course, if you are on an unusual platform, or have specialized needs which dictate recompilation with different options than any available prebuilt binary, you will still need to understand how to do this.

My library does not load on other systems but works fine on the system it was compiled on

My project includes a library and example projects for how to use it. I place the library in the "bin" folder along with all executable examples. I can run the example projects on the machine where they were compiled but when I try to run them on another machine I get:
./example: error while loading shared libraries: libMyLib.so: cannot
open shared object file: No such file or directory
This makes no sense since the library is in the same folder. What is causes it to ignore the library on other machines?
Just because the library is in the same directory as the executable doesn't mean it will look there for it. By default on linux, executables will only look in a limited set of directories, set by ldconfig and the LD_LIBRARY_PATH environment variable.
One trick that is very useful is to link your program with the extra linker option
-Wl,-rpath,'$ORIGIN'
which will cause the executable to also look in the directory the executable is in for shared objects.
You can usually set this by adding to your Makefile:
LDFLAGS := -Wl,-rpath,'$$ORIGIN'
Note the double-$ here -- make will interpret this as a make variable which expands to just $
The current directory is not necessarily a place where the dynamic linker will look for dynamic libraries. The directory where the executable is much less.
You might want to check ldconfig to see where it looks for them.

Autoconf, Libtool shared and static library

I am using autoconf gnu tools to build my product.
It generates both the shared as well as static library for any library where *.la is mentioned.
The issue is if you use .la to link your binary in Makefile.am.
It links with the dynamic library but when you use ldd to the binary, it says
"not a dynamic executable" although it links with shared library. I proved it by removing the shared library after the binary is built and then tried to run the binary. It didn't find the shared library and couldn't run.
Another question is how to put library in a specified location using Makefile.am direction ?
Looks like you run ldd on the wrapper scripts created by libtool. They are used to link uninstalled libraries with uninstalled executables. Real binaries are placed in .libs directory.
You can install a lib to some specific place in this way
mylibrary_LTLIBRARIES = libmylibrary.la
mylibrarydir = ${libdir}/my_plugins/

Linking against a specific shared library version in linux

My build process consists of Qt's qmake Makefile generator and the typical make utility bundled with linux.
My application consists of a few shared libraries and the main application is linked against them.
How can I apply the typical linux versioning scheme on my libraries? (Use version 2 -> link against foo.so.2 that points to foo.so.2.y.z with an ldconfig generated link).
The answer doesn't have to be specific for my build process.
Your library should be named libfoo.so.2.y.z, with symlinks of libfoo.so.2 and libfoo.so both pointing to that. The library should be created using -soname libfoo.so.2 in the linker command line (or -Wl,-soname,libfoo.so.2 on the gcc command line).
Hope that helps!

Resources