简体   繁体   中英

CMake shared (or static?) library fails to link

I am currently trying to compile a project using some shared and static pre-compiled libraries on an ARM platform using CMake. Here's an overview of the project structure.

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

Here's the directory structure where the libraries I'm trying to link are.

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

Now here's an explanation:

I am using OpenCV with the dnn module right now to do facial detection (and eventually recognition) on a BeagleBoard AI (TI Sitara processor). The code compiles and runs just fine without the TI Deep Learning API (TIDL), but for some reason when I try to make the project it throws the following error (builds fine, fails in linking stage):

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 nm tidl_api.a | grep GetNumDevices shows that the symbols are indeed in the library, so I think it must be a problem with CMake. In addition, the examples shipped with the board leveraging the TIDL API work, so I know the API works fine.

What could be causing the linker failure? I will put my CMakeLists.txt file below. I've got some unnecessary lines in there from trying stuff to make it work. Thanks for looking!

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

EDIT: As per squareskittles' suggestion, I changed the final line of CMakeLists.txt to target_link_libraries( face_detect PUBLIC ${OpenCV_LIBS} tidl tidl_api tidl_imgutil ) . I now get a long list of undefined references to Python methods/objects such as 'PyFloat_Type' and 'PyList_New' inside tidl.so . Not sure why it's depending on Python types for a pure c++ project.

The add_library() lines in your CMake define IMPORTED targets for the tidl libraries. You can link to these directly . Because these are targets , and not variables , you do not need to use ${} syntax for variable de-referencing. Also, there is no need to append the _LIBS suffix. The _LIBS suffix is typically used on variables that are defined during calls to find_package() , but you only use find_package() with OpenCV here. Try something like this instead for your target_link_libraries() call:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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