Boost C++ 库

世界上备受推崇且设计精湛的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Boost 在 Windows 上的入门指南 - Boost C++ 函数库

在 Windows 上的入门指南

CygwinMinGW 用户的一则说明

如果您计划从 Windows 命令提示符使用这些工具,那么您来对了地方。如果您计划从 Cygwin bash shell 构建,那么您实际上是在一个 POSIX 平台上运行,应该遵循 在 Unix 变体上入门 的说明。其他命令行 shell,例如 MinGW 的 MSYS,不受支持—它们可能可用,也可能不可用。

1   获取 Boost

获取 Boost 的最可靠方法是下载 boost_1_82_0.7zboost_1_82_0.zip 并解压到安装完整的 Boost 发行版。1

2   Boost 发行版

这是由此产生的目录结构的草图

boost_1_82_0\ .................The “boost root directory”
   index.htm .........A copy of www.boost.org starts here
   boost\ .........................All Boost Header files
   lib\ .....................precompiled library binaries
   libs\ ............Tests, .cpps, docs, etc., by library
     index.html ........Library documentation starts here
     algorithm\
     any\
     array\
                     …more libraries…
   status\ .........................Boost-wide test suite
   tools\ ...........Utilities, e.g. Boost.Build, quickbook, bcp
   more\ ..........................Policy documents, etc.
   doc\ ...............A subset of all Boost library docs

请务必注意以下事项

  1. 指向Boost 根目录的路径(通常是C:\Program Files\boost\boost_1_82_0)在文档和邮件列表中有时被称为$BOOST_ROOT

  2. 要编译 Boost 中的任何内容,您需要在您的boost\路径中包含#include路径。在 Microsoft Visual Studio 中设置的#include路径的具体步骤将在本文档稍后介绍;如果您使用其他 IDE,请咨询您的产品文档以获取说明。

  3. 由于 Boost 的所有头文件都具有.hpp扩展名,并且位于 Boost 根目录的boost\子目录中,您的 Boost#include指令将如下所示

    #include <boost/whatever.hpp>
    

    #include "boost/whatever.hpp"
    

    取决于您对使用尖括号包含的偏好。即使是 Windows 用户也可以(并且,出于可移植性原因,可能应该)在#include指令中使用正斜杠;您的编译器并不在意。

  4. 不要被doc\子目录所迷惑;它只包含 Boost 文档的子集。如果您要查找完整的文档,请从libs\index.html开始。

3   仅标头文件库

许多人首先想知道的是:“我如何构建 Boost?” 好消息是,通常情况下,没有什么需要构建的。

无需构建?

大多数 Boost 库都是仅标头文件的:它们完全由包含模板和内联函数的标头文件组成,不需要单独编译的库二进制文件或链接时的特殊处理。

唯一必须单独构建的 Boost 库是

少数库有可选的单独编译的二进制文件

  • Boost.Graph 还有一个二进制组件,仅在您打算 解析 GraphViz 文件时才需要。
  • Boost.Math 包含 TR1 和 C99 cmath 函数的二进制组件。
  • Boost.Random 有一个二进制组件,仅在您使用random_device.
  • 时才需要。Boost.Test 可以以“仅标头文件”或“单独编译”模式使用,尽管对于严肃的使用,建议单独编译
  • Boost.Exception 为 32 位 _MSC_VER==1310 和 _MSC_VER==1400 提供了非侵入式 exception_ptr 实现,这需要一个单独编译的二进制文件。这通过 #define BOOST_ENABLE_NON_INTRUSIVE_EXCEPTION_PTR 启用。
  • Boost.System 自 Boost 1.69 起为仅标头文件。仍然会构建一个存根库以实现兼容性,但不再需要链接到它。

4   使用 Boost 构建简单程序

为了保持简单,让我们从使用一个仅标头文件库开始。以下程序从标准输入读取一系列整数,使用 Boost.Lambda 将每个数字乘以三,并将它们写入标准输出

#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

int main()
{
    using namespace boost::lambda;
    typedef std::istream_iterator<int> in;

    std::for_each(
        in(std::cin), in(), std::cout << (_1 * 3) << " " );
}

将此程序的文本复制到一个名为example.cpp.

