Совместно используемая (или stati c?) Библиотека CMake не может связать - PullRequest
0 голосов
/ 09 января 2020

В настоящее время я пытаюсь скомпилировать проект, используя несколько общих и предварительно скомпилированных c библиотек на платформе ARM с использованием CMake. Вот обзор структуры проекта.

<main project directory>
  |-- CMakeLists.txt
  |-- face_detect.cpp
  |-- face_detect.hpp
  |-- video_test.cpp
  |-- build
  |     |-- <various CMake build files>

Вот структура каталогов, в которой находятся библиотеки, которые я пытаюсь связать.

</usr/share/ti>
  |-- opencl
  |   |-- <various header files for TI OpenCL including dsp.h>
  |   |-- dsp.out
  |   |-- dsp.syms
  |   |-- dsp_syms.obj
  |-- tidl
  |   |-- tidl_api
  |   |     |-- inc
  |   |     |     |-- congfiguration.h
  |   |     |     |-- execution_object.h
  |   |     |     |-- execution_object_internal.h
  |   |     |     |-- execution_object_pipeline.h
  |   |     |     |-- executor.h
  |   |     |     |-- imgutil.h
  |   |     |-- tidl_api.a
  |   |     |-- tidl_imgutil.a
  |   |     |-- tidl.so

Теперь вот объяснение:

Я сейчас использую OpenCV с модулем dnn для определения лица (и, в конечном итоге, распознавания) на BeagleBoard AI (процессор TI Sitara). Код компилируется и прекрасно работает без API глубокого обучения TI (TIDL), но по какой-то причине, когда я пытаюсь make проект, он выдает следующую ошибку (сборка работает нормально, сбой на этапе компоновки):

face_detect.cpp:(.text+0x16): undefined reference to `tidl::Executor::GetNumDevices(tidl::DeviceType)'
collect2: error: ld returned 1 exit status
CMakeFiles/face_detect.dir/build.make:142: recipe for target 'face_detect' failed
make[2]: *** [face_detect] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/face_detect.dir/all' failed
make[1]: *** [CMakeFiles/face_detect.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2 

nm tidl_api.a | grep GetNumDevices показывает, что символы действительно есть в библиотеке, поэтому я думаю, что это проблема с CMake. Кроме того, примеры, поставляемые с платой, использующей API TIDL, работают, поэтому я знаю, что API работает нормально.

Что может быть причиной сбоя компоновщика? Я положу свой файл CMakeLists.txt ниже. У меня есть несколько ненужных строк, когда я пытаюсь заставить их работать. Спасибо за просмотр!

project( hello_face )

cmake_minimum_required( VERSION 3.7 )

set( CMAKE_CXX_STANDARD 14 )
set( CMAKE_CXX_STANDARD_REQUIRED True )
set( OpenCV_DIR /opt/opencv-4.2.0/lib/cmake/opencv4 )

find_package( OpenCV REQUIRED )

include_directories( "/usr/share/ti/tidl/tidl_api/inc" )
include_directories( "/usr/share/ti/tidl/tidl_api" )
include_directories( "/usr/share/ti/opencl" )
link_directories( "/usr/share/ti/tidl/tidl_api" )
link_directories( "/usr/share/ti/tidl/tidl_api/inc" )
link_directories( "/usr/share/ti/opencl" )

add_library( tidl SHARED IMPORTED )
set_property( TARGET tidl PROPERTY IMPORTED_LOCATION "/usr/share/ti/tidl/tidl_api/tidl.so" )

add_library( tidl_api STATIC IMPORTED )
set_property( TARGET tidl_api PROPERTY IMPORTED_LOCATION "/usr/share/ti/tidl/tidl_api/tidl_api.a" )

add_library( tidl_imgutil STATIC IMPORTED )
set_property( TARGET tidl_imgutil PROPERTY IMPORTED_LOCATION "/usr/share/ti/tidl/tidl_api/tidl_imgutil.a" )

add_executable( video_test video_test.cpp )
target_link_libraries( video_test ${OpenCV_LIBS} )

add_executable( face_detect face_detect.cpp )
target_link_libraries( face_detect ${OpenCV_LIBS} ${tidl_LIBS} ${tidl_api_LIBS} ${tidl_imgutil_LIBS} )

РЕДАКТИРОВАТЬ: Согласно предложению squareskittles, я изменил окончательную строку CMakeLists.txt на target_link_libraries( face_detect PUBLIC ${OpenCV_LIBS} tidl tidl_api tidl_imgutil ). Теперь я получаю длинный список неопределенных ссылок на Python методы / объекты, такие как 'PyFloat_Type' и 'PyList_New' внутри tidl.so. Не уверен, почему это зависит от Python типов для чистого проекта C ++.

1 Ответ

1 голос
/ 09 января 2020

Строки add_library() в вашем CMake определяют цели IMPORTED для библиотек tidl. Вы можете ссылаться на эти напрямую . Поскольку это цели , а не переменные , вам не нужно использовать синтаксис ${} для разыменования переменных. Кроме того, нет необходимости добавлять суффикс _LIBS. Суффикс _LIBS обычно используется для переменных , которые определены во время вызовов к find_package(), но вы используете find_package() только с OpenCV здесь. Попробуйте вместо этого что-то подобное для своего target_link_libraries() звонка:

target_link_libraries(face_detect PUBLIC ${OpenCV_LIBS} tidl tidl_api tidl_imgutil)
...