我目前正在尝试使用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)