agx(TX2)下 ROS cantkin_make編譯含opencv連結庫未定應引用的問題
把opencv工程移植到ROS cantkin_make中
agx(TX2)下 ROS cantkin_make編譯含opencv連結庫未定應引用的問題
之前在opencv上跑了一個視覺檢測的工程,想把檢測結果的某個數值通過ros節點發出來,就建立了一個工作空間和功能包寫了個釋出者節點。
重點是寫catkin_make裡面的cmakelist.txt
最初單獨的opencv工程如下,復現這位大神的工作https://github.com/enazoe/yolo-tensorrt
cmakelist
如下
cmake_minimum_required (VERSION 3.1)
project(yolo-trt VERSION 1.0)
enable_language(CUDA)
set(CMAKE_CXX_COMPILIER "/usr/bin/g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wno-write-strings")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$ORIGIN")
#cuda
#export PATH=/usr/local/cuda-11.0/bin:$PATH
#include_directories(/usr/local/cuda/include)
#link_directories(/usr/local/cuda/lib64)
find_package(CUDA REQUIRED)
#opencv
#set(OpenCV_DIR /opt/opencv-4.1.2/share/OpenCV)
find_package(OpenCV REQUIRED)
#detector lib (cuda)
file(GLOB_RECURSE sources modules/*.hpp modules/ *.cpp modules/*.h modules/*.cu extra/*.h)
add_library(detector SHARED ${sources})
target_include_directories(detector PRIVATE extra/ modules/ ${OpenCV_INCLUDE_DIRS} ${CUDA_TOOLKIT_ROOT_DIR}/include)
target_link_libraries(detector nvinfer nvinfer_plugin nvcaffe_parser "stdc++fs")
#sample
add_executable(yolo-trt samples/sample_detector.cpp)
target_include_directories(yolo-trt PRIVATE modules/ extra/)
target_link_libraries(yolo-trt detector ${OpenCV_LIBS})
可見該工程把構建構建工程的原始檔都打包成了動態庫還有它依賴的opencv的標頭檔案還有cuda的標頭檔案 還有一些nvinfer nvinfer_plugin nvcaffe_parse庫都連結到了detector動態庫中
然後我們看他的可執行檔案是怎麼構建的
target_include_directories(yolo-trt PRIVATE modules/ extra/)包含可執行檔案生成需要的標頭檔案
target_link_libraries(yolo-trt detector ${OpenCV_LIBS})連結OpenCV_LIBS庫和打包生成的detector庫
那麼我們移植的時候只需要把生成可執行檔案需要暴露的標頭檔案(也就是可執行檔案.cpp檔案#include的源.h檔案)以及detector拷到新的工程(ros功能包裡),然後還要連結opencv庫,最後進行連結編譯就行了
功能包工程目錄
include裡面包括,extra,modules是存放頭(源)檔案的,一個動態庫libdetector.so
cmakelist如下
cmake_minimum_required(VERSION 3.1)
project(yolo_rt)
enable_language(CUDA)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
)
set(CMAKE_CXX_COMPILIER "/usr/bin/g++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wno-write-strings")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,$ORIGIN")
set(OpenCV_LIB_DIR "/usr/local/share/OpenCV/")
find_package(OpenCV REQUIRED)
include_directories(
${catkin_INCLUDE_DIRS} ./include/extra ./include/modules
)
link_directories(
${catkin_LIB_DIRS} ./include ${OpenCV_LIB_DIRS}
)
add_executable(yolo_rt src/sample.cpp)
target_link_libraries(yolo_rt ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} detector
)
編譯之後老是報錯,是什麼cv::xxxx未定義引用
[ 50%] Linking CXX executable /home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt
/home/nubot/cc/preception_ws/src/yolo_rt/./include/libdetector.so: undefined reference to `cv::dnn::dnn4_v20190621::blobFromImages(cv::_InputArray const&, double, cv::Size_<int>, cv::Scalar_<double> const&, bool, bool, int)'
collect2: error: ld returned 1 exit status
yolo_rt/CMakeFiles/yolo_rt.dir/build.make:127: recipe for target '/home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt' failed
make[2]: *** [/home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt] Error 1
CMakeFiles/Makefile2:477: recipe for target 'yolo_rt/CMakeFiles/yolo_rt.dir/all' failed
make[1]: *** [yolo_rt/CMakeFiles/yolo_rt.dir/all] Error 2
Makefile:140: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j4 -l4" failed
查閱資料,很多部落格都說opencv庫沒有連結,給的都是最基本的連結方法,何況我已經連結了,所以未能解決
去ros社群看了下,有的說是ros一般會自己自帶一個opencv路徑,findpackage不能找到正確的opencv庫路徑
讓我設定一下,在find前面加下路徑
參考 https://answers.ros.org/question/312235/error-linking-to-opencv-dnn-library/
set(OpenCV_LIB_DIR “/usr/local/share/OpenCV/”)
find_package(OpenCV REQUIRED)
但還是報相同的錯誤
是不是這個路徑加的也不對呢,人家是正常電腦安裝的opencv庫,我是ARM板子刷機的
報錯是libdetector.so
沒有定義cv::dnn::dnn4
,查了一下cv::dnn::dnn4
屬於ibopencv_dnn
問題應該出在它沒有正確連結opencv庫於是跑到這個libdetector.so
庫去找,那當然找不到
簡單粗暴直接找這個庫路徑在哪
sudo find / -iname "*opencv*"
找到libopencv_dnn
,果然它不再share
裡面,而在/usr/lib/aarch64-linux-gnu
裡面
/usr/lib/aarch64-linux-gnu/libopencv_objdetect.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_features2d.so
/usr/lib/aarch64-linux-gnu/libopencv_imgproc.so.4.1
/usr/lib/aarch64-linux-gnu/libopencv_ml.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_videoio.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_core.so.4.1.1
/usr/lib/aarch64-linux-gnu/libopencv_dnn.so.4.1.1
於是cmakelist中直接target_link_libraries加入該庫的絕對路徑/usr/lib/aarch64-linux-gnu/libopencv_dnn.so
target_link_libraries(yolo_rt ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} detector /usr/lib/aarch64-linux-gnu/libopencv_dnn.so
)
最後catkin_make
nubot@nubot-desktop:~/cc/preception_ws$ catkin_make
Base path: /home/nubot/cc/preception_ws
Source space: /home/nubot/cc/preception_ws/src
Build space: /home/nubot/cc/preception_ws/build
Devel space: /home/nubot/cc/preception_ws/devel
Install space: /home/nubot/cc/preception_ws/install
[ 50%] Linking CXX executable /home/nubot/cc/preception_ws/devel/lib/yolo_rt/yolo_rt
[100%] Built target yolo_rt
終於解決!
碼字不易讀後一讚手有餘香