Cmake Mlpack Ubuntu 问题

Posted

技术标签:

【中文标题】Cmake Mlpack Ubuntu 问题【英文标题】:Cmake Mlpack Ubuntu Issue 【发布时间】:2020-04-30 22:35:07 【问题描述】:

我在 Ubuntu 上的 VSC 中使用 cmake 来实现简单的数据集群算法。为此,我想使用已经存在的 Mlpack 库。如果我尝试运行我的代码,我会收到这样的错误

的main.cpp :( text._ZN6mlpack8neighbor14NeighborSearchINS0_19NearestNeighborSortENS_6metric7LMetricILi1ELb0EEEN4arma3MatIdEENS_4tree6KDTreeENS9_15BinarySpaceTreeIS5_NS0_18NeighborSearchStatIS2_EES8_NS_5bound10HRectBoundENS9_13MidpointSplitEE17DualTreeTraverserENSH_19SingleTreeTraverserEE6SearchEmRNS7_ImEERS8 _ [_ _ ZN6mlpack8neighbor14NeighborSearchINS0_19NearestNeighborSortENS_6metric7LMetricILi1ELb0EEEN4arma3MatIdEENS_4tree6KDTreeENS9_15BinarySpaceTreeIS5_NS0_18NeighborSearchStatIS2_EES8_NS_5bound10HRectBoundENS9_13MidpointSplitEE17DualTreeTraverserENSH_19SingleTreeTraverserEE6SearchEmRNS7_ImEERS8] + 0x6b4):Warnung:undefinierter Verweis奥夫»mlpack ::登录::信息« P>

这似乎是一个错误,因为错误链接到 Mlpack。我按照这个例子Getting Started with mlpack 创建了我自己的 CmakeLists 文件

cmake_minimum_required(VERSION 3.8)
set (CMAKE_CXX_STANDARD 14)
project(HelloBoost)

set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)

set(SOURCE main.cpp)

IF (MLPACK_INCLUDE_DIRS)
  # Already in cache, be silent
  SET(MLPACK_FIND_QUIETLY TRUE)
ENDIF (MLPACK_INCLUDE_DIRS)

FIND_PATH(MLPACK_INCLUDE_DIR core.hpp
      PATHS /usr/local/include/mlpack
                /usr/include/mlpack
         )

SET(MLPACK_LIBRARY_DIR NOTFOUND CACHE PATH "The directory where the MLPACK libraries can be found.")
SET(SEARCH_PATHS
    "$MLPACK_INCLUDE_DIR/../lib"
    "$MLPACK_INCLUDE_DIR/../../lib"
    "$MLPACK_LIBRARY_DIR")
FIND_LIBRARY(MLPACK_LIBRARY NAMES mlpack PATHS $SEARCH_PATHS)

INCLUDE (FindPackageHandleStandardArgs)

FIND_PACKAGE_HANDLE_STANDARD_ARGS(mlpack DEFAULT_MSG MLPACK_LIBRARY MLPACK_INCLUDE_DIR)

IF (MLPACK_FOUND)
   SET(MLPACK_LIBRARIES "$MLPACK_LIBRARY")
   SET(MLPACK_INCLUDE_DIRS "$MLPACK_INCLUDE_DIR")
ENDIF (MLPACK_FOUND)




find_package(Armadillo REQUIRED)
find_package(Boost 1.65.1.0 COMPONENTS thread regex system)
if(Boost_FOUND)
  include_directories($Boost_INCLUDE_DIRS)
  include_directories($MLPACK_INCLUDE_DIR)
  include_directories($Armadillo_INCLUDE_DIR)
  add_executable($PROJECT_NAME $SOURCE)
  target_link_libraries($PROJECT_NAME $Boost_THREAD_LIBRARY $Boost_REGEX_LIBRARY $Boost_SYSTEM_LIBRARY $ARMADILLO_LIBRARIES $MLPACK_LIBRARY)
endif()

我的 main.cpp 文件看起来像

#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <string>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <mlpack/core.hpp>
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>

using namespace std;
using namespace mlpack;
using namespace mlpack::neighbor;
using namespace mlpack::metric;


