Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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中链接第三方库(LibUSB)_C++_Cmake_Linker Errors - Fatal编程技术网

C++ 如何在CMake中链接第三方库(LibUSB)

C++ 如何在CMake中链接第三方库(LibUSB),c++,cmake,linker-errors,C++,Cmake,Linker Errors,我正试图在一个项目中使用LibUSB。但是,每当我尝试使用基本libUSB函数时,都会出现以下错误: ...src/main/main.cpp.o: In function `main': ...src/main/main.cpp:10: undefined reference to `libusb_init' ...src/main/main.cpp:11: undefined reference to `libusb_set_debug' collect2: error: ld return

我正试图在一个项目中使用LibUSB。但是,每当我尝试使用基本libUSB函数时,都会出现以下错误:

...src/main/main.cpp.o: In function `main':
...src/main/main.cpp:10: undefined reference to `libusb_init'
...src/main/main.cpp:11: undefined reference to `libusb_set_debug'
collect2: error: ld returned 1 exit status
安装了LibUSB-devel包(我在fedora 22上),我的IDE KDevelop找到并识别头文件,在添加import语句后,它提供LibUSB代码完成。我的IDE或CMake(我的构建系统)中都没有任何自定义的包含行,因此我想知道我需要做什么才能使CMake找到LibUSB头

这是
main.cpp
的内容,以防我搞砸了:

#include <iostream>
#include <libusb-1.0/libusb.h>

int main(int argc, char **argv) {
      libusb_init(NULL);
      libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);

      /*snip*/

      std::cout << "Hello, world! PTPID="  << std::endl;
      return 0;
}
…/src/cmakelists.txt只添加子目录

…/src/main/

add_executable(main main.cpp)

通常,要链接第三方库,您需要添加include目录,编译器将在其中查找头以及链接器使用的库。
要添加包含目录,请使用
target\u包含目录
;要添加要链接到目标的库,请使用
target\u链接库

对于libUSB和
testLibUSB.cpp
源文件,这将导致

add_executable(targetTestLibUSB testLibUSB.cpp)
target_include_directories(targetTestLibUSB ${LIBUSB_INCLUDE_DIR})
target_link_libraries(targetTestLibUSB ${LIBUSB_LIBRARY})
如果您有多个目标,在定义任何目标之前,您可能希望使用
包含_目录
链接_库
。这些命令在设置后应用于项目的所有目标,并节省大量重复

您可以手动指定
LIBUSB\u INCLUDE\u DIR
LIBUSB\u库
的路径。但更灵活和可移植的是使用CMake内置机制查找标题和库。
头可以通过
find_path
搜索,库可以通过
find_library
搜索
在你的情况下,这可能是

find_path(LIBUSB_INCLUDE_DIR
  NAMES libusb.h
  PATH_SUFFIXES "include" "libusb" "libusb-1.0")
find_library(LIBUSB_LIBRARY
  NAMES usb
  PATH_SUFFIXES "lib" "lib32" "lib64")
路径后缀是可选的。如果已将库安装在默认位置,CMake将自动找到它。否则,指定
CMAKE\u PREFIX\u PATH
,CMAKE也会在那里查找头和库。您可以通过在CMake GUI中添加变量或向CMake调用添加
-DCMAKE_PREFIX_PATH=/PATH/to/add
来指定变量


一个常见的陷阱是不删除build目录中的CMakeCache.txt文件。CMake缓存
LIBUSB\u INCLUDE\u DIR
LIBUSB\u LIBRARY
的值,如果您调整前缀路径或搜索逻辑,它仍然不会重新计算变量值,而是坚持缓存的值。

从您的项目
CMakeLists.txt
文件中,我不清楚您是如何尝试链接libusb的。我的做法如下:

目标链接库(项目名称usb-1.0)

(为了澄清,我指的是添加可执行文件的CMakeLIsts.txt文件)

您正试图从
导入,因此需要链接usb-1.0(链接器命令中总是省略lib!)

我在Fedora 23上,也使用KDevelop,不需要指定路径。特别是因为在我的系统上,前面答案中使用的所有环境变量都是空的

要确认将来在何处以及如何安装库,您只需执行以下操作:

找到libusb | grep.so


希望这有点帮助。

未定义的引用是链接器错误,所以它们是关于查找库,而不是头的。也许您可以展示您的项目如何使用CMake来链接LibUSB?您是从LibUSB链接二进制文件吗?看起来您对LibUSB的一些LinkerFlag设置了错误。包含路径(存储头的位置)和库之间存在差异。您需要显式配置buildsystem以链接您正在使用的库。我没有看到
target\u link\u libraries()。次要提示:目前
include_目录
target_include_目录
更为常见,尤其是对于CMake初学者。最后一段实际上描述了开发人员的调试过程——它不应该以某种方式与“如何编写CMake脚本”内容分隔开来吗?这很好,是一个非常有用的答案,但在我的例子中,当我和find_path似乎都不知道DNF将库放在哪里时,它就没有帮助了。我想这是另一个问题though@LordNibbler
repoquery--list
mayhelp@Tsyvarev谢谢你的提示,我也添加了
包含目录
。你是对的,缓存有点不相关,但这是一个常见的陷阱。这就是我提到它的原因。@usr1234567为我的项目
rookery
修复了它,我添加了
target\u link\u库(rookery usb-1.0)
,但这给了我
CMakeLists.txt:6(target\u link\u库)上的CMake错误:无法为目标“rookery”指定链接库,而目标“rookery”不是由这个项目构建的。
find_path(LIBUSB_INCLUDE_DIR
  NAMES libusb.h
  PATH_SUFFIXES "include" "libusb" "libusb-1.0")
find_library(LIBUSB_LIBRARY
  NAMES usb
  PATH_SUFFIXES "lib" "lib32" "lib64")