local gcc build links system dynamic libraries - gcc

i build and installed gcc-4.6.4 into my home dir (i don't have root proviliges).
When I link a few object files to an executable with g++, it links the "wrong" libstdc++.so.6.
It does not use the newer one wich is located in the install dir but the one of the system.
Is there a way to specify an exclusive search path for libraries?
My bashrc:
PATH=$PATH:/home/testuser/selfcompiled/gcc-4.6.4/bin:/usr/local/cuda/bin
export PATH
C_INCLUDE_PATH=/home/testuser/selfcompiled/gcc-4.6.4/include
export C_INCLUDE_PATH
CPLUS_INCLUDE_PATH=/home/testuser/selfcompiled/gcc-4.6.4/include
export CPLUS_INCLUDE_PATH
LIBRARY_PATH=/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LIBRARY_PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin:/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LD_LIBRARY_PATH
GCC_EXEC_PREFIX=/home/testuser/selfcompiled/gcc-4.6.4/lib/gcc/
export GCC_EXEC_PREFIX
COMPILER_PATH=/home/testuser/selfcompiled/gcc-4.6.4/bin/:/home/testuser/selfcompiled/gcc-4.6.4/libexec/:/home/testuser/selfcompiled/gcc-4.6.4/lib/gcc/
export COMPILER_PATH
Even if I specify the dir with the local libstdc++.so.6 via g++ -L...., the one located in /usr/... is linked to the executable according to ldd.
Thanks very much!

Nothing goes wrong when linking (or you'd get a linker error to symbols not present in the old library version).
This is a runtime thing. This:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin:/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LD_LIBRARY_PATH
Should be
LD_LIBRARY_PATH=/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib:$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin
export LD_LIBRARY_PATH
The executable loader needs to look at your new libraries first, before it looks at the old ones. Of course, there is strong binary compatibility, so if no new symbols are used, the old libs will do just fine.

I am guessing you have built 64-bit executable. This path:
/home/testuser/self‌​compiled/gcc-4.6.4/lib64/lib
looks wrong, and should likely be:
/home/testuser/self‌​compiled/gcc-4.6.4/lib64
To use it, set LD_LIBRARY_PATH, or better use -Wl,-rpath=/home/testuser/self‌​compiled/gcc-4.6.4/lib64

Related

Linking with 2 libraries

I'm trying to link a program with 2 libraries this way:
LNOPT = -Wl,-rpath,$(MKLROOT)/lib/intel64 -Wl,-rpath,/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin
However I either get one of these errors:
./dftb+: error while loading shared libraries: libmkl_gf_lp64.so: cannot open shared object file: No such file or directory
./dftb+: error while loading shared libraries: libiomp5.so: cannot open shared object file: No such file or directory
Depending on which -rpath I put first. How can I address this problem?
Is putting both paths (separated by :) in the environment variable LD_LIBRARY_PATH at runtime an option? (This way, the hard-coded rpath doesn't have to work.)
Example:
LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin ./dftb+
Or put export LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin in some profile rc file so that the library path is always set.
In either case, if there are already other paths which are needed in LD_LIBRARY_PATH add the above to it via LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin:$LD_LIBRARY_PATH instead of simply overriding LD_LIBRARY_PATH completely.
What could/should also work is sourceing the environment variable setup .sh files shipped with both the Intel compilers and the MKL, which, among other variables such as MKLROOT, should setup LD_LIBRARY_PATH pointing to both libiomp5.so and also the dynamic MKL link libraries.

Choose right library version

I have a project which uses libibverbs. I have to compile this project on a server to run it there. The server has libibverbs installed system-wide, but unfortunately it doesn't support a feature which I need.
I decided to compile and use my own version of libibverbs, which has the corresponding feature. So I compiled the library, installed it to my home directory, and updated following environment variables: PATH, LD_LIBRARY_PATH, C_INCLUDE_PATH, LIBRARY_PATH, CPLUS_INCLUDE_PATH
Now I have to compile my project. First I call configure and it fails with following error message:
conftest.c:(.text.startup+0x7): undefined reference to `ibv_open_xrc_domain'
This is the symbol, which is missing in the system-wide version, but is present in the version I installed. First entry in LIBRARY_PATH is the path to the new libibversion, so I expected it is going to be used first, but it seems that the old version is used anyway.
Compilation command which ./configure uses, contains flag -L/libibverbs/1.1.4/lib, which points to the directory with the new library version. This flag goes just after -L/usr/lib/../lib64 which point to the directory, with system-wide libibverbs
If I put -L with new version in the end of command, the conftest compiles successfully.
To be clear following fails: https://gist.github.com/planetA/a421669269b14e69026c53f56fa45b2b
And following works:
https://gist.github.com/planetA/3b0e22bf6aca3a1c67f30bfa3666d9a8
Could you help me to enforce picking the new version of the library in a way that configure catches it?
LD_LIBRARY_PATH specifies directories to be searched, before the
defaults, for a library that is to be loaded in a process at runtime.
It does not affect the directories that are searched for a library
in order to link it at buildtime.
The linker searches for libraries in the directories that are specified
with the -Ldir option in its commandline, before it searches its
default directories. Your configure script tests whether it can find a libibverbs library in the linker's search directories that defines the function
ibv_open_xrc_domain, and fails because it cannot. The value of LD_LIBRARY_PATH does
not matter to this test.
For GNU make, the -L-options it should pass to the linker
are conventionally specified in the environment variable LDFLAGS. GNU autoconf - which
generates your configure script - follows this convention. autoconf generates
the configure script from the project's configure.ac file.
So, if your want your modified package to generate a generate a configure
script such that running ./configure will in turn generate makefiles
in which -L/my/library/version/is/here is passed to the linker then
you need to modify the project's configure.ac like:
LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
and you need to do this in the configure.ac before it runs the test for
the libibverbs library. After making this change you will need to reconfigure
the package by running autoreconf in the project directrory, to regenerate
the configure script.
If you don't want to change the configure.ac like this then you can achieve the same
effect by:
./configure LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
or:
export LDFLAGS="$LDFLAGS -L/my/library/version/is/here"
... # in same shell or a subshell
./configure
Then until the next time you run the configure script the project's makefiles
will pass -L/my/library/version/is/here to the linker. But the next time
you run ./configure you must remember to set LDFLAGS in the same way, or
the regenerated makefiles will revert to the default behaviour.

proper linking of PATH and LD_LIBRARY_PATH after gcc-5.2 install in own directory

I just compiled and installed gcc-5.2. I did not have root access so I installed it in my own directory. I forget at the end what I am meant to link through LD_LIBRARY_PATH and PATH
setenv LD_LIBRARY_PATH /bigbang/data/username/lib/gcc-5.2/lib
setenv LD_LIBRARY_PATH /bigbang/data/username/lib/gcc-5.2/lib64:$LD_LIBRARY_PATH
setenv PATH /bigbang/data/username/lib/gcc-5.2/bin:$PATH
When I simply run ./gcc I get the following error:
gcc: error while loading shared libraries: libiconv.so.2:
Is there something wrong with how I am linking the lib paths? Thanks in advance. Also, I simple did configure with ./configure --prefix=/bigbang/data/username/lib/gcc-5.2/, what is the recommended configuration flags I should use? I'm aiming to use graph_tool.
If you have successfully installed GCC with some non-standard prefix
/my/gcc/prefix then you can use that installation without any
special preparations by passing:
-B/my/gcc/prefix
whenever you call the frontend (gcc, g++, etc). You just call the frontend with the usual command:
gcc -B/my/gcc/prefix ...
This assumes some version of GCC is installed standardly.
See 3.15 Options for Directory Search

How to specify non-default shared-library path in GCC Linux? Getting "error while loading shared libraries" when running

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

Why doesn't Xcode recognize my LIBRARY_SEARCH_PATHS?

I've set LIBRARY_SEARCH_PATHS to /opt/local/lib, and verified that the library in question is there (I'm linking to GLEW):
$ls /opt/local/lib
libGLEW.1.5.1.dylib libfreetype.a libz.a
libGLEW.1.5.dylib libfreetype.dylib libz.dylib
libGLEW.a libfreetype.la pkgconfig
libGLEW.dylib libz.1.2.3.dylib
libfreetype.6.dylib libz.1.dylib
but Xcode gives me the linker error
library not found for -lGLEW
I'm generating the Xcode project with CMake, so I don't want to explicitly modify the Xcode project (if someone suggests adding it as a framework, or something like that). Xcode recognizes USER_HEADER_SEARCH_PATHS fine (as in this question); why doesn't it work here?
Perhaps adding something like this to your CMakeLists.txt?
find_library(GLEW_LIB GLEW /opt/local/lib)
if(NOT ${GLEW_LIB})
message(FATAL_ERROR "Could not find GLEW")
endif()
target_link_libraries(myprogram ${GLEW_LIB} ...)
Where myprogram is the name of the target executable that needs to link with the library. You would replace the ... with the other libraries you are using on that executable.
This way CMake would handle the library path details for you.
Xcode works on potentially multiple SDK's, so whenever your define these kinds of things (like HEADER_SEARCH_PATHS or LIBRARY_SEARCH_PATHS) the current SDK root is prepended to the actual path that's getting passed to the linker.
So, one way to make this work would be to add your directory to the SDK. For example, assuming you're building with the Mac OS X 10.5 sdk, you could add your opt dir:
ln -s /opt /Developer/SDKs/MacOSX10.5.sdk/opt
Your library would now be found on your system.
If you don't want to do this, then you will have to look at CMake and find out how to get it to generate a library requirement for your actual library (I don't know anything about CMake, so I can't help you there). This is also why you see a difference between USER_HEADER_SEARCH_PATHS and HEADER_SEARCH_PATHS re your other question.
As another option, you could also specify this path with the OTHER_LDFLAGS build variable:
OTHER_LDFLAGS=-L/opt/local/lib
This would cause the linker to search /opt/local/lib as well as its standard paths and wouldn't require you to generate a different project file.

Resources