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

时间:2016-01-25 15:14:57

标签: 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 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只添加子目录

... / SRC /主/

add_executable(main main.cpp)

2 个答案:

答案 0 :(得分:3)

通常,要链接第三方库,您需要添加编译器将查找标头的include目录以及链接器使用的库。
要添加包含目录,请使用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内置机制来查找标题和库 标题可由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也会在那里查找标题和库。您可以通过在CMake GUI中添加变量或将-DCMAKE_PREFIX_PATH=/path/to/add添加到CMake呼叫来指定变量。

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

答案 1 :(得分:1)

从您的项目CMakeLists.txt文件中,我不知道您是如何尝试链接libusb的。我将采取以下措施:

target_link_libraries(project_name <other_dependencies> usb-1.0)

(只是为了澄清我的意思是你添加可执行文件的CMakeLIsts.txt文件)

您正尝试从<libusb-1.0/...>导入,因此您需要链接usb-1.0(lib 始终从链接器命令中省略!)

我在使用Fedora 23,也使用KDevelop,我没有指定路径。特别是因为在我的系统中,前一个答案中使用的所有环境变量都是NULL。

要确认将来安装库的位置和方式,您可以这样做: locate libusb | grep .so

希望这有点帮助。