vcpkg快速入门手册

文章目录

    • 1. 简介
    • 2. 安装与使用
      • 2.1 获取vcpkg
      • 2.2 编译vcpkg
      • 2.3 vcpkg的文件夹层次结构
      • 2.4 设置vcpkg的环境变量
      • 2.5 vcpkg的常用命令
      • 2.6 安装包与Visual Studio集成
    • 3. 常见的C++库的CMake配置方式
      • 3.1 Boost
      • 3.2 cereal
      • 3.3 Ceres Solver
      • 3.4 CGAL
      • 3.5 FLANN
      • 3.6 GDAL
      • 3.7 GLEW
      • 3.8 GMP
      • 3.9 GTest
      • 3.10 GSL
      • 3.11 HDF5
      • 3.12 Lastools/Laslib
      • 3.13 OpenCV
      • 3.14 OpenNI2
      • 3.15 OSG
      • 3.16 PDAL
      • 3.17 PROJ
      • 3.18 Pybind11库
      • 3.19 Range-v3
      • 3.20 SltBench
      • 3.21 VTK
    • 4. vcpkg常见的错误解决
      • 4.1 未安装VS英文语言包
      • 4.2 未关闭防病毒软件
      • 4.3 未正确下载软件源
      • 4.4 常见C++库编译错误的解决办法

如果你希望了解vcpkg,希望解决包括如何使用vcpkg构建软件包,如何将vcpkg构建的软件包集成到Visual Studio,如何使用vcpkg构建指定版本的软件包,如何解决vcpkg的常见报错信息,如何与CMake配合构建工程等等问题,请你认真阅读本文档以快速入门!

1. 简介

vcpkg 是适用于 C 和 C++ 库的跨平台命令行包管理器。 它简化了 Windows、Linux 和 macOS 上第三方库的购置与安装。 如果项目要使用第三方库,建议通过 vcpkg 来安装它们。 vcpkg 同时支持开源和专有库。 已测试 vcpkg Windows 目录中所有库与 Visual Studio 2015、Visual Studio 2017 及 Visual Studio 2019 的兼容性。 在 Windows 和 Linux/macOS 目录之间,vcpkg 现已支持数千个库。 C++ 社区会不断向两个目录添加更多的库。

微软官方介绍链接

2. 安装与使用

2.1 获取vcpkg

vcpkg的官方源码站点为:https://github.com/microsoft/vcpkg

可以使用git命令获取官方代码仓库

git clone https://github.com/microsoft/vcpkg

2.2 编译vcpkg

  • Windows平台

    在控制台中切换到vcpkg所在目录,运行vcpkg目录下的bootstrap-vcpkg.bat命令,编译好后会在vcpkg所在目录下生产vcpkg.exe文件。

      C:\Users\Administrator>F:
      F:\>cd vcpkg/vcpkg
      F:\vcpkg\vcpkg>bootstrap-vcpkg.bat
    

    注意:最新版官方去掉了本地编译的过程,会从官方仓库中下载已经生成好的vcpkg.exe文件

  • Linux平台

    在终端中执行vcpkg目录下的sudo bash ./ bootstrap-vcpkg.sh命令,会生成一个可执行文件vcpkg。定义环境变量VCPKG_ROOT="/vcpkg"

2.3 vcpkg的文件夹层次结构

所有 vcpkg 功能和数据都自包含在实例的单独目录层次结构中。 没有注册表设置或环境变量。 可以在一台计算机上设置任意数量的 vcpkg 实例,它们彼此互不干扰。vcpkg 的文件夹层次结构如下:

  • buildtrees - 包含从中生成每个库的源的子文件夹。
  • docs - 文档和示例。
  • downloads - 所有已下载的工具或源的缓存副本。 运行安装命令时,vcpkg 会首先搜索此处。
  • installed - 包含每个已安装库的标头和二进制文件。 与 Visual Studio 集成时,实质上是相当于告知它将此文件夹添加到其搜索路径。
  • packages - 在不同的安装之间用于暂存的内部文件夹。
  • ports - 用于描述每个库的目录、版本和下载位置的文件。 如有需要,可添加自己的端口。
  • scripts - 由 vcpkg 使用的脚本(CMake、PowerShell)。
  • toolsrc - vcpkg 和相关组件的 C++ 源代码。
  • triplets - 包含每个受支持目标平台(如 x86-windows 或 x64-uwp)的设置。

2.4 设置vcpkg的环境变量

为了方便vcpkg的使用,建议在环境变量中设置如下值:

环境变量 描述
VCPKG_DEFAULT_TRIPLET x64-windows vcpkg默认构建的三元组,通常在Windows 64位平台下可以直接设置为x64-windows
VCPKG_ROOT F:\vcpkg\vcpkg vcpkg的工作目录,对于本地存在多个版本的vcpkg,不建议设置此变量
VCPKG_DOWNLOADS F:\vcpkg\downloads vcpkg下载软件源和工具的缓存目录,建议保留此文件夹中的所有文件。

