Reputation: 662
I have some CMake packages that depend on Protobuf v2.5, and one that depend on Protobuf v3.4. I have v2.5 installed system-wide in /usr
, whereas v3.4 is only used in a single package. Therefore, I put the headers for v3.4 in a 3rdparty
subdirectory inside the package where it is being used, and then I call include_directories(3rdparty)
in my CMakeLists.txt so it can be found.
As for the shared libraries, the .so files for v2.5 are present in /usr/lib/x86_64-linux-gnu
, and I installed the .so files for v3.4 to /usr/lib
. In short, this is what the directory structure looks like:
v2.5:
headers: /usr/include
libraries: /usr/lib/x86_64-linux-gnu
v3.4:
headers: <MY_PACKAGE_SRC_DIRECTORY>/3rdparty
libraries: /usr/lib
Now, the problem arises when I try to link against v3.4. To simplify things, I don't use any CMake module files to find protobuf v3.4, rather I just add a hard-coded path /usr/lib/libprotobuf.so
to the list of libraries to link against when creating a target. But even so, when I run ldd my_target_executable
, the result is:
libprotobuf.so.8 => /usr/lib/x86_64-linux-gnu/libprotobuf.so.8
meaning that it is linking against the libraries for v2.5 in /usr/lib/x86_64-linux-gnu
, even though I added a hard-coded path to the correct .so file in /usr/lib
in the call to target_link_libraries
when building this executable.
What is worth noting is that if I remove the .so files in /usr/lib/x86_64-linux-gnu
, then it does link against the correct .so file in /usr/lib
, so it appears that for some reason, CMake searches in /usr/lib/x86_64-linux-gnu
before using the library path that I provide it. How can I change this behavior, or fix this problem in any other way?
UPDATE
The library file for v3.4 /usr/lib/x86_64-linux-gnu/libprotobuf.so
is a link to /usr/lib/x86_64-linux-gnu/libprotobuf.so.14
which in turn is a link to the actual file /usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0
.
Now, if I change the hard-coded path that I give in target_link_libraries
from /usr/lib/x86_64-linux-gnu/libprotobuf.so
to either the second symlink /usr/lib/x86_64-linux-gnu/libprotobuf.so.14
, or to the actual file /usr/lib/x86_64-linux-gnu/libprotobuf.so.14.0.0
, then my executable correctly links againt v3.4. It appears that the name of the provided symlink has some effect on CMake's behavior.
Upvotes: 0
Views: 4307
Reputation: 3564
This isn't cmake specifically but also how things work on Linux with gcc and shared libraries.
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
When you specify target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so)
this sets up linking as -lprotobuf
. In this case it should just use any version of the library it finds first.
target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so.14)
adjusts the cmake generated link line to use a specific library version. This seems to tell gcc to link against that version which will change what happens at run-time and library searches.
There are some cases where CMake may ask the linker to search for the library (e.g. /usr/lib/libfoo.so becomes -lfoo), such as when a shared library is detected to have no SONAME field. See policy CMP0060 for discussion of another case.
Upvotes: 2