I'm using cmake in VSC on Ubuntu for a simple data cluster algorithm. For this I want to use the already existing Mlpack library. If I try to run my code I receive errors like this
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 auf »mlpack::Log::Info«
This seems to be an error because of false linking to Mlpack. I followed this example Getting Started with mlpack and created my own CmakeLists file
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()
My main.cpp file looks like
#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;
}
Output off 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)
Output of nm
nm -D -C /usr/local/lib/libmlpack.so | grep Log::Info000000000044c2e0 B mlpack::Log::Info
Is there something I am missing ? The cmake build does work just fine. Does anyone has a working CmakeList file for using Mlpack wit Cmake on Ubuntu?
I missunderstood the concept of Cmake. I thought running my main.cpp will automatically link the necessary libraries after using Cmake. I know understand that I have to run the CMake Executable in order to get the desired output. This works as expected.