浅谈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两个扩展模块,可以很好解决第一次配置工程前要手动下载、编译和安装扩展库的问题。