Nominate library directory at compilation - linux

I was able to generate an executable using
gcc myexec -o obj1.obj -o obj2.obj ...and link xxx.dylib
I deploy myexec to a different machine. myexec, ofcourse, would need xxx.dylib to run.
For that, I create myInstallFolder with xxx.dylib and myexec
On deployment, I was able to make myexec pick xxx.dylib by setting DYLD_LIBRARY_PATH point to myInstallFolder.
However, I want to avoid using DYLD_LIBRARY_PATH.
What change should be done at compilation/linking to make myexec pick up from myInstallFolder?
~Ryder

You can instruct the linker to write a path into the binary that the loader will use to load .so files:
-Wl,-R<path to myInstallFolder>
For example
-Wl,-R/usr/local/mybin/lib

Related

Is it possible to permanently add directories to the default ld search path?

I'm attempting to install a library that will be used generally on this node. Currently the library is installed in a location that includes it's version name /opt/sample-x.y.z/lib/libsample.so. Ideally I'd like to be able to update the library, change the sys configs and not bother other devs with needing to change paths on trivial changes. I've added the library directory to the /etc/ld.so.conf.d/sample.conf and run ldconfig, but this only seems to affect loading not linking.
When I run ldconfig -v | grep sample, I correctly see libsample.so.
However, whenever I run ld -lsample --verbose, it fails to find the library. In the verbose output, it details the directories that it searches and the one I added with ldconfig isn't there. As a workaround, I tested adding a symlink to the library in /usr/lib and ld was able to find it.
Are there other ways to add the library to the default linker path? Ideally I'm looking for a config file that I can modify similar to the one for loading.
If it matters, the node is a Centos7 node.
No, it is not possible. The paths that ld uses during the linking phase are configured via scripts which are pulled into ld during its build process. There isn't a way to update these after ld is built. There are other questions and answers related to accomplishing this for GCC specifically which seem to involve the LIBRARY_PATH environment variable. That solution, however, is gcc specific.

Does an executable need so file even after it is linked during the creation?

I have started looking into the concepts of linking libraries with exes and working in Linux machine. I'm struggling to understand the concept of linking so files with executables.
app:$(CC) $(CFLAGS) $(LDFLAGS) app.o app_dep.o -L . -ldynamic -Wl,-rpath . \
-o app
I'm trying to create an executable app with the above lines in makefile. I have to link it with a libdynamic.so file which exists in the working directory. So i used -L flag and -rpath to point to the directory and name of the so file. It worked and executable is created.
But when i tried to run the executable, it again complains that libdynamic.so: cannot open shared object file: No such file or directory.
Why do i need it since i linked the sharedlibrary during the creation of executable itself?
If the answer to the question is "Yes, it is required to point to the lib even it is linked". How could i point to the folder where it presents during the execution of binary?
One way i found is using LD_LIBRARY_PATH environment variable. Is there any other way to do without environment variable?
Thanks
Why do i need it since i linked the sharedlibrary during the creation of executable itself?
Because linking against a shared library does not embed that shared library into the executable. That is the main difference between linking with a shared versus archive library.
How could i point to the folder where it presents during the execution of binary?
There are no "folders" in UNIX. They are directories.
The correct link command to make an executable look in current directory is:
gcc -o app app.o ... -L. -ldynamic -Wl,-rpath=.
Note that in general it's a really bad idea to do so: your executable will or will not run depending on your current directory (or it may use different versions of libdynamic.so depending on which directory you are in).
Your link command should have worked if you invoked app in the directory with libdynamic.so present (i.e. if you invoked it like ./app), but not if you used /path/to/app (and were not in the same directory).
A significantly better approach is to do this:
gcc -o app app.o ... -L. -ldynamic -Wl,-rpath='$ORIGIN'
That tells the app binary to look for libdynamic.so in the same directory in which app is located, regardless of your current directory.

shared library not found during compilation

