Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking to Armadillo libraries with CMake

I am trying to install MLPack on windows 8. I configure the CMakeLists.txt file with:

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

Then when I ran CMake I had a whole series of warning like these ones:

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

In \mlpack-1.0.4\src\mlpack directory I found another CMakeLists file with:

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

that I changed to (not sure if that was a good idea):

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

then CMake seems to be running smoothly:

-- 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

but now when running make I have tons of such errors :

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_'

which after investigation seems to be related to Armadillo.

Any idea what is happening ? I guess I should use target_link_libraries for Armadillo but I am not sure how.

like image 969
Vince Avatar asked Apr 11 '13 02:04

Vince


People also ask

Does armadillo use Lapack?

Armadillo uses LAPACK for various matrix decompositions and factorisations, meaning the speed is dependent on the implementation of LAPACK and/or BLAS. You can use high-speed LAPACK and BLAS replacements to obtain considerably higher performance, such as the multi-threaded OpenBLAS or MKL.


2 Answers

The issue is hopefully pretty easy to resolve. When you do this...

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

you're effectively short-circuiting the find_package(Armadillo 2.4.2 REQUIRED) call, since it expects to have to do the work to find these paths. However, when find_package does the work, the variable ARMADILLO_LIBRARY gets set to the path to the library itself - not the path to the lib's directory.

So the problem boils down to setting ARMADILLO_LIBRARY to the path to the lib's directory rather than the lib itself. This ultimately yields a linker error since the target gmm (added in src\mlpack\methods\gmm\CMakeLists.txt) links to mlpack, and mlpack has been set to link to ${ARMADILLO_LIBRARIES}, which isn't set correctly.

It turns out that find_package(Armadillo ...) already checks in "$ENV{ProgramFiles}/Armadillo/lib" and "$ENV{ProgramFiles}/Armadillo/include", and I expect these resolve to "C:\\Program Files (x86)\\armadillo\\lib" and "C:\\Program Files (x86)\\armadillo\\include" on your machine.

So to fix this, you should delete the lines setting ARMADILLO_LIBRARY and ARMADILLO_INCLUDE_DIR, and revert your change in src\mlpack\CMakeLists.txt (using link_directories is generally a bad idea anyway).

After making these changes, you should delete at least your CMakeCache.txt (in the root of your build tree), or even your entire build tree before re-running CMake to avoid the possibility of using bad cached values from previous failed attempts.

like image 72
Fraser Avatar answered Dec 28 '22 15:12

Fraser


I realize this is a late answer, and I hope you have it figured out by now. Even so, I believe your issue is that the ARMADILLO_LIBRARY variable should hold the exact location of the library, instead of the directory the library is in. So, maybe this would work:

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

The variable LIBXML2_LIBRARIES should also contain the actual path of libxml2.lib (or whatever the actual library is called).

Have you seen this page of instructions I wrote a while back for compiling mlpack on Windows?

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

Feel free to file a bug report on Trac if you have further problems in the future. I only stumbled upon this by chance, so I don't monitor Stack Overflow for issues.

like image 41
ryan Avatar answered Dec 28 '22 14:12

ryan