void mlModel(string filename) 
 
    // Armadillo is a C++ linear algebra library;  
    // mlpack uses its matrix data type. 
    arma::mat data; 

    /* 
    data::Load is used to import data to the mlpack,  
    It takes 3 parameters, 
        1. Filename = Name of the File to be used 
        2. Matrix = Matrix to hold the Data in the File 
        3. fatal = true if you want it to throw an exception 
         if there is an issue 
    */
    data::Load(filename, data, true); 

    /* 
    Create a NeighborSearch model. The parameters of the  
    model are specified with templates: 
        1. Sorting method: "NearestNeighborSort" - This  
        class sorts by increasing distance. 
        2. Distance metric: "ManhattanDistance" - The  
        L1 distance, the sum of absolute distances. 
        3. Pass the reference dataset (the vectors to  
        be searched through) to the constructor. 
     */
    NeighborSearch<NearestNeighborSort, ManhattanDistance> nn(data); 
    // in the above line we trained our model or  
    // fitted the data to the model 
    // now we will predict 

    arma::Mat<size_t> neighbors; // Matrices to hold 
    arma::mat distances; // the results 

    /* 
    Find the nearest neighbors. Arguments are:- 
        1. k = 1, Specify the number of neighbors to find 
        2. Matrices to hold the result, in this case,  
        neighbors and distances 
    */
    nn.Search(1, neighbors, distances); 
    // in the above line we find the nearest neighbor 

    // Print out each neighbor and its distance. 
    for (size_t i = 0; i < neighbors.n_elem; ++i) 
     
        std::cout << "Nearest neighbor of point " << i << " is point "
                  << neighbors[i] << " and the distance is " 
                  << distances[i] << ".\n"; 
     
 




int main()


    mlModel("../Example Data/collectedData_Protocol1.csv"); 

    return 0;

从 ldd "ProjectName" 输出

linux-vdso.so.1 (0x00007ffcc7d1e000) libmlpack.so.3 => /usr/local/lib/libmlpack.so.3 (0x00007ff8b44d9000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff8b4150000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff8b3f38000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff8b3b47000) libarmadillo.so.8 => /usr/lib/libarmadillo.so.8 (0x00007ff8b393e000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff8b35a0000) libgomp.so.1 => /usr/lib/x86_64-linux-gnu/libgomp.so.1 (0x00007ff8b3371000) /lib64/ld-linux-x86-64.so.2 (0x00007ff8b4b54000) libblas.so.3 => /usr/lib/x86_64-linux-gnu/libblas.so.3 (0x00007ff8b3104000) liblapack.so.3 => /usr/lib/x86_64-linux-gnu/liblapack.so.3 (0x00007ff8b2866000) libarpack.so.2 => /usr/lib/x86_64-linux-gnu/libarpack.so.2 (0x00007ff8b261c000) libsuperlu.so.5 => /usr/lib/x86_64-linux-gnu/libsuperlu.so.5 (0x00007ff8b23ac000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff8b21a8000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff8b1f89000) libgfortran.so.4 => /usr/lib/x86_64-linux-gnu/libgfortran.so.4 (0x00007ff8b1baa000) libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007ff8b196a000)

纳米的输出

nm -D -C /usr/local/lib/libmlpack.so | grep 日志::Info000000000044c2e0 B mlpack::Log::Info

我有什么遗漏吗? cmake 构建确实工作得很好。有没有人有一个可以在 Ubuntu 上使用 Mlpack wit Cmake 的 CmakeList 文件?

我误解了 Cmake 的概念。我认为运行我的 main.cpp 会在使用 Cmake 后自动链接必要的库。我知道我必须运行 CMake Executable 才能获得所需的输出。这按预期工作。

【问题讨论】:

mlpack 安装在您计算机的什么位置?您只为其指定了两个搜索路径。你确定图书馆真的在那里吗?也许使用message(FATAL_ERROR "mlpack not found") 来定位您的问题。调用 cmake 时是否设置了“MLPACK_LIBRARY_DIR”?你的变量MLPACK_FOUND 设置在哪里?好像你只是忘了设置它。因此,您的其他变量永远不会设置。 您遵循的文档开头有一条警告:“它已过时”。也许最好遵循另一个文档。本文档解释了如何在 ubuntu 上构建 mlpack。 mlpack.org/doc/mlpack-3.0.4/doxygen/build.html 也许我误解了 CmakeList.txt 背后的概念,正如下面提到的答案。这些库可以在路径“/usr/lib/”中找到,包含目录是“usr/include/mlpack/” 【参考方案1】:

只需在您的系统中安装mlpack 并使用mlpack models repo 中提供的FindMLPACK.cmake。您的根 CMakeLists.txt 应该如下所示:

cmake_minimum_required(VERSION 3.8)
set (CMAKE_CXX_STANDARD 14)
project(MlpackSample)

set(CMAKE_MODULE_PATH $CMAKE_MODULE_PATH "$CMAKE_CURRENT_SOURCE_DIR/cmake")
find_package(MLPACK REQUIRED)

add_executable(mlpack_sample main.cpp)
target_link_libraries(mlpack_sample $MLPACK_LIBRARY)

你只需要把FindMLPACK.cmake文件放到你项目的cmake目录中

*
   - CMakeLists.txt
   - main.cpp
   * cmake
      - FindMLPACK.cmake

