这篇文章讲了如何在ubuntu20.04中使用ArenaView MP,虽然已经运行成功,但是发现想要编译并运行C++实例还是遇到了一些问题。
问题一:编译链接阶段-间接依赖库缺失
错误现象:
root@yygpc:/opt/arena/ArenaSDK_Linux_x64/Examples/Arena/Cpp_Acquisition# make
g++ -L../../../lib64 -L../../../GenICam/library/lib/Linux64_x64 -L../../../ffmpeg -L../../../OpenCV/lib -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_highgui -lopencv_imgproc -lopencv_video Cpp_Acquisition.o stdafx.o -o Cpp_Acquisition -larena -lsave -lgentl -lGCBase_gcc54_v3_3_LUCID -lGenApi_gcc54_v3_3_LUCID -lLog_gcc54_v3_3_LUCID -llog4cpp_gcc54_v3_3_LUCID -lMathParser_gcc54_v3_3_LUCID -lNodeMapData_gcc54_v3_3_LUCID -lXmlParser_gcc54_v3_3_LUCID -lavcodec -lavformat -lavutil -lswresample -lpthread -llucidlog -L../../../OpenCV/lib -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_highgui -lopencv_imgproc -lopencv_video
/usr/bin/ld: warning: libopencv_flann.so.4.0, needed by ../../../lib64/libopencv_calib3d.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libmetavision_sdk_core.so.4, needed by ../../../lib64/libgentl.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libmetavision_sdk_base.so.4, needed by ../../../lib64/libgentl.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setInt(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::Index::~Index()'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setFloat(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, float)'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::KDTreeIndexParams::KDTreeIndexParams(int)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::add_events(Metavision::EventCD const*, Metavision::EventCD const*)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::~CDFrameGenerator()'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::Index::knnSearch(cv::_InputArray const&, cv::_OutputArray const&, cv::_OutputArray const&, int, cv::flann::SearchParams const&)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::RateEstimator::add_data(long long, unsigned long)'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::IndexParams()'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::CDFrameGenerator(long, long, bool)'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::getAll(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::vector<cv::flann::FlannIndexType, std::allocator<cv::flann::FlannIndexType> >&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::vector<double, std::allocator<double> >&) const'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setBool(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::~IndexParams()'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::start(unsigned short, std::function<void (long long, cv::Mat&)> const&)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::RateEstimator::RateEstimator(std::function<void (long long, double, double)> const&, long long, long long, bool)'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::SearchParams::SearchParams(int, float, bool)'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setDouble(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, double)'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setAlgorithm(int)'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::LinearIndexParams::LinearIndexParams()'
/usr/bin/ld: ../../../lib64/libopencv_features2d.so: undefined reference to `cv::flann::IndexParams::setString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::Index::Index(cv::_InputArray const&, cv::flann::IndexParams const&, cvflann::flann_distance_t)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::stop()'
/usr/bin/ld: ../../../lib64/libopencv_calib3d.so: undefined reference to `cv::flann::IndexParams::~IndexParams()'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::set_display_accumulation_time_us(long long)'
/usr/bin/ld: ../../../lib64/libgentl.so: undefined reference to `Metavision::CDFrameGenerator::set_colors(cv::Scalar_<double> const&, cv::Scalar_<double> const&, cv::Scalar_<double> const&, bool)'
collect2: error: ld returned 1 exit status
make: *** [../common.mk:97: Cpp_Acquisition] Error 1
原因分析:
-
SDK 自带 OpenCV 库和 Metavision 库存放在
lib64、OpenCV/lib、Metavision/lib等非系统标准路径下。 -
链接器通过
-L选项能找到直接指定的库(如-larena),但对于这些库自身依赖的间接库(如libopencv_flann.so),链接器不会自动使用-L路径去搜索。 -
需要使用
-Wl,-rpath-link选项告知链接器间接依赖库的搜索路径。
解决方案:
修改 common.mk 文件,在 LDFLAGS 中添加 -Wl,-rpath-link 选项指向 SDK 提供的库目录
bash
LDFLAGS = -L../../../lib64 \
-L../../../GenICam/library/lib/Linux64_x64 \
-L../../../ffmpeg \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/lib64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/lib64 \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/Metavision/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/Metavision/lib \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/OpenCV/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/OpenCV/lib \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/GenICam/library/lib/Linux64_x64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/GenICam/library/lib/Linux64_x64 \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/ffmpeg \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/ffmpeg \
$(LIB_OPENCV_SHARED)
注意 看自己是什么系统,我是amd64就在 这个条件下修改 ifeq ($(ARCH_TYPE), amd64)
同时,针对 C++11 ABI 兼容性问题(出现 std::__cxx11::basic_string 符号),修改CFLAGS :
bash
CFLAGS=-Wall -g -O2 -std=c++11 -Wno-unknown-pragmas -D_GLIBCXX_USE_CXX11_ABI=0
问题二:运行时阶段-动态库找不到(libarena.so.1 liblucidlog.so.1、libGenApi_gcc54_v3_3_LUCID.so)
错误现象:
./Cpp_Acquisition: error while loading shared libraries: libarena.so.1: cannot open shared object file: No such file or directory
原因分析:
-
编译成功,但运行时动态链接器只在系统默认路径(
/lib、/usr/lib等)中查找共享库,无法找到 SDK 自定义路径下的库文件。 -
编译时添加的
-rpath-link仅作用于链接阶段,不写入可执行文件;运行时需要-rpath或LD_LIBRARY_PATH环境变量。
解决方案:
在common.mk文件的OUTDIR = ../../../OutputDirectory/Linux/x64Release/语句后面另起一行,加上
bash
# 固化运行时库搜索路径
LIBS += -Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/lib64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/Metavision/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/OpenCV/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/GenICam/library/lib/Linux64_x64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/ffmpeg
最终修改汇总(common.mk 中 amd64 部分)
bash
ifeq ($(ARCH_TYPE), amd64)
OPENCV_ROOT_PATH = ../../../OpenCV
INC_OPENCV_PATH = -I$(OPENCV_ROOT_PATH)/include
LIB_OPENCV_SHARED = -L$(OPENCV_ROOT_PATH)/lib \
-lopencv_calib3d \
-lopencv_core \
-lopencv_features2d \
-lopencv_highgui \
-lopencv_imgproc \
-lopencv_video
LDFLAGS = -L../../../lib64 \
-L../../../GenICam/library/lib/Linux64_x64 \
-L../../../ffmpeg \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/lib64 \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/Metavision/lib \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/OpenCV/lib \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/GenICam/library/lib/Linux64_x64 \
-Wl,-rpath-link=/opt/arena/ArenaSDK_Linux_x64/ffmpeg \
$(LIB_OPENCV_SHARED)
GENICAMLIBS = -lGCBase_gcc54_v3_3_LUCID \
-lGenApi_gcc54_v3_3_LUCID \
-lLog_gcc54_v3_3_LUCID \
-llog4cpp_gcc54_v3_3_LUCID \
-lMathParser_gcc54_v3_3_LUCID \
-lNodeMapData_gcc54_v3_3_LUCID \
-lXmlParser_gcc54_v3_3_LUCID
OUTDIR = ../../../OutputDirectory/Linux/x64Release/
# 固化运行时库搜索路径
LIBS += -Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/lib64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/Metavision/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/OpenCV/lib \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/GenICam/library/lib/Linux64_x64 \
-Wl,-rpath=/opt/arena/ArenaSDK_Linux_x64/ffmpeg
endif
全局编译修改选项(解决ABI兼容性):
bash
CFLAGS=-Wall -g -O2 -std=c++11 -Wno-unknown-pragmas -D_GLIBCXX_USE_CXX11_ABI=0
重新编译,运行即可。