2013-04-12 2 views
1

My программного обеспечения, составленного штрафа на Linux несколько месяцев назад перестал компиляции на моем новом убунту:Linking терпит неудачу с CMake, DSO-Link-Change

Linking CXX executable myApp 
/usr/bin/ld: ../libMyLib/libMyLib.a(MyFile.cpp.o): undefined reference to symbol '_ZN2cv6resizeERKNS_11_InputArrayERKNS_12_OutputArrayENS_5Size_IiEEddi' 
/usr/bin/ld: note: '_ZN2cv6resizeERKNS_11_InputArrayERKNS_12_OutputArrayENS_5Size_IiEEddi' is defined in DSO /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libopencv_imgproc.so so try adding it to the linker command line 
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../../lib/libopencv_imgproc.so: could not read symbols: Invalid operation 
collect2: error: ld returned 1 exit status 
make[2]: *** [myApp/myApp] Error 1 
make[1]: *** [myApp/CMakeFiles/myApp.dir/all] Error 2 
make: *** [all] Error 2 

Я предполагаю, что это связано с https://fedoraproject.org/wiki/UnderstandingDSOLinkChange.

Мой проект (все cmake) содержит несколько библиотек и приложение, как библиотеки, так и приложение зависят от opencv и/или boost (каждый на некоторых разных). Мои собственные библиотеки создаются как .a-файлы, ocv/boost вставляются в качестве разделяемых библиотек, а связь приложения с ошибкой выше.

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

FIND_PACKAGE(Boost REQUIRED) 
FIND_PACKAGE(OpenCV REQUIRED core) 
...stuff... 
include_directories(${OpenCV_INCLUDE_DIRS}) 
include_directories(${Boost_INCLUDE_DIRS}) 
add_library(${SUBPROJECT_NAME} ${SOURCE} ${HEADERS}) 

The CMakeLists приложения выглядит

FIND_PACKAGE(OpenCV REQUIRED core imgproc highgui) 
include_directories(${OpenCV_INCLUDE_DIRS}) 
TARGET_LINK_LIBRARIES(${SUBPROJECT_NAME} ${OpenCV_LIBS} MyLib) 

Это все правильно, и я всегда думал, что это способ сделать это, но теперь с этим DSO вещи я просто не могу получить он больше работает.

Если это необходимо, я попытался использовать CMake 2.8.7 и 2.8.10 и g ++ 4.7.2 и 4.8, все производят те же ошибки.

+0

Я не помню, имеет ли порядок библиотек значение в CMake (т. Е. Передает ли он в надлежащем порядке GCC), но это, безусловно, имеет значение для самого GCC. Может быть, вы должны поставить 'MyLib' перед' $ {OpenCV_LIBS} '? –

+0

О, чувак, ты должен шутить ... когда MyLib зависит от $ {OpenCV_LIBS}, он должен идти до него на cmdline? Это очень неинтуитивно для меня, я думаю, сначала вам нужно связать с $ {OpenCV_LIBS} (тогда это «определено»), а затем связать с MyLib, который зависит от $ {OpenCV_LIBS} и который может его найти сейчас ... Но на самом деле вы правы, и я ошибался с тех пор, как использовал gcc ... Если вы сформулируете это как ответ, я соглашусь ... :-) Спасибо, так глупо ... – Ela782

ответ

2

НКА очень чувствительна к порядку, в котором вы указуете библиотеки на этапе компоновки. Например, если libA.a зависит от libB.a и исполняемым App зависит от обоих, то вы должны были бы вызвать линкера следующим образом:

gcc main.o object1.o ... object2.o -lA -lB -o App 

ПРИМЕЧАНИЕ: Обратите внимание на тот факт, что, хотя A зависит от B, все еще A до B. В качестве вывода, должен быть связан самый независимый артефакт. Конечно, это в некотором смысле противоречиво, но старайтесь рассматривать его так же, как в C++ применяется квалификатор const. :)

+0

Похоже, что до того, как это изменение связанного поведения было связано выше, в моем случае это не имело значения (кроме неправильного), но теперь линкер стал более педантичным, и это имеет значение. Огромное вам спасибо :-) – Ela782

+0

@ Ela782: Но, возможно, есть лучшее решение. Система сборки, такая как CMake, - это абстрагирование от компилятора и платформы. Поэтому, в общем, не рекомендуется модифицировать 'CMakeLists' для соответствия конкретному компилятору. Лучше добавить 'target_link_libraries (MyLib $ {OpenCV_LIBS})' в 'CMakeLists', соответствующий' MyLib'. Таким образом, вы не только явно определяете зависимости ваших артефактов, что очень хорошо читается, но вы также используете систему отслеживания зависимостей CMake. Другими словами, пусть CMake обрабатывает для вас порядок ссылок, умело помогая ему сделать это. –

+0

Хорошо, но я всегда думал, что вы предлагаете плохую практику, и хорошая практика заключается только в том, чтобы приложение заключило связь. Разве это не так или нет? Я узнал о себе год назад, и я прочитал эту рекомендацию по нескольким домашним страницам (также на SO, я полагаю). – Ela782

1

Имеет ли OpenCV_LIBS -lopencv_imgproc? Если нет, то попробуйте добавить вручную -lopencv_imgproc командной строки ссылки (запустить сделать V = 1) Если он работает добавить его в TARGET_LINK

+0

Да конечно, он содержит его, вот полная команда связывания приложения, которое не работает: '/ usr/bin/C++ -std = C++ 11 -O3 -DNDEBUG CMakeFiles/myApp.dir/myApp.cpp.o - o myApp -L/home/user/MCR/v81/bin/glnxa64 -rdynamic -lboost_program_options-mt -lmx -lmat -lopencv_gpu -lopencv_contrib -lopencv_legacy -lopencv_objdetect -lopencv_calib3d -lopencv_features2d -lopencv_video -lopencv_highgui -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core ../MyLib/MyLib.a -Wl, -rpath,/home/user/MCR/v81/bin/glnxa64' – Ela782

+0

Спасибо, что у меня была такая же проблема, и я включил исправление! –

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