2.5 vcpkg的常用命令

  • help命令

    可以查看vcpkg的常用命令

      vcpkg help
    
  • install命令

    安装一个指定的软件包,该C++软件包必须被vcpkg支持,即在ports文件夹内能找到该软件包的端口描述。

      vcpkg install gdal
    

    需要注意的是,通常一个软件包可以附带多种其他三方库的功能支持,部分功能已经被vcpkg支持(可以通过 s e a r c h search search命令查看软件包附带的第三方支持),通过vcpkg安装软件包时也可以同时制定三方库特性的支持。例如安装一个Windows系统64位版本的带libspatialite支持的gdal库可以使用如下命令:

      vcpkg install gdal[core,libspatialite]  --triplet=x64-windows
    

    vcpkg在编译软件包时,会将从软件包官方源中下载到的tar格式源码解压到buildtrees文件夹,并且编译的中间文件也会在buildtrees文件夹。默认情况下,buildtrees文件夹在vcpkg的根目录下,也可以在安装软件包时指定buildtrees文件夹的实际位置,例如:

    vcpkg install gdal[core,libspatialite]  --triplet=x64-windows --x-buildtrees-root=F:/vcpkg/buildtrees
    
  • remove命令

    移除一个指定的安装包,例如删除已经安装好的gdal包使用如下命令:

     vcpkg remove gdal
    

    如果希望移除所有outdated的安装包,可以使用以下命令:

     vcpkg remove --outdated
    

    有些时候,仅仅通过remove命令删除已经安装好的软件包会出现异常。例如可能出现删除安装包后,重新安装包提示“已经安装”。如果我们需要彻底将包从installed目录中移除,需要执行以下流程

    • packages目录中找到包对应的目录(注意区分版本),将整个目录全部删除;

    • buildtrees 目录中找到包对应的目录,将整个目录全部删除;

    • 进入installed\vcpkg\info目录,查找包对应的 l i s t list list文件。 l i s t list list文件中记录了包生成后的lib、dll、pdb、include头文件和其他辅助文件,手动删除这些文件,最后删除 l i s t list list文件本身;

    • 进入installed\vcpkg目录,打开 s t a t u s status status文件,搜索包,将包相关内容手动删除。

vcpkg快速入门手册_第1张图片

  • list命令

    列表所有已经安装的软件包,也可以指定名以列出按照的某一具体软件包

     vcpkg list # list all installed packages
     vcpkg list gdal # list installed gdal
    

    通过 l i s t list list命令可以方便地查询某个安装包是否安装以及对应的安装版本:

  • search命令

    搜索vcpkg支持的安装包:

     vcpkg search gdal
    

    当需要查看安装包附带哪些三方库支持时,使用 s e a r c h search search命令也很方便:

    vcpkg快速入门手册_第2张图片

  • depend-info命令

    搜索安装包的依赖,如果安装时指定了第三方库的支持,搜索依赖时也需要指定软件包具有哪些三方库特性。例如,搜索一个带Qt、Cuda支持的OpenCV库依赖哪些包,可以使用以下命令:

     vcpkg depend-info opencv[qt,cuda]
    

vcpkg快速入门手册_第3张图片

**如果希望知道哪些软件包依赖包,目前vcpkg没有命令直接支持这一功能。**可以打开 s t a t u s status status文件,进行检索判断。例如如果想知道哪些包依赖hdf5库,在 s t a t u s status status文件中搜索hdf5,所有depends一栏有hdf5列出的包都依赖hdf5库,例如OpenCV

vcpkg快速入门手册_第4张图片

  • x-history命令

    查询vcpkg中软件包的更新记录,需要注意的是,vcpkg引入一个包的端口更新时需要兼容所有依赖它的其他端口,以保证兼容性。因此,vcpkg支持的软件包的更新记录和的官方更新记录并不一定同步

    当需要安装一个特定版本的包(非vcpkg查询到的最新版),可以使用x-history命令获取的更新记录,并借助git reset命令获取对应记录的端口信息,此时可以构建一个特定版本的包。

    Boost库为例,使用x-history命令查询可知,目前vcpkg支持构建的Boost库最新版为1.75.0版:

     vcpkg x-history boost
    

    vcpkg快速入门手册_第5张图片

    如果我们希望构建Boost 1.74.0 版本,通过查询可知,1.74.0版的提交记录为:7944ed328a10833c4a6b3ab3ff94,使用git回退到指定版本(工作区也回退到对应commit的状态),然后重新构建。整个过程的命令如下:

     vcpkg x-history boost # get boost_1.74.0 commit id: 7944ed328a10833c4a6
     git reset --hard 7944ed328a10833c4a6
     vcpkg install boost
    

    需要注意的是,git reset --hard 7944ed328a10833c4a6命令会将vcpkg支持的所有安装包对应的端口描述回退到commit 7944ed328a10833c4a6的状态。而通常情况下,我们并不希望其他已经安装的软件包受到回退的影响,我们可以采用不同目录下的vcpkg解决这个问题!由于vcpkg并不会将信息记录到当前工作目录以外的区域(如注册表),我们可以将vcpkg拷贝到不同文件夹实现不同版本的区分。例如我采用F:/vcpkg/vcpkg作为与官方同步的vcpkg版,保持与Microsoft Vcpkg小组的同步更新,同时采用F:/vcpkg/vcpkg-bak作为本地需要构建特殊版本安装包的备用版。因此,我会在F:/vcpkg/vcpkg-bak目录下运行git reset --hard 7944ed328a10833c4a6命令。

    当构建完成Boost 1.74.0 版,如果希望vcpkg的端口描述文件恢复到官方最新的维护状态,可以使用git pull命令。运行此命令不会改变本地以及构建好的编译结果

    vcpkg快速入门手册_第6张图片

  • export命令

    导出指定安装包,可以指定安装包的导出方式(如raw、nuget、zip、7zip等等),例如以zip压缩包导出gdal安装包可以运行以下命令:

     vcpkg export gdal --zip
    

    运行完成后,会在vcpkg目录下以运行时间生成一个zip压缩包。zip包内的目录结构如下:

    vcpkg快速入门手册_第7张图片

    • installed - 包含导出安装包的头文件和二进制文件(lib、pdb、dll等)。
    • scripts - 由 vcpkg 使用的脚本(CMake、PowerShell)

在下一节会介绍如何使用vcpkg生成的脚本文件配合CMake完成工程的构建。
当我们拥有多个版本的vcpkg,同时希望将不同版本vcpkg编译的二进制软件包合并在一个installed目录,我们也可以将制定的安装包通过命令export导出,然后将导出包中installed目录下的构建平台文件夹与目的installed目录下的平台文件夹直接合并(例如x64-windows文件夹)。installed\vcpkg\info目录也可以直接合并,而对于installed\vcpkg目录下的 s t a t u s status status文件,需要手动进行合并。

  • update命令

    可以查询已经安装的软件包中哪些包可以更新,将查询信息输出至upinfo.txt文件的命令如下:

     vcpkg update > upinfo.txt
    

    upinfo.txt文件中记录的查询结果如下:

    Using local portfile versions. To update the local portfiles, use git pull.
    The following packages differ from their port versions:
    boost:x64-windows 1.74.0 -> 1.75.0
    boost-accumulators:x64-windows 1.74.0 -> 1.75.0
    boost-algorithm:x64-windows 1.74.0 -> 1.75.0
    boost-align:x64-windows 1.74.0 -> 1.75.0
    boost-any:x64-windows 1.74.0 -> 1.75.0
    boost-array:x64-windows 1.74.0 -> 1.75.0
    boost-asio:x64-windows 1.74.0 -> 1.75.0#1
    boost-assert:x64-windows 1.74.0 -> 1.75.0
    boost-assign:x64-windows 1.74.0 -> 1.75.0
    boost-atomic:x64-windows 1.74.0 -> 1.75.0
    boost-beast:x64-windows 1.74.0 -> 1.75.0
    boost-bimap:x64-windows 1.74.0 -> 1.75.0
    boost-bind:x64-windows 1.74.0 -> 1.75.0
    boost-build:x64-windows 1.74.0 -> 1.75.0.beta1#1
    boost-callable-traits:x64-windows 1.74.0 -> 1.75.0
    boost-chrono:x64-windows 1.74.0 -> 1.75.0
    boost-circular-buffer:x64-windows 1.74.0 -> 1.75.0
    boost-compatibility:x64-windows 1.74.0 -> 1.75.0
    boost-compute:x64-windows 1.74.0 -> 1.75.0
    boost-concept-check:x64-windows 1.74.0 -> 1.75.0
    boost-config:x64-windows 1.74.0 -> 1.75.0
    boost-container:x64-windows 1.74.0 -> 1.75.0
    boost-container-hash:x64-windows 1.74.0 -> 1.75.0
    boost-context:x64-windows 1.74.0 -> 1.75.0
    boost-contract:x64-windows 1.74.0 -> 1.75.0
    boost-conversion:x64-windows 1.74.0 -> 1.75.0
    boost-convert:x64-windows 1.74.0 -> 1.75.0
    boost-core:x64-windows 1.74.0 -> 1.75.0
    boost-coroutine:x64-windows 1.74.0 -> 1.75.0
    boost-coroutine2:x64-windows 1.74.0 -> 1.75.0
    boost-crc:x64-windows 1.74.0 -> 1.75.0
    boost-date-time:x64-windows 1.74.0 -> 1.75.0
    boost-detail:x64-windows 1.74.0 -> 1.75.0
    boost-dll:x64-windows 1.74.0 -> 1.75.0
    boost-dynamic-bitset:x64-windows 1.74.0 -> 1.75.0
    boost-endian:x64-windows 1.74.0 -> 1.75.0
    boost-exception:x64-windows 1.74.0 -> 1.75.0
    boost-fiber:x64-windows 1.74.0 -> 1.75.0
    boost-filesystem:x64-windows 1.74.0 -> 1.75.0
    boost-flyweight:x64-windows 1.74.0 -> 1.75.0
    boost-foreach:x64-windows 1.74.0 -> 1.75.0
    boost-format:x64-windows 1.74.0 -> 1.75.0
    boost-function:x64-windows 1.74.0 -> 1.75.0
    boost-function-types:x64-windows 1.74.0 -> 1.75.0
    boost-functional:x64-windows 1.74.0 -> 1.75.0
    boost-fusion:x64-windows 1.74.0 -> 1.75.0
    boost-geometry:x64-windows 1.74.0 -> 1.75.0
    boost-gil:x64-windows 1.74.0 -> 1.75.0
    boost-graph:x64-windows 1.74.0 -> 1.75.0
    boost-graph-parallel:x64-windows 1.74.0 -> 1.75.0
    boost-hana:x64-windows 1.74.0 -> 1.75.0
    boost-heap:x64-windows 1.74.0 -> 1.75.0
    boost-histogram:x64-windows 1.74.0 -> 1.75.0
    boost-hof:x64-windows 1.74.0 -> 1.75.0
    boost-icl:x64-windows 1.74.0 -> 1.75.0
    boost-integer:x64-windows 1.74.0 -> 1.75.0
    boost-interprocess:x64-windows 1.74.0 -> 1.75.0
    boost-interval:x64-windows 1.74.0 -> 1.75.0
    boost-intrusive:x64-windows 1.74.0 -> 1.75.0
    boost-io:x64-windows 1.74.0 -> 1.75.0
    boost-iostreams:x64-windows 1.74.0 -> 1.75.0
    boost-iterator:x64-windows 1.74.0 -> 1.75.0
    boost-lambda:x64-windows 1.74.0 -> 1.75.0
    boost-lexical-cast:x64-windows 1.74.0 -> 1.75.0
    boost-local-function:x64-windows 1.74.0 -> 1.75.0
    boost-locale:x64-windows 1.74.0#3 -> 1.75.0
    boost-lockfree:x64-windows 1.74.0 -> 1.75.0
    boost-log:x64-windows 1.74.0 -> 1.75.0
    boost-logic:x64-windows 1.74.0 -> 1.75.0
    boost-math:x64-windows 1.74.0 -> 1.75.0
    boost-metaparse:x64-windows 1.74.0 -> 1.75.0
    boost-modular-build-helper:x64-windows 1.74.0#2 -> 1.75.0#4
    boost-move:x64-windows 1.74.0 -> 1.75.0
    boost-mp11:x64-windows 1.74.0 -> 1.75.0
    boost-mpi:x64-windows 1.74.0 -> 1.75.0
    boost-mpl:x64-windows 1.74.0 -> 1.75.0
    boost-msm:x64-windows 1.74.0 -> 1.75.0
    boost-multi-array:x64-windows 1.74.0 -> 1.75.0
    boost-multi-index:x64-windows 1.74.0 -> 1.75.0
    boost-multiprecision:x64-windows 1.74.0 -> 1.75.0
    boost-nowide:x64-windows 1.74.0 -> 1.75.0
    boost-numeric-conversion:x64-windows 1.74.0 -> 1.75.0
    boost-odeint:x64-windows 1.74.0 -> 1.75.0
    boost-optional:x64-windows 1.74.0 -> 1.75.0
    boost-outcome:x64-windows 1.74.0 -> 1.75.0
    boost-parameter:x64-windows 1.74.0 -> 1.75.0
    boost-parameter-python:x64-windows 1.74.0 -> 1.75.0
    boost-phoenix:x64-windows 1.74.0 -> 1.75.0
    boost-poly-collection:x64-windows 1.74.0 -> 1.75.0
    boost-polygon:x64-windows 1.74.0 -> 1.75.0
    boost-pool:x64-windows 1.74.0 -> 1.75.0
    boost-predef:x64-windows 1.74.0 -> 1.75.0
    boost-preprocessor:x64-windows 1.74.0 -> 1.75.0
    boost-process:x64-windows 1.74.0 -> 1.75.0
    boost-program-options:x64-windows 1.74.0 -> 1.75.0
    boost-property-map:x64-windows 1.74.0 -> 1.75.0
    boost-property-tree:x64-windows 1.74.0 -> 1.75.0
    boost-proto:x64-windows 1.74.0 -> 1.75.0
    boost-ptr-container:x64-windows 1.74.0 -> 1.75.0
    boost-python:x64-windows 1.74.0 -> 1.75.0#1
    boost-qvm:x64-windows 1.74.0 -> 1.75.0
    boost-random:x64-windows 1.74.0 -> 1.75.0
    boost-range:x64-windows 1.74.0 -> 1.75.0
    boost-ratio:x64-windows 1.74.0 -> 1.75.0
    boost-rational:x64-windows 1.74.0 -> 1.75.0
    boost-regex:x64-windows 1.74.0 -> 1.75.0
    boost-safe-numerics:x64-windows 1.74.0 -> 1.75.0
    boost-scope-exit:x64-windows 1.74.0 -> 1.75.0
    boost-serialization:x64-windows 1.74.0 -> 1.75.0
    boost-signals2:x64-windows 1.74.0 -> 1.75.0
    boost-smart-ptr:x64-windows 1.74.0 -> 1.75.0
    boost-sort:x64-windows 1.74.0 -> 1.75.0
    boost-spirit:x64-windows 1.74.0 -> 1.75.0
    boost-stacktrace:x64-windows 1.74.0 -> 1.75.0
    boost-statechart:x64-windows 1.74.0 -> 1.75.0
    boost-static-assert:x64-windows 1.74.0 -> 1.75.0
    boost-static-string:x64-windows 1.74.0 -> 1.75.0
    boost-stl-interfaces:x64-windows 1.74.0 -> 1.75.0
    boost-system:x64-windows 1.74.0 -> 1.75.0
    boost-test:x64-windows 1.74.0 -> 1.75.0
    boost-thread:x64-windows 1.74.0 -> 1.75.0
    boost-throw-exception:x64-windows 1.74.0 -> 1.75.0
    boost-timer:x64-windows 1.74.0 -> 1.75.0
    boost-tokenizer:x64-windows 1.74.0 -> 1.75.0
    boost-tti:x64-windows 1.74.0 -> 1.75.0
    boost-tuple:x64-windows 1.74.0 -> 1.75.0
    boost-type-erasure:x64-windows 1.74.0 -> 1.75.0
    boost-type-index:x64-windows 1.74.0 -> 1.75.0
    boost-type-traits:x64-windows 1.74.0 -> 1.75.0
    boost-typeof:x64-windows 1.74.0 -> 1.75.0
    boost-ublas:x64-windows 1.74.0 -> 1.75.0
    boost-uninstall:x64-windows 1.74.0 -> 1.75.0
    boost-units:x64-windows 1.74.0 -> 1.75.0
    boost-unordered:x64-windows 1.74.0 -> 1.75.0
    boost-utility:x64-windows 1.74.0 -> 1.75.0
    boost-uuid:x64-windows 1.74.0 -> 1.75.0
    boost-variant:x64-windows 1.74.0 -> 1.75.0
    boost-variant2:x64-windows 1.74.0 -> 1.75.0
    boost-vmd:x64-windows 1.74.0 -> 1.75.0
    boost-wave:x64-windows 1.74.0 -> 1.75.0
    boost-winapi:x64-windows 1.74.0 -> 1.75.0
    boost-xpressive:x64-windows 1.74.0 -> 1.75.0
    boost-yap:x64-windows 1.74.0 -> 1.75.0
    pcl:x64-windows 1.11.1#1 -> 1.11.1#2

    To update these packages and all dependencies, run
    .\vcpkg upgrade

    To only remove outdated packages, run
    .\vcpkg remove --outdated

    说明本地安装的软件包中Boost库可以升级到1.75.0版,pcl库可以升级到1.11.1#2版,其他已经安装的软件包均为vcpkg支持的最新版。

  • upgrade命令
    如果希望直接重建所有可升级的安装包,可以用以下方式运行命令:

     vcpkg upgrade --no-dry-run 
    
  • integrate命令
    将vcpkg构建的安装包与Vistual Stuido集成:当需要设置为所有项目均可使用vcpkg构建的安装包时,可以使用vcpkg integrate install命令;当需要解除与Visual Studio的集成时,可以使用vcpkg integrate remove命令;当需要与某一具体工程集成时,可以使用vcpkg integrate project命令生成一个参考包配合nuget与单一工程集成。

    相关集成的方法将在下一小节具体介绍。

