修订:20201115
自定义PCL编译过程
本教程解释怎样修改PCL cmake选项,并调整编译过程以更好地满足项目和/或系统的需求。
受众
目标用户具有CMake、c++编译器、链接器、flags和make的基本知识。
预备知识
我们假设您已经下载了PCL的最新版本。
PCL基本设置
假设PCL位于/PATH/TO/PCL下,我们将其称为PCL_ROOT:
$ cd $PCL_ROOT
$ mkdir build && cd build
$ cmake ..
cmake将在build目录中使用默认选项创建一个名为CMakeCache.txt的文件。
让我们来看看启用了哪些cmake选项:
$ ccmake ..
您应该在屏幕上看到如下内容:
BUILD_common ON
BUILD_features ON
BUILD_filters ON
BUILD_global_tests OFF
BUILD_io ON
BUILD_kdtree ON
BUILD_keypoints ON
BUILD_octree ON
BUILD_range_image ON
BUILD_registration ON
BUILD_sample_consensus ON
BUILD_segmentation ON
BUILD_surface ON
BUILD_visualization ON
CMAKE_BUILD_TYPE
CMAKE_INSTALL_PREFIX /usr/local
PCL_SHARED_LIBS ON
PCL_VERSION 1.0.0
VTK_DIR /usr/local/lib/vtk-5.6
解释
- BUILD_common: 选项启用/禁用公共库的编译
- BUILD_features: 选项可启用/禁用特性库的编译
- BUILD_filters: 选项可启用/禁用滤波库的编译
- BUILD_global_tests: 选项以启用/禁用全局单元测试的编译
- BUILD_io: 选项启用/禁用io库的编译
- BUILD_kdtree: 选项可启用/禁用kdtree库的编译
- BUILD_keypoints: 选项可启用/禁用关键点库的编译
- BUILD_octree: 选项可启用/禁用构建八叉树库的编译
- BUILD_range_image: 选项可启用/禁用深度图库的编译
- BUILD_registration: 选项可启用/禁用配准库的编译
- BUILD_sample_consensus: 选项可启用/禁用采样一致性库的编译
- BUILD_segmentation: 选项可启用/禁用分割库的编译
- BUILD_surface: 选项可启用/禁用表面库的编译
- BUILD_visualization: 选项可启用/禁用可视化库的编译
- CMAKE_BUILD_TYPE: 这里指定构建类型。在CMake中,CMAKE_BUILD_TYPE对应于传递给编译器的一组选项和标志,以激活/禁用功能并约束编译过程。
- CMAKE_INSTALL_PREFIX: 头文件和编译的库将安装在哪里
- PCL_SHARED_LIBS: 启用共享库编译的选项,默认启用。
- PCL_VERSION: 这是PCL库版本,它影响编译库的名称。
- VTK_DIR: VTK库的目录(如果找到)
上述变量称为cmake缓存变量。在这个层次上,我们只关注基本的。
调整基本设置
根据您的工程/系统,您可能希望启用/禁用某些选项。例如,你可以禁止:
- tests:将BUILD_global_tests设置为OFF
- a library:将对应的BUILD_LIBRARY_NAME设置为OFF
注意,如果禁用了编译YYY所需的XXX库,但会编译XXX,只是不会出现在缓存中。
您还可以更改编译类型:
- Debug:意味着不进行优化,所有调试符号都嵌入到库文件中,这取决于平台和编译器。在使用gcc的Linux上,这相当于使用-O0 -g -ggdb -Wall运行gcc
- Release:编译后的代码经过优化,不会输出任何调试信息。这相当于-O3运行gcc和-O5运行clang
- RelWithDebInfo:编译后的代码经过优化,但是调试数据也嵌入到库中,这是前两者之间的折中。
- MinSizeRel:这通常会构建最小的库。这在为Android或受限内存/空间系统构建时非常有趣。
可用的CMAKE_BUILD_TYPEs列表可输入如下代码查看:
$ cmake --help-variable CMAKE_BUILD_TYPE
修改高级设置
现在我们已经完成了所有的基本设置。要打开高级缓存设置选项,在ccmake中按 t 键。当您将依赖项安装在不常用的位置时,高级选项会变得特别有用,这时cmake显示XXX_NOT_FOUND,这甚至会阻止您编译PCL,尽管您已经安装了所有依赖项。在本节中,我们将讨论每个依赖项入口,以便您可以根据您的系统配置/构建或更新/构建PCL。
建立单元测试
如果您想对PCL有所贡献,或者正在修改代码,您需要编译单元测试。通过将BUILD_global_tests选项设置为ON来实现的,但有几个注意事项。如果您正在使用ccmake,并且在确认时发现BUILD_global_tests恢复为OFF,则可以将光标向上移动到BUILD_global_tests行查看错误消息。
在BUILD_global_tests之前需要打开的两个选项是BUILD_outofcore和BUILD_people,你的设置可能不是这样。
单元测试还需要谷歌c++测试框架的源代码。这通常非常简单,只需下载源代码并提取它,然后将GTEST_SRC_DIR和GTEST_INCLUDE_DIR选项指向可用的源代码位置。在Ubuntu上,您可以简单地运行apt-get install libgtest-dev。
这些步骤使测试make target成为可能,因此您可以使用make test来运行测试。
注解
在${PCL_ROOT}/cmake/Modules下有一个FindXXX.cmake文件用于定位依赖项并设置它们的相关变量。它们有一个默认的可搜索路径列表查找它们。此外,如果pkg-config可用,则会触发它来获取关于其位置的提示。如果它们都失败了,那么我们将寻找一个名为XXX_ROOT的CMake入口或环境变量来查找头文件和库。我们建议设置一个环境变量,因为它独立于CMake,并且在您可以对配置进行更改的过程中一直有效。
可以设置的可用根目录(ROOTs)如下:
- BOOST_ROOT: 位于C:/Program Files/boost-1.4.6的boost库
- CMINPACK_ROOT: 位于 C:/Program Files/CMINPACK 1.1.13 的cminpack
- QHULL_ROOT: 位于C:/Program Files/qhull 6.2.0.1373的qhull
- FLANN_ROOT: 位于C:/Program Files/flann 1.6.8 的flann
- EIGEN_ROOT: 位于C:/Program Files/Eigen 3.0.0的eigen
为了确保正确地找到所有依赖项,除了从CMake获得的信息外,还可以检查或编辑每个依赖项特定的变量,并为其设定最适合您需要的值。
UNIX用户通常不必为调试版本和完全兼容的发布版本操心。如果您使用release库版本而不是debug,那么您只会丢失调试符号,而最终您将得到更详细的输出和更慢的执行。这就是说,Windows MSVC用户和苹果iCode用户可以从同一个项目编译调试/发布版本,这样做会更安全,也更连贯。
细节说明
下面列出每个依赖变量,解释其含义,然后给出一个示例值供参考。
- Boost
缓存变量 | 含义 | 示例值 |
---|---|---|
Boost_DATE_TIME_LIBRARY | boost_date-time的完整路径[so, lib, a] | /usr/local/lib/libboost_date_time.so |
Boost_DATE_TIME_LIBRARY_DEBUG | boost_date-time的完整路径[so, lib, a] (Debug版本) | /usr/local/lib/libboost_date_time-gd.so |
Boost_DATE_TIME_LIBRARY_RELEASE | boost_date-time的完整路径[so, lib, a] (Release版本) | /usr/local/lib/libboost_date_time.so |
Boost_FILESYSTEM_LIBRARY | boost_filesystem的完整路径[so, lib, a] | /usr/local/lib/libboost_filesystem.so |
Boost_FILESYSTEM_LIBRARY_DEBUG | boost_filesystem的完整路径[so, lib, a] (Debug版本) | /usr/local/lib/libboost_filesystem-gd.so |
Boost_FILESYSTEM_LIBRARY_RELEASE | boost_filesystem的完整路径[so, lib, a] (Release版本) | /usr/local/lib/libboost_filesystem.so |
Boost_INCLUDE_DIR | boost头文件的路径 | /usr/local/include |
Boost_LIBRARY_DIRS | boost库目录的路径 | /usr/local/lib |
Boost_SYSTEM_LIBRARY | boost_system的完整路径[so, lib, a] | /usr/local/lib/libboost_system.so |
Boost_SYSTEM_LIBRARY_DEBUG | boost_system的完整路径[so, lib, a] (Debug版本) | /usr/local/lib/libboost_system-gd.so |
Boost_SYSTEM_LIBRARY_RELEASE | boost_system的完整路径[so, lib, a] (Release版本) | /usr/local/lib/libboost_system.so |
- CMinpack
缓存变量 | 含义 | 示例值 |
---|---|---|
CMINPACK_INCLUDE_DIR | cminpack头文件的路径 | /usr/local/include/cminpack-1 |
CMINPACK_LIBRARY | cminpack的完整路径[so, lib, a] (Release版本) | /usr/local/lib/libcminpack.so |
CMINPACK_LIBRARY_DEBUG | cminpack的完整路径[so, lib, a] (Debug版本) | /usr/local/lib/libcminpack-gd.so |
- FLANN
缓存变量 | 含义 | 示例值 |
---|---|---|
FLANN_INCLUDE_DIR | flann头文件的路径 | /usr/local/include |
FLANN_LIBRARY | libflann_cpp的完整路径[so, lib, a] (Release版本) | /usr/local/lib/libflann_cpp.so |
FLANN_LIBRARY_DEBUG | libflann_cpp的完整路径[so, lib, a] (Debug版本) | /usr/local/lib/libflann_cpp-gd.so |
- Eigen
缓存变量 | 含义 | 示例值 |
---|---|---|
EIGEN_INCLUDE_DIR | eigen头文件的路径 | /usr/local/include/eigen3 |