我将文件内容粘贴到此处以防 github 链接过期

#.rst:
# FindMLPACK
# -------------
#
# Find MLPACK
#
# Find the MLPACK C++ library
#
# Using MLPACK::
#
#   find_package(MLPACK REQUIRED)
#   include_directories($MLPACK_INCLUDE_DIRS)
#   add_executable(foo foo.cc)
#   target_link_libraries(foo $MLPACK_LIBRARIES)
#
# This module sets the following variables::
#
#   MLPACK_FOUND - set to true if the library is found
#   MLPACK_INCLUDE_DIRS - list of required include directories
#   MLPACK_LIBRARIES - list of libraries to be linked
#   MLPACK_VERSION_MAJOR - major version number
#   MLPACK_VERSION_MINOR - minor version number
#   MLPACK_VERSION_PATCH - patch version number
#   MLPACK_VERSION_STRING - version number as a string (ex: "1.0.4")

include(FindPackageHandleStandardArgs)

# UNIX paths are standard, no need to specify them.
find_library(MLPACK_LIBRARY
  NAMES mlpack
  PATHS "$ENVProgramFiles/mlpack/lib"  "$ENVProgramFiles/mlpack/lib64" "$ENVProgramFiles/mlpack"
)
find_path(MLPACK_INCLUDE_DIR
  NAMES mlpack/core.hpp mlpack/prereqs.hpp
  PATHS "$ENVProgramFiles/mlpack"
)


if(MLPACK_INCLUDE_DIR)
  # Read and parse mlpack version header file for version number
  file(STRINGS "$MLPACK_INCLUDE_DIR/mlpack/core/util/version.hpp" _mlpack_HEADER_CONTENTS REGEX "#define MLPACK_VERSION_[A-Z]+ ")
  string(REGEX REPLACE ".*#define MLPACK_VERSION_MAJOR ([0-9]+).*" "\\1" MLPACK_VERSION_MAJOR "$_mlpack_HEADER_CONTENTS")
  string(REGEX REPLACE ".*#define MLPACK_VERSION_MINOR ([0-9]+).*" "\\1" MLPACK_VERSION_MINOR "$_mlpack_HEADER_CONTENTS")
  string(REGEX REPLACE ".*#define MLPACK_VERSION_PATCH \"?([0-9x]+).*" "\\1" MLPACK_VERSION_PATCH "$_mlpack_HEADER_CONTENTS")

  unset(_mlpack_HEADER_CONTENTS)

  set(MLPACK_VERSION_STRING "$MLPACK_VERSION_MAJOR.$MLPACK_VERSION_MINOR.$MLPACK_VERSION_PATCH")
endif()

find_package_handle_standard_args(MLPACK
  REQUIRED_VARS MLPACK_LIBRARY MLPACK_INCLUDE_DIR
  VERSION_VAR MLPACK_VERSION_STRING
)

if(MLPACK_FOUND)
  set(MLPACK_INCLUDE_DIRS $MLPACK_INCLUDE_DIR)
  set(MLPACK_LIBRARIES $MLPACK_LIBRARY)
endif()

# Hide internal variables
mark_as_advanced(
  MLPACK_INCLUDE_DIR
  MLPACK_LIBRARY
)

【讨论】:

我知道了解Cmake目录中指定的FindMLPACK.cmake文件的概念。可惜附加的 FindMLPACK.cmake 找不到打包好的 MLPACKConfig.cmake 和 mlpack-config.cmake @skop,对不起,我不明白你的评论。 “找不到打包的MLPACKConfig.cmake 是什么意思?文件MLPACKConfig.cmake 不需要任何东西。FindMLPACK.cmake 已经以一种无需任何额外先决条件即可找到mlpack 库的方式编写。 我刚刚发现我的目录是“Cmake”而不是“cmake”。现在构建工作正常。但是如果我尝试运行 main.cpp,我仍然会收到相同的错误 这意味着你没有正确安装你的库或者你有冲突的版本。验证您的二进制文件是否与正确版本的 libmlpack 链接:ldd mlpack_sample。验证您的 libmlpack 是否有 mlpack::Log::Info 符号:nm -D -C /usr/local/lib/libmlpack.so | grep Log::Info 我正在尝试删除所有依赖项并以手动方式重新构建它。之后我会更新帖子

以上是关于Cmake Mlpack Ubuntu 问题的主要内容,如果未能解决你的问题,请参考以下文章

ubuntu18.04 中使用cmake 时候配置qt模块的路径的问题

ubuntu16.04升级cmake

ubuntu16.04升级cmake

Ubuntu/Linux 升级 CMake 版本

转载:Ubuntu14.04下升级cmake工具

CMake 在 Ubuntu 中找不到 GoogleTest 所需的库