注意

要构建本指南中的示例,您可以使用 Visual Studio 等集成开发环境 (IDE),或者从 命令提示符 发出命令。由于每个 IDE 和编译器都有不同的选项,并且 Microsoft 的编译器是 Windows 上占主导地位的编译器,因此我们仅在此为 Visual Studio 2005 和 .NET 2003 IDE 及其各自的命令提示符编译器提供具体说明(使用命令提示符会更简单一些)。如果您使用的是其他编译器或 IDE,应该很容易将这些说明改编到您的环境中。

4.1   从 Visual Studio IDE 构建

  • 从 Visual Studio 的 *文件* 菜单中,选择 *新建* > *项目…*

  • 在弹出的 *新建项目* 对话框的左窗格中,选择 *Visual C++* > *Win32*。

  • 在右窗格中,选择 *Win32 控制台应用程序* (VS8.0) 或 *Win32 控制台项目* (VS7.1)。

  • 在 *名称* 字段中,输入“example”

  • 在 *解决方案资源管理器* 窗格中右键单击 **example**,然后从弹出的菜单中选择 *属性*

  • 在 *配置属性* > *C/C++* > *常规* > *附加包含目录* 中,输入 Boost 根目录的路径,例如

    C:\Program Files\boost\boost_1_82_0

  • 在 *配置属性* > *C/C++* > *预编译头* 中,将 *使用预编译头 (/Yu)* 更改为 *不使用预编译头*。2

  • 替换 IDE 生成的example.cpp中的内容为上面的示例代码。

  • 从 *生成* 菜单中,选择 *生成解决方案*。

要测试您的应用程序,请按 F5 键,然后在出现的窗口中键入以下内容,然后按 Return 键

1 2 3

然后按住 Control 键并按“Z”,然后按 Return 键。

跳到下一步

4.2   或者,从命令提示符构建

从您计算机的 *开始* 菜单中,如果您是 Visual Studio 2005 用户,请选择

*所有程序* > *Microsoft Visual Studio 2005* > *Visual Studio 工具* > *Visual Studio 2005 命令提示符*

或者,如果您是 Visual Studio .NET 2003 用户,请选择

*所有程序* > *Microsoft Visual Studio .NET 2003* > *Visual Studio .NET 工具* > *Visual Studio .NET 2003 命令提示符*

来启动一个特殊的 命令提示符 窗口,该窗口已为 Visual Studio 编译器进行了设置。在该窗口中,将 当前目录 设置到适合创建一些临时文件的位置,然后键入以下命令并按 Return 键

cl /EHsc /I path\to\boost_1_82_0 path\to\example.cpp

要测试结果,请键入

echo 1 2 3 | example

4.3   错误和警告

如果您看到源自 Boost 头文件的编译器警告,请不要惊慌。我们试图消除它们,但这并非总是可行的。4 **错误则是另一回事**。如果您在此教程阶段看到编译错误,请检查您是否正确复制了 示例程序,并且您是否正确识别了 Boost 根目录

5   准备使用 Boost 库二进制文件

如果您想使用任何单独编译的 Boost 库,您需要获取库的二进制文件。

5.1   从源代码简化构建

如果您希望使用 Visual C++ 从源代码构建,您可以使用本节中描述的简单构建过程。打开命令提示符并将当前目录更改为 Boost 根目录。然后,键入以下命令

bootstrap
.\b2

第一个命令为使用 Boost.Build 系统做准备。第二个命令调用 Boost.Build 来构建单独编译的 Boost 库。有关允许选项的列表,请参阅 Boost.Build 文档

5.2   或者,从源代码构建二进制文件

如果您使用的是早期版本的 Visual C++ 或其他供应商的编译器,您将需要使用 Boost.Build 来创建您自己的二进制文件。

5.2.1   安装 Boost.Build

Boost.Build 是一个用于开发、测试和安装软件的基于文本的系统。首先,您需要构建并安装它。要做到这一点

  1. 转到目录tools\build\.
  2. 运行bootstrap.bat
  3. 运行b2 install --prefix=PREFIX,其中PREFIX是您希望 Boost.Build 安装到的目录
  4. PREFIX添加到您的 PATH 环境变量中。\bin首先,在以下表中找到与您的编译器对应的工具集(始终可以在Boost.Build 文档中找到最新列表)。

