Reputation: 3143
I have a project in C++ which currently is not linked against any external dynamic library. I'm thinking about using some of boost libraries in future which need to be built (not header-only). For now, in the stage of development, I build my project with three different tool chains: g++
, LLVM/Clang++
and Intel C++
, the platform is Linux
. These compilers, AFAIK, are binary compatible with each other, e.g. g++-compiled app can use Intel C++-compiled dynamic library.
I've built boost binaries and installed them into different folders. e.g. build_gcc
, build_icc
. Then I added paths to these folders to the system LIBRARY_PATH
. The question is: if I now build my project with either g++
or Intel C++
and link some dynamic library, e.g. write
-lboost_math_tr1
in the makefile
, how does the linker decide which exact library file to link against if the binaries from different compilers are compatible with each other?
The motivation of the question is simple: Intel C++
is an optimizing compiler, so if I build things with it, I expect them to be linked against dynamic library compiled with Intel C++
compiler, not against the one compiled with g++
. Of course, I know that I can simply use multiple conditional statements in the makefile
to set the exact directories with library binaries for each used tool chain but it is just a bit inconvenient. I am wandering, is the linker smart enough to recognize which exact shared library file it should use or does it simply use the first occurrence found in the system LIBRARY_PATH
?
Upvotes: 0
Views: 651
Reputation: 31374
the linker won't know. if the first found library is incompatible, it will even bail out, rather than search all libs until it finds a compatible one.
confirm something like:
$ cat foo.c
int main() {
return 0;
}
$ mkdir bar
$ touch bar/libm.so
$ gcc foo.c -o foo -Lbar -lm
/usr/bin/ld: error: b/libm.so: file is empty
collect2: error: ld returned 1 exit status
otoh, the beauty of dynamic linking lies in being able to exchange the dylib with a better one, without having to recompile. so you can link against the g++ version, but if performance is poor install the icc version on the target host (on a place that will be searched for before the g++-version) and your application will magically use it (as long as they are compatible).
you could also use the LD_LIBRARY_PATH
variable to search for libraries in a non-standard location when running your application:
LD_LIBRARY_PATH=/path/to/super/libs/ ./app-dylinked-with-generic-libs
Upvotes: 1
Reputation: 12117
You need to add these libraries to $LIBRARY_PATH
(linking) and $LD_LIBRARY_PATH
(runtime) not the $PATH
. I feel like you can set these variables in your Makefile
one at a time to decide which binary to link against.
Upvotes: 0
Reputation: 64308
The PATH environment variable is used for finding executables, not for finding libraries. Each compiler has a set of standard places it looks for libraries, plus places that are specified explicitly using -L. It isn't going to care about which compiler created the library.
Upvotes: 0