So I got several shared libraries that I am trying to permanently install on my Ubuntu system but I am having some difficulty with it.
I want to install the libraries and the headers in a separate folder under /usr/local/lib and /usr/local/include (for example a folder named agony) so it would be clean and removing them would just require that I delete those folders. so it looks something like this:
/usr/local/lib/agony/libbtiGPIO.so
/usr/local/lib/agony/libbtiDSP.so
...
/usr/local/include/agony/GPIO.h
/usr/local/include/agony/DSP.h
...
And I added a file here /etc/ld.so.conf.d/agony.conf which include a line describing the path to the library folder:
$ cat /etc/ld.so.conf.d/agony.conf
/usr/local/lib/agony
and I perform sudo ldconfig to update the library database.
So to double check if the library is found I do ldconfig -p | grep bti* and
I see the following result:
$ ldconfig -p | grep bti
...
libbtiGPIO.so (libc6,x86-64) => /usr/local/lib/agony/libbtiGPIO.so
libbtiDSP.so (libc6,x86-64) => /usr/local/lib/agony/libbtiDSP.so
...
At this point I should be able to use the libraries without specifying the library path. But When I attempt to compile an application without providing the library path (-L) it fails. However, when I supply gcc with the library path ex:
gcc source.c -L /usr/local/lib/agony output -lbtiGPIO -lbtiDSP
it works!!
I don't want to use LD_LIBRARY_PATH environment variable because this library is going to be used everywhere on the system and I don't want other compilers to worry about providing LD_LIBRARY_PATH.
What am I doing wrong here?
At this point I should be able to use the libraries without specifying the library path
Here lies the confusion.
You have built your shared library libbtiGPIO.so (just sticking with that one),
placed it in /usr/local/lib/agony, and updated the ldconfig database accordingly.
The effect of that is when you run a program that has been linked with libbtiGPIO
then the dynamic linker (/lib/x86_64-linux-gnu/ld-2.21.so, or similar) will know where to look
to load that library into the process and you will not need to tell it by setting an LD_LIBRARY_PATH in the environment.
However, you haven't done anything that affects the list of default library
search directories that are hardwired into your build of gcc, that it passes to
the linker (/usr/bin/ld) when you link a program with libbtiGPIO in the first place.
That list of default search directories is what you will find if your do a verbose
build of your program - gcc -v ... - and then pick out the value of LIBRARY_PATH
from the output, e.g.
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:\
/lib/x86_64-linux-gnu/:\
/lib/../lib/:\
/usr/lib/x86_64-linux-gnu/:\
/usr/lib/../lib/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../:\
/lib/:\
/usr/lib
/usr/local/lib/agony is not one of those and to make it one of those you
would have to build gcc from source yourself. Hence, in order to link your
program with libbtiGPIO you still need to tell ld where to find it with
-L/usr/local/lib/agony -lbtiGPIO.
man, you misunderstand the procedure of complier and link.
First, libbtiGPIO.so is a shared link library not a static link library. it is important to know those difference .
Then you need to know something else. changing ld.so.conf.d/*.conf and run sudo ldconfig, it affects the procedure of link. in other words, if you don't add agony.conf and sudo ldconfig, you will receive a error when you run ./a.out rather than gcc source.c -L ...., the gcc command can run successfully even thougth you don't ldconfig.
Finally,if you don't pollute the LD_LIBRARY_PATH environment variable, you have to add -L ... options in your gcc command. What'more, if you don't want to input too many words in your shell frequently, you can learn to use Makefile.

Compiling library in linux when in another folder

I'm new in Linux. I have a library in a folder next to my C program source but I don't know how to compile it. I've compiled everything when my library was in the same folder as program code file. However, I do not understand how to use the library from another location?
Use gcc's -L option to specify where your library located, and -l option to specify what your library is.
If you're using 'make' to build your program, just open the Makefile and find out where -L option has used.
For example,
gcc -L ./my_program/my_library -lmylib -o my_executable ./my_program/src/my_program.c
Also, you can use LD_LIBRARY_PATH environment variable to specify your library path to your program.
Say that you have ready to run your excutable, but the library is not in any standard library path (such as /usr/lib),
then you can run your program by following command.
$ LD_LIBRARY_PATH=/home/my_name/my_program/my_library my_executable

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

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.

Resources