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

qybjjes1  于 2023-08-09  发布在  其他
关注(0)|答案(3)|浏览(342)

我正在尝试在一个项目中使用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;
}


以下是CMakeLists.txt
../

cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_BUILD_TYPE Debug)

project(aProjectThatHasHadIt'sNameObcured)
add_subdirectory(src)


./src/cmakelists.txt只是添加子目录
联系我们

add_executable(main main.cpp)

fkaflof6

fkaflof61#

通常,要链接第三方库,您需要添加包含目录,编译器将在其中查找头文件,以及链接器使用的库。
要添加包含目录,请使用target_include_directories;要添加要链接到目标的库,请使用target_link_libraries
对于libUSB和testLibUSB.cpp源文件,这将导致

add_executable(targetTestLibUSB testLibUSB.cpp)
target_include_directories(targetTestLibUSB ${LIBUSB_INCLUDE_DIR})
target_link_libraries(targetTestLibUSB ${LIBUSB_LIBRARY})

字符串
如果您有多个目标,您可能希望在定义任何目标之前使用include_directorieslink_libraries。这些命令在设置后应用于项目的所有目标,并保存了大量的重复
您可以手动指定LIBUSB_INCLUDE_DIRLIBUSB_LIBRARY的路径。但更灵活和可移植的是使用CMake内置机制来查找头和库。
Header可以通过find_path搜索,libraries可以通过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")


PATH_SUFFIXES是可选的。如果你在默认位置安装了库,CMake会自动找到它。否则,指定CMAKE_PREFIX_PATH,CMake也会在那里查找头文件和库。您可以通过在CMake GUI中添加变量或将-DCMAKE_PREFIX_PATH=/path/to/add添加到CMake调用中来指定该变量。
一个常见的陷阱是不删除构建目录中的CMakeCache.txt文件。CMake缓存LIBUSB_INCLUDE_DIRLIBUSB_LIBRARY的值,如果您调整前缀路径或搜索逻辑,它仍然不会重新计算变量值,而是坚持缓存的值。

slwdgvem

slwdgvem2#

从您的项目CMakeLists.txt文件中,我看不出您是如何链接libusb的。我会这样做:
target_link_libraries(project_name <other_dependencies> usb-1.0)
(Just为了澄清,我指的是CMakeLists.txt文件,您可以在其中添加可执行文件)
你正试图从<libusb-1.0/...>导入,因此你需要链接usb-1.0(链接器命令中总是省略了这个库!))
我使用Fedora 23,也使用KDevelop,我不需要指定路径。特别是因为在我的系统上,前面的答案中使用的所有环境变量都是NULL。
要确认将来在何处以及如何安装库,您只需执行以下操作:locate libusb | grep .so
希望这对你有所帮助。

lkaoscv7

lkaoscv73#

最近(2023年5月),有一个完全不同的替代方案:https://github.com/libusb/libusb-cmake
需要注意的几件事:

  • 到目前为止,CMake导出/包不可用(即CMake的find_package将不会使用);
  • 这并不被主线libusb维护者正式支持,而是托管在Libusb Org下。在Github上,并得到社区的支持;
  • 这对于那些需要将libusb作为subdirectory项目的一部分的人来说是最有用的;

相关问题