【问题标题】:Linking to Armadillo libraries with CMake使用 CMake 链接到 Armadillo 库
【发布时间】:2013-04-03 02:51:50
【问题描述】:

我正在尝试在 Windows 8 上安装 MLPack。 我配置了 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,但我不确定如何。

【问题讨论】:

  • 是的,你肯定需要 target_link_libraries() 在你自己的 CMakeLists.txt 中链接到犰狳。你能发布你的完整/相关部分 CMakeLists.txt
  • 非常感谢。我想知道我是否真的可以发布整个文件,它很长。对于相关部分,我刚刚找到了一行“find_package(Armadillo 2.4.2 REQUIRED)”,后来又找到了一行“include_directories(${ARMADILLO_INCLUDE_DIRS})”。但我是真正的初学者,我可能肯定会错过一些东西。完整文件在这里:mlpack.org/files/mlpack-1.0.4.tar.gz我刚刚做了帖子中描述的更改...
  • 添加如下内容:target_link_libraries(gmm.exe ${ARMADILLO_LIBRARIES})。看看这是否有效。或者只是使用“gmm”而不是“gmm.exe”再试一次
  • 用 .exe 尝试过,cmake 抱怨 gmm.exe 不是用这个项目构建的。如果没有 .exe,cmake 会抱怨 gmm 未在此目录中构建...

标签: linker cmake armadillo mlpack


【解决方案1】:

希望这个问题很容易解决。当你这样做时......

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 被设置为库本身的路径,而不是库目录的路径。

所以问题归结为将ARMADILLO_LIBRARY 设置为lib 目录的路径,而不是lib 本身。这最终会产生链接器错误,因为目标 gmm(在 src\mlpack\methods\gmm\CMakeLists.txt 中添加)链接到 mlpack,并且 mlpack 已设置为链接到 ${ARMADILLO_LIBRARIES},这不是t 设置正确。

事实证明find_package(Armadillo ...) 已经签入"$ENV{ProgramFiles}/Armadillo/lib""$ENV{ProgramFiles}/Armadillo/include",我希望这些解析到您机器上的"C:\\Program Files (x86)\\armadillo\\lib""C:\\Program Files (x86)\\armadillo\\include"

因此,要解决此问题,您应该删除设置 ARMADILLO_LIBRARYARMADILLO_INCLUDE_DIR 的行,并恢复您在 src\mlpack\CMakeLists.txt 中所做的更改(无论如何,使用 link_directories 通常是个坏主意)。

进行这些更改后,您应该至少删除您的 CMakeCache.txt(在构建树的根目录中),甚至是整个构建树,然后再重新运行 CMake,以避免使用之前失败的坏缓存值的可能性尝试。

【讨论】:

  • 谢谢!试过这个,但我得到这个错误:CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:97(消息):找不到犰狳:发现不合适的版本“0.0 .0”,但要求至少是“2.4.2”(找到 C:/Program Files (x86)/armadillo/lib/libarmadillo.dll)...可能是我的犰狳安装以某种方式搞砸了吗?
  • 是的 - 可能。您是否使用与编译 Armadillo 相同的生成器来生成 MLPack? (MinGW?)看起来犰狳库找到正确,但无法正确读取以找出其版本。
  • 我使用 cmake 然后 mingw32-make install 编译了犰狳。现在,我只是再次执行它,没有对 cmake 文件进行任何更改(除了删除缓存和树),事情进展顺利(与我几天前做的一样)。现在我不确定上次我在哪里搞砸了,因为在那之后使用 cmake for mlpack 现在似乎对犰狳感到满意(检测版本 3.800.2)。但现在我有关于 libxml2 的警告(“目标可能只链接到库”)。没有编译 libxml2,只是下载了二进制文件......可能来自那个? (顺便说一句,超级感谢帮助)
  • 我们到了:-) 你也没有明确设置LIBXML2_LIBRARIES 是吗?如果是这样,它可能还应该引用库而不是库所在的文件夹。我自己不使用 MinGW,但看起来 libxml2 的 Windows 二进制文件只适用于 MSVC,而不是 MinGW。您需要使用 mingw32-make 构建 libxml2,或者使用 mingw-get 获取它。尝试谷歌搜索“libxml2 mingw”
  • 现在正在为 libxml2 (*.com/questions/16007716/…) 苦苦挣扎……一旦解决,就会回来 (arghhh)。
【解决方案2】:

我意识到这是一个迟到的答案,我希望你现在已经弄清楚了。即便如此,我相信你的问题是 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 的实际路径(或任何实际调用的库)。

您是否看过我不久前为在 Windows 上编译 mlpack 编写的说明页面?

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

如果您将来遇到其他问题,请随时在 Trac 上提交错误报告。我只是偶然发现了这个,所以我没有监控 Stack Overflow 的问题。

【讨论】:

    【解决方案3】:

    我遇到了同样的问题。有两个项目符号aramadillo library faq 要求您取消注释这些行

    #define ARMA_USE_LAPACK 
    #define ARMA_USE_WRAPPER
    

    在文件中

    include/armadillo_bits/config.hpp
    

    在犰狳源代码树中。

    取消注释后重新编译时,您可以看到犰狳共享库/dll 中的符号。希望这会有所帮助!

    【讨论】: