Связывание с библиотеками Armadillo с помощью CMake

Я пытаюсь установить MLPack в Windows 8. Я настраиваю файл CMakeLists.txt с помощью:

set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")

Затем, когда я запустил CMake, у меня была целая серия предупреждений, подобных этим:

WARNING: Target "mlpack" requests linking to directory "C:\Program Files (x86)\armadillo\lib".  Targets may link only to libraries.  CMake is dropping the item.

В каталоге \mlpack-1.0.4\src\mlpack я нашел еще один файл CMakeLists с:

target_link_libraries(mlpack
  ${ARMADILLO_LIBRARIES}
  ${Boost_LIBRARIES}
  ${LIBXML2_LIBRARIES}
)

что я изменил на (не уверен, что это была хорошая идея):

target_link_libraries(mlpack
  ${Boost_LIBRARIES}
)
link_directories(mlpack
  ${ARMADILLO_LIBRARIES}
  ${LIBXML2_LIBRARIES}
)

тогда CMake, кажется, работает гладко:

-- Found Armadillo: C:\Program Files (x86)\armadillo\lib (found suitable version "3.800.2", minimum required is "2.4.2")
-- Found LibXml2: C:\cpp\libraries\libxml2-2.7.8.win32\lib (found suitable version "2.7.8", minimum required is "2.6.0")
-- Boost version: 1.53.0
-- Found the following Boost libraries:
--   program_options
--   unit_test_framework
-- Boost version: 1.53.0
-- Found the following Boost libraries:
--   random
-- Could NOT find Doxygen (missing:  DOXYGEN_EXECUTABLE)
-- Configuring done
-- Generating done
-- Build files have been written to: C:/cpp/libraries/mlpack-1.0.4

но теперь при запуске make у меня куча таких ошибок:

Linking CXX executable ..\..\..\..\gmm.exe
CMakeFiles\gmm.dir/objects.a(gmm_main.cpp.obj):gmm_main.cpp:(.text+0xb9): undefined reference to `wrapper_dgemv_'
CMakeFiles\gmm.dir/objects.a(gmm_main.cpp.obj):gmm_main.cpp:(.text$_ZN4arma6auxlib10det_lapackIdEET_RKNS_3MatIS2_EEb[__ZN4arma6auxlib10det_lapackIdEET_RKNS_3MatIS2_EEb]+0x115): undefined reference to `wrapper_dgetrf_'

который после расследования кажется связанным с Армадилло.

Любая идея, что происходит? Думаю, мне следует использовать target_link_libraries для Armadillo, но я не знаю, как это сделать.


person Vince    schedule 11.04.2013    source источник
comment
Да, вам определенно нужно target_link_libraries() для ссылки на Armadillo в вашем собственном CMakeLists.txt. Можете ли вы опубликовать свои полные / соответствующие части CMakeLists.txt   -  person Vaibhav Desai    schedule 11.04.2013
comment
Большое спасибо. Интересно, смогу ли я выложить весь файл, он довольно длинный. Для соответствующих частей я только что нашел строку с find_package(Armadillo 2.4.2 REQUIRED), а затем строку с include_directories(${ARMADILLO_INCLUDE_DIRS}). Но я настоящий новичок, я определенно могу что-то упустить. Полные файлы находятся здесь:mlpack.org/files/mlpack-1.0. 4.tar.gz Я только что внес изменения, описанные в посте...   -  person Vince    schedule 11.04.2013
comment
добавьте что-то вроде этого: target_link_libraries(gmm.exe ${ARMADILLO_LIBRARIES}). Посмотрите, работает ли это. Или просто используйте gmm вместо gmm.exe и повторите попытку.   -  person Vaibhav Desai    schedule 11.04.2013
comment
пробовал с .exe и cmake жалуется, что gmm.exe не был собран с этим проектом. Без .exe cmake жалуется, что gmm не был построен в этом каталоге...   -  person Vince    schedule 11.04.2013


Ответы (3)


Надеюсь, проблема довольно легко разрешима. Когда ты это сделаешь...

set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")

вы эффективно сокращаете вызов find_package(Armadillo 2.4.2 REQUIRED), так как он ожидает, что ему придется выполнить работу, чтобы найти эти пути. Однако, когда find_package выполняет свою работу, переменной ARMADILLO_LIBRARY присваивается путь к самой библиотеке, а не путь к каталогу lib.

Таким образом, проблема сводится к установке ARMADILLO_LIBRARY на путь к каталогу lib, а не к самой lib. В конечном итоге это приводит к ошибке компоновщика, поскольку цель gmm (добавленная в src\mlpack\methods\gmm\CMakeLists.txt) ссылается на mlpack, а mlpack была настроена на ссылку на ${ARMADILLO_LIBRARIES}, что установлено неправильно.

