Boost入门(linux)
Index
1 获取boost
获取 Boost 副本的最可靠方法是从SourceForge下载发行版:
-
在你想安装Boost 的目录中,执行
tar --bzip2 -xf /path/to/boost_1_76_0.tar.bz2
2 Boost 目录结构
这是生成的目录结构的草图:
boost_1_76_0/ .................The “boost root directory”
index.htm .........A copy of www.boost.org starts here
boost/ .........................All Boost Header files
`` ``
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
头文件组织
Boost 库头文件的组织并不完全统一,但大多数库都遵循一些模式:
-
一些较旧的库和大多数非常小的库将所有公共头文件直接放入boost /。
-
大多数库的公共头文件都位于boost /的子目录中 ,以库的名字命名。例如,您将在以下位置找到 Python 库的def.hpp标头
boost/python/def.hpp.
-
一些库在boost /中有一个“聚合头文件” , #include包含该库的所有其他头文件。例如,Boost.Python的聚合头文件是
boost/python.hpp.
-
大多数库将私有头文件放在名为detail /或aux_ /的子目录中 。不要指望在这些目录中找到任何可以使用的东西。
请务必注意以下几点:
-
boost 根目录(通常为/usr/local/ boost_1_76_0)的路径有时在文档和邮件列表中称为$BOOST_ROOT。
-
为了编译依赖boost的项目,需要需要在引用目录中加上这样一个目录:boost/子目录所在的目录。
-
由于所有 Boost 的头文件都具有.hpp扩展名,并且位于boost 根目录的boost /子目录中,因此您的 Boost #include指令将如下所示:
#include <boost/whatever.hpp>
或者
#include "boost/whatever.hpp"
这取决于您的偏好。
-
不要被doc /子目录迷惑:它只包含 Boost 文档的一个子集。如果您向从整体上了解boost,请从libs / index.html开始 。
3 仅包含头文件的库
许多人想知道的第一件事是,“我如何构建 Boost?” 好消息是,通常情况下,没有什么可构建的。
没有什么可构建的?
大多数 Boost 库都是头文件:它们完全由包含模板和内联函数的头文件组成,并且在链接时不需要单独编译的库二进制文件或特殊处理。
必须单独构建的唯一 Boost 库是:
- Boost.Chrono
- Boost.Context
- Boost.Filesystem
- Boost.GraphParallel
- Boost.IOStreams
- Boost.Locale
- Boost.Log(参见构建文档)
- Boost.MPI
- Boost.ProgramOptions
- Boost.Python( 在构建和安装之前请参阅Boost.Python 构建文档)
- Boost.Regex
- Boost.Serialization
- Boost.Thread
- Boost.Timer
- Boost.Wave
一些库具有可选的单独编译的二进制文件:
- Boost.Graph还有一个二进制组件,只有在您打算解析 GraphViz 文件时才需要它。
- Boost.Math具有用于 TR1 和 C99 cmath 函数的二进制组件。
- Boost.Random有一个二进制组件,只有在您使用random_device时才需要。
- Boost.Test可以在“header-only”或“separatelycompiled”模式下使用,尽管建议在认真使用时单独编译。
- 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 将每个数字乘以 3,然后将它们写入标准输出:
#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的文件中。
现在,在您保存example.cpp的目录中,执行以下命令:
c++ -I path/to/boost_1_76_0 example.cpp -o example
要测试结果,请输入:
echo 1 2 3 | ./example
5 使用Boost二进制库的准备
如果要使用任何单独编译的 Boost 库,则需要获取库二进制文件。
5.1 简单构建和安装
在 shell 中输入以下命令(不要键入$;$代表 shell 的提示符):
$ cd path/to/boost_1_76_0
$ ./bootstrap.sh --help
选择您的配置选项并在没有--help选项的情况下再次调用./bootstrap.sh。除非您在系统的/usr/local/目录中具有写权限,否则您可能至少需要使用
$ ./bootstrap.sh --prefix=path/to/installation/prefix
安装在其他地方。此外,请考虑使用 --show-libraries和--with-libraries= library-name-list选项来限制您在构建所有内容时遇到的长时间等待。最后,
$ ./b2 install
会将 Boost 二进制文件留在安装目录prefix的lib/子目录中。您还将在安装目录prefix的include/子目录中找到 Boost 头文件的副本,因此您以后可以使用该目录作为#include 路径来代替 Boost 根目录。
5.2 定制化构建
如果您使用的是系统默认编译器以外的编译器,则需要使用Boost.Build来创建二进制文件。
如果您需要非标准的构建版本,您也将使用此方法(有关更多详细信息,请参阅 Boost.Build 文档)。
5.2.1 安装 Boost.Build
Boost.Build是一个基于文本的系统,用于开发、测试和安装软件。首先,您需要构建并安装它。步骤如下:
- 转到目录tools / build /。
- 运行bootstrap.sh
- 运行b2 install --prefix= PREFIX其中PREFIX是您希望安装 Boost.Build 的目录
- 将PREFIX / bin添加到您的 PATH 环境变量中。
5.2.2 确定你的编译工具
首先,在下表中找到与您的编译器相对应的工具集(Boost.Build 文档中始终提供最新列表)。
提示:
如果您之前选择了一个工具集来 构建 b2,您应该假设它不起作用,而是从下表中选择新的。
工具集名称 | 厂商 | 提示 |
---|---|---|
acc | HP | 已知只有最近的版本才能很好地与 Boost 配合使用 |
borland | Borland | |
como | Comeau Computing | 使用此工具集可能需要配置另一个工具集作为其后端。 |
darwin | Apple Computer | Apple 版本的 GCC 工具链,支持 Darwin 和 MacOS X 功能,例如框架。 |
gcc | The Gnu Project | 包括对 Cygwin 和 MinGW 编译器的支持。 |
hp_cxx | HP | 针对 Tru64 操作系统。 |
intel | intel | |
msvc | Microsoft | |
sun | Oracle | 已知只有最近的版本才能很好地与 Boost 配合使用。请注意,Oracle/Sun 编译器具有大量影响二进制兼容性的选项:使用您的应用程序将使用的相同选项构建库至关重要。特别要注意,默认标准库可能不适用于 Boost,除非您是为 C++11 构建的。您需要的特定编译器选项可以通过 b2 命令行选项 cxxflags=`` 和``linkflags= 注入。例如,在 C++03 模式下使用 Apache 标准库构建使用 b2 cxxflags=-library=stdcxx4 linkflags=-library=stdcxx4。 |
vacpp | IBM | VisualAge C++ 编译器。 |
如果您安装了特定编译器的多个版本,您可以将版本号附加到工具集名称,前面有一个连字符,例如intel-9.0或 borland-5.4.3。````
5.2.3 选择构建目录
Boost.Build将把它在构建时生成的所有中间文件放到构建目录中。如果您的 Boost 根目录是可写的,则这一步不是绝对必要的:默认情况下,Boost.Build 将在您当前的工作目录中为此创建一个bin.v2/子目录。
5.2.4 调用b2
切换到 Boost 根目录并调用b2,如下所示:
b2 --build-dir=build-directory toolset=toolset-name `` `` stage
有关这些和其他调用选项的完整说明,请参阅Boost.Build 文档。
例如,您的操作可能如下所示:
$ cd ~/boost_1_76_0
$ b2 --build-dir=/tmp/build-boost toolset=gcc stage
这将构建库的静态和共享的非调试多线程版本。要构建所有版本,请加上附加选项“ --build-type=complete ”。
特殊构建目标stage 将 Boost 库二进制文件放置在 Boost 目录的stage / lib /子目录中。要使用不同的目录,请将 --stagedir=directory选项传递 给b2。
说明
b2区分大小写;重要的是上面以粗体显示的所有部分都完全小写。
有关调用b2时可以传递的其他选项的说明 ,请输入:
b2 --help
特别是,为了缩短构建所花费的时间,您可能对以下内容感兴趣:
- 使用--show-libraries查看库名称列表
- 使用--with- library-name或--without- library-name选项限制构建哪些库
- 通过向命令行添加release 或 debug 来选择特定的构建版本。
说明
Boost.Build 可以产生大量输出,这很容易遗漏构建过程中输出的问题。如果您想确保一切顺利,您可以通过将“ >build.log 2>&1 ”附加到您的命令行来将输出重定向到一个文件中。
5.3 预期的构建输出
在构建 Boost 库的过程中,您可能会看到一些消息打印在控制台上。这些可能包括
-
关于 Boost 库配置的注意事项——例如,Regex 库在没有 Unicode 支持的情况下构建时会输出一条关于 ICU 的消息,如果您没有安装 Python,则可能会跳过 Python 库而不会出错(但有一个通知)。
-
来自构建工具的消息,报告构建或跳过的目标数量。如果这些数字对您没有任何意义,请不要感到惊讶;每个库有很多目标。
-
构建描述工具正在执行的操作的操作消息,如下所示:
toolset-name.c++ long/path/to/file/being/built
-
编译器警告。
5.4 构建错误的情况
在构建Boost(如果有的话)时,您看到的唯一错误消息应该与IOStreams库对zip和bzip2格式的支持有关,如本文所述。如果需要这些特性,请安装libz和libbz2的相关开发包。构建Boost库时的其他错误也值得关注。
如果构建系统似乎找不到您的编译器和/或链接器,请考虑按照此处所述设置user-config.jam文件 。如果这不是您的问题,或者user-config.jam文件对您不起作用,请将有关为您的编译器配置 Boost 的问题发送到Boost 用户的邮件列表。
6 将您的程序链接到 Boost 库
为了演示与 Boost 二进制库的链接,我们将使用以下简单程序从电子邮件中提取主题行。它使用Boost.Regex库,该库具有单独编译的二进制组件。
#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
std::string line;
boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );
while (std::cin)
{
std::getline(std::cin, line);
boost::smatch matches;
if (boost::regex_match(line, matches, pat))
std::cout << matches[2] << std::endl;
}
}
与链接相关的主要挑战有两个:
- 工具配置,例如选择命令行选项或 IDE 构建设置。
- 在所有构建版本中识别库二进制文件,其编译配置与项目的其余部分兼容。
链接到库有两种主要方式:
-
您可以指定每个库的完整路径:
$ c++ -I path/to/boost_1_76_0 example.cpp -o example \ ~/boost/stage/lib/libboost_regex-gcc34-mt-d-1_36.a
-
您可以分别指定要搜索的目录(使用-L directory)和要搜索的库名称(使用-l library,不包括库文件名的前缀 lib和 后缀(在本例中为.a):
$ c++ -I path/to/boost_1_76_0 example.cpp -o example \ -L~/boost/stage/lib/ -lboost_regex-gcc34-mt-d-1_36
如您所见,此方法与方法 A 编译一个库一样简洁;当您使用同一目录中的多个库时,它真的很划算。但是请注意,如果您将此方法与同时具有静态 ( .a ) 和动态 ( .so ) 构建的库一起使用,系统可能会自动为您选择一个,除非您在命令中传递一个特殊选项,例如 -static。
6.1 库命名规则
为了为您的构建配置选择正确的二进制文件,您需要知道 Boost 二进制文件的命名方式。每个库文件名由描述其构建方式的一串通用元素组成。例如, libboost_regex-vc71-mt-d-x86-1_34.lib可以分解为以下元素:
lib
前缀:除了在 Microsoft Windows 上,每个 Boost 库名称都以此字符串开头。在 Windows 上,只有普通的静态库使用lib前缀;导入库和 DLL 没有。4
boost_regex
库名:所有 boost 库文件名都以boost_ 开头。
-vc71
工具集标签:标识用于构建二进制文件的工具集和版本。
-mt
Threading 标签:表示该库是在启用多线程支持的情况下构建的。可以通过缺少-mt来识别在没有多线程支持的情况下构建的库。
-d
ABI 标签:编译特性,影响库与其他编译代码互操作性。对于每个这样的特性,标签中都会添加一个字符:
钥匙 在以下情况下使用此库: Boost.Build 选项 s 静态链接到 C++ 标准库和编译器运行时库。 运行时链接=静态 g 使用标准和运行时库的调试版本。 运行时调试=on y 使用Python的特殊调试版本。 蟒蛇调试=开 d 构建代码的调试版本。 变体=调试 p 使用 STLPort 标准库而不是编译器提供的默认库。 标准库=stlport
例如,如果您构建代码的调试版本以与静态运行时库和 STLPort 标准库的调试版本一起使用,则标记将为:-sgdp。如果以上都不适用,则省略 ABI 标记。
-x86
架构和地址模型标签:在第一个字母中,将架构编码如下:
key 架构 Boost.Build 选项 x x86-32, x86-64 architecture=x86 a ARM architecture=arm i IA-64 architecture=ia64 s Sparc architecture=sparc m MIPS/SGI architecture=mips p RS/6000 和 PowerPC architecture=power
字母后面的两位数字对地址模型进行如下编码:
key address mode Boost.Build 选项 32 32位 address-model=32 64 64位 address-model=64
-1_34
版本标签:完整的 Boost 版本号,用下划线代替句点。例如,版本 1.31.1 将被标记为“-1_31_1”。
.lib
扩展名:根据操作系统的通常约定确定。在大多数 Unix 风格的平台上,静态库(存档)和共享库的扩展名分别是 .a和.so。在 Windows 上,.dll表示共享库,.lib表示静态或导入库。在 unix 变体上的工具集支持的情况下,将添加完整版本扩展名(例如“.so.1.34”),并且还将创建指向库文件的符号链接,名称不带尾随版本号。
6.2 测试你的程序
为了测试我们的 主题提取程序,我们将过滤以下文本文件。将其从浏览器中复制并保存为jayne.txt:
To: George Shmidlap
From: Rita Marlowe
Subject: Will Success Spoil Rock Hunter?
---
See subject.
如果您链接到共享库,您可能需要准备一些特定于平台的设置,以便系统能够在您的程序运行时找到并加载它。大多数平台都有一个环境变量,您可以向其中添加包含库的目录。在许多平台(Linux、FreeBSD)上,该变量是 LD_LIBRARY_PATH,但在 MacOS 上它是DYLD_LIBRARY_PATH,而在 Cygwin 上它只是PATH。在除csh 和tcsh之外的大多数 shell 中,您可以按如下方式调整变量(同样,不要键入$ — 代表 shell 提示符):
$ VARIABLE_NAME=path/to/lib/directory:${VARIABLE_NAME}
$ export VARIABLE_NAME
在csh和tcsh 上,它是
$ setenv VARIABLE_NAME path/to/lib/directory:${VARIABLE_NAME}
设置必要的变量(如果有)后,您可以按如下方式运行程序:
$ path/to/compiled/example < path/to/jayne.txt
该程序应以电子邮件主题进行回复,“成功会破坏岩石猎人吗?”
7 结论和更多资源
您对 Boost 的介绍以及将其与您的程序集成到此结束。当您开始认真地使用 Boost 时,您肯定希望我们已经涵盖了一些额外的要点。有一天,我们可能会有一本“入门系列中的第 2 册”来解决这些问题。在此之前,我们建议您使用以下资源。如果您找不到您需要的内容,或者我们可以做任何事情来使此文档更清晰,请将其发布到Boost 用户的邮件列表。
一往无前
祝好运, 玩得开心!
— Boost 开发人员