2016-01-25 6 views
0

Я пытаюсь использовать LibUSB в проекте. Однако всякий раз, когда я пытаюсь использовать основные функции libUSB я получаю следующее сообщение об ошибке:Как связать стороннюю библиотеку (LibUSB) в CMake

...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 находит и распознает заголовки, до точки он предлагает завершение кода 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/main/

+0

Неопределенные ссылки - это ошибки компоновщика, поэтому они собираются найти библиотеки, а не заголовки. Возможно, вы можете показать, как ваш проект использует CMake для связи с LibUSB? – Angew

+0

Вы связываете двоичные файлы с libusb? – Otomo

+0

похоже, что вы misisng некоторые линкер-флагов для libusb –

ответ

1

Из ваших проектов CMakeLists.txt файл мне не кажется очевидным, как вы пытались связать libusb.То, как я бы сделать, это следующее:

target_link_libraries(project_name <other_dependencies> usb-1.0)

(Просто для уточнения я имею в виду файл CMakeLists.txt, в котором вы добавить свой исполняемый файл)

Вы пытаетесь импортировать из <libusb-1.0/...>, таким образом, вам нужно связать usb-1.0 (lib is всегда пропущено из команд компоновщика!)

Я нахожусь на Fedora 23, также используя KDevelop, и мне не нужно было указывать путь. Тем более, что в моей системе все переменные среды, используемые в предыдущем ответе, в любом случае равно NULL.

И чтобы подтвердить, где и как установлена ​​библиотека в будущем вы можете просто сделать: locate libusb | grep .so

Надеется, что это было несколько полезно.

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_directories и link_libraries перед определением какой-либо цели. Эти команды применяются ко всем объектам проекта после их установки и сохранения большого количества повторений.

Вы можете указать пути для LIBUSB_INCLUDE_DIR и LIBUSB_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") 

The PATH_SUFFIXES являются необязательными. Если вы установили библиотеку в папку по умолчанию, CMake найдет ее автоматически. В противном случае укажите CMAKE_PREFIX_PATH, и CMake также будет искать заголовки и библиотеки. Вы можете указать эту переменную, добавив ее в графический интерфейс CMake или добавив -DCMAKE_PREFIX_PATH=/path/to/add к вашему вызову CMake.

Общая ошибка заключается в том, чтобы не удалять файл CMakeCache.txt в каталоге сборки. CMake кэширует значения для LIBUSB_INCLUDE_DIR и LIBUSB_LIBRARY, и если вы выполняете настройку пути префикса или логики поиска, он по-прежнему не переоценивает значения переменных, а придерживается кешированных значений.

+1

Хорошие объяснения. Незначительное примечание: в настоящее время 'include_directories' гораздо чаще встречается, чем' target_include_directories', особенно для начинающих CMake. В последнем абзаце на самом деле описывается ** отладка ** процесса для * разработчиков * - не следует ли это каким-то образом ограничивать содержимое «Как писать сценарий CMake»? – Tsyvarev

+0

Это все замечательно, и действительно полезный ответ, но в моем случае это не помогает, когда ни я, ни find_path, похоже, не знают, где DNF помещает библиотеку. Я думаю, что для отдельного вопроса, хотя –

+0

@LordNibbler 'repoquery --list ' может помочь – usr1234567

Смежные вопросы