我目前正在尝试使用CMake在ARM平台上使用一些共享的和静态的预编译库来编译项目。这是项目结构的概述。

<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处理器)上进行面部检测(并最终识别)。该代码无需TI深度学习API(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一定有问题。此外,开发板附带的示例利用TIDL API可以正常工作,因此我知道该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 )。现在,我在tidl.so中获得了一长串未定义的对Python方法/对象的引用,例如'PyFloat_Type'和'PyList_New'。不确定为什么纯c++项目依赖于Python类型。

最佳答案

CMake中的add_library()行定义了IMPORTED库的tidl目标。您可以直接链接到这些。由于这些是目标,而不是变量,因此不需要使用${}语法进行变量取消引用。另外,不需要附加_LIBS后缀。 _LIBS后缀通常用于在调用find_package()的过程中定义的变量,但是您在此处仅将find_package()与OpenCV一起使用。对于 target_link_libraries() call ,请尝试以下类似方法:

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

10-08 05:56