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.
答案 0 :(得分:1)
这不是专门的问题,而是在具有gcc和共享库的Linux上的工作方式。
http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
当您指定@Lock
时,会将链接设置为target_link_libraries( target /usr/lib/x86_64-linux-gnu/libprotobuf.so)
。在这种情况下,它应该只使用它首先找到的任何版本的库。
-lprotobuf
调整cmake生成的链接行以使用特定的库版本。这似乎告诉gcc链接到该版本,它将更改运行时和库搜索时发生的情况。
在某些情况下,CMake可能会要求链接程序搜索该库(例如/usr/lib/libfoo.so变为-lfoo),例如,当检测到共享库中没有SONAME字段时。有关其他情况的讨论,请参阅策略CMP0060。