Boost 是一个 C++ 库集合,这些库由 Boost 社区根据 Boost 软件许可来开发、审核和发布。Boost 中的库使用 C++ 程序设计中的高级特性和最新创新,增强了编程语言的功能。多年来,许多 Boost 库已在经过调整后包含在 C++ 标准库中。
Boost 包中包含构建 Boost 库的代码库,引导构建引擎的源代码,以及推进构建流程的 JAM 配置。尽管一些用户仍在采用使用 make
实用工具构建常规 C++ 应用程序的相同方式来构建 Boost 库,但业界的部分用户现在已经开始使用 Boost 构建引擎 b2
构建和安装这些库。因为构建流程所需的所有 JAM 配置文件会与每个 Boost 版本一起发布,所以使用 b2
构建 Boost 库是一个非常简单的过程。
b2/bjam
b2
是构建引擎的官方名称,该引擎是根据一个名为 bjam
的早期构建工具来开发的。在较新的 Boost 版本中, b2
和 bjam
实际上是相同的。这可以通过在两个文件上运行校验和函数来验证。为了便于讨论,本文将 Boost 构建工具称为 b2
。
b2
和 bjam
是相同的 b2
支持许多平台上的大量编译器。每个编译器都代表构建引擎的一个工具集。不同于为 IBM XL 编译器指定的传统工具集 vacpp ,Boost 1.59.0 为较新的 IBM 编译器引入了一个名为 xlcpp 的新工具集。编写本文时,小端系统上的 IBM XL for Linux 编译器支持 xlcpp 工具集。
表 1 显示了 Boost 版本、编译器版本和用于小端系统上的 Linux 的相应工具集之间的关系。对于其他平台上的 IBM XL 编译器对 Boost xlcpp 工具集的支持,请参阅 IBM C 和 C++ 编译器家族 网站。
Linux(小端)编译器版本 | Boost 版本 | 工具集 |
---|---|---|
XL C/C++ V13.1.2 | 1.55.0 | vacpp |
XL C/C++ V13.1.3 | 1.59.0 | xlcpp |
有关 Boost.Jam 语言、Boost 构建引擎、构建配置和安装的详细信息,很容易在 www.boost.org 网站上找到。本文将重点介绍使用用于 IBM XL 编译器的新 xlcpp 工具集构建和安装 Boost 库所需的具体配置。讨论中使用了 1.59.0 版,这是随 xlcpp 工具集一起发布的第一个 Boost 版本。但是,这些内容可能也适用于更高的 Boost 版本。
通常,构建 Boost 库的过程包含以下 3 个步骤:
b2
b2
构建和安装 Boost 库 在指定位置构建和安装 Boost 库后,该库和 Boost 头文件即可供软件工程师在其应用程序中使用。
您可以从 www.boost.org 网站下载 Boost 源代码。您需要先解压下载的包,然后才能使用它。清单 1 给出了一个获取和解压 Boost 1.59.0 版源代码的示例。
$ wget http://sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz $ gunzip < boost_1_59_0.tar.gz | tar –xvf-
无需像清单 1 中那样分开使用 gunzip 和 tar ,用户可结合使用 z 标志和 tar
实用工具,使用 gunzip 解压 .gz 文件。但是,在命令中包含 f
作为最后一个标志非常重要。 f
标志指定了压缩文件的路径和名称。
解压过程会创建一个名为 boost_1_59_0 的目录。在讨论构建和安装过程时,将此目录称为 BOOST_ROOT。
需要打补丁才能使用 xlcpp 工具集构建 Boost 库。用户必须获取相应的补丁文件并应用于已解压的 Boost 源代码,然后才能继续操作。在修补过程中,将会适当地修改 Boost 头文件和 JAM 配置文件,以确保成功创建 Boost 库。请参阅 IBM XL 编译器的 Boost 库回归测试摘要页面 ,查看可用补丁文件的列表。补丁文件可通过 FTP 客户端或系统工具(比如 wget )获取。用户必须避免复制 Web 浏览器上呈现的补丁文件内容,因为这可能导致丢失该文件的一些部分。清单 2 给出了一个为 Boost 1.59.0 的源代码获取和应用补丁文件的示例。
$ wget ftp://public.dhe.ibm.com/software/xlcpp/boost/bst1590/boost_modfile_le_1313.txt $ cd <the-directory-where-boost_1_59_0-resides> $ patch –p0 < <path-to-the-pathfile>/boost_modfile_le_1313.txt
备注:由于某些限制,比如存在遗留代码,一些用户将无法向 Boost 源代码应用补丁文件。这将在本文的一篇配套文件中解决。
尽管压缩包相对较小,但解压、构建、安装以及测试整个 Boost 库集合的构建产品需要数 GB 的磁盘空间。如果要测试 Boost 库,必须准好充足的磁盘空间。
Boost 提供了一个名为 bootstrap.sh 的脚本来构建 b2
,b2 是构建、安装和测试 Boost 库所需的 Boost 构建引擎。可以在 BOOST_ROOT 目录 boost_1_59_0 中找到 bootstrap.sh 脚本。
要使用 xlcpp 工具集引导 b2
,用户必须确保 IBM xlC 编译器的路径包含在 $PATH
环境变量中。您可以使用 which
命令验证这一点,如清单 3 所示。
$ which xlC #xlC is not on $PATH which: 0652-141 There is no xlC in … $ PATH=/full-path-to-xlC:${PATH} #Add path of xlC to $PATH export PATH $ which xlC #xlC is on the $PATH /full-path-to-xlCxlC
准备好 $PATH
变量,让构建引擎能够找到 xlC 编译器,然后使用选项 --with-toolset=xlcpp
从 BOOST_ROOT 目录中调用 bootstrap.sh 脚本。
b2
/ bjam
$ cd boost_1_59_0 $ ./bootstrap.sh --with-toolset=xlcpp Building Boost.Build engine with toolset xlcpp... … Generating Boost.Build configuration in project-config.jam... Bootstrapping is done. To build, run: ./b2 To adjust configuration, edit 'project-config.jam'. …
如果 bootstrap.sh 脚本成功运行,将在目录 boost_1_59_0 中创建两个名为 b2
和 bjam
的可执行文件。如图 1 所示, b2
和 bjam
事实上是两个相同的文件。
如果引导失败,查看 boost_1_59_0 目录中存储的日志文件 bootstrap.log 可能会了解失败的原因。请注意,尽管 bootstrap.log 中的信息描述了当前工作目录 "." 中的问题,但在某些地方,目录 "." 实际指向 boost_1_59_0/tools/build/src/engine 。这是因为在构建过程中,脚本 bootstrap.sh 发出了 cd
命令来导航到 boost_1_59_0/tools/build/src/engine 目录。
如果没有指定工具集, bootstrap.sh 脚本会尝试使用系统上的其他可用编译器。该脚本执行的所有活动都将记录在 BOOST_ROOT 目录 boost_1_59_0 中的日志文件 bootstrap.log 中。
在极少数情况下, bootstrap.sh 脚本未能使用 xlcpp 工具集创建可执行文件 b2
和 bjam
,这时用户可尝试使用系统上的不同编译器来调用该脚本。其他编译器创建的构建引擎 b2/bjam
可用作替代引擎,以便在后续步骤中继续使用 xlcpp 工具集构建、安装和测试 Boost。
使用引导程序创建后, b2/bjam
可用于构建、安装和测试 Boost 库。如果调用 b2/bjam
时未使用任何命令行选项,将会使用默认配置来构建 Boost。对于大多数软件项目,具有默认配置的构建版本可能还不够。下一节将讨论使用 xlcpp 工具集和 b2
的命令行选项执行完整的 Boost 构建所需的步骤。可以在 www.boost.org 网站上找到所有构建选项的文档;本文只重点介绍用于 xlcpp 工具集的主要选项。
设置一个目录来启动 Boost 构建
为方便讨论,我们假设构建过程将从一个名为 mybuild 的工作目录中执行。Boost 源代码的路径(也称为 BOOST_ROOT
)是 <path>/boost_1_59_0
。工作目录的的设置如清单 5 所示。
$ mkdir mybuild #Create working directory $ cd mybuild $ BOOST_ROOT=<path>/boost_1_59_0 #Set $BOOST_ROOT $ export BOOST_ROOT $ mkdir boost_build #Create build directory $ BOOST_BUILD=<path>/boost_build #Set $BOOST_BUILD $ export BOOST_BUILD
您需要正确设置所创建目录的权限,构建流程才能访问它们。
指定 BOOST_ROOT
路径对构建过程至关重要;它会告知构建引擎在系统上的何处查找源代码。除了如清单 5 中所示指定 BOOST_ROOT
作为环境变量之外,用户还可以在使用 –s
选项调用 b2
时直接提供该值作为命令行选项。
<path>/b2 -s BOOST_ROOT=<path>/boost_1_59_0 …
指定要用于 Boost 构建流程的编译器
无需修改 xlcpp.jam 和 user_config.jam 文件, b2
将在 $PATH 上使用 xlC 编译器,使用 xlcpp 工具集构建 Boost 库。您可以在清单 3 中了解在 $PATH 上设置 xlC 编译器的详细信息。
用户可修改配置文件来灵活地指定编译器作为构建参数。有关细节将在下一篇文章中讨论。
Boost 构建引擎 b2
接受 3 种命令行标志:选项、属性和目标。可以按任意顺序指定命令行标志,并按以下方式区分它们。
b2
的行为)以一个或两个连字符开头,比如 –a
、 --build-dir
。 feature=value
格式的标志,比如 link=static
。 主要命令行选项
表 2 列出了一些常用于构建 Boost 库的最重要的选项。对于支持的选项的完整列表,请参阅 www.boost.org 发布的 Boost.Build 用户手册 。
选项 | 描述 |
---|---|
-a | 重新构建所有内容,即使目标已存在 |
-n | 不运行命令,而是将它们打印到标准输出 |
-d0 | 启用调试级别 0(也就是说,不会显示信息性消息) |
-dN | 启用从 1 到 N 的累积调试级别。 –d1 是默认值,它显示了在运行调试时为构建每个目标而采取的动作的信息 |
-d+N | 仅启用调试级别 N |
-jN | 并行运行最多 N 个命令 |
-s var=value | 使用指定的 value 覆盖变量 var 的值(从环境中导入) |
--debug-configuration | 显示了加载 Boost.Build 和工具集文件的过程的调试信息 |
--clean | 清理当前目录和任何子项目中的所有目标 |
--help | 显示帮助信息 |
常用属性
表 3 中列出了最常用的属性,用户可能经常在命令行上以 feature=value
形式指定这些属性。对于可接受的属性的完整列表,请参阅 www.boost.org 发表的 内置特性 节。
特性 | 可接受的值 | 描述 |
---|---|---|
variant | debug 、 release | 确定构建版本将是调试构建还是发布构建 |
link | shared 、 static | 确定创建的库将是共享对象还是静态对象 |
threading | single 、 multiple | 如果指定了 multiple ,则生成的库是线程安全的。这需要在源代码中提供适当的支持。 |
cxxflags | (任意字符串) | 指定要传递给 C++ 编译器的选项集 |
cflags | (任意字符串) | 指定要传递给 C 编译器的选项集 |
linkflags | (任意字符串) | 指定要传递给链接器的选项集 |
对于一些特性,比如 link
和 threading
,可在命令行中为它们指定多个值。在这种情况下,目标将被构建多次,为特性的每个指定值都构建一次。例如,如果命令行属性是 link=static link=shared threading=single threading=multi
或等效的 link=static,shared threading=single,multi
,将总共执行 4 次构建。
组合属性 | Build | Link | Threading |
---|---|---|---|
link=static,shared threading=single,multi | 1 | static | single |
2 | static | multiple | |
3 | shared | single | |
4 | shared | multiple |
构建和安装 Boost
准备好 Boost 源代码并设置环境后,用户就可以开始从 mybuild 目录构建和安装 Boost 库。请参阅清单 7 了解有关的命令。
$ mkdir mybuild $ cd mybuild $ BOOST_ROOT=<path>/boost_1_59_0 $ export BOOST_ROOT $ mkdir <path>/boost_build $ BOOST_INSTALL=<path>/boost_install $ export BOOST_ INSTALL $ BOOST_BUILD=<path>/boost_build $ export BOOST_BUILD $ cd $BOOST_ROOT $ ./b2 install --prefix=$BOOST_ INSTALL --build-dir=$BOOST_BUILD -j8 -l1200 toolset=xlcpp variant=release target-os=linux -s OS=LINUX -d2 -a
命令 b2 install
执行一次配置检查,然后根据检查结果来构建和安装所有库。
与架构独立的文件(例如头文件)将安装在值 --prefix
指定的位置中由 --includedir
指定的子目录。如果没有提供相关选项,则使用默认值。
选项 | 默认值 | 描述 |
---|---|---|
--prefix=<PREFIX> | /usr/local | 指定安装独立于架构的文件的位置 |
--includedir=<HDRDIR> | <PREFIX>/include | 指定安装头文件的位置 |
在清单 7 中所示的例子中, --prefix
值是显式指定的位置 <path>/boost_install
。另外,因为命令行上缺少 --includedir
,所以会使用它的默认值 <PREFIX>/include
。因此,在这种情况下,Boost 的头文件将被复制到 <path>/boost_install/include
。
将根据相应的 JAM 配置文件来创建编译的库。然后将它们复制到值 --exec-prefix
规定的位置中由 --libdir
指定的子目录。如果没有这些选项,则使用默认值。
选项 | 默认值 | 描述 |
---|---|---|
--exec-prefix=<EPREFIX> | <PREFIX> | 指定安装独立于架构的文件的位置 |
--libdir=<DIR> | <EPREFIX>/lib | 指定安装库文件的位置 |
在清单 7 中所示的例子中, --exec-prefix
的值是默认值 <PREFIX>
,即 <path>/boost_install
,因为未显式指定该值。类似地,由于命令行上还缺少 --libdir
,所以将使用它的默认值 <EPREFIX>/lib
。相应地,这些库将安装在 <path>/boost_install/lib
中。
--build-dir=$BOOST_BUILD
属性规定必须在 $BOOST_BUILD 目录而不是分布树中执行构建。这在分布树位于只读位置时必不可少。
–j8
选项指定最多可并行运行 8 个命令。 –l1200
选项指示 Boost 构建引擎将在 1200 秒后超时。 –d2
选项启用调试级别 2,该级别会向标准输出显示运行的命令的所有动作文本。 toolset=xlcpp
属性告知构建引擎,将使用 IBM XL 编译器进行编译。 target-os
属性告诉构建引擎为 Linux 操作系统创建库。
因为绝大部分 Boost 库都只是头文件,所以在未优化的情况下,Boost 库的构建和安装相对较快。在更高的优化级别上,比如 –O2
和 –qipa
(过程间分析优化),编译 Boost 库可能会花更多的时间。
要向编译器传递更多选项,可以使用 cxxflags
、 cflags
或 linkflags
。例如,可以按照清单 8 中所示的方式,将 -qnoxlcompatmacros
选项传递给编译器。下一篇介绍 Boost 配置的进一步优化的文章将会讨论将额外选项传递给编译器的其他方式。
$ ./b2 install cxxflags="-qnoxlcompatmacros" cflags="-qnoxlcompatmacros" --prefix=$BOOST_ INSTALL --build-dir=$BOOST_BUILD -j8 -l1200 toolset=xlcpp variant=release target-os=linux -s OS=LINUX -d2 -a
显示要构建到 Boost 版本中的库名称
Boost 版本中的库数量在不同版本中可能有所不同。要显示所有要构建到某个 Boost 版本中的库的准确名称,可以使用 --show-libraries
选项调用 b2
。
$ BOOST_ROOT/b2 --show-libraries The following libraries require building: - atomic - chrono - container - context < … >
使用此选项获取的库的准确名称将与其他选项一起使用,比如 --
with-<library>
和 --without-<library>
。这些选项将在下一节介绍。
仅构建和安装特定的库
仅使用 install
命令调用时,Boost 构建引擎 b2
将构建和安装项目中包含的所有库。要规定只构建某些库,用户可以使用 --with-<library>
命令行选项。通过此选项调用时,Boost 构建引擎 b2
仍将安装所有头文件,但只会构建以下两组中的库:
例如,以下调用规定将只构建 chrono
库。尽管未指定 system
库,但仍然构建了它,因为显式指定的库 chrono
需要它。
$BOOST_ROOT/bjam install --with-chrono -j4 -l1200 toolset=xlcpp variant=release target-os=linux -s OS=LINUX -d2 -a
图 4 表明显式库 chrono 和隐式库 system, 均已构建。
排除特定的库
不需要某些库时,用户可以使用选项 --without-<library>
告知 b2
这一事实。但是请注意,如果其他某个库需要指定的库,仍会构建它。例如,因为 chrono
库需要 system
库,所以即使没有显式提到要构建 system
库,仍会创建它作为 chrono
库的隐式库。
$BOOST_ROOT/bjam install --without-system -j4 -l1200 toolset=xlcpp variant=release target-os=linux -s OS=LINUX -d2 -a
从 1.59.0 版开始,Boost 支持用于 IBM XL 编译器的 xlcpp 工具集。使用 b2/bjam
和 xlcpp 工具集构建 Boost 库很简单,尤其是在项目允许使用补丁文件来修改 Boost 头文件和 JAM 配置文件时。在不适合使用补丁文件的情况下,或者在不容易获取补丁文件时,需要完成更多工作才能构建 Boost 库。
本文介绍了在正确修补 Boost 头文件和 JAM 配置文件后,从 Boost 源代码构建和安装 Boost 库的基本过程。后续的一篇文章将会进一步介绍如何自定义 Boost 配置来轻松构建 Boost 库,甚至在不允许使用补丁文件时也能实现此操作。
感谢 Nha-Vy Tran 女士在创作本文期间提供的意见和建议。