PCL在VS2019下配置C++开发环境

[TOC]

参考链接

  • Using PCL in your own project
  • Windows + VS2017超详细点云库(PCL)配置
  • PCL1.10.1+VS2019+Qt5.14.2下载、安装及配置

1. 前置条件

1.1 安装必要软件

  1. 安装 Visual Studio 2017 以上
  2. 安装 PCL 套件(PCL-1.11.0-AllInOne-msvc2019-win64.exe
    ) 官网下载
  3. 安装时注意设置将PCL加入到系统环境变量
  4. 需要安装 OpenNI2 工具

1.2 环境变量检查

环境变量 类型 操作类型
PCL_ROOT Machine 自动添加 PCL安装路径,通常为 C:\Program Files\pcl_1_xx_0 等
OPENNI2_INCLUDE64 Machine 自动添加 C:\Program Files\OpenNI2\Include\
OPENNI2_LIB64 Machine 自动添加 C:\Program Files\OpenNI2\Lib\
OPENNI2_REDIST64 Machine 自动添加 C:\Program Files\OpenNI2\Redist\
# 环境变量检查
$CHECK_LIST=@("PCL_ROOT", "OPENNI2_REDIST64", "OPENNI2_INCLUDE64", "OPENNI2_LIB64")
foreach($VARNAME in $CHECK_LIST){
  if ([String]::IsNullOrEmpty([System.Environment]::GetEnvironmentVariable($VARNAME))){
    $message = "未设置 " +$VARNAME +" 变量"
    echo $message
  }
}

1.3 配置辅助路径

在 PCL 开发中需要示用到若干 Include / Lib 的路径,在配置时,需要将这些路径添加到 Visual Studio 项目中,可以通过 PowerShell 脚本获取到这些路径在你系统上的值。

$PCL_3RDPARTY_BOOST = ($env:PCL_ROOT + "/3rdParty/Boost")
$PCL_3RDPARTY_EIGEN = ($env:PCL_ROOT + "/3rdParty/EIGEN")
$PCL_3RDPARTY_VTK = ($env:PCL_ROOT + "/3rdParty/VTK")
$PCL_3RDPARTY_QHULL = ($env:PCL_ROOT + "/3rdParty/QHULL")
$PCL_3RDPARTY_FLANN = ($env:PCL_ROOT + "/3rdParty/FLANN")

# 查找 OPENNI2 相关变量
$OPENNI2_ROOT = (Get-Item $env:OPENNI2_INCLUDE64).Parent.FullName
$OPENNI2_TOOLS = (Get-ChildItem -Directory -Filter "Tools" $OPENNI2_ROOT)[0].FullName

# 查找PCL相关变量
$PCL_ROOT_INCLUDE = (Get-ChildItem -Directory -Filter "pcl-*" ($env:PCL_ROOT + "/include"))[0].FullName
$PCL_BOOST_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "boost-*" $PCL_3RDPARTY_BOOST | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_EIGEN_INCLUDE = (Get-ChildItem -Directory -Filter "eigen*" $PCL_3RDPARTY_EIGEN)[0].FullName
$PCL_VTK_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "vtk-*" $PCL_3RDPARTY_VTK | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_QHULL_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_FLANN)[0].FullName

$PCL_ROOT_LIB = (Get-ChildItem -Directory -Filter "lib" $env:PCL_ROOT)[0].FullName
$PCL_BOOST_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_BOOST)[0].FullName
$PCL_VTK_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_VTK)[0].FullName
$PCL_QHULL_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_FLANN)[0].FullName

$VARLIST = @("OPENNI2_TOOLS", "PCL_BOOST_INCLUDE", "PCL_BOOST_LIB", "PCL_EIGEN_INCLUDE", "PCL_FLANN_INCLUDE", "PCL_FLANN_LIB", "PCL_QHULL_INCLUDE", "PCL_QHULL_LIB", "PCL_ROOT_INCLUDE", "PCL_ROOT_LIB", "PCL_VTK_INCLUDE", "PCL_VTK_LIB")

Get-Variable -Include $VARLIST

以 PCL-1.11 为例,上述脚本运行结果如下

