c++ - CMake 共享(或静态?)库无法链接
问题描述
我目前正在尝试使用 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
现在解释一下:
我现在正在使用带有 dnn 模块的 OpenCV 在 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 )
. 我现在得到一长串对 Python 方法/对象的未定义引用,例如 'PyFloat_Type' 和 'PyList_New' inside tidl.so
。不知道为什么它依赖于纯 c++ 项目的 Python 类型。
解决方案
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)
推荐阅读
- android - 如何直接打开媒体浏览器到照片库?
- node.js - node.js 中的 promise 发生错误,希望将其作为承诺的连接并修复
- yeoman - 无法构建我的第一个 Hello Word SPFX。“yo @microsoft/sharepoint”正在返回“TypeError:lookups.flatMap 不是函数”
- scheme - 在 Scheme 中返回有状态函数的修改版本
- api - Twitter API get webhooks for my account [PHP]
- jquery - 如何在跨度中包装按钮的文本/值?
- r - 在 R 的 vrtest 包中使用 Lo.Mac 函数时出现 UseMethod("filter") 错误
- typescript - 在 vue 中访问从 axios 获取请求中创建的计算值
- mongodb - 在 k8s 中连接 mongo-express 到 mongoDb 失败
- flutter - 如果 firebase 没有要显示的数据,则不会在 firebase 动画列表小部件中执行构建方法