Setting path to shared library inside a makefile for execution - linker

I want to run a program from inside my makefile which is linked against some shared libraries which are of my own creation. But I don't want them to be permanently added to the library pool of my system.
How can I accomplish this?
I already figured that I somehow have to use/set the LD_LIBRARY_PATH but how as this doesn't seem to work for me:
run:
export LD_LIBRARY_PATH=$(TESTLIB):$(DEPENDENCIES)
./testit
Also trying to run an extra export task wasn't successfull:
export:
ldconfig -n $(DEPENDENCIES)
ldconfig -n $(TESTLIB)

Each line in a recipe is run in its own shell, so change it to:
run:
export LD_LIBRARY_PATH=$(TESTLIB):$(DEPENDENCIES); \
./testit
or
run:
LD_LIBRARY_PATH=$(TESTLIB):$(DEPENDENCIES) ./testit

Related

Where do the pkg-config targets get defined?

When I perform the command
pkg-config --variable pc_path pkg-config
The output is
/usr/lib64/pkgconfig:/usr/share/pkgconfig
However, there are two other pkgconfig directories on my system: /usr/lib/pkgconfig and /usr/local/lib/pkgconfig
If I try
echo $PKG_CONFIG_PATH
the result is
Undefined variable
I also tried to
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
but the response was
export: Command not found.
Now, I have built Gstreamer on multiple occasions and it will put the
metadata files (gstreamer-1.0.pc) into the other pkgconfig folder (usr/local/lib/pkgconfig). (I have been able to overcome this issue by modifying the configure file, changing lib to lib64 at the libdir definition.) But I would rather understand my system rather than try work-arounds.
So two questions: where does the pkg-config program get its target directories?
And why and how do the metadata files get put into a directory that is not apparently indicated by the pkg-config program?
Since the command is not working because that variable was not present
first check that variable is there or not for to do this
execute command
env
root#localhost:/etc/apt# env
if the path is not declare in env
then do something like
root#localhost:/etc/apt# PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
root#localhost:/etc/apt# export PKG_CONFIG_PATH
root#localhost:/etc/apt# echo $PKG_CONFIG_PATH
/usr/local/lib/pkgconfig
root#localhost:/etc/apt# env
Hope this will work for you
for any further help please post the queries with error
When you install a foo package, foo package has an appropriate foo.pc that gets installed in the default pkgconfig directories. If a package puts its *.pc file in a custom location, as you already know, you should set your PKG_CONFIG_PATH accordingly. So, the pkg-config will not only look in the default directories, but also in the custom path you specified in PKG_CONFIG_PATH. This guide explains it well:
pkg-config guide

Cython not finding shared library

My issue started identical to this one: Python executable not finding libpython shared library
I updated .bashrc with export LD_LIBRARY_PATH=$HOME/local/lib/python/2.7.6/lib and things were fine. Python works, and I installed pip. But now, I'm running into something similar when installing cython with pip. I get this error message when I execute pip install cython:
gcc -pthread -shared build/temp.linux-x86_64-2.7/tmp/pip_build/cython/Cython/Plex/Scanners.o -L. -lpython2.7 -o build/lib.linux-x86_64-2.7/Cython/Plex/Scanners.so
/usr/bin/ld: cannot find -lpython2.7
collect2: ld returned 1 exit status
error: command 'gcc' failed with exit status 1
I cannot add $HOME/local/lib/python/2.7.6/lib to /etc/ld.so.conf and run ldconfig as I do not have root. I was under the impression that setting the LD_LIBRARY_PATH was the way around this, but this appears to not be true for compilation. Is there a way to get the compiler to see this local library without running root commands?
Update:
The LD_LIBRARY_PATH is only used by the dynamic loader at runtime, not at build time, so that is not the issue. The issue is that you forgot to put the -L/path/to/pylib before the -l. I've never had to use LIBRARY_PATH because a build requires path extension that is specific to a given build, so you never set LIBRARY_PATH you just use -L. You would only set if if you are going to regularly do builds that use a specific library, and even then I find it better to use -L because sooner or later this will cause linker to find the wrong lib and by then you will have forgotten that it's because LIBRARY_PATH is set permanently.
There are many ways to set -L values in a build: if you run the compiler from command line you don't need that env var, you just specify as many -L as required as part of the command; if you use a makefile, you edit whatever make variable you are using, such as CFLAGS or other, different platforms have different conventions. So whereas setting -L directly will always work, setting CFLAGS will only work if that is the variable used by the makefile.
Now this is a python installation so where to set this may not be obvious, but I am sure there is another way than setting LIBRARY_PATH. In principle any python package you install, if it involves compilation of C++ modules, could require edit of the setup.py to set library paths. For example
Extension(...,
library_dirs=['/usr/X11R6/lib'],
...)
Since you mention nympy, another place to set this might be in site.cfg (see Supplying NumPy site.cfg arguments to pip).
Old (wrong) answer:
Set your LD_LIBRARY_PATH in your bash console. If this doesn't work then it's because you have the wrong path: check by echoing the environment var.
Once you get that to work, edit your .bashrc or .profile then exit your shell and restart it. Echo the env var to verify that contains the part you added.
Also, ensure that you are appending to the path rather overwriting it:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/...
export LD_LIBRARY_PATH
Because python lib might depend on .so in other folders, if the linker can't find them it may appear as though it is the python lib that was not found. This is not explained on the page you linked to in your question.
OK after some more digging I found this: LD_LIBRARY_PATH vs LIBRARY_PATH
Setting LIBRARY_PATH to the same path as LD_LIBRARY_PATH made the compiler aware of the python lib. cython/numpy/scipy all built and installed no problem afterwords.