2.6 安装包与Visual Studio集成

  • 全局集成
    vcpkg可以自动为VS工程适配目录,开发者并不需要关心已安装的库的目录在哪里,也不需要设置库目录和引用目录就能自由地使用。使用以下命令可以完成全局集成:

     vcpkg integrate install
    

    vcpkg快速入门手册_第8张图片

    我们新建一个hello-world工程测试下全局集成的效果,建立好hello-world工程后,可以在工程属性选项中看到vcpkg的选项卡:

    vcpkg快速入门手册_第9张图片

    可以在选项卡中进行vcpkg的相关设置,简单为hello-world工程引入OpenCV库,只需要包含好相应的头文件就可以正常调用OpenCV的相关函数:

    #include 
    #include 
    #include 
    
    int main()
    {
    	const std::string imgFile = "F:/TestData/Imagery/image_small.tif";
    	auto imgMat = cv::imread(imgFile, cv::IMREAD_GRAYSCALE);
    	cv::namedWindow("image_small", cv::WINDOW_NORMAL);
    	cv::imshow("image_small", imgMat);
    	cv::waitKey(0);
    	return 0;
    }
    

    可以看到工程正常编译没有任何报错信息,并且编译后的执行程序可以正常运行:

    vcpkg快速入门手册_第10张图片

    进入二进制文件生成文件夹,可以看到vcpkg自动将hello-world.exe依赖的库拷贝到生成目录了!

    vcpkg快速入门手册_第11张图片

    如果希望去掉vcpkg的全局集成可以使用以下命令:

    vcpkg integrate remove
    
  • 集成到单一工程
    使用以下命令生成nuget配置文件:

     vcpkg integrate project
    

    运行完成后会有如下提示:

    F:\vcpkg\vcpkg>vcpkg integrate project
    Created nupkg: F:\vcpkg\vcpkg\scripts\buildsystems\vcpkg.F.vcpkg.vcpkg.1.0.0.nupkg

    With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste:
    Install-Package vcpkg.F.vcpkg.vcpkg -Source “F:\vcpkg\vcpkg\scripts\buildsystems”

    此时需要配合nuget包管理工具完成工程设置。在Viusal Studio中点击工具Nuget包管理器程序包管理器设置,在打开的选项卡中完成如下设置:

    vcpkg快速入门手册_第12张图片

    设置完成后点击工具Nuget包管理器管理解决方案的NuGet程序包,在打开的选项卡中完成如下设置:

    vcpkg快速入门手册_第13张图片

    安装完成后,hello-world工程即可以正常编译!

  • 与CMake集成使用

    除开以上方式直接与Visual Studio集成使用,vpckg还提供了脚本可以直接与CMake、Powershell等工具集成使用构建工程。这里简单介绍下如何与CMake集成使用。

    在CMake申明创建第一个project前,加上以下定义:

    set(VCPKG_ROOT "F:/vcpkg/vcpkg")
    SET(CMAKE_TOOLCHAIN_FILE "${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
    if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
        set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
    endif()
    set(VCPKG_3RD_PARTY_ROOT "${VCPKG_ROOT}/installed/${VCPKG_TARGET_TRIPLET}")
    set(VCPKG_3RD_PARTY_INCLUDE "${VCPKG_3RD_PARTY_ROOT}/include")
    

    即指明CMAKE_TOOLCHAIN_FILE的路径和软件包的编译三元组(需要从环境变量中读取相应的值),此时可以定义vcpkg编译的三方库应用目录为VCPKG_3RD_PARTY_INCLUDE

    在为目标工程引入三方库前,需要使用 f i n d _ p a c k a g e {find\_package} find_package命令和 i n c l u d e _ d i r e c t o r i e s {include\_directories} include_directories命令(或 t a r g e t _ i n c l u d e _ d i r e c t o r i e s {target\_include\_directories} target_include_directories命令):

    #找到OpenCV软件包
    find_package(OpenCV REQUIRED)
    #为所有子工程增加附加引用目录 ${VCPKG_3RD_PARTY_INCLUDE}
    include_directories(${VCPKG_3RD_PARTY_INCLUDE})
    
    add_executable(${proj_name} ${RCS})
    #为工程${proj_name}链接OpenCV的libs
    target_link_libraries(${proj_name} PRIVATE ${OpenCV_LIBS})	
    #为工程${proj_name}增加附加引用目录 ${VCPKG_3RD_PARTY_INCLUDE}
    target_include_directories(${proj_name} PRIVATE ${VIS_INCLUDES})
    

    需要注意的是,CMake对不同的三方软件包提供的查找方式、设置引用目录方式和链接库方式没有固定模板,我们将在下一章介绍常见的第三方软件包的CMake配置方式。

3. 常见的C++库的CMake配置方式

CMake对不同的三方软件包提供的查找方式、设置引用目录方式和链接库方式没有固定模板,这里我们介绍了部分常见第三方软件包的CMake配置方式。由于时间原因,并不是所有的配置信息都完成了测试,设置仅做参考,可能会因为实际情况做变更与调整

3.1 Boost

Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称。

官方网站:https://www.boost.org/

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
#只申明需要的组件
find_package(Boost 1.74.0 REQUIRED COMPONENTS filesystem date_time iostreams program_options python39 locale)
target_link_libraries(${proj_name} PRIVATE ${Boost_LIBRARIES})

3.2 cereal

cereal是一个只包含头文件的C++ 11序列化库。cereal接受任意数据类型,并可逆地将它们转换为不同的表示形式,如紧凑二进制编码、XML或JSON。cereal被设计成快速、轻量级、易于扩展——它没有外部依赖,可以很容易地与其他代码绑定或独立使用。

官方网站:https://uscilab.github.io/cereal/

find_package(cereal CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name}  PRIVATE cereal)