Оказывается, find_package(Armadillo ...) уже регистрирует "$ENV{ProgramFiles}/Armadillo/lib" и "$ENV{ProgramFiles}/Armadillo/include", и я ожидаю, что на вашем компьютере они разрешатся в "C:\\Program Files (x86)\\armadillo\\lib" и "C:\\Program Files (x86)\\armadillo\\include".

Поэтому, чтобы исправить это, вы должны удалить строки, устанавливающие ARMADILLO_LIBRARY и ARMADILLO_INCLUDE_DIR, и отменить изменения в src\mlpack\CMakeLists.txt (используя link_directories в любом случае является плохой идеей).

После внесения этих изменений вы должны удалить как минимум файл CMakeCache.txt (в корне вашего дерева сборки) или даже все дерево сборки перед повторным запуском CMake, чтобы избежать возможности использования неверных кэшированных значений из предыдущих неудачных попыток.

person Fraser    schedule 11.04.2013
comment
Спасибо ! Пробовал это, но получаю эту ошибку: CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:97 (сообщение): НЕ удалось найти Armadillo: найдена неподходящая версия 0.0. 0, но требуется как минимум 2.4.2 (найден C:/Program Files (x86)/armadillo/lib/libarmadillo.dll) ... может ли быть так, что моя установка броненосца как-то испорчена? - person Vince; 12.04.2013
comment
Да, возможно. Используете ли вы для MLPack тот же генератор, что и для компиляции Armadillo? (MinGW?) Похоже, что библиотека Armadillo найдена правильно, но ее нельзя правильно прочитать, чтобы узнать ее версию. - person Fraser; 12.04.2013
comment
Я скомпилировал броненосец с помощью cmake, а затем установил mingw32-make. Теперь я просто выполнил это снова без каких-либо изменений в файлах cmake (кроме удаления кеша и дерева), и все прошло гладко (так же, как когда я сделал это пару дней назад). Теперь я не уверен, где я ошибся в прошлый раз, потому что после этого использование cmake для mlpack, кажется, теперь устраивает броненосца (обнаружена версия 3.800.2). Но теперь у меня есть предупреждения о libxml2 (цели могут ссылаться только на библиотеки). Не компилировал libxml2, просто скачал бинарники... может из-за этого? (кстати, супер спасибо за помощь) - person Vince; 12.04.2013
comment
Мы приближаемся к этому :-) Вы же не устанавливаете LIBXML2_LIBRARIES явно, не так ли? Если это так, то, вероятно, это также должно относиться к библиотеке, а не к папке, в которой находится библиотека. Я сам не использую MinGW, но похоже, что двоичные файлы Windows для libxml2 подходят только для использования с MSVC, а не с MinGW. Вам нужно собрать libxml2 с помощью mingw32-make или, возможно, получить его с помощью mingw-get. Попробуйте поискать в гугле libxml2 mingw - person Fraser; 12.04.2013
comment
теперь борется с libxml2 (stackoverflow.com/questions/16007716/) ... вернется, как только это будет решено (ааааа). - person Vince; 15.04.2013
comment
теперь cmake, кажется, хорошо выполняет свои обязанности, находя все и ни на что не жалуясь. Но теперь, когда я использую mingw32-make для компиляции mlpack, на 32% он отображает сканирующие зависимости целевого det, компьютер работает как сумасшедший, но, казалось бы, ничего не происходит. Прошел уже час, я думаю, что-то не так... - person Vince; 16.04.2013

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

set(ARMADILLO_LIBRARY "C:\\Program Files (x86)\\armadillo\\lib\\armadillo.lib")
set(ARMADILLO_INCLUDE_DIR "C:\\Program Files (x86)\\armadillo\\include")

Переменная LIBXML2_LIBRARIES также должна содержать фактический путь к libxml2.lib (или как там называется реальная библиотека).

Вы видели эту страницу с инструкциями, которые я написал некоторое время назад для компиляции mlpack в Windows?

http://www.mlpack.org/trac/wiki/MLPACKOnWindows

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

person ryan    schedule 13.05.2013

Я столкнулся с той же проблемой. Есть два пункта часто задаваемые вопросы по библиотеке aramadillo, которые просят вас раскомментировать строки

#define ARMA_USE_LAPACK 
#define ARMA_USE_WRAPPER

в файле

include/armadillo_bits/config.hpp

который находится в исходном дереве броненосца.

Когда вы перекомпилируете после раскомментирования строк, вы можете увидеть символы в общей библиотеке броненосца/dll. Надеюсь это поможет!

person Kedar Grama    schedule 31.07.2013