介紹了使用自動化構建工具 BuildCppDependency 在 Windows 和 Linux 平台編譯 Ceres Solver 的方法,詳細説明了其依賴庫及關鍵 CMake 構建參數,最終以靜態庫形式成功構建。

1 引言

Ceres Solver 是一個由 Google 開發的開源 C++ 庫,用於求解大規模非線性最小二乘問題,廣泛應用於計算機視覺、機器人和三維重建等領域。

2 構建

記得以前構建Ceres Solver經常失敗,其中一個原因是因為 Google 系的 C/C++ 程序庫很喜歡使用靜態庫,Google 的程序員認為靜態庫可以避免二進制兼容的問題。至於構建的性能問題,他們通過在專門的高性能機器上構建來解決。不過,像 Ceres Solver 這樣的大型庫需要的依賴庫太多,它們不一定是靜態庫,動態庫和靜態庫混合使用,構建時很容易出現找不到符號的問題。

筆者這裏構建 Ceres Solver 使用的有依賴庫有 eigen、gflags、glog、OpenBLAS 和 SuiteSparse。這裏面大部分庫的構建前面的文章《CMake構建學習筆記-目錄》都介紹過,gflags、glog 構建也比較簡單,使用本系列文章實現的自動化工具 BuildCppDependency 安裝 Ceres Solver 的時候會自動進行安裝。

在 Windows 平台下輸入指令:

./BuildCppDependency.ps1 `
  -Generator "Visual Studio 16 2019" `
  -InstallDir "$env:GISBasic" `
  -SymbolDir "$env:GISBasic/symbols" `
  -Install ceres-solver

在 Linux (Ubuntu) 平台下輸入指令:

./build.sh -install ceres-solver -installdir "$GISBasic"

還是展開看一下 Windows 下的構建腳本中的 CMake 構建參數:

# ceres-solver.ps1
param(    
    [string]$Name = "ceres-solver-2.2.0",
    [string]$SourceDir = "../Source",
    [string]$Generator,
    [string]$InstallDir,  
    [string]$SymbolDir,  
    [bool]$Force = $false,        # 是否強制重新構建
    [bool]$Cleanup = $true        # 是否在構建完成後刪除源碼和構建目錄
)

# 目標文件
$DllPath = "$InstallDir/lib/ceres.lib"

# 依賴庫數組
$Librarys = @("eigen", "gflags", "glog", "OpenBLAS", "SuiteSparse")  

# 符號庫文件
$PdbFiles = @(
    "lib/RelWithDebInfo/ceres.pdb"
    "lib/RelWithDebInfo/ceres_cuda_kernels.pdb"
) 

# 額外構建參數
$CMakeCacheVariables = @{
    BUILD_TESTING = "OFF"
    BUILD_EXAMPLES = "OFF"
    BUILD_SHARED_LIBS = "OFF"    
    USE_CUDA = "ON"
}

. ./build-common.ps1 -Name $Name `
    -SourceDir $SourceDir `
    -InstallDir $InstallDir `
    -SymbolDir $SymbolDir `
    -Generator $Generator `
    -TargetDll $DllPath `
    -PdbFiles $PdbFiles `
    -CMakeCacheVariables $CMakeCacheVariables `
    -MultiConfig $false `
    -Force $Force `
    -Cleanup $Cleanup `
    -Librarys $Librarys

解釋一下這幾個 CMake 構建參數:

BUILD_TESTING = "OFF"&&BUILD_EXAMPLES = "OFF":一般含有TEST或者EXAMPLE的構建項都不是必須的,一般都可以去掉,減少構建時間和構建體積。

BUILD_SHARED_LIBS = "OFF":嘗試過構建動態庫,但是失敗了,原因待查。這裏關掉表示構建靜態庫。

USE_CUDA = "ON":如果沒有安裝 CUDA SDK 就可以關掉。