3.3 Ceres Solver

Ceres Solver是一个开源c++库,用于建模和解决大型、复杂的优化问题。它可用于求解非线性有界约束最小二乘问题和一般无约束优化问题。

官方网站:http://ceres-solver.org/index.html

find_package(Ceres CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE ceres Ceres::ceres)

3.4 CGAL

CGAL(The Computational Geometry Algorithms Library)以C++库的形式提供了方便的访问高效可靠的几何算法。CGAL用于需要几何计算的各个领域,如地理信息系统、计算机辅助设计、分子生物学、医学成像、计算机图形学和机器人技术。

CGAL库提供了丰富的数据结构和算法,如三角剖分,Voronoi图,布尔操作的多边形和多面体,点集处理,安排曲线,曲面和体积网格生成,几何处理,阿尔法形状,凸壳算法,形状重建,AABB和KD树…

官方网站:https://www.cgal.org/

find_package(CGAL CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE CGAL::CGAL)

3.5 FLANN

FLANN是一个用于在高维空间中执行快速近似最近邻搜索的库。它包含了一组我们发现最适合最近邻搜索的算法,以及一个根据数据集自动选择最佳算法和最优参数的系统。

官方网站:https://github.com/mariusmuja/flann

find_package(flann CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name}  PRIVATE flann::flann flann::flann_cpp)