5.2.2   确定您的工具集

如果您先前为构建 b2 的目的选择了一个工具集,您应该假设它不起作用,而是从下表中重新选择。

注意

工具集名称

供应商 acc 注意
Hewlett Packard 只有非常近期的版本已知能与 Boost 良好配合 borland
Borland como  
Comeau Computing 使用此工具集可能需要配置另一个工具集作为其后端。 darwin
Apple Computer Apple 的 GCC 工具链版本,支持 Darwin 和 MacOS X 功能(如框架)。 GNU 项目
gcc 包括对 Cygwin 和 MinGW 编译器的支持。 hp_cxx
针对 Tru64 操作系统。 只有非常近期的版本已知能与 Boost 良好配合 intel
Intel msvc  
Microsoft Oracle  
sun 只有非常近期的版本已知能与 Boost 良好配合。请注意,Oracle/Sun 编译器有大量的选项会影响二进制兼容性:库必须使用与您的应用程序将使用的相同选项构建,这一点至关重要。特别是要意识到默认的标准库可能与 Boost 工作不佳,除非您正在为 C++11 构建。您需要的特定编译器选项可以通过 b2 命令行选项注入 只有非常新的版本才能很好地与 Boost 一起使用。请注意,Oracle/Sun 编译器有许多影响二进制兼容性的选项:至关重要的是,库的构建必须与您的应用程序将使用的选项相同。特别是要注意,默认的标准库可能与 Boost 工作不佳,*除非您正在为 C++11 构建*。您需要的特定编译器选项可以通过 b2 命令行选项注入。例如,要使用 Apache 标准库以 C++03 模式构建,请使用b2 cxxflags=-library=stdcxx4 linkflags=-library=stdcxx4vacpp.
IBM VisualAge C++ 编译器。 如果您安装了同一编译器的多个版本,您可以将版本号附加到工具集名称后,前面加上连字符,例如

intel-9.0borland-5.4.3在 Windows 上,即使您只有一个编译器版本,也要附加版本号(除非您使用 msvc 或 gcc 工具集,它们有特殊的版本检测代码),否则自动链接将失败。。 **在 Windows 上,即使您只安装了一个版本,也要附加一个版本号**(除非您使用的是 msvc 或 gcc 工具集,它们具有特殊的版本检测代码),否则 自动链接 将失败。

5.2.3   选择构建目录

Boost.Build 将在构建过程中生成的所有中间文件放置在 **构建目录** 中。如果您的 Boost 根目录是可写的,此步骤不是必需的:默认情况下,Boost.Build 将创建一个子目录用于此目的。将当前目录更改为 Boost 根目录,然后调用

5.2.4   调用b2

如下b2有关这些和其他调用选项的完整描述,请参阅Boost.Build 文档

b2 --build-dir=build-directory toolset=toolset-name --build-type=complete stage

例如,您的会话可能如下所示:3

例如,您的会话可能看起来像这样:3

C:\WINDOWS> cd C:\Program Files\boost\boost_1_82_0
C:\Program Files\boost\boost_1_82_0> b2 ^
More? --build-dir="C:\Documents and Settings\dave\build-boost" ^
More? --build-type=complete msvc stage

