Weird behavior of gcc while linking BLAS library - gcc

I have ATLAS library "libatlas.so" in an unstandard directory "/opt/apps/gcc4_7/atlas/3.10.2/lib/"
I put the path along with other search paths in environment variable
LD_LIBRARY_PATH=/opt/apps/gcc4_7/atlas/3.10.2/lib:and_others
Then link my code with it as follow:
g++ mycode.o -L$LD_LIBRARY_PATH -latlas
It then say "ld: cannot find -latlas"
But if I add the path again as follow:
g++ mycode.o -L$LD_LIBRARY_PATH -L/opt/apps/gcc4_7/atlas/3.10.2/lib/ -latlas
I have no issues.
I cannot think of any reasons this could happen. Is it because the $LD_LIBRARY_PATH has too many paths in it?

Related

setting LD_LIBRARY_PATH doesn't have any effect in bash, why? [duplicate]

I'm building a simple C++ program and I want to temporarily substitute a system supplied shared library with a more recent version of it, for development and testing.
I tried setting the LD_LIBRARY_PATH variable but the linker (ld) failed with:
/usr/bin/ld: cannot find -lyaml-cpp
I expected that to work because according to the ld man page:
The linker uses the following search
paths to locate required shared
libraries: ... For a native linker,
the contents of the environment variable
"LD_LIBRARY_PATH"...
I then tried setting the LIBRARY_PATH, and that worked.
According to the GCC manual:
The value of
LIBRARY_PATH is a colon-separated list
of directories, much like PATH. When
configured as a native compiler, GCC
tries the directories thus specified
when searching for special linker
files, if it can't find them using
GCC_EXEC_PREFIX. Linking using GCC
also uses these directories when
searching for ordinary libraries for
the -l option (but directories
specified with -L come first).
As the (GCC) manual suggests, LIBRARY_PATH works because I link with GCC.
But..
Since I link with gcc why ld is
being called, as the error message
suggests?
What's the point of
having two variables serving the same
purpose? Are there any other
differences?
LIBRARY_PATH is used by gcc before compilation to search directories containing static and shared libraries that need to be linked to your program.
LD_LIBRARY_PATH is used by your program to search directories containing shared libraries after it has been successfully compiled and linked.
EDIT:
As pointed below, your libraries can be static or shared. If it is static then the code is copied over into your program and you don't need to search for the library after your program is compiled and linked. If your library is shared then it needs to be dynamically linked to your program and that's when LD_LIBRARY_PATH comes into play.
LD_LIBRARY_PATH is searched when the program starts, LIBRARY_PATH is searched at link time.
caveat from comments:
When linking libraries with ld (instead of gcc or g++), the LIBRARY_PATH or LD_LIBRARY_PATH environment variables are not read.
When linking libraries with gcc or g++, the LIBRARY_PATH environment variable is read (see documentation "gcc uses these directories when searching for ordinary libraries").
Since I link with gcc why ld is being called, as the error message suggests?
gcc calls ld internally when it is in linking mode.
LIBRARY_PATH is used by linker (ld)
LD_LIBRARY_PATH is used by loader (ld.so)

automake program libtool wrapper linking