3.6 GDAL

GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。OGR是GDAL项目的一个分支,功能与GDAL类似,只不过它提供对矢量数据的支持。

官方网站:https://gdal.org/

find_package(GDAL REQUIRED)
target_include_directories(${proj_name} PRIVATE ${GDAL_INCLUDE_DIRS})
target_link_libraries(${proj_name} PRIVATE ${GDAL_LIBRARIES})

3.7 GLEW

OpenGL Extension Wrangler Library (GLEW)是一个跨平台的开源C/ C++扩展加载库。GLEW提供了高效的运行时机制来确定目标平台支持哪些OpenGL扩展。OpenGL的核心和扩展功能在一个头文件中公开。GLEW已经在各种操作系统上进行了测试,包括Windows、Linux、Mac OS X、FreeBSD、Irix和Solaris。

官方网站:http://glew.sourceforge.net/

find_package(GLEW REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE GLEW::GLEW)

3.8 GMP

GMP是一个用于任意精度算法的免费库,可操作有符号整数、有理数和浮点数。除了运行GMP的机器中的可用内存所暗示的精度之外,对精度没有实际限制。GMP具有丰富的功能集,各功能具有规范的接口。GMP的主要目标应用是密码学应用与研究、互联网安全应用、代数系统、计算代数研究等。

官方网站:https://gmplib.org/

find_package(GMP REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} gmp libgmp)

3.9 GTest

GTest(googletest)是测试技术团队根据谷歌的具体要求和限制开发的测试框架。googletest跨平台地支持任意类型的C++开发相关测试,不仅仅是单元测试…

官方网站:https://github.com/google/googletest

find_package(GTest REQUIRED)
target_link_libraries(${proj_name} PRIVATE GTest::gmock GTest::gtest GTest::gmock_main GTest::gtest_main)
#也有以下方式链接库${GTEST_LIBRARIES}
#target_link_libraries(${proj_name} PRIVATE  ${GTEST_LIBRARIES})

3.10 GSL

GNU科学库(GSL)是一个面向C和c++程序员的数字库。它是GNU通用公共许可证下的自由软件。该库提供了广泛的数学例程,如随机数生成器,特殊函数和最小二乘拟合。总共有超过1000个函数和一个广泛的测试套件。

官方网站:https://www.gnu.org/software/gsl/

find_package(GSL REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name}  PRIVATE GSL::gsl GSL::gslcblas)

3.11 HDF5

HDF(High-performance data management and storage suite)是美国国家高级计算应用中心(National Center for Supercomputing Application,NCSA)为了满足各种领域研究需求而研制的一种能高效存储和分发科学数据的新型数据格式 。HDF5是为快速I/O处理和存储而构建的。

官方网站:https://www.hdfgroup.org/solutions/hdf5/

find_package(hdf5 CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name}  PRIVATE hdf5::hdf5-shared hdf5::hdf5_hl-shared)

3.12 Lastools/Laslib

LASlib(带有LASzip)是一个用于读写激光雷达的C++编程API。

官方网站:https://github.com/LAStools/LAStools

 #以下链接方式似乎有问题,无法正确链接
