如何在 CMake 中 Link 第三方库 (LibUSB)

How to Link a third Party Library (LibUSB) in CMake

我正在尝试在项目中使用 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 发现并识别 headers,一旦你提供 LibUSB 代码补全添加了导入语句。我的 IDE 或 CMake(我的构建系统)中没有任何自定义包含行,所以我想知道我需要做什么才能让 CMake 找到 LibUSB headers.

这是 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 只是添加子目录

.../src/main/

add_executable(main main.cpp)

一般来说,对于link第三方库,需要添加编译器查找headers的include目录,以及link使用的库=]呃
要添加包含目录,请使用 target_include_directories,要将要 linked 的库添加到目标,请使用 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 built-in 机制来查找 headers 和库。
Header 可以被 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")

PATH_SUFFIXES 是可选的。如果您已将库安装在默认位置,CMake 会自动找到它。否则指定 CMAKE_PREFIX_PATH,CMake 也会在那里寻找 headers 和库。您可以通过将变量添加到 CMake GUI 或将 -DCMAKE_PREFIX_PATH=/path/to/add 添加到您的 CMake 调用来指定变量。

一个常见的陷阱是不删除构建目录中的 CMakeCache.txt 文件。 CMake 缓存 LIBUSB_INCLUDE_DIRLIBUSB_LIBRARY 的值,如果您调整前缀路径或搜索逻辑,它仍然不会重新评估变量值,而是坚持缓存的值。

从您的项目 CMakeLists.txt 文件中,我看不出您是如何尝试 link libusb.我的做法如下:

target_link_libraries(project_name <other_dependencies> usb-1.0)

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

您正在尝试从 <libusb-1.0/...> 导入,因此您需要 link usb-1.0(库 总是 从 linker 命令!)

我在 Fedora 23 上,也在使用 KDevelop,我不需要指定路径。特别是因为在我的系统上,上一个答案中使用的所有环境变量无论如何都是 NULL。

要确认将来库的安装位置和安装方式,您只需执行以下操作: locate libusb | grep .so

希望这对您有所帮助。