Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Cmake无法使用“找到库”;链接“U目录”;_C++_Cmake_Makefile - Fatal编程技术网

C++ Cmake无法使用“找到库”;链接“U目录”;

C++ Cmake无法使用“找到库”;链接“U目录”;,c++,cmake,makefile,C++,Cmake,Makefile,我喜欢Ubuntu,我正在学习cmake和make,只是尝试一个简单的例子。我有两个目录:src和build。在src中,我有两个文件:main.cpp,和CMakeLists.txt,其中(只有)以下文本: add_executable(test main.cpp) link_directories(/usr/lib/x86_64-linux-gnu) target_link_libraries(test protobuf) 在/usr/lib/x86_64-linux-gnu中,有一个名为

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

add_executable(test main.cpp)
link_directories(/usr/lib/x86_64-linux-gnu)
target_link_libraries(test protobuf)
/usr/lib/x86_64-linux-gnu
中,有一个名为
libprotobuf.so
的共享库,我想链接它。My
main.cpp
通过包含相关头文件
#include
来使用此库中的函数

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

但是,如果我在
CMakeLists.txt
文件中删除
link\u目录
行,并在指定可执行文件时写入库的完整路径,即
target\u link\u库(test/usr/lib/x86\u 64-linux-gnu/libprotobuf.so)
,它编译和链接都很好


为什么
link\u目录
不允许cmake查找此库?

不要在cmake中这样使用
link\u目录

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

请注意,此命令[
link\u目录
]很少是必需的。归还图书馆位置 通过
find_package()
find_library()
是绝对路径。传递这些 直接指向
目标链接库()的绝对库文件路径
指挥部。CMake将确保链接器找到它们

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

find_library(PROTOBUF_LIBRARY protobuf HINTS /usr/lib/x86_64-linux-gnu)
target_link_libraries(test PUBLIC ${PROTOBUF_LIBRARY})
这有一个巨大的好处,即如果无法找到预期的库,您可能会在CMake配置时得到诊断,而不是在编译时出现随机链接器错误。此外,如果目标机器具有非标准目录布局,这允许用户通过GUI指定库位置


因此,如果它不能立即工作,请务必检查
查找库
调用的结果,并查阅手册页,以找出它无法按预期查找库的原因。

确保在调用相关的
添加可执行文件
之前调用
链接目录


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

确保顺序是链接目录、设置项目链接库、添加可执行文件,然后是目标链接库

下面是演示它的示例:

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} )

cmake手册中提到了关于链接库,“该命令将仅应用于调用后创建的目标。”目标是否使用add_executable()命令创建?可能您需要将add_executable()命令移动到link_directories()之后。如果我这样做,则会出现错误
无法为目标“test”指定链接库,而目标“test”不是由此项目生成的。
只是为了确保:现在命令的顺序是1)link_directories(),2)add_executable(),以及3)target_link_libraries()?使用
find_package(Protobuf)
而不是试图直接定位它。有关更多信息,请参阅。如果find_package()不适用于您,那么下一个最佳选项是find_库(PROTOBUF PROTOBUF/usr/lib/x86_64-linux-gnu),然后在您的target_link_libraries()命令中使用${PROTOBUF}。环顾网络,你会看到许多人(有时强烈)反对使用link_目录()。甚至CMake文档似乎也建议使用find_library()来代替。。。。但是,为什么它不起作用呢?我知道有人建议不要使用它,但它是否仍然有效?如果您使用pkg_check_模块来查找库,您已经获得了所需的所有信息,使用pkg_check_模块是有意义的。@aardvark文档说
该命令将仅应用于调用它后创建的目标
FYI在Windows上我发现如果库位于子目录中,您可能需要在提示中添加
/*
“谢谢您的回答!”!我有一个FindSomething.cmake文件,它使用link_目录,事实上,当使用静态库上的target_link_库将其与库“某物”链接,然后使用二进制程序链接该静态库时,链接器无法链接库,因为link_目录未被考虑在内……这是问题的正确答案。这里的关键字是通话前的
。。。