2022-02-09

浅谈C++包管理

包管理系统并不是一开始就出现在编程的世界中的。C++ 语言对于通用代码的管理,最初使用的是函数。这在汇编中,将参数压栈再使用 call 指令来调用是同样的概念。慢慢的,开源软件开始流行,越来越多的项目会使用别人写好的库,虽然是方便,但导致项目依赖变得越来越复杂。新的编程语言都直接带了了官方的包管理工具,比如 Go 或 Rust,而古老的 C++ 语言也开始引入包管理工具。

C++ 包管理的发展简述

传统 Linux 下,使用各 Linux 发行版的包管理工具来安装程序要使用的扩展库,比如,在 Debian 下若要使用 OpenSSL,则可以使用apt-get来安装 libssl-dev,然后在代码中就可以用#include <openssl/sha.h>来使用OpenSSL中的功能。

C++ 迫切的需要一个具有跨平台能力的包管理工具,此时 VcPKG 就诞生了。例如,你可以使用vcpkg install openssl来下载并安装 OpenSSL,并且可以指定版本号。安装完毕后,在当前的项目里稍做配置则可以使用 OpenSSL 库的各种功能。关于 VcPKG 可以查看VcPKG来了解它是如何被安装到各平台上的。

使用 VcPKG 可以方便的在不同的平台安装和管理依赖库,让跨平台开发中,对库的依赖变得简单和方便,但是,我们仍然会碰到一些库并没有被 VcPKG 收录的情况。

CMake 与扩展库支持

CMake 在 3.14 版本中引入了 FetchContent 模块,使用该模块可以使用不同的协议从互联网上下载依赖库到本地。于是我们可以使用该模块来下载并配置一些未被 VcPKG 收录的库。但是 FetchContent 需要被依赖的库是使用 CMake 来构建的,于是,那些不是使用 CMake 来构建的库,FetchContent 模块则不适用了。

当 FetchContent 不适用的时候,我们可以使用 CMake 的 ExternalProject 模块,该模块和 FetchContent 模块很相似,也可以下载某个依赖库并且配置,编译和安装。使用它可以添加非 CMake 的项目,因为 ExternalProject 模块可以指定配置方式,编译方式等各种参数。

遵循的包管理原则

使用 C++ 包管理和 CMake,遵循一个简单的原则:若需要安装的扩展库在 VcPKG 中存在,则尽量使用 VcPKG 中的库,若该扩展库并没有被 VcPKG 收录,但是该扩展库使用了 CMake 作为项目管理,则使用 CMake 的 FetchContent 模块来下载和使用该库,否则,使用 ExternalProject 模块来下载和使用该库。

C++ 的包管理工具,不只有 VcPKG,在世界上还有很多优秀的 C++ 包管理器,VcPKG 可能并不是最强大的。但是相对来说却是简单易用的。同时配合使用 CMake 的 FetchContent 和 ExternalProject 两个扩展模块,可以很好解决第一次配置工程前要手动下载、编译和安装扩展库的问题。

MATTHEW
桂ICP备17005075号