修订: 20201115
在您自己的工程中使用PCL
本教程将解释如何在您自己的工程中使用PCL。
预备知识
我们假设您已经在下载、编译并安装了PCL。
工程设置
假设项目位于/PATH/TO/MY/GRAND/PROJECT下,其中包含一个单独的cpp文件名pcd_write.cpp(从将点云数据写入PCD文件教程中复制)。在同一个文件夹中,创建一个名为CMakeLists.txt的文件,该文件包含:
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
add_definitions(-std=c++11)
project(MY_GRAND_PROJECT)
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcd_write_test pcd_write.cpp)
target_link_libraries(pcd_write_test ${PCL_LIBRARIES})
代码释义
现在,来看下每行代码的含义。
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
这对于cmake是强制性的,因为我们正在编译非常基础的项目,所以不需要cmake 2.8或更高版本的特性。
add_definitions(-std=c++11)
此为添加C++11支持,若pcl及cmake版本较高,需要添加C++11标准才能通过编译,此为在原英文教程基础上添加。
project(MY_GRAND_PROJECT)
这一行命名您的工程,并设置一些有用的cmake变量,例如引用源目录(MY_GRAND_PROJECT_SOURCE_DIR)和调用cmake的目录(MY_GRAND_PROJECT_BINARY_DIR)的变量。也就是当写上这行代码时,隐含定义了MY_GRAND_PROJECT_SOURCE_DIR、MY_GRAND_PROJECT_BINARY_DIR这两个变量
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
我们要求至少找到1.3版的PCL包,这是必需的,如果找不到,cmake将会失败。由于PCL是模块化的,可以要求:
- 只有一个组件: find_package(PCL 1.3 REQUIRED COMPONENTS io)
- 几个组件: find_package(PCL 1.3 REQUIRED COMPONENTS io common)
- 所有组件: find_package(PCL 1.3 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
当找到PCL时,就设置几个相关变量:
- PCL_FOUND: 找到PCL包时设置为1,否则不设置;
- PCL_INCLUDE_DIRS: 设置为PCL已安装头文件和依赖项头文件的路径;
- PCL_LIBRARIES: 设置为已构建和已安装的PCL库的文件名;
- PCL_LIBRARY_DIRS: 设置到PCL库和第三方依赖项所在的路径;
- PCL_VERSION: 找到的PCL版本;
- PCL_COMPONENTS: 列出所有可用组件;
- PCL_DEFINITIONS:列出所需的预处理器定义和编译器标志;
要让cmake知道项目中包含的外部头信息,需要使用include_directory()宏。在我们的例子中,PCL_INCLUDE_DIRS恰好包含我们需要的内容,因此我们要求cmake搜索它包含的路径,以查找可能包含的头文件。
add_executable(pcd_write_test pcd_write.cpp)
在这里,我们告诉cmake,我们试图从一个源文件pcd_write.cpp生成一个名为pcd_write_test的可执行文件。CMake将负责后缀(Windows平台上的.exe和UNIX上的空白后缀)和权限。
target_link_libraries(pcd_write_test ${PCL_LIBRARIES})
我们正在构建的可执行文件调用PCL函数。到目前为止,我们只包含了PCL头,以便编译器知道我们调用的方法。我们还需要让链接器知道我们所链接的库。如前所述,PCL找到的库被称为PCL_LIBRARIES变量的引用,接下来的就是触发我们调用target_link_libraries()宏的链接操作。PCLConfig.cmake使用一个名为EXPORT的cmake特殊特性,它允许使用其他人的工程目标,就像您自己构建它们一样。当您使用这些目标时,它们被称为导入目标,其行为与任何其他工程一样。
编译和运行项目
使用命令行CMake
创建一个名为build的目录,编译将在其中完成。作如下操作:
$ cd /PATH/TO/MY/GRAND/PROJECT
$ mkdir build
$ cd build
$ cmake ..
你将会看到类似的东西:
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Found PCL_IO: /usr/local/lib/libpcl_io.so
-- Found PCL: /usr/local/lib/libpcl_io.so (Required is at least version "1.0")
-- Configuring done
-- Generating done
-- Build files have been written to: /PATH/TO/MY/GRAND/PROJECT/build
如果你想看看CMake缓存写的什么:
CMAKE_BUILD_TYPE
CMAKE_INSTALL_PREFIX /usr/local
PCL_DIR /usr/local/share/pcl
现在,我们可以构建我们的项目,只需输入:
$ make
结果如下:
Scanning dependencies of target pcd_write_test
[100%] Building CXX object
CMakeFiles/pcd_write_test.dir/pcd_write.cpp.o
Linking CXX executable pcd_write_test
[100%] Built target pcd_write_test
项目现已编译、连结然后准备测试:
$ ./pcd_write_test
运行结果如下:
Saved 5 data points to test_pcd.pcd.
0.352222 -0.151883 -0.106395
-0.397406 -0.473106 0.292602
-0.731898 0.667105 0.441304
-0.734766 0.854581 -0.0361733
-0.4607 -0.277468 -0.916762
使用CMake gui(例如Windows)
运行CMake GUI,并填充这些字段:
- 源代码在哪里:这是包含CMakeLists.txt文件和源代码的文件夹。
- 在哪里构建二进制文件:这里将生成Visual Studio项目文件
然后,单击Configure。将提示您输入生成器/编译器。然后单击Generate按钮。如果没有错误,项目文件将生成到构建二进制文件文件夹的位置。
打开sln文件,然后构建您的项目!
奇怪的安装
CMake有一个寻找FindXXX的默认可搜索路径列表。cmake或XXXConfig.cmake。如果您碰巧安装在某个不明显的存储库中(比如在文档中),那么您可以帮助cmake查找PCLConfig.cmake,要添加这一行:
set(PCL_DIR "/path/to/PCLConfig.cmake")
在这句之前:
find_package(PCL 1.3 REQUIRED COMPONENTS common io)
...