Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

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

I am attempting to use LibUSB in a project. However whenever I attempt to use basic libUSB functions I get the following error:

...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. 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.

This is the contents of main.cpp, just in case I messed something up:

#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:
../

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/main/

add_executable(main main.cpp)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.
For libUSB and a testLibUSB.cpp source file this would result in

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. 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. But more flexible and portable is to use CMake built-in mechanisms to find headers and libraries.
Header can be searched by find_path and libraries by 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. If you have installed the library in a default location, CMake will find it automatically. Otherwise specify CMAKE_PREFIX_PATH and CMake will look for the headers and libraries there, too. 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.

A common pitfall is to not delete the CMakeCache.txt file in the build directory. 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...