Name                           Value
----                           -----
OPENNI2_TOOLS                  C:\Program Files\OpenNI2\Tools
PCL_BOOST_INCLUDE              C:\Program Files\PCL_1_11_0\3rdParty\Boost\include\boost-1_73
PCL_BOOST_LIB                  C:\Program Files\PCL_1_11_0\3rdParty\Boost\lib
PCL_EIGEN_INCLUDE              C:\Program Files\PCL_1_11_0\3rdParty\EIGEN\eigen3
PCL_FLANN_INCLUDE              C:\Program Files\PCL_1_11_0\3rdParty\FLANN\include
PCL_FLANN_LIB                  C:\Program Files\PCL_1_11_0\3rdParty\FLANN\lib
PCL_QHULL_INCLUDE              C:\Program Files\PCL_1_11_0\3rdParty\QHULL\include
PCL_QHULL_LIB                  C:\Program Files\PCL_1_11_0\3rdParty\QHULL\lib
PCL_ROOT_INCLUDE               C:\Program Files\PCL_1_11_0\include\pcl-1.11
PCL_ROOT_LIB                   C:\Program Files\PCL_1_11_0\lib
PCL_VTK_INCLUDE                C:\Program Files\PCL_1_11_0\3rdParty\VTK\include\vtk-8.2
PCL_VTK_LIB                    C:\Program Files\PCL_1_11_0\3rdParty\VTK\lib

1.4 通过系统环境变量使用辅助路径(非必须)

在 Visual Studio 中,项目的属性引用宏变量可以直接访问系统环境变量(注意,必须是系统环境变量,用户环境变量是无法识别的,至少截至到 VS2019 是这样的),因此,可以通过 PowerShell 直接自动设置系统环境变量的方式提供对 VS 的支持,脚本如下:


# Step1 检查 PCL_ROOT, OPENNI2_REDIST64, OPENNI2_INCLUDE64, OPENNI2_LIB64 是否已设置
$CHECK_LIST=@("PCL_ROOT", "OPENNI2_REDIST64", "OPENNI2_INCLUDE64", "OPENNI2_LIB64")
foreach($VARNAME in $CHECK_LIST){
  if ([String]::IsNullOrEmpty([System.Environment]::GetEnvironmentVariable($VARNAME))){
    $message = "未设置" +$VARNAME +"变量,程序中断"
    echo $message
    exit
  }
}

# Step2: 基础路径设置

$PCL_3RDPARTY_BOOST = ($env:PCL_ROOT + "\3rdParty\Boost")
$PCL_3RDPARTY_EIGEN = ($env:PCL_ROOT + "\3rdParty\EIGEN")
$PCL_3RDPARTY_FLANN = ($env:PCL_ROOT + "\3rdParty\FLANN")
$PCL_3RDPARTY_QHULL = ($env:PCL_ROOT + "\3rdParty\QHULL")
$PCL_3RDPARTY_VTK = ($env:PCL_ROOT + "\3rdParty\VTK")

# Step3: 设置系统环境变量

# 查找 OPENNI2 相关变量
$OPENNI2_ROOT = (Get-Item $env:OPENNI2_INCLUDE64).Parent.FullName
$OPENNI2_TOOLS = (Get-ChildItem -Directory -Filter "Tools" $OPENNI2_ROOT)[0].FullName

# 查找PCL相关变量
$PCL_ROOT_INCLUDE = (Get-ChildItem -Directory -Filter "pcl-*" ($env:PCL_ROOT + "/include"))[0].FullName
$PCL_BOOST_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "boost-*" $PCL_3RDPARTY_BOOST | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_EIGEN_INCLUDE = (Get-ChildItem -Directory -Filter "eigen*" $PCL_3RDPARTY_EIGEN)[0].FullName
$PCL_VTK_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "vtk-*" $PCL_3RDPARTY_VTK | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_QHULL_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_FLANN)[0].FullName

$PCL_ROOT_LIB = (Get-ChildItem -Directory -Filter "lib" $env:PCL_ROOT)[0].FullName
$PCL_BOOST_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_BOOST)[0].FullName
$PCL_VTK_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_VTK)[0].FullName
$PCL_QHULL_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_FLANN)[0].FullName


$VARLIST = @("OPENNI2_TOOLS", "PCL_BOOST_INCLUDE", "PCL_BOOST_LIB", "PCL_EIGEN_INCLUDE", "PCL_FLANN_INCLUDE", "PCL_FLANN_LIB", "PCL_QHULL_INCLUDE", "PCL_QHULL_LIB", "PCL_ROOT_INCLUDE", "PCL_ROOT_LIB", "PCL_VTK_INCLUDE", "PCL_VTK_LIB")

