简体   繁体   English

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

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

I am attempting to use LibUSB in a project. 我正在尝试在项目中使用LibUSB。 However whenever I attempt to use basic libUSB functions I get the following error: 但是,每当我尝试使用基本的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

The package LibUSB-devel is installed (I'm on fedora 22) and my IDE KDevelop finds and recognises the headers, to the point it offers LibUSB code completions once you have added the import statement. 安装了LibUSB-devel软件包(我在fedora 22上),并且我的IDE KDevelop查找并识别了标头,以至于一旦您添加了import语句,它就会提供LibUSB代码完成。 I don't have any custom include lines in either my IDE or CMake (my build system) so I would like to know what I need to to to make CMake find the LibUSB headers. 我的IDE或CMake(我的构建系统)中都没有任何自定义包含行,因此我想知道让CMake查找LibUSB标头所需的内容。

This is the contents of main.cpp , just in case I messed something up: 这是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;
}

The following are the CMakeLists.txt : 以下是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 just adds subdirectories ... / src / cmakelists.txt仅添加子目录

.../src/main/ ... / src目录/主/

add_executable(main main.cpp)

In general, to link a third party library, you need to add the include directory where the compiler will look for the headers, and the libraries which are used by the linker. 通常,要链接第三方库,您需要添加包含目录,编译器将在其中查找标头以及链接器使用的库。
To add include directories use target_include_directories , to add a library to be linked to a target use target_link_libraries . 要添加包含目录,请使用target_include_directories ,要添加要链接到目标的库,请使用target_link_libraries
For libUSB and a testLibUSB.cpp source file this would result in 对于libUSB和一个testLibUSB.cpp源文件,这将导致

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

If you have several targets, you might want to use include_directories and link_libraries before defining any target. 如果您有多个目标,则可能需要在定义任何目标之前使用include_directorieslink_libraries These commands apply to all targets of a project after they are set and save a lot of repetition 这些命令在设置后适用于项目的所有目标,并节省了大量重复

You can specify the paths for LIBUSB_INCLUDE_DIR and LIBUSB_LIBRARY by hand. 您可以手动指定LIBUSB_INCLUDE_DIRLIBUSB_LIBRARY的路径。 But more flexible and portable is to use CMake built-in mechanisms to find headers and libraries. 但是更灵活和可移植的是使用CMake内置机制来查找标头和库。
Header can be searched by find_path and libraries by find_library . 头可以通过find_path搜索,而库可以通过find_library
in your case this could be 在你的情况下,这可能是

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

The PATH_SUFFIXES are optional. PATH_SUFFIXES是可选的。 If you have installed the library in a default location, CMake will find it automatically. 如果您已将库安装在默认位置,则CMake会自动找到它。 Otherwise specify CMAKE_PREFIX_PATH and CMake will look for the headers and libraries there, too. 否则,请指定CMAKE_PREFIX_PATH ,CMake也会在其中查找标头和库。 You can specify the variable either by adding it in the CMake GUI or adding -DCMAKE_PREFIX_PATH=/path/to/add to your CMake call. 您可以通过在CMake GUI中添加变量或将-DCMAKE_PREFIX_PATH=/path/to/add到CMake调用中来指定变量。

A common pitfall is to not delete the CMakeCache.txt file in the build directory. 一个常见的陷阱是不删除构建目录中的CMakeCache.txt文件。 CMake caches the values for LIBUSB_INCLUDE_DIR and LIBUSB_LIBRARY and if you makes adjustment to the prefix path or your search logic, it still does not reevaluate the variable values but sticks to the cached values. CMake缓存LIBUSB_INCLUDE_DIRLIBUSB_LIBRARY的值,并且如果您对前缀路径或搜索逻辑进行了调整,它仍然不会重新评估变量值,但会坚持缓存的值。

From your projects CMakeLists.txt file it doesn't become apparent to me how you've tried to link libusb. 在您的项目CMakeLists.txt文件中,您如何尝试链接libusb对我而言并不明显。 The way I would do is the following: 我要做的方法如下:

target_link_libraries(project_name <other_dependencies> usb-1.0)

(Just to clarify I mean the CMakeLIsts.txt file in which you add your executable) (只是为了澄清我的意思是您在其中添加可执行文件的CMakeLIsts.txt文件)

You're trying to import from <libusb-1.0/...> thus you need to link usb-1.0 (the lib is always omitted from linker commands!) 您尝试从<libusb-1.0/...>导入,因此需要链接usb-1.0(链接器命令中始终省略lib!)

I'm on Fedora 23, also using KDevelop and I didn't have to specify a path. 我在Fedora 23上,也使用KDevelop,因此不必指定路径。 Especially because on my system all the environment variables used in the previous answer are NULL anyways. 特别是因为在我的系统上,上一个答案中使用的所有环境变量始终为NULL。

And to confirm where and how a library is installed in the future you can just do: locate libusb | grep .so 要确认将来在何处以及如何安装库,您可以执行以下操作: locate libusb | grep .so locate libusb | grep .so

Hope this was somewhat helpful. 希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM