C++ Cmake 无法使用“link_directories”找到库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31438916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:56:59  来源:igfitidea点击:

Cmake cannot find library using "link_directories"

c++cmakemakefile

提问by Karnivaurus

I Ubuntu, I am learning about cmake and make, and just trying a simple example. I have two directories: srcand build. In src, I have two files: main.cpp, and CMakeLists.txt, which has (only) the following text:

我是 Ubuntu,我正在学习 cmake 和 make,只是尝试了一个简单的例子。我有两个目录:srcbuild. 在 中src,我有两个文件:main.cpp, 和CMakeLists.txt,其中(仅)包含以下文本:

add_executable(test main.cpp)
link_directories(/usr/lib/x86_64-linux-gnu)
target_link_libraries(test protobuf)

In /usr/lib/x86_64-linux-gnu, there is a shared library called libprotobuf.so, which I want to link against. My main.cppuses functions in this library, by including the releveant header file, #include <google/protobuf/message.h>.

在 中/usr/lib/x86_64-linux-gnu,有一个名为 的共享库libprotobuf.so,我想对其进行链接。我main.cpp在这个库中使用函数,包括相关的头文件,#include <google/protobuf/message.h>.

Now, in my builddirectory, I run cmake ../src, and then make. However, I then get linker errors telling me that there are undefined references to some of the functions in the protobuf library. If I do a search through all the files and subdirectories in build, there is not mention of anything related to protobuf.

现在,在我的build目录中,我运行cmake ../src,然后make. 但是,我随后收到链接器错误,告诉我对 protobuf 库中的某些函数存在未定义的引用。如果我搜索 中的所有文件和子目录build,则不会提及与 protobuf 相关的任何内容。

However, if I remove the link_directoriesline in my CMakeLists.txtfile, and instead write the full path to the library when specifying the executable, i.e. target_link_libraries(test /usr/lib/x86_64-linux-gnu/libprotobuf.so), it compiles and links fine.

但是,如果我删除文件中的link_directoriesCMakeLists.txt,而是在指定可执行文件时写入库的完整路径,即target_link_libraries(test /usr/lib/x86_64-linux-gnu/libprotobuf.so),它可以正常编译和链接。

Why is link_directoriesnot allowing cmake to find this library?

为什么link_directories不允许 cmake 找到这个库?

回答by ComicSansMS

Do not use link_directorieslike this in CMake.

不要link_directories在 CMake 中这样使用。

This is a common beginner's mistake, as many other build environments work like this, but in CMake it's just asking for trouble. Even the manpagespecifically advises against it:

这是一个常见的初学者错误,因为许多其他构建环境都是这样工作的,但在 CMake 中它只是自找麻烦。甚至联机帮助页也特别反对它:

Note that this command [link_directories] is rarely necessary. Library locations returned by find_package()and find_library()are absolute paths. Pass these absolute library file paths directly to the target_link_libraries()command. CMake will ensure the linker finds them.

请注意,此命令 [ link_directories] 很少需要。由find_package()和返回的库位置find_library()是绝对路径。将这些绝对库文件路径直接传递给target_link_libraries()命令。CMake 将确保链接器找到它们。

So instead, always pass absolute pathsto target_link_librariesand use find_libraryto resolve the link directory:

因此,请始终将绝对路径传递target_link_libraries并用于find_library解析链接目录:

find_library(PROTOBUF_LIBRARY protobuf HINTS /usr/lib/x86_64-linux-gnu)
target_link_libraries(test PUBLIC ${PROTOBUF_LIBRARY})

This has the huge benefit that you will probably get a diagnostic at CMake configure time if the expected library cannot be found, instead of a random linker error at compile time. Also, this allows the user to specify a library location via the GUI if the target machine has a non-standard directory layout.

这有一个巨大的好处,如果找不到预期的库,您可能会在 CMake 配置时得到诊断,而不是在编译时出现随机链接器错误。此外,如果目标机器具有非标准目录布局,这允许用户通过 GUI 指定库位置。

So if it doesn't work right away, be sure to check the result of the find_librarycall and consult the manpage to track down why it doesn't find your library as intended.

因此,如果它不能立即工作,请务必检查find_library调用的结果并查阅联机帮助页以找出它没有按预期找到您的库的原因。

回答by aardvarkk

Make sure that your call to link_directoriestakes place before your callto the relevant add_executable.

请确保您的来电link_directories进行呼叫之前,给相关add_executable

I had mistakenly believed it only needed to be before the call to target_link_libraries, but that's not the case. After moving the call, the library is linked properly.

我错误地认为它只需要在调用 之前target_link_libraries,但事实并非如此。移动调用后,库正确链接。

回答by user6882413

Make sure that the order will be link_directories, set PROJECT_LINK_LIBS, add_executable and then target_link_libraries.

确保顺序是link_directories,设置PROJECT_LINK_LIBS、add_executable 和target_link_libraries。

Below is example to demonstarte it:

下面是演示它的示例:

cmake_minimum_required(VERSION 2.8.9)
project (Logging)
include_directories(include)
file(GLOB LOGGINGSOURCES "libsrc/*.cpp")
file(GLOB SOURCES "src/*.cpp")
add_library(convertString SHARED ${LOGGINGSOURCES})
install(TARGETS convertString DESTINATION /root/Deepak/)
link_directories( /root/Deepak/ )
set(PROJECT_LINK_LIBS libconvertString.so)
add_executable(hello ${SOURCES})
target_link_libraries(hello ${PROJECT_LINK_LIBS} )