foreach($VARNAME IN $VARLIST){
  [System.Environment]::SetEnvironmentVariable($VARNAME, (Get-Variable -Name $VARNAME).Value, "Machine");
}

1.5 Path 路径调整(非必须)

通过修改 PATH 路径可以便于开发调试过程中引用对应的dll,而不需要专门进行copy操作。

环境变量 类型 操作类型
PATH User 手动更新 %PCL_ROOT%\bin
PATH User 手动更新 %PCL_ROOT%\3rdParty\FLANN\bin
PATH User 手动更新 %PCL_ROOT%\3rdParty\VTK\bin
PATH User 手动更新 %PCL_ROOT%\3rdParty\OpenNI2\bin
PATH User 手动更新 %PCL_ROOT%\3rdParty\Qhull\bin
PATH User 手动更新 %OPENNI2_REDIST64%
PATH User 手动更新 %OPENNI2_TOOLS%

# Step1 检查 PCL_ROOT, OPENNI2_REDIST64, OPENNI2_INCLUDE64, OPENNI2_LIB64 是否已设置
$CHECK_LIST=@("PCL_ROOT", "OPENNI2_REDIST64", "OPENNI2_INCLUDE64", "OPENNI2_LIB64")
foreach($VARNAME in $CHECK_LIST){
  if ([String]::IsNullOrEmpty([System.Environment]::GetEnvironmentVariable($VARNAME))){
    $message = "未设置" +$VARNAME +"变量,程序中断"
    echo $message
    exit
  }
}

# Step2: 基础路径设置
$OPENNI2_ROOT = (Get-Item $env:OPENNI2_INCLUDE64).Parent.FullName
$OPENNI2_TOOLS = (Get-ChildItem -Directory -Filter "Tools" $OPENNI2_ROOT)[0].FullName
$PCL_3RDPARTY_BOOST = ($env:PCL_ROOT + "\3rdParty\Boost")
$PCL_3RDPARTY_EIGEN = ($env:PCL_ROOT + "\3rdParty\EIGEN")
$PCL_3RDPARTY_FLANN = ($env:PCL_ROOT + "\3rdParty\FLANN")
$PCL_3RDPARTY_QHULL = ($env:PCL_ROOT + "\3rdParty\QHULL")
$PCL_3RDPARTY_VTK = ($env:PCL_ROOT + "\3rdParty\VTK")

# Step3 配置 PATH 环境变量

$PathList = $env:Path.Split(";");
$PathList_User = [System.Environment]::GetEnvironmentVariable("Path","User").Split(";");

$PCL_3RDPARTY_FLANN_bin = $PCL_3RDPARTY_FLANN + "\bin";
if( ! $PathList.Contains($PCL_3RDPARTY_FLANN_bin)){ $PathList_User += $PCL_3RDPARTY_FLANN_bin; }

$PCL_3RDPARTY_QHULL_bin = $PCL_3RDPARTY_QHULL + "\bin";
if( ! $PathList.Contains($PCL_3RDPARTY_QHULL_bin)){ $PathList_User += $PCL_3RDPARTY_QHULL_bin; }

$PCL_3RDPARTY_VTK_bin = $PCL_3RDPARTY_VTK + "\bin";
if( ! $PathList.Contains($PCL_3RDPARTY_VTK_bin)){ $PathList_User += $PCL_3RDPARTY_VTK_bin; }

if( ! $PathList.Contains($env:OPENNI2_REDIST64)){ $PathList_User += $env:OPENNI2_REDIST64; }
if( ! $PathList.Contains($OPENNI2_TOOLS)){ $PathList_User += $OPENNI2_TOOLS; }

[System.Environment]::SetEnvironmentVariable("Path", [String]::Join(";",$PathList_User),"User")

2. 基于 Visual Studio 2019 的环境搭建

如果直接进行项目初始化,则 方案 2 更加简单稳定,方案1更适合于考虑用于对既有项目的改造指导

2.1 方案1:直接配置 Visual Studio 2019 项目

2.1.1 待配置清单

  • "项目属性"->"VC++ 目录"->"包含目录"
  • "项目属性"->"VC++ 目录"->"库目录"
  • "项目属性"->"C/C++"->"预处理器"->"预处理器定义"
  • "项目属性"->"链接器"->"输入"->"附加依赖项"