Automake error './ltmain.sh' not found

I've installed mingw and msys by using mingw-get-setup.exe. I've also installed Autotools(autoconf, automake,m4,libtool) into C:\/opt/autotools.
When I run automake, the following error always occurs:
configure.ac:11: error: required file './ltmain.sh' not found
If I copy ltmain.sh from libtool’s installed tree, execution will finish normally.
How can I configuure automake to find ltmain.sh without copying?
In an autoconf/automake/libtool project you need to run:
libtoolize: this copies/links a few support scripts, including ltmain.sh (which is the main component of libtool).
aclocal: this looks up all m4 macros that your configure script will need, and make a local copy for easier access.
autoheader: optional, if you want to use config.h/AC_CONFIG_HEADERS, otherwise all the test result macros will be inlined when you call the compiler.
autoconf: to expand all the macros used by configure.ac into the configure script.
automake: to convert all the Makefile.am into Makefile.in templates. You probably want to invoke this with --add-missing so additional support scripts can be linked/copied to your project (such as compile, missing, depcomp, test-driver, etc).
Don't worry about running each tool. Just invoke autoreconf -i and it'll run the tools that are needed. Add -v if you want to see what tools is being executed. To avoid mistakes, just put a script like this at the root of your project:
#!/bin/bash -x
mkdir -p m4
exec autoreconf --install "$#"
Users that checkout/clone the project directly from the source repository will need to run this ./bootstrap script at least once. This is not needed if the user got a tarball distribution.
Automake can take fairly good care of itself; it'll re-invoke the above tools when needed, when you run make. But if you generate a broken Makefile, you'll need to invoke ./bootstrap and ./configure again to generate new Makefiles.
As DanielKO stated, ltmain.sh is created by libtoolize.
However, what if it doesn't?
The following requirements need to be met:
configure.ac must exist and contain at least one of:
AM_PROG_LIBTOOL,AC_PROG_LIBTOOL,LT_INIT
(see function func_require_seen_libtool in /usr/bin/libtoolize)
If configure.ac does not contain a AC_CONFIG_AUX_DIR, libtoolize will look for a file called 'install-sh' or 'install.sh' in ., .. and ../.. and if found use that as "auxdir" and install ltmain.sh there (see function func_require_aux_dir inside libtoolize).
In my case, I was working on an "example project" in a subdirectory of another project, and the example project did not have a AC_CONFIG_AUX_DIR in its configure.ac; therefore libtoolize found the root of the parent project and installed ltmain.sh there instead of in the example project's root.

How to build example with shared object in GnuTLS

I'm trying to compile example from GnuTLS. I can compile GnuTLS with no problem.
I usually use this command when I have default GnuTLS package installed. I compile the example with this commend.
gcc -o server ex-serv-srp.c -lgnutls
I build GnuTLS from source. I can compile the example with the same command but when I try to run the example I get this error:
./server: error while loading shared libraries: libgnutls.so.28: cannot open shared object file: No such file or directory
The location of libgnutls.so.28 is in /usr/local/lib directory. How I can link the example during compilation time so that they will know where to find libgnutls.so.28
Regards
For a permanent solution add /usr/local/lib to /etc/ld.so.conf and rerun ldconfig, otherwise do as zvbra proposes.
You should set LD_LIBRARY_PATH variable like this export LD_LIBRARY_PATH=/usr/local/lib.

linking libraries -rpath LD_LIBRARY_PATH

I have some 3rd party libraries and includes (I have copied them to the this location /usr/ssd/include and /usr/ssd/lib) that I need to link with my application. I have just created a test application to see if I can link ok. However, when I try to run my app I get the following message.
./app: error while loading shared libraries: libssdn.so: cannot open shared object file: No such file or directory
On the command line I am compiling like this:
gcc -g -Wall -I/usr/ssd/include -L/usr/ssd/lib -lssdn test_app.c -o app
Everything compiles ok, as I don't get any warnings or errors. However, I get the error when I try and run the app.
In the usr/ssd/lib the library is called libssdn.so
I am been looking for solution and I have read something about -rpath, -Wl and LD_LIBRARY_PATH, but not sure what they are and how to include them when I compile.
I am using Ubuntu 9.04 Linux,
Thanks for any advice,
Test if adding /usr/ssd/lib to your $LD_LIBRARY_PATH helps:
In a shell:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/ssd/lib
If that solves the problem, make it permanent by adding /usr/ssd/lib to /etc/ld.so.conf or by running
ldconfig -n /usr/ssd/lib
My personal preference is not to bake the location of a shared object into an executable (which is what -rpath would do).
Instead, you should add /usr/ssd/lib to your LD_LIBRARY_PATH at run time. Assuming you are running bash or a bash like shell, do:
export LD_LIBRARY_PATH=/usr/ssd/lib:${LD_LIBRARY_PATH}
and once you do that, you can run your executable.

Resources