0
votes

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?

3

3 Answers

1
votes

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
0
votes

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.

0
votes

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.