2.1.2 配置方法1:手动配置

  1. 通过前述方法(参考“配置辅助路径”一节)获取到相关的路径后,按照以下配置清单,直接替换相应的变量为具体的值;
  2. 如果配置了系统环境变量(参考“通过系统环境变量使用辅助路径(非必须)”一节),可以直接将环境变量作为宏变量引入,引用的方法为 $(环境变量名),例如,PCL_ROOT_INCLUDE 这一变量,在配置中,可以直接引用为 $(PCL_ROOT_INCLUDE)

配置清单

  • "项目属性"->"VC++ 目录"->"包含目录",添加以下项(相关值自行替换为对应值)
$(OPENNI2_INCLUDE64)
$(PCL_FLANN_INCLUDE)
$(PCL_QHULL_INCLUDE)
$(PCL_VTK_INCLUDE)
$(PCL_EIGEN_INCLUDE)
$(PCL_BOOST_INCLUDE)
$(PCL_ROOT_INCLUDE)
  • "项目属性"->"VC++ 目录"->"库目录",添加以下项
$(PCL_FLANN_LIB)
$(PCL_QHULL_LIB)
$(PCL_VTK_LIB)
$(PCL_BOOST_LIB)
$(PCL_ROOT_LIB)
$(OPENNI2_LIB64)
  • "项目属性"->"C/C++"->"预处理器"->"预处理器定义",添加以下项
_SCL_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
  • "项目属性"->"链接器"->"输入"->"附加依赖项",添加以下项
# 从 PCL_ROOT 下遍历 lib 文件并通过名称过滤,由于文件过多,且需要考虑不同版本文件名不同,考虑使用 powershell 遍历获取文件清单
# 对 debug 模式,选用 debug 相关的 lib,文件名应当以 d 结尾或者包含 -gd- 字样
Get-ChildItem -Filter "*.lib" -File -Recurse $env:PCL_ROOT | ? {$_.BaseName -like "*d" -or $_.BaseName -like "*-gd-*" } | % { echo $_.FullName}
Get-ChildItem -Filter "*.lib" -File -Recurse $env:OPENNI2_LIB64 | % { echo $_.FullName}

# 对 release 模式,选用 release 相关的 lib,文件名应当不以 d 结尾且不包含 -gd- 字样
Get-ChildItem -Filter "*.lib" -File -Recurse $env:PCL_ROOT | ? { -not ($_.BaseName -like "*d" -or $_.BaseName -like "*-gd-*" )} | % { echo $_.FullName}
Get-ChildItem -Filter "*.lib" -File -Recurse $env:OPENNI2_LIB64 | % { echo $_.FullName}

2.1.3 配置方法2:通过 PowerShell 生成项目属性表并导入

可在 Visual Studio 2019 解决方案窗口中,通过切换选项卡选择“属性管理器”,选择项目后“添加现有属性表”直接导入配置。

使用项目属性表的优点有:

  1. 生成了项目属性表文件后可以单独保存、共享给相同机器(或相关的PCL版本、安装路径都一样的其他机器)的不同项目进行共享;
  2. 项目属性表支持自定义VS宏变量,因此可以在不设置系统环境变量的前提下(参考“通过系统环境变量使用辅助路径(非必须)”一节)直接在配置中引用宏变量;
  3. 项目属性表本质上为一个 XML 文件,因此可以使用 powershell 生成该属性表,从而自适应不同的机器环境、安装路径、版本的需要。

使用项目属性表的注意事项如下:

  1. 在导入项目属性表后,如果在VS中对该项目属性表进行了修改,修改内容会直接反馈到项目属性表文件XML中;
  2. 在导入项目属性表后,如果手动修改(含使用 powershell 重新生成)了属性表XML文件,该变化无法在VS2019中直接自动同步,需要关闭并重启VS2019以后才能看到更新值(原因我也不知道……)

生成项目属性表代码如下(基于Debug环境):

$xmlPropertySheet = ([xml]::new())
$xmlPropertySheet.AppendChild($xmlPropertySheet.CreateXmlDeclaration("1.0", "utf-8", ""))