请务必阅读 这则说明,了解^, 更多?以及该行中的引号(")。

选项“**--build-type=complete**”使 Boost.Build 构建所有支持的库变体。有关如何仅构建特定变体的说明,请在 Boost 用户邮件列表 上提问。

目标会将 Boost 库的二进制文件放置在 Boost 树的lib子目录中。要使用不同的目录,请将lib\--stagedir=\directory 选项传递给对大小写敏感;确保所有上面用粗体显示的单词都全部小写很重要。有关调用b2.

注意

b2时可以传递的其他选项的描述,请键入

特别是,为了限制构建所花费的时间,您可能对b2通过

b2 --help

--show-libraries

  • 查看库名称列表通过
  • --with-library-name--without-library-name 选项限制要构建的库通过在命令行中添加
  • 来选择特定的构建变体。releasedebugBoost.Build 会产生大量的输出,这可能很容易让人忽略问题。如果您想确保一切顺利,可以将输出重定向到一个文件,方法是在命令行末尾添加“

注意

>build.log 2>&1”。在构建 Boost 库的过程中,您可能会在控制台上看到一些消息。这些消息可能包括

5.3   预期的构建输出

关于 Boost 库配置的通知—例如,Regex 库在未构建 Unicode 支持时会输出关于 ICU 的消息,如果未安装 Python,Python 库可能会被跳过而不会报错(但会附带通知)。

  • 构建工具报告已构建或已跳过的目标数量的消息。如果这些数字对您没有意义,请不要感到惊讶;每个库都有许多目标。

  • 描述工具正在做什么的构建操作消息,看起来像

  • 编译器警告。

    toolset-name.c++ long/path/to/file/being/built
    
  • 在构建 Boost 库时您可能看到的唯一错误消息(如果有)应该与 IOStreams 库对 zip 和 bzip2 格式的支持有关,如此处所述。如果您需要这些功能,请安装 libz 和 libbz2 的相应开发包。构建 Boost 库时出现其他错误则需要引起关注。

5.4   在构建错误的情况下

当您构建 Boost 时看到的唯一错误消息(如果有)应该与 IOStreams 库对 zip 和 bzip2 格式的支持有关,如 此处所述。如果您需要这些功能,请安装 libz 和 libbz2 的相关开发包。构建 Boost 库时出现的其他错误则应引起担忧。

user-config.jam文件,如此处所述。如果这不是您的问题,或者该文件对您不起作用,请将关于为您的编译器配置 Boost 的问题提交给Boost 用户邮件列表文件,如此处所述。如果这不是您的问题,或者该为了演示链接到一个 Boost 二进制库,我们将使用以下简单的程序,该程序从电子邮件中提取主题行。它使用了Boost.Regex 库,该库有一个单独编译的二进制组件。

7   结论和进一步的资源

这标志着您对 Boost 以及如何将其集成到您的程序中的介绍的结束。当您开始认真使用 Boost 时,肯定会有一些额外的问题您希望我们已经涵盖。有一天我们可能会有一个“入门系列丛书第二卷”来解决它们。在此之前,我们建议您查阅以下资源。如果您找不到所需内容,或者有什么我们可以让本文档更清晰的地方,请发布到 Boost 用户邮件列表

继续前进

祝您好运,玩得开心!

—Boost 开发者

[1]我们推荐下载 boost_1_82_0.7z 并使用 7-Zip 来解压缩它。我们不再推荐 .zip 文件用于 Boost,因为它们的大小是等效 .7z 文件的两倍。我们也不建议使用 Windows 内置的解压缩功能,因为它对于大型压缩文件可能非常缓慢。
[2]使用预编译头文件与 Boost 一起使用没有问题;本指南只是避免使用预编译头文件,因为它需要对示例中使用的源代码进行 Visual Studio 特定的更改。
[3]

在此示例中,插入符号字符^是一种将命令继续到多行的方式,并且必须是继续行的 **最后一个字符**(即,不要在其后跟空格)。命令提示符会响应更多?以提示更多输入。您可以随意省略插入符号和后续的换行符;我们使用它们是为了让示例能适合合理的页面宽度。

命令提示符将命令中的每个空格视为参数分隔符。这意味着每当单个命令行参数包含空格时,都需要使用引号(")将文本组合在一起,例如

--build-dir="C:\Documents_and_Settings\dave\build-boost"

同样,例如,您不能在=符号周围添加空格,例如

--build-dir_=_"C:\Documents and Settings\dave\build-boost"
[4]请记住,警告特定于每个编译器实现。给定 Boost 库的开发人员可能无法访问您的编译器。此外,一些警告极难在通用代码中消除,以至于不值得费心。最后,一些编译器没有任何抑制警告的源代码机制。
[5]此约定区分了 Boost 库的静态版本与具有相同配置的 Boost DLL 的导入库,否则它们将具有相同的名称。
[6]这些库在没有优化或内联的情况下编译,启用了完整的调试符号,并且没有NDEBUG #defined。尽管有时这些选择确实不会影响与其他编译代码的二进制兼容性,但您不能指望 Boost 库也会如此。