2014-10-08 2 views
2

Ну, это действительно имеет меня в течение нескольких часов :)C++ проблема с исполняемым кодом

У меня есть проект 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/[email protected]/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()' 

Учитывая, что один из недостающих символов является резюме :: 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 на статический, а не динамический, как видно выше, этот исполняемый файл будет просто отлично.

ответ

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 конструкция не заставляет компоновщик сканировать все между снова и снова до тех пор, он либо разрешил все неопределенные символы, либо может окончательно доказать, что это просто невозможно. Добавление -Wl,--as-needed исправляет ошибку, о которой я упоминал ранее, поэтому вы не будете всасывать библиотеки, которые вы фактически не используете.

+0

Цитата из ссылки Фабио: «Однако нет требований к порядку связывания объектных файлов или динамических библиотек». Думаю, я тоже видел это в gcc docs. Я попробую то, что вы предлагаете, и сообщите, если он решает проблему. Спасибо за ваши усилия. –

+0

Опасный, поскольку он говорит, что лампочка ошибочна, на самом деле, лампочка ошибается. Он прав, говоря, что динамические библиотеки, а также объектные файлы безоговорочно включаются в окончательный исполняемый файл (это ошибка, о которой я упомянул, исправленный «-ас необходимым»), но это не означает, что линкер будет искать эти библиотеки для неопределенных символов из других библиотек или объектов позже в линии ссылок. – zwol

+0

NP, проверите это. благодаря –

1

В прошлом я столкнулся с несколькими аналогичными проблемами; Я не помню конкретных примеров, но я очень хорошо помню, что порядок библиотек имеет значение; Я закончил тем, что перетасовал их до тех пор, пока мой проект не будет построен должным образом.

+0

Порядок библиотек в командной строке абсолютно важен. – zwol

+1

Это важно при создании статической библиотеки/исполняемого файла, но не динамически связанной с ним. По крайней мере, это то, что так предлагает –

+1

@AlexKreimer Это всегда важно. Все, что говорит иначе, неверно. – zwol

Смежные вопросы