function CreateSection
{
    param (
        [string]$SectionName,
        [string]$SectionLabel,
        [string]$SectionText
    )
   
    $XMLSheet = $xmlPropertySheet
   
    $element = $XMLSheet.CreateElement($SectionName)
    if($SectionLabel)
    {
        $element.SetAttribute("Label",$SectionLabel)
    }
    if($SectionText){
      $element.InnerText=$SectionText
    }
    return $element
}
function CreateBuildMacro
{
    param(
       $ItemGroup,
       [string[]]$ListMacroName
    )
    $ListMacroName | % {
        $elementItemBuildMacro = (CreateSection -SectionName "BuildMacro")
        $elementItemBuildMacro.SetAttribute("Include", $_);
        $elementItemBuildMacro.AppendChild((CreateSection -SectionName "Value" -SectionText ('$('+$_+')')))
        $ItemGroup.AppendChild($elementItemBuildMacro)    
    }
}

# 检查用户环境变量、系统环境变量
# Step1 检查 PCL_ROOT, OPENNI2_REDIST64, OPENNI2_INCLUDE64, OPENNI2_LIB64 是否已设置
$CHECK_LIST=@("PCL_ROOT", "OPENNI2_REDIST64", "OPENNI2_INCLUDE64", "OPENNI2_LIB64")
foreach($VARNAME in $CHECK_LIST){
  if ([String]::IsNullOrEmpty([System.Environment]::GetEnvironmentVariable($VARNAME))){
    $message = "未设置" +$VARNAME +"变量,程序中断"
    echo $message
    exit
  }  
}


# 创建 Project 根目录
$rootElement = $xmlPropertySheet.CreateElement("Project")
$rootElement.SetAttribute("ToolsVersion", "4.0")
$rootElement.SetAttribute("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003")
$xmlPropertySheet.AppendChild($rootElement)
# 创建 Project.ImportGroup 节
$elementImportGroup = (CreateSection -SectionName "ImportGroup" -SectionLabel "PropertySheets")
$rootElement.AppendChild($elementImportGroup)

# 创建默认"用户宏"节: Project.PropertyGroup
$elementPropertyGroup_UserMacros = (CreateSection -SectionName "PropertyGroup" -SectionLabel "UserMacros")
$rootElement.AppendChild($elementPropertyGroup_UserMacros)

# 将各个PCL相关路径定义为宏变量:

$PCL_3RDPARTY_BOOST = ($env:PCL_ROOT + "/3rdParty/Boost")
$PCL_3RDPARTY_EIGEN = ($env:PCL_ROOT + "/3rdParty/EIGEN")
$PCL_3RDPARTY_VTK = ($env:PCL_ROOT + "/3rdParty/VTK")
$PCL_3RDPARTY_QHULL = ($env:PCL_ROOT + "/3rdParty/QHULL")
$PCL_3RDPARTY_FLANN = ($env:PCL_ROOT + "/3rdParty/FLANN")

# 设置 OPENNI2 相关变量
$OPENNI2_ROOT = (Get-Item $env:OPENNI2_INCLUDE64).Parent.FullName
$OPENNI2_TOOLS = (Get-ChildItem -Directory -Filter "Tools" $OPENNI2_ROOT)[0].FullName

# 设置PCL相关变量
$PCL_ROOT_INCLUDE = (Get-ChildItem -Directory -Filter "pcl-*" ($env:PCL_ROOT + "/include"))[0].FullName
$PCL_BOOST_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "boost-*" $PCL_3RDPARTY_BOOST | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_EIGEN_INCLUDE = (Get-ChildItem -Directory -Filter "eigen*" $PCL_3RDPARTY_EIGEN)[0].FullName
$PCL_VTK_INCLUDE = (Get-ChildItem -Directory -Depth 2 -Filter "vtk-*" $PCL_3RDPARTY_VTK | ? {$_.Parent.BaseName -eq 'include' })[0].FullName
$PCL_QHULL_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_INCLUDE = (Get-ChildItem -Directory -Filter "include" $PCL_3RDPARTY_FLANN)[0].FullName

$PCL_ROOT_LIB = (Get-ChildItem -Directory -Filter "lib" $env:PCL_ROOT)[0].FullName
$PCL_BOOST_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_BOOST)[0].FullName
$PCL_VTK_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_VTK)[0].FullName
$PCL_QHULL_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_QHULL)[0].FullName
$PCL_FLANN_LIB = (Get-ChildItem -Directory -Filter "lib" $PCL_3RDPARTY_FLANN)[0].FullName

