1. Boost 库简介
Boost 是一个开源的 C++ 库集合,提供了许多高质量的库,涵盖了许多不同的领域,如智能指针、多线程编程、正则表达式、数学库等等。Boost 的目标是提高 C++ 程序员的生产力和代码质量,同时遵循现代 C++ 的最佳实践。
Boost 库是由一些 C++ 标准委员会成员创建和维护的,因此 Boost 中的一些组件被认为是 C++ 标准库的前身。Boost 库在 C++ 标准化之前提供了很多常用的工具,因此被广泛地应用于各种开源和商业项目中。它的一些主要组件包括:
- 智能指针:提供了多种智能指针类型,如 shared_ptr、unique_ptr、weak_ptr 等,可以方便地管理动态分配的内存,避免内存泄漏和野指针问题。
- 多线程库:提供了多线程编程的支持,包括线程、互斥锁、条件变量、原子操作等。
- 泛型编程库:提供了元编程和泛型编程的支持,如类型推导、类型萃取、可变参数模板等。
- 正则表达式库:提供了正则表达式的支持,可以进行字符串匹配和替换等操作。
- 数学库:提供了一些数学算法和函数,如矩阵运算、随机数生成、数值计算等。
- 文件系统库:提供了对文件系统的支持,可以进行文件和目录的遍历、读写操作等。
2. Boost 库下载
我们可以从 Boost 官方网站下载源代码 👉 Boost C++ Libraries
具体下载过程不在这里展开说明,最新版本可以在 Boost Downloads 中直接下载,历史版本在 Boost Version History 页面下载。
这里我们下载 Boost 库最新版本 1.81.0:
如果你需要在 Windows 上使用 Boost 库,则下载 windows 那一行里的任意一个压缩包;如果是在 Unix/Linux 中使用 Boost 库,则下载 unix 那一行里的任意一个压缩包。
3. Boost 库编译
我们作为 C++ 开发者,有时会在不同架构、不同系统中使用 Boost 库,下面我将会讲解以下编译过程:
👉 如何在 Windows 操作系统下使用 MSVC、MinGW 编译 Boost 库
👉 如何在 Windows 操作系统下使用交叉编译器编译 Boost 库
👉 如何在 Linux 下使用 GCC 编译 Boost 库
👉 如何在 Linux 下使用交叉编译器编译 Boost 库。
3.1 在 Windows 下使用 MSVC 编译 Boost 库
我们需要准备最新版 VisualStudio,并打开 VisualStudio 的命令行工具。如果你还没有安装 VisualStudio,可以到它的官方网站中去下载安装 👉 Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 (microsoft.com)。具体的下载和安装过程这里不展开说明,如果需要可查看官方文档和其他博客。
3.1.1 生成 b2.exe
打开 Powershell, 由于我的电脑的操作系统是 Windows11 22H2,控制台窗口会自动由 Windows Terminal 接管,关于 Powershell 的相关说明文档可以从这里查看 👉 PowerShell 文档 - PowerShell | Microsoft Learn
使用 cd
进到 Boost 库源码目录。注意,如果你的目录中由空格,需要加双引号。
执行命令:.\bootstrap.bat
,生成可执行文件 b2.exe
生成成功后,可以看到目录下多了一个 b2.exe
3.1.2 编译和安装
查看 Boost 组件库列表:./b2.exe --show-libraries
。如果我们只用到其中几个库,则可以只编译需要的库,当然也可以全部编译。
接下来我们就需要用 b2.exe 来组织和构建 Boost 库的编译了。在进行操作之前,先对 b2 的使用参数做一下说明介绍:
- **
stage
生成链接库(动态库或静态库)到stagedir
**中。(不含头文件) - **
--stagedir=
**: 在stage
生成模式下的输出目录,支持相对路径。 - **
install
**: 生成链接库(动态库或静态库)到prefix
/lib 中,并将头文件放入到prefix
/include 中 - **
--prefix=
**: 在install
生成模式下的输出目录 - **
toolset=
**: 指定编译器。b2 会自行检索当前系统下的编译器,如果该参数为缺省值,那么 b2 将使用 Boost 源码根目录下的project-config.jam
文件中的第一个编译器。 - **
--without-
**: 排除哪些库,例如--without-wave --without-test
,表示除了 wave 库和 test 库其他都编译。 - **
--with-
**: 编译哪些库,例如--with-wave --with-test
,表示只编译 wave 和 test 库。 - **
--build-dir=
**: 设置编译过程中间产物的存放路径,默认是bin.v2
。 - **
link=
** : 设置生成的链接库是动态shared
链接库还是静态static
链接库。默认值为static
- **
runtime-link=
**: 设置运行时库的链接方式,是静态链接static
还是动态链接shared
。默认值为shared
- **
threading=
**: 设置是否支持多线程(线程安全)。允许的值为单single
线程和多multi
线程。默认值为多线程multi
- **
variant=
**: 设置生成的库是调试版本还是发布版本,允许的值为debug
或release
,默认值为release debug
即两者都编译。 - **
address-model=
**: 设置生成的库地址模式,是 32 位还是 64 位,允许的值为32
和64
,默认两者都编译。 - **
--project-config=
** : 加载指定项目配置文件,默认值为project-config.jam
关于 toolset
参数允许为以下值:
基本的参数说明完毕,接下来编译 Boost 库,我们想要对 b2 做以下功能约束:
- 将 Boost 组件全部编译,并将库和头文件输出到../install/msvc 下。
- 静态链接运行时库
- 使用 MSVC 编译器
- 生成的库为静态库
- 支持多线程,生成 32 位和 64 位库,并且生成 debug 和 release 版本库。
- 将中间编译产物放到 build/msvc 目录下
根据上述约束条件,则命令可以这样写:
./b2.exe install --prefix="../install/msvc" --build-dir="build/msvc" runtime-link=static
可以看到,我并没有指定 MSVC 编译器,因为 b2 会默认使用源文件目录下的 project-config.jam
文件,其中只有一个编译器,那就是 MSVC,所以一切保持默认值,只设置生成模式为 install
,设置安装目录,设置中间编译产物生成目录,设置运行时库链接模式即可。
编译完成,看下安装目录:
因为是 MSVC 编译出来的,所以静态链接库默认的后缀名为 **.lib
**,检查一下库文件命名,例如:libboost_wave-vc143-mt-s-x64-1_81.lib
- libboost_wave: 库名称
- vc143: MSVC 14.3
- mt: 多线程
- s: 静态链接运行时库
- x64: 64 位库
- 1_81: Boost 版本号
经检查,b2 根据我们的命令在指定目录正确生成了静态链接库和头文件,并且符合我们的要求。关于 Boost 库文件命名规则,可以查看官网 👉 Boost Getting Started on Unix Variants - 1.66.0
3.2 在 Windows 下使用 MinGW 编译 Boost 库
首先,需要准备 MinGW,这里使用目前最新版 w64devkit 开发套件,当前最新版本为 1.16.1,其内部包含以下工具:
- GCC 12.2.0
- busybox-w32 FRP-4716
- GDB 10.2
- Mingw-w64 10.0.0
- GNU Make 4.2
- Vim 9.0
- Universal Ctags 20200824
- NASM 2.15.05
- binutils 2.39
- Cppcheck 2.8
安装步骤如下:
一、w64devkit 下载
-
下载地址 1: w64devkit-1.16.1.zip
二、添加环境变量
下载完成后解压压缩包,将文件夹中的 bin 目录添加到 PATH 环境变量,此步骤不展开讨论
添加完成后验证 MinGW 是否添加到 PATH 中:
3.2.1 生成 b2.exe
如果已经生成了 b2.exe, 则可跳过本小结,过程这里不再赘述,详情可查看前文 👉 ****
3.2.2 编译和安装
根据 3.1.2 小结,我们已经知道了 b2 的使用方法,那么我们就直接开练!
- 只编译 system 和 filesystem 库,并将库和头文件输出到../install/mingw 下。
- 静态链接运行时库
- 使用 MinGW 编译器
- 生成的库为静态库
- 支持多线程,生成 32 位和 64 位库,并且生成 debug 和 release 版本库。
- 将中间编译产物放到 build/mingw 目录下
根据上述功能约束,我们可以写如下命令:
./b2.exe install --prefix="../install/mingw" --build-dir="build/mingw" runtime-link=static toolset=gcc --with-system --with-filesystem
其中 toolset=gcc
表示使用我们刚才安装的 MinGW 作为编译器.(由于刚才设置了环境变量,所以默认的 gcc 就是我们刚才安装的 MinGW)。
编译完成,检查输出:
3.3 在 Windows 下交叉编译 Boost 库
这里我们使用 gcc-aarch64-linux-gnu 交叉编译工具链进行编译,下载地址 👉Linaro Releases
下载之后解压即可。
3.3.1 生成 b2.exe
如果已经生成了 b2.exe, 则可跳过本小结,过程这里不再赘述,详情可查看前文 👉 ****
3.3.2 编译和安装
根据 3.1.2 小结 提到的可以根据 --project-config=
指定配置文件,这里我们为了交叉编译,单独写一份 project-config-aarch64.jam
文件:
# Boost.Build Configuration
# Automatically generated by bootstrap.bat
import option ;
using gcc : aarch64 : "E:/Design_ProgramEnv/GNU/ARM/aarch64-linux-gnu 7.2.1/bin/aarch64-linux-gnu-g++.exe" ;
option.set keep-going : false ;
详情可参考 b2 官方文档 👉 B2 User Manual - 1.81.0 (boost.org) 5.9 小节和 4.3 小节
当然也可以把 using gcc : aarch64 : 7.2.1 : "E:/Design_ProgramEnv/GNU/ARM/aarch64-linux-gnu 7.2.1/bin/aarch64-linux-gnu-g++" ;
写在默认的 project-config.jam 文件中也是可以的,我们向根据以下约束进行编译:
- 只编译 system 和 filesystem 库,并将库和头文件输出到../install/aarch64 下。
- 静态链接运行时库
- 使用 gcc-aarch64-linux-gnu 交叉编译工具链
- 生成的库为静态库
- 支持多线程,生成 32 位和 64 位库,并且生成 debug 和 release 版本库。
- 将中间编译产物放到 build/aarch64 目录下
根据上述功能约束,我们可以写如下命令:
./b2.exe install --prefix="../install/aarch64" --build-dir="build/aarch64" runtime-link=static toolset=gcc-aarch64 --with-system --with-filesystem target-os=linux --project-config="./project-config-aarch64.jam"
其中 **target-os=linux
** 为目标操作系统,当交叉编译平台操作系统与目标操作系统不一致时,需要指定该参数,该参数的值可以是:aix
, android
, appletv
, bsd
, cygwin
, darwin
, freebsd
, haiku
, hpux
, iphone
, linux
, netbsd
, openbsd
, osf
, qnx
, qnxnto
, sgi
, solaris
, unix
, unixware
, windows
, vms
, vxworks
, freertos
. 详情查阅 👉 B2 User Manual - 1.81.0 (boost.org)
编译完成,检查安装目录以及库文件:
3.4 在 Ubuntu 20.04 下使用 GCC 编译 Boost 库
参考 👉 第二节 Boost 库下载 拿到 boost_1_81_0.tar.gz
下载链接,用 SSH 连接到 Ubuntu 后,使用 wget 命令下载源码包:
wget https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.gz
如果下载很慢,则可以用其他方式下载并传输到 Ubuntu 中。下载完成之后解压缩:
tar -zxvf ./boost_1_81_0.tar.gz
3.4.1 编译 b2
与在 windows 下编译不同,这里执行 bootstrap.sh
编译完成后,可以看到文件夹中多出来一个 b2 可执行文件
3.4.2 编译和安装
Linux 下的编译过程与在 Windows 操作系统编译 Boost 过程几乎一致,这里直接演示:
- 将 Boost 组件全部编译,并将库和头文件输出到../install/amd64 下。
- 静态链接运行时库
- 使用 gcc 编译器
- 生成的库为静态库
- 支持多线程,只生成 64 位库,并且生成 debug 和 release 版本库。
- 将中间编译产物放到 build/amd64 目录下
根据上述约束条件,则命令可以这样写:
./b2 install --prefix="../install/amd64" --build-dir="build/amd64" runtime-link=static
编译完成,查看下输出:
可以看到在 Linux 下并没有区分 debug/release 版本, 是否支持多线程等命名标识。于是在 StackOverflow 上查到了相关提问:在 Unix 或 Linux 下,自 Boost1.40.0 中就已经默认取消了库的名称修饰,如果需要名称修饰的话,则添加 b2 参数 **--layout=tagged
**
修改后的命令为:
./b2 install --prefix="../install/amd64" --build-dir="build/amd64" runtime-link=static --layout=tagged
编译,查看输出:
发现输出的库都是 Release 版本,所以我们再次修改命令,显式的声明各项参数:
./b2 install --prefix="../install/amd64" --build-dir="build/amd64" runtime-link=static --layout=tagged variant=debug variant=release address-model=64
其中 **variant
** 声明了两遍,这样理论上 b2 就会帮我们编译两种不同类型的库,如下所示:
3.5 在 Ubuntu 20.04 下交叉编译 Boost 库
首先需要在 Ubuntu 上安装交叉编译器,这里我还是用 gcc-aarch64-linux-gnu 工具链,可以从 ARM 官网上或者 Linaro 中下载,也可以直接从 apt 镜像站下载,我这里就直接用 apt 下载安装了:
sudo apt-get install gcc-aarch64-linux-gnu
安装完成后,查看编译器是否正确安装:
3.5.1 编译 b2
如果已经生成了 b2, 则可跳过本小节,过程这里不再赘述,详情可查看前文 👉 ****
3.5.2 编译和安装
这里直接编辑 **project-config.jam
** 文件,将交叉编译器写入到配置文件中:
using gcc : aarch64 : aarch64-linux-gnu-g++ ;
其交叉编译过程与 Windows 下过程基本一致,这里参考 3.3.2 与 3.4.2 小节内容,做以下功能约束:
- 只编译 system 和 filesystem 库,并将库和头文件输出到../install/aarch64 下。
- 静态链接运行时库
- 使用 gcc-aarch64-linux-gnu 交叉编译工具链
- 生成的库为静态库
- 支持多线程,生成 64 位库,并且生成 debug 和 release 版本库。
- 将中间编译产物放到 build/aarch64 目录下
输入命令:
./b2 install --prefix="../install/aarch64" --build-dir="build/aarch64" runtime-link=static --layout=tagged variant=debug variant=release address-model=64 toolset=gcc-aarch64 --with-system --with-filesystem target-os=linux
查看输出:
4. 总结
看了 B2 的官方文档后,其实发现 B2 还是很好用的,比如支持一次构建多个平台的 Boost 组件库,Debug 和 Release 版本同时编译输出,区分 install 模式和 stage 模式等,基本上涵盖了日常开发大部分编译的需求。
关于 install 模式和 stage 模式,我认为这是两种不同的依赖方式:
- install 模式:头文件导出,并且将编译好的库与 Boost 源代码彻底分离。这种模式下适合做 git-submodule 依赖导入。
- stage 模式:只生成链接库。这种模式非常适合 CMake 的 FatchContent 依赖管理模式,自己工程的代码与 Boost 一起编译(当然有依赖顺序,CMake 就非常适合处理这种事务关系)。
我个人两种依赖方式都用,但是对于 Boost,我还是偏向于用 git-submodule 作为依赖管理器,对于其他小组件,例如 fmt, spdlog 等,用 CMake-FathContent 就很舒服了。
5. 参考资料
- B2 User Manual - 1.81.0 (boost.org)
- Boost Getting Started on Unix Variants - 1.66.0
- Building Boost on Linux - library names - Stack Overflow
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于