c ++可执行链接问题

时间:2014-10-08 19:43:24

标签: c++ opencv

嗯,这真的让我有几个小时了:)

我有一个c ++项目,它使用cmake。我有链接问题,我无法解决。下面只是最终可执行文件的链接命令:

/usr/bin/c++ -std=c++0x CMakeFiles/calib_sfm.dir/calib_sfm.cpp.o \
    -o calib_sfm -rdynamic libviso.so -lboost_log -lboost_log_setup \
    -lboost_system -lboost_filesystem -lboost_thread -lpthread \
    /home/kreimer/opencv3.0/lib/libopencv_viz.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_videostab.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_video.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_ts.a \
    /home/kreimer/opencv3.0/lib/libopencv_superres.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_stitching.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_softcascade.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_shape.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_photo.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_optim.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_objdetect.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_nonfree.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_ml.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_legacy.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_imgproc.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_highgui.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_flann.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_features2d.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudawarping.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudastereo.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudaoptflow.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudaimgproc.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudafilters.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudafeatures2d.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudacodec.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudabgsegm.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudaarithm.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cuda.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_core.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_contrib.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_calib3d.so.3.0.0 \
    -ldl -lm -lpthread -lrt \
    /home/kreimer/opencv3.0/share/OpenCV/3rdparty/lib/libippicv.a \
    /home/kreimer/opencv3.0/lib/libopencv_cudawarping.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_legacy.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudaimgproc.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudafilters.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_video.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_objdetect.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_nonfree.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_ml.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_cudaarithm.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_calib3d.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_features2d.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_highgui.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_imgproc.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_flann.so.3.0.0 \
    /home/kreimer/opencv3.0/lib/libopencv_core.so.3.0.0 \
    -Wl,-rpath,/home/kreimer/alex.kreimer@gmail.com/Technion/projects/robil/viso/debug/src:/home/kreimer/opencv3.0/lib

产生这个:

libviso.so: undefined reference to `cv::DescriptorExtractor::compute(cv::_InputArray const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::_OutputArray const&) const'
libviso.so: undefined reference to `cv::calcHist(cv::Mat const*, int, int const*, cv::_InputArray const&, cv::_OutputArray const&, int, int const*, float const**, bool, bool)'
libviso.so: undefined reference to `cv::DescriptorExtractor::~DescriptorExtractor()'
libviso.so: undefined reference to `cv::namedWindow(cv::String const&, int)'
libviso.so: undefined reference to `cv::flann::SearchParams::SearchParams(int, float, bool)'
libviso.so: undefined reference to `cv::computeCorrespondEpilines(cv::_InputArray const&, int, cv::_InputArray const&, cv::_OutputArray const&)'
libviso.so: undefined reference to `cv::DescriptorExtractor::~DescriptorExtractor()'
libviso.so: undefined reference to `cv::destroyWindow(cv::String const&)'
libviso.so: undefined reference to `cv::imwrite(cv::String const&, cv::_InputArray const&, std::vector<int, std::allocator<int> > const&)'
libviso.so: undefined reference to `cv::imread(cv::String const&, int)'
libviso.so: undefined reference to `cv::cornerHarris(cv::_InputArray const&, cv::_OutputArray const&, int, int, double, int)'
libviso.so: undefined reference to `cv::FeatureDetector::detect(cv::_InputArray const&, std::vector<cv::KeyPoint, std::allocator<cv::KeyPoint> >&, cv::_InputArray const&) const'
libviso.so: undefined reference to `cv::waitKey(int)'
libviso.so: undefined reference to `cv::findEssentialMat(cv::_InputArray const&, cv::_InputArray const&, double, cv::Point_<double>, int, double, double, cv::_OutputArray const&)'
libviso.so: undefined reference to `cv::cvtColor(cv::_InputArray const&, cv::_OutputArray const&, int, int)'
libviso.so: undefined reference to `cv::FeatureDetector::~FeatureDetector()'
libviso.so: undefined reference to `typeinfo for cv::FeatureDetector'
libviso.so: undefined reference to `cv::Sobel(cv::_InputArray const&, cv::_OutputArray const&, int, int, int, int, double, double, int)'
libviso.so: undefined reference to `cv::FeatureDetector::empty() const'
libviso.so: undefined reference to `cv::undistortPoints(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::_InputArray const&, cv::_InputArray const&, cv::_InputArray const&)'
libviso.so: undefined reference to `cv::DescriptorExtractor::empty() const'
libviso.so: undefined reference to `cv::FeatureDetector::~FeatureDetector()'
libviso.so: undefined reference to `cv::FeatureDetector::~FeatureDetector()'
libviso.so: undefined reference to `typeinfo for cv::DescriptorExtractor'
libviso.so: undefined reference to `cv::imshow(cv::String const&, cv::_InputArray const&)'
libviso.so: undefined reference to `cv::flann::IndexParams::~IndexParams()'
libviso.so: undefined reference to `cv::DescriptorExtractor::~DescriptorExtractor()'

鉴于缺少的符号之一是cv :: namedWindow,我这样做:

nm -gC /home/kreimer/opencv3.0/lib/libopencv_highgui.so.3.0.0 | grep namedWindow
000000000002df80 T cv::namedWindow(cv::String const&, int)

因此符号出现在提供的共享库中。在我阅读时,库的顺序与动态构建无关,那么问题可能是什么呢?

顺便说一句,如果我将libviso的构建更改为静态而不是动态,如上所示,此可执行文件链接就可以了。

2 个答案:

答案 0 :(得分:1)

我过去遇到过几个类似的问题;我不记得具体的例子,但我记得很清楚图书馆的顺序很重要;最后我把它们洗牌,直到我的项目最终得到适当的构建。

答案 1 :(得分:1)

使用Unix风格的链接器时,链接命令行的顺序总是很重要。所有目标文件,.a文件,.so文件和-l选项都严格从左到右处理。每个项目只能解析左侧项目的未定义符号。您可能误解了文档,这些文档实际上是在讨论链接器人拒绝修复的相关错误(一直回到Solaris 2.0,iirc),其中无条件地包含共享库,而静态库则没有。

但是,这不是唯一的问题,因为libviso.so是命令行中的第一件事。我怀疑你所拥有的是一个错误的错误消息,libviso.so正在使用未定义的符号,而在命令行后面的其他内容也是如此,但仅归因于 libviso.so

有一个简单的大锤子修复:安排让你的命令行读取如下:

/usr/bin/c++ -std=c++0x CMakeFiles/calib_sfm.dir/calib_sfm.cpp.o -o calib_sfm \
    -rdynamic -Wl,--as-needed -Wl,--group \
    $(ALL_THE_LIBRARIES_HERE) \
    -Wl,--end-group \
    -Wl,-rpath,$(SAME_RPATH_AS_BEFORE)

-Wl,--group ... -Wl,--end-group构造强制链接器一遍又一遍地扫描其中的所有内容,直到它解析了 all 未定义的符号或者可以最终证明它无法完成。添加-Wl,--as-needed修复了我之前提到的错误,所以你不会吮吸你实际上没有使用过的库。