$MACROLIST = @("PCL_3RDPARTY_BOOST", "PCL_3RDPARTY_EIGEN", "PCL_3RDPARTY_VTK", "PCL_3RDPARTY_QHULL", "PCL_3RDPARTY_FLANN", "OPENNI2_ROOT", "OPENNI2_TOOLS", "PCL_ROOT_INCLUDE", "PCL_BOOST_INCLUDE", "PCL_EIGEN_INCLUDE","PCL_VTK_INCLUDE", "PCL_QHULL_INCLUDE", "PCL_FLANN_INCLUDE", "PCL_ROOT_LIB", "PCL_BOOST_LIB", "PCL_VTK_LIB", "PCL_QHULL_LIB", "PCL_FLANN_LIB")


$MACROLIST | % {
    $elementPropertyGroup_UserMacros.AppendChild((CreateSection -SectionName $_ -SectionText (Get-Variable -Name $_).Value))
}

# 创建"VC++目录"节: Project.PropertyGroup 
$elementPropertyGroup_vcppCategory = (CreateSection -SectionName "PropertyGroup")
$rootElement.AppendChild($elementPropertyGroup_vcppCategory)
# 创建 Project.PropertyGroup.IncludePath
$elementIncludePath = (CreateSection -SectionName "IncludePath" -SectionText '$(OPENNI2_INCLUDE64);$(PCL_FLANN_INCLUDE);$(PCL_QHULL_INCLUDE);$(PCL_VTK_INCLUDE);$(PCL_EIGEN_INCLUDE);$(PCL_BOOST_INCLUDE);$(PCL_ROOT_INCLUDE);$(IncludePath)')
$elementPropertyGroup_vcppCategory.AppendChild($elementIncludePath)
# 创建 Project.PropertyGroup.LibraryPath
$elementLibraryPath = (CreateSection -SectionName "LibraryPath" -SectionText '$(PCL_FLANN_LIB);$(PCL_QHULL_LIB);$(PCL_VTK_LIB);$(PCL_BOOST_LIB);$(PCL_ROOT_LIB);$(OPENNI2_LIB64);$(LibraryPath)')
$elementPropertyGroup_vcppCategory.AppendChild($elementLibraryPath)
# 创建 Project.ItemDefinitionGroup
$elementItemDefinitionGroup = (CreateSection -SectionName "ItemDefinitionGroup")
$rootElement.AppendChild($elementItemDefinitionGroup)
# 创建 Project.ItemDefinitionGroup.ClCompile
$elementClCompile = (CreateSection -SectionName "ClCompile")
$elementItemDefinitionGroup.AppendChild($elementClCompile)
# 创建 Project.ItemDefinitionGroup.ClCompile.PreprocessorDefinitions
$elementPreprocessorDefinitions = (CreateSection -SectionName "PreprocessorDefinitions" -SectionText '_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)')
$elementClCompile.AppendChild($elementPreprocessorDefinitions)
# 创建 Project.ItemDefinitionGroup.Link
$elementLink = (CreateSection -SectionName "Link")
$elementItemDefinitionGroup.AppendChild($elementLink)
# 创建 Project.ItemDefinitionGroup.Link.AdditionalDependencies
$elementAdditionalDependencies = (CreateSection -SectionName "AdditionalDependencies" -SectionText '%(AdditionalDependencies)')
$elementLink.AppendChild($elementAdditionalDependencies)

Get-ChildItem -Filter "*.lib" -File -Recurse $env:PCL_ROOT | ? {$_.BaseName -like "*d" -or $_.BaseName -like "*-gd-*" } | % { $elementAdditionalDependencies.InnerText = $_.Name + ';' + $elementAdditionalDependencies.InnerText }
Get-ChildItem -Filter "*.lib" -File -Recurse $env:OPENNI2_LIB64 | % { $elementAdditionalDependencies.InnerText = $_.Name + ';' + $elementAdditionalDependencies.InnerText }

# 创建 Project.ItemGroup 节
$elementItemGroup = (CreateSection -SectionName "ItemGroup")
$rootElement.AppendChild($elementItemGroup)
CreateBuildMacro -ItemGroup $elementItemGroup -ListMacroName $MACROLIST

$xmlPath = "C:\Path\to\Project\PCL_CPP_VS_PropertySheet.props"
$xmlPropertySheet.Save($xmlPath)

