bibatn / special_seminar_

0 stars 0 forks source link

Как собрать PCL на POLUS. #12

Open bibatn opened 1 year ago

bibatn commented 1 year ago

Основные особенности и сложности: 1) Нельзя собрать пакетным менеджером.(Константин Адреевич сказал что у него истекли права.) 2) Нету прав супер пользователя(Нельзя выполнить команды требующие sudo) 3) старое програмное обеспечение, в частности старый компилятор не поддерживающий все старше (с++11 стандарта (201103L)). 4) Библиотека требует другие зависимости. Из основных, это FLANN (используется для построения KD-дерева и последующего поиска по нему), Eigen(используется для операций линейной алгебры), BOOST. Их придется также собрать. 5) Память на хосте не доступна на других узлах.

step by step

1)Сначала нужно собрать cmake. https://github.com/Kitware/CMake.git (v3.23.1) на момент сборки библиотеки на POLUS работал git и был доступ на github. Если его нет то нужно попросить Константин Андреевича его вернуть, либо склонировать репозиторий на свой компьютер а затем скопировать через scp на POLUS. git clone https://github.com/Kitware/CMake.git cd CMake ./bootstrap make -j n, где n кол-во потоков сборки В директории bin появится собранный cmake файл. Если возникли проблемы возможно поможет сделать git checkout v3.23.1 2) Нужно собрать библиотеку Eigen. Еigen является библиотекой реализованной полностью в header файлах поэтому нужно просто ее склонировать в репозиторию где выполняется сборка PCL. git clone https://gitlab.com/libeigen/eigen.git 3) Нужно собрать библиотеку FLANN. в директории в которой собираем PCL: git clone https://github.com/flann-lib/flann.git cd flann git checkout 1.9.1 при сборке возникает странная ошибка которая решается следующим образом:

In your flann dir run touch src/cpp/empty.cpp In src/cpp/CMakeLists.txt replace add_library(flann_cpp SHARED "") and add_library(flann SHARED "") with add_library(flann_cpp SHARED empty.cpp) and add_library(flann SHARED empty.cpp)

собираем пакет с помощью cmake: в корневой директории выполняем команду mkdir build cd build
путь/до/файла/cmake ..
(в моем случае: /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/CMake/bin/cmake ..) make -j 4 4) Теперь приступаем к сборке самого PCL. Тут возникает сложность №2. Дело в том, что в PCL, как и в большинстве библиотек реализована некоторая автоматизация предполагающая, что пользователь не должен знать как работает cmake. Это автоматизация реализована из предположения, что все зависимости требующиеся библиотеки(BOOST, FLANN, EIGEN) находятся по системным путям. В нашем случае это не так. При наличие прав суперпользователя можно было просто закинуть собранные пакеты по системным путям командой sudo make install. В нашем случае придется лезть в cmake файлы и разбираться в стандарте cmake. Также возникает сложность №3 а именно старый компилятор. Последняя версия PCL написанная на С++11 стандарте pcl-1.9.1. В директории в которой собираем PCL: git clone https://github.com/PointCloudLibrary/pcl.git git checkout pcl-1.9.1 cd pcl/cmake/Modules в файле FindEigen.cmake заменить

 find_path(EIGEN_INCLUDE_DIR Eigen/Core
-    HINTS "${EIGEN_ROOT}" "$ENV{EIGEN_ROOT}" ${PC_EIGEN_INCLUDEDIR} ${PC_EIGEN_
-    PATHS "$ENV{PROGRAMFILES}/Eigen" "$ENV{PROGRAMW6432}/Eigen"
-          "$ENV{PROGRAMFILES}/Eigen3" "$ENV{PROGRAMW6432}/Eigen3"
-    PATH_SUFFIXES eigen3 include/eigen3 include)

на find_path(EIGEN_INCLUDE_DIR Eigen/Core PATHS /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/eigen NO_DEFAULT_PATH ) где /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/eigen путь до вашей библиотеки Eigen.

В файле FindFLANN.cmake заменить

-    find_path(FLANN_INCLUDE_DIR flann/flann.hpp
-              HINTS "${FLANN_ROOT}" "$ENV{FLANN_ROOT}"
-              PATHS "$ENV{PROGRAMFILES}/flann" "$ENV{PROGRAMW6432}/flann"
-              PATH_SUFFIXES include)

на

    find_path(FLANN_INCLUDE_DIR
      NAMES
        flann/flann.hpp
      PATHS
         /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/flann/src/cpp
      NO_DEFAULT_PATH
     ) 
     message(STATUS "marat ${FLANN_INCLUDE_DIR}")

где /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/flann/src/cpp путь до вашей библиотеки flann + "src/cpp". заменить

-    find_library(FLANN_LIBRARY
-                 NAMES ${FLANN_RELEASE_NAME}
-                 HINTS "${FLANN_ROOT}" "$ENV{FLANN_ROOT}"
-                 PATHS "$ENV{PROGRAMFILES}/flann" "$ENV{PROGRAMW6432}/flann"
-                 PATH_SUFFIXES lib)

на

     find_library(FLANN_LIBRARY
       NAMES
         flann_cpp
       PATHS
          /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/flann/build/lib
       PATH_SUFFIXES
         lib
       NO_DEFAULT_PATH
     ) 

где /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/PCL/flann/build/lib путь до вашей библиотеки flann + "build/lib"

cd .. в файле pcl_find_sse.cmake изменить list(APPEND SSE_FLAGS "-march=native") на list(APPEND SSE_FLAGS )


Le ballet de la Merlaison
В корневой директории pcl: mkdir build cd build
путь/до/файла/cmake ..
(в моем случае: /home_edu/edu-cmc-sqi19/edu-cmc-sqi19-24/CMake/bin/cmake ..) make -j 3 (слишком много потоков могут сожрать всю оперативку и сборка зависнет)

Использование собранной библиотеки:

Здесь возникает сложность №5. Дело в том что pcl использует библиотеку BOOST, которая находится по системным путям на хосте. При линковке pcl использует динамические библиотеки BOOST (.so файлы). А как известно они подгружаются при запуске программы. Соответсвенно при запуске программы на других узлах(не на хосте) программа их не найдет, так как их там нет. Решением проблемы является либо, сборака BOOST версии 1.53 и подключение ее аналогично flann и eigen. Либо, так сделал я, скопировать эти .so файлы к себе. В директории в которой собираем PCL: cp /usr/lib64/libboost_thread-mt.so.1.53.0 libboost_thread-mt.so.1.53.0 cp /usr/lib64/libboost_filesystem.so.1.53.0 libboost_filesystem.so.1.53.0 cp /usr/lib64/libboost_system-mt.so.1.53.0 libboost_system-mt.so.1.53.0 cp /usr/lib64/libboost_system.so.1.53.0 libboost_system.so.1.53.0

Вот пример CMakeLists.txt файла с использованием собранной библиотеки: https://github.com/bibatn/special_seminar/blob/branch_for_polus/CMakeLists.txt INCLUDE_DIRECTORIES(path) //Подключает заголовочные файлы. В аргументе указан путь до .h файла. add_library(name_of_library SHARED IMPORTED) //объявление используемой библиотеки set_property(TARGET name_of_library PROPERTY IMPORTED_LOCATION "path/to/so/file") //указывается путь до .so файла библиотеки. add_executable (name_of_your_project src/main.cpp) //объявление исполняемого файла получаемого на выходе target_link_libraries (name_of_your_project name_of_library) //линковка библиотеки