find_package(laslib CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE LASlib)
#手动link lib文件
set(LASLIB_INCLUDE_DIR "${VCPKG_3RD_PARTY_INCLUDE}/LASlib")
set(LASLIB_LIBRARY debug "${VCPKG_3RD_PARTY_ROOT}/debug/lib/LASlib.lib"
               optimized "${VCPKG_3RD_PARTY_ROOT}/lib/LASlib.lib")
target_link_libraries(${proj_name} PRIVATE ${LASLIB_LIBRARY})

3.13 OpenCV

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用,并在可用时利用MMX和SSE指令, 如今也提供对于C#、Ch、Ruby,GO的支持。

官方网站:https://opencv.org/

find_package(OpenCV REQUIRED)
target_link_libraries(${proj_name} PRIVATE ${OpenCV_LIBS})

3.14 OpenNI2

OpenNI(开放自然交互)是一个多语言,跨平台的框架,它定义了编写应用程序,并利用其自然交互的API。OpenNI API由一组可用来编写通用自然交互应用的接口组成。OpenNI的主要目的是要形成一个标准的API,来搭建视觉和音频传感器与视觉和音频感知中间件通信的桥梁。

官方网站:https://structure.io/openni

# openni2库的配置全部未测试
set(OPENNI2_FOUND TRUE) # auto 
set(OPENNI2_VERSION 1.0.0)
set(OPENNI2_ROOT_DIR "C:/car_libs/OpenNI2")

find_path(OPENNI2_INCLUDE_DIR NAMES OpenNI.h PATHS "${OPENNI2_ROOT_DIR}/Include") 
mark_as_advanced(OPENNI2_INCLUDE_DIR) # show entry in cmake-gui

find_library(OPENNI2_LIBRARY NAMES OpenNI2.lib PATHS "${OPENNI2_ROOT_DIR}/Lib") 
mark_as_advanced(OPENNI2_LIBRARY) # show entry in cmake-gui

set(OPENNI2_INCLUDE_DIRS ${OPENNI2_INCLUDE_DIR} )
set(OPENNI2_LIBRARIES ${OPENNI2_LIBRARY} )

3.15 OSG

OpenSceneGraph是一个开源的高性能3D图形工具包,用于可视化仿真、游戏、虚拟现实、科学可视化和建模等领域的应用程序开发人员。它完全用标准c++和OpenGL编写,可以在所有Windows平台上运行,包括OSX、GNU/Linux、IRIX、Solaris、HP-Ux、AIX和FreeBSD操作系统。OpenSceneGraph现已成为世界领先的场景图技术,广泛应用于可视化模拟、空间、科学、石油天然气、游戏和虚拟现实行业。

官方网站:http://www.openscenegraph.org/