2.2 方案2:通过 CMake 生成 Visual Studio 解决方案

  1. 假定 PCL 项目名称 pcl_study
  2. 源码文件将统一放置在 C:\myproject\source_code 路径下

通过该方案生成 VS 项目后,项目中的源码修改都会直接作用于 C:\myproject\source_code 路径下的对应文件

2.2.1 cmake 软件的下载

  • 官网下载页面
  • cmake-3.19.2-win64下载链接

2.2.2 CMake 文件准备

2.2.2.1 PCL 基本环境搭建

在 C:\myproject\source_code 下新建文件:

  1. 准备任意 c++ 代码文件 demo.cpp, 文件名不做限制,内容为随意准备的可执行的 cpp 代码即可;
  2. 准备 CMakeLists.txt,文件名不可修改,文件内容如下:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(pcl_study)
find_package(PCL 1.11 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcl_study demo.cpp)
target_link_libraries(pcl_study ${PCL_LIBRARIES})

cmake 代码说明:

  • cmake_minimum_required(VERSION 3.0 FATAL_ERROR): 定义了 cmake 支持的最低版本,本处使用 3.0
  • project(pcl_study): 定义了项目名称为 pcl_study
  • find_package(PCL 1.11 REQUIRED):定义了项目将自动在本地搜索 PCL 1.11 版本的相关库文件路径,并据此自动定义变量 ${PCL_INCLUDE_DIRS}、${PCL_LIBRARY_DIRS}、${PCL_DEFINITIONS}
  • include_directories(${PCL_INCLUDE_DIRS}):设置附加的包含目录: PCL include 相关路径
  • link_directories(${PCL_LIBRARY_DIRS}):设置附加Lib路径目录:PCL Lib相关路径
  • add_definitions(${PCL_DEFINITIONS})
  • add_executable(pcl_study demo.cpp):设置将 demo.cpp 编译为 pcl_study.exe
  • target_link_libraries(pcl_study ${PCL_LIBRARIES}):为 pcl_study.exe 绑定静态链接库

2.2.1.2 PCL + SQLite3 环境搭建

在项目中如果要调用 SQLite3,需要对项目进行设置,可以参考(基于 Visual Studio 在 C++ 环境中使用 SQLite3)。可以通过对 CMakeLists.txt 调整,自动为生成的项目添加部分设置。

假定 sqlite 相关文件都在 C:/reference/sqlitedll 路径下

cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(pcl_study)
find_package(PCL 1.11 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
include_directories(C:/reference/sqlitedll)
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(pcl_study demo.cpp)
target_link_libraries(pcl_study ${PCL_LIBRARIES})
target_link_libraries(pcl_study C:/reference/sqlitedll/sqlite3.lib)

完成项目生成后,则只需要添加生成后自动复制 dll 这一步设置即可

2.2.2 生成项目文件

2.2.2.1 方法1. 使用 cmake gui 进行生成

安装 CMAKE 后运行 cmake-gui

cmake-gui.png

直接手动选择源码路径和生成的目标路径后,点击生成(generate)即可

2.2.2.2 方法2. 使用 cmake 命令行进行生成

启动 powershell或 cmd

# 说明:
#   -S 参数表示源代码以及cmakelists文件所在路径
#   -B 参数表示要生成的项目文件路径,如果路径不存在,会自动创建
#   -Wno-dev 表示隐藏警告信息
cmake -S 'C:\myproject\source_code' -B 'C:\myproject\solution' -Wno-dev

生成后即可通过VS打开 C:\myproject\solution\pcl_study.sln 进行进一步设置和开发

3. 调试时项目的运行

3.1 开发环境下

  1. 利用配置 Path 环境变量实现目的(参考 配置环境变量 一节)
  2. 也可以通过 "项目属性"->"VC++ 目录"->"可执行文件目录"中添加上述Path相关路径来实现

3.2 生产环境下

由于运行时需要调用PCL相关dll,当前暂时使用暴力的方式,将PCL相关dll直接全部复制到目标文件夹,可以使用 powershell 运行如下代码:

Get-ChildItem -R -File $env:PCL_ROOT|?{$_.Extension -eq ".dll"}|%{ cp $_.FullName D:\Path\to\your\project\x64\Release\}

你可能感兴趣的:(PCL在VS2019下配置C++开发环境)