PCL在VS2019下配置C++開發環境

[TOC]

參考鏈接

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 軟件的下載

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\}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378