Am stumped on an automake link. Even after pouring over the manuals for hours and searching online it is probably a misunderstanding of autotools.
I have one .la library made by libtool, one .dylib shared library and am creating a program. The .la is linked to the .dylib and the program uses the .la.
Makefile.am for the .la library
lib_LTLIBRARIES = libA.la
libA_la_LDFLAGS = ${AM_LDFLAGS} -no-undefined
libA_la_LIBADD = $(LIBM) -Ldir/to/ -lB
libA_la_CPPFLAGS = ${AM_CPPFLAGS}
Makefile.am for program with libtool wrapper
noinst_PROGRAMS = test
test_SOURCES = test_source.c
test_LDADD = libA.la -Ldir/to/ -lB
libA.la is created and links to B.dylib but the test program "wrapper" created by automake is exporting DYLD_LIBRARY_PATH to find libA.la while not linking to B.dylib. Giving the error
dyld: Library not loaded: ./B.dylib
Referenced from: /dir/to/test/.libs/test
Reason: image not found
Trace/BPT trap: 5
Some things that I have tried are adding -Ldir/to/ -lB to test_LDFLAGS in addition to already being added in test_LDADD. And have tried setting test_LDFLAGS = -rpath -Ldir/to in the hopes that setting the runtime search path to the directory where B.dylib is would help.
If I manually export DYLD_LIBRARY_PATH to include /dir/to/B.dylib then the test program is able to run but I'm looking to have autotools take care of this rather than requiring someone to export a path before being able to run it.
libB.dylib includes an rpath that gets copied into your binary and that is used to resolve -lB at runtime.
And it seems that this rpath is not /path/to, so libB.dylib cannot be resolved by the runtime linker.
The reasons why it works for libA.la is that libtools knows that the rpath in libA.dylib is wrong anyhow (as you haven't done a make install) and so it needs to be set manually.
The only way around this that i have found is to use install_name_tool to fix the stored rpath in the resulting binary.
(that is: I don't think that libtool will do this for you, as it contradicts the intended use of libB.dylib - as declared in its rpath)
The problem is that Libtool wasn't involved in building libB.dylib, so it does not know how to fix up your environment to find it. That means it is up to you. You can add path/to/ libB in your environment, or add a hardcoded search path to libA.la so that libA will find it.
libA_la_LIBADD = $(LIBM) -Ldir/to/ -rpath dir/to/ -lB
This will not only add the path to B in libA's binary, but will add it to dependency-libs in Libtool's libA.la file so that on platforms that won't automatically inherit the rpath specification it can be added by Libtool when linking.

ld: After successful linking shared lib not found on execution

I am currently working on a simple data synchonizer in a mixture of Fortran and C/C++ by using OpenMPI libraries. The synchonizer compiles and links correctly, as far as I can see:
f95 -o fortran_mpi_test *.o -L/usr/lib/gcc/x86_64-redhat-linux/4.1.1/
-L/usr/lib64/openmpi/1.4-gcc/lib/ -lmpi -lmpi_cxx -lstdc++
But when I execute the resulting executable on the same machined I get an error stating that one of the shared libraries is not found. That is confirmed by ldd.
Nevertheless the missing library libmpi_cxx.so.0 is located in one of the specified folders.
Could anyone give me a hint what I could have done wrong?
Check your environment variables. If your LIBRARY_PATH, LD_LIBRARY_PATH or similar vars have gotten out of sync or set to silly values you might not be searching the same directories for static libraries as you do for dynamics.
Also check out the ld.so manpage

preparing lapack dll with mingw

I downloaded lapack 3.3.0 version and mingw (with all libraries) after that I succeded to make blas.dll by gfortran --shared -o blas.dll blas\src\*.f -O
I could not succeeded to make lapack.dll by gfortran --shared -o lapack.dll src\*.f blas.dll -O
I got the following error
gfortran: error: CreateProccess: No such file or directory
Note: I set path to mingw/bin and also copied dlamch.f and slamch.f from install directory to src directory.
:: instructions got from this site
http://www.codingday.com/compile-lapack-and-blas-as-dll-on-windows/
What should I do
I donwloaded lapack and can reproduce the error.
As is indicated in the comments on the page you referred to, you might be running into a problem with the command line being too long for the shell to handle. Try first compiling all source files, and then linking them, in two separate steps.
gfortran -c src/*.f -O
gfortran -shared -o lapack.dll *.o blas.dll
When I did this the CreateProcess error went away, but unfortunately some undefined reference errors popped up next. It appears there are references to a couple of blas functions which aren't included in the blas sources accompanying lapack (I think they might be C functions).

LD_LIBRARY_PATH vs LIBRARY_PATH

I'm building a simple C++ program and I want to temporarily substitute a system supplied shared library with a more recent version of it, for development and testing.
I tried setting the LD_LIBRARY_PATH variable but the linker (ld) failed with:
/usr/bin/ld: cannot find -lyaml-cpp
I expected that to work because according to the ld man page:
The linker uses the following search
paths to locate required shared
libraries: ... For a native linker,
the contents of the environment variable
"LD_LIBRARY_PATH"...
I then tried setting the LIBRARY_PATH, and that worked.
According to the GCC manual:
The value of
LIBRARY_PATH is a colon-separated list
of directories, much like PATH. When
configured as a native compiler, GCC
tries the directories thus specified
when searching for special linker
files, if it can't find them using
GCC_EXEC_PREFIX. Linking using GCC
also uses these directories when
searching for ordinary libraries for
the -l option (but directories
specified with -L come first).
As the (GCC) manual suggests, LIBRARY_PATH works because I link with GCC.
But..
Since I link with gcc why ld is
being called, as the error message
suggests?
What's the point of
having two variables serving the same
purpose? Are there any other
differences?
LIBRARY_PATH is used by gcc before compilation to search directories containing static and shared libraries that need to be linked to your program.
LD_LIBRARY_PATH is used by your program to search directories containing shared libraries after it has been successfully compiled and linked.
EDIT:
As pointed below, your libraries can be static or shared. If it is static then the code is copied over into your program and you don't need to search for the library after your program is compiled and linked. If your library is shared then it needs to be dynamically linked to your program and that's when LD_LIBRARY_PATH comes into play.
LD_LIBRARY_PATH is searched when the program starts, LIBRARY_PATH is searched at link time.
caveat from comments:
When linking libraries with ld (instead of gcc or g++), the LIBRARY_PATH or LD_LIBRARY_PATH environment variables are not read.
When linking libraries with gcc or g++, the LIBRARY_PATH environment variable is read (see documentation "gcc uses these directories when searching for ordinary libraries").
Since I link with gcc why ld is being called, as the error message suggests?
gcc calls ld internally when it is in linking mode.
LIBRARY_PATH is used by linker (ld)
LD_LIBRARY_PATH is used by loader (ld.so)

Resources