find_package(OpenSceneGraph 3.6.5 REQUIRED osgDB osgUtil)
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS})
target_link_libraries(${proj_name}  ${OPENSCENEGRAPH_LIBRARIES}

3.16 PDAL

PDAL是一个用于转换和操作点云数据的C++ BSD库。它非常像处理光栅和矢量数据的GDAL库。除了库代码之外,PDAL还提供了一套命令行应用程序,用户可以方便地使用它们来处理、过滤、翻译和查询点云数据。

官方网站:https://pdal.io/

find_package(PDAL REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE pdalcpp pdal_util pdal_arbiter pdal_kazhdan)

3.17 PROJ

PROJ是一个通用的坐标转换软件,它将地理空间坐标从一个坐标参考系统(CRS)转换到另一个。这包括地图投影和大地变换。PROJ包括命令行应用程序,可以方便地从文本文件或直接从用户输入转换坐标。除了命令行实用程序之外,PROJ还公开了一个应用程序编程接口,简称API。该API允许开发人员在自己的软件中使用PROJ的功能,而不必自己实现类似的功能。

官方网站:https://proj.org/

find_package(proj4 CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE PROJ::proj PROJ4::proj)

3.18 Pybind11库

Pybind11是一个轻量级的头文件库,它在Python中公开c++类型,反之亦然,主要用于创建现有c++代码的Python绑定。它的目标和语法与优秀的Boost相似,主要是用来在已有的 C++代码的基础上做扩展,它的语法和目标非常像Boost.Python,但Boost.Python为了兼容现有的基本所有的C++编译器而变得非常复杂和庞大,而因此付出的代价是很多晦涩的模板技巧以及很多不必要的对旧版编译器的支持。Pybind11摒弃了这些支持,它只支持python2.7以上以及C++ 11以上的编译器,使得它比Boost.Python更加简洁高效。

官方网站:https://github.com/pybind/pybind11

find_package(pybind11 CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE mylib pybind11::lto pybind11::embed pybind11::module)

3.19 Range-v3

C++14/17/20的Range库,是C++20的Range库的基础。

官方网站:https://ericniebler.github.io/range-v3/

find_package(range-v3 CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE range-v3 range-v3-meta range-v3::meta range-v3-concepts)

3.20 SltBench

C++ benchmark工具

官方网站:https://github.com/ivafanas/sltbench

find_package(sltbench CONFIG REQUIRED)
#以下链接方式未作测试
target_link_libraries(${proj_name} PRIVATE sltbench)

3.21 VTK

可视化工具包(VTK)是用于操作和显示科学数据的开源软件。它提供了最先进的3D渲染工具,一套用于3D交互的小部件,以及广泛的2D绘图功能。

官方网站:https://vtk.org/

# vcpkg给的例子,链接方式未作测试,不一定对
find_package(3.13 CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE ZLIB::ZLIB)

find_package(3.16 CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE PostgreSQL::PostgreSQL)

find_package(99 CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE X11::SM X11::Xi X11::Xt X11::Xv)

find_package(vtk CONFIG REQUIRED)
target_link_libraries(${proj_name} PRIVATE LZ4::LZ4 OGG::OGG VTK::lz4 VTK::mpi)

4. vcpkg常见的错误解决

vcpkg编译第三方软件包时可能出现各种错误导致编译失败,这里列举了一些使用vcpkg安装软件包时可能发生的错误及解决办法。

4.1 未安装VS英文语言包

在Windows中文版操作系统下,Visual Studio可能默认安装为中文版,并不带英文语言包。如果Viusal Studio没有应用英文语言包,很多三方库很容易编译失败,因此首先需要给Visual Studio安装英文语言包。

运行Visual Studio Installer,在对应版本的Viusal Studio选项卡右方点击修改按钮,在弹出的新对话框中点击语言包选项卡,勾选英语语言包并安装。

vcpkg快速入门手册_第14张图片

vcpkg快速入门手册_第15张图片

4.2 未关闭防病毒软件

vcpkg在编译某些软件包时会调用Microsoft Windows软件开发工具包中的Mt.exe生成签名文件和目录,这一行为通常会被一些防病毒软件误报为危险操作而被防病毒软件禁用,最终导致一些软件包的安装失败!因此,为了保证获取正确的安装结果,在运行vcpkg的全程内请暂时禁用所有的防病毒软件!

4.3 未正确下载软件源

vcpkg支持的软件包提供的官方源通常托管在github上或者是官方镜像服务器上,这些服务器国内访问速度很慢,而且通过vcpkg下载源码网络很不稳定。因为vcpkg并不支持断点续传,同时在安装软件包过程中下载的任何源文件,vcpkg都会默认进行文件哈希码检验,在网络不稳定的情况下,很容易发生下载异常,到账编译失败!

目前在没有更好的解决办法下,可以将控制台界面中展现的vcpkg正在下载的文件超链接地址复制到其他下载器手动下载,需要注意的是,vcpkg通常会将超链接中的文件重新命名(文件名通常不会保持一致)。因此,在我们手动下载完软件源后,还需要重命名文件。重命名后的文件名也可以在控制台界面查看到,同时也可以在vcpkg下载某一软件源时,在vcpkg的downloads\temp文件夹内找到重命名后的临时文件,可以参考这个临时文件将手动下载好的软件源重命名,然后复制到vcpkg的downloads文件夹。

vcpkg快速入门手册_第16张图片

4.4 常见C++库编译错误的解决办法

  • Boost
    Boost库通常会被很多优秀的开源C++库依赖,因此建议使用vcpkg最先编译Boost库。截止到2021年2月8日,vcpkg最新支持的Boost库为1.75.0版。1.75.0Boost库与CMake集成使用时,目前CMake会弹出警告;同时,目前测试最新版(1.11.1版)的pcl库使用Boost 1.75.0版编译会编译失败。因此,建议目前仅安装Boost 1.74.0

  • Qt5
    很多C++库在安装时也可以指定Qt的支持,因此建议也优先使用vcpkg安装Qt库。截止到2021年2月8日,vcpkg最新支持的Qt库为5.15.2版,经测试,如果在安装Qt5前,已经安装了protobufqt-webengine会编译失败。因此,如果qt-webengine无法正常编译,可以先尝试删除protobuf。目前,qt-wayland会编译失败,考虑到我们的项目不需要这一特性,在编译Qt5时去掉了wayland的支持。

  • GMP
    需要先安装 yasm-tool:x86-windows

  • PCL
    暂不支持Boost 1.75.0版,用Boost 1.74.0版可以编译通过

  • VTK

    • VTK8.x版本依赖PROJ6.X版本;

    • VTK指定libmysql支持时,若已经安装libmariadb,则会因为libmysqllibmariadb库不兼容导致安装失败,可去掉二者其一;

    • VTK库必须指定mpi支持;

    • OpenCV4.5.1版指定VTK支持时,暂不支持VTK 9.0版。

  • OpenCV

    • 需要关闭防病毒软件;

    • OpenCV4.5.1版指定VTK支持时,暂不支持VTK 9.0版;

    • 编译xfeature2d时,可能因为几个描述文件下载失败而导致整体编译失败,可以参考前文手动下载描述文件,或者通过以下方式下载:

      #!/bin/bash
      cd ./cache/xfeatures2d/
      cd boostdesc
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_lbgm.i > 0ae0675534aa318d9668f2a179c2a052-boostdesc_lbgm.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_binboost_256.i > e6dcfa9f647779eb1ce446a8d759b6ea-boostdesc_binboost_256.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_binboost_128.i > 98ea99d399965c03d555cef3ea502a0b-boostdesc_binboost_128.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_binboost_064.i > 202e1b3e9fec871b04da31f7f016679f-boostdesc_binboost_064.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_bgm_hd.i > 324426a24fa56ad9c5b8e3e0b3e5303e-boostdesc_bgm_hd.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_bgm_bi.i > 232c966b13651bd0e46a1497b0852191-boostdesc_bgm_bi.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/34e4206aef44d50e6bbcd0ab06354b52e7466d26/boostdesc_bgm.i > 0ea90e7a8f3f7876d450e4149c97c74f-boostdesc_bgm.i
      cd ../vgg
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d/vgg_generated_120.i > 151805e03568c9f490a5e3a872777b75-vgg_generated_120.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d/vgg_generated_64.i > 7126a5d9a8884ebca5aea5d63d677225-vgg_generated_64.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d/vgg_generated_48.i > e8d0dcd54d1bcfdc29203d011a797179-vgg_generated_48.i
      curl https://raw.githubusercontent.com/opencv/opencv_3rdparty/fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d/vgg_generated_80.i > 7cd47228edec52b6d82f46511af325c5-vgg_generated_80.i
      

你可能感兴趣的:(C++,c++,github)