Reputation: 1106
Well, this really has me for a few hours now :)
I have a c++ project, which uses cmake. I have link issue, which I cannot resolve. Below is only the link command of a final executable:
/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/[email protected]/Technion/projects/robil/viso/debug/src:/home/kreimer/opencv3.0/lib
which produces this:
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()'
Given that one of the missing symbols is a cv::namedWindow I do this:
nm -gC /home/kreimer/opencv3.0/lib/libopencv_highgui.so.3.0.0 | grep namedWindow
000000000002df80 T cv::namedWindow(cv::String const&, int)
So the symbol is present in a provided shared library. As I read around the order of the libraries does not matter for the dynamic build, so what could be the issue?
By the way, if I change the build of libviso to static instead of dynamic, as seen above, this executable links just fine.
Upvotes: 2
Views: 1102
Reputation: 140786
With a Unix-style linker, the order of the link command line always matters. All object files, .a
files, .so
files, and -l
options are processed strictly left to right. Each item can resolve undefined symbols only for items to its left. You may have misunderstood documentation that's actually talking about the related bug that the linker people refuse to fix (going all the way back to Solaris 2.0, iirc) where shared libraries are unconditionally included whereas static libraries are not.
However, that's not the only problem, because libviso.so
is one of the first things on the command line. I suspect what you have is a case of bad error messages, where the undefined symbols are being used by libviso.so
and also something else much later on the command line, but are being attributed only to libviso.so
.
There is a simple big-hammer fix: arrange to make your command line read as follows:
/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)
The -Wl,--group
... -Wl,--end-group
construction forces the linker to scan everything in between over and over again until it either has resolved all the undefined symbols or can prove conclusively that it just can't be done. Adding -Wl,--as-needed
fixes the bug I mentioned earlier, so you won't suck in libraries you don't actually use.
Upvotes: 1
Reputation: 2036
I have run into several similar problems in the past; I don't remember concrete examples, but I remember very well that the order of libraries matters; I ended up shuffling them until my project eventually built appropriately.
Upvotes: 1