Linking to Armadillo libraries with CMake

armadillo, cmake, linker, mlpack

Solution

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.

Problem

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.

Original source