1.4.3 高级议题
本节讨论关于Boost编译的一些高级议题。
Boost库的命名规则
Boost库的文件名遵循的规则十分清晰明了,基本形式如下:
- libboost_filesystem-vc80-mt-sgdp-1_51.lib
前缀 :统一为lib,但在Windows下只有静态库有lib前缀;
库名称:以"boost_"开头的库名称,在这里是boost_filesystem;
编译器标识:编译该库文件的编译器名称和版本,在这里是-vc80;
多线程标识:支持多线程使用-mt,没有表示不支持多线程;
ABI标识:这个标识比较复杂,标识了Boost库的几个编译链接选项;
s : 静态库标识
gd : debug版标识
p : 使用STLport而不是编译器自带STL实现
版本号:Boost库的版本号,小数点用下画线代替,在这里是1_51;
扩展名:在Windows上是.lib,在Linux等类UNIX操作系统上是.a或者.so。
对于Clang、GCC等编译器,在链接Boost程序库时可以有两种方式:一种是在编译命令行直接指明库文件全路径,另一种是用-L指定库文件所在路径,再用-l指定库文件名。
Boost库在VC编译器下支持库自动链接技术(使用#pragma comment(lib, XXX)),只要把所有生成的lib拷贝到VC的搜索路径下,不需要你费心,编译器会自动根据编译选项找到合适的库链接成可执行文件。
部分编译Boost
完整编译Boost费时费力,而且这些库并不可能在开发过程中全部用到,因此,b2也允许用户自行选择要编译的库。
执行"b2 --show-libraries",可查看所有必须编译才能使用的库。在完全编译命令的基础上,使用--with或者--without选项可打开或者关闭某个库的编译,如:
- ./b2 --with-date_time --buildtype=complete stage
将仅编译date_time库。
b2还有其他很多选项,如指定安装路径、指定debug或release版等。对b2的进一步介绍已经超出了本书的范围,读者可使用--help选项或者参考Boost文档以获得更多信息,本书不再叙述。
- unity build
编译库的方法使用Boost费时费力,有时还要面临链接的烦恼。本书推荐使用作者自行实践的另一种方式:unity build--把Boost源代码嵌入到自己的工程中编译。
这种方法的原理类似VC的预编译技术,在工程中直接包含Boost库的cpp文件,不但可以省略库的编译步骤,而且源代码还获得了独立于编译器、操作系统和Boost库版本的好处(任何一个因素发生变化时都不需要换编译器重新编译库),能够增强程序的可移植性。
不过这种方法也有小小的代价,就是每个工程都要重新编译Boost库,不如前两种方式那样可以(暂时的)"一劳永逸",但作者认为其平台无关的优点还是大于缺点。在其后的章节里会向读者示范这种嵌入工程编译的方式如何具体实现,这里暂举一个小例子:
- /// sysprebuild.cpp 一个嵌入编译源代码文件
- #define BOOST_SYSTEM_NO_LIB //禁用Boost的自动链接功能
- #include <libs/system/src/error_code.cpp> //包含嵌入编译源代码
以上代码实现了boost.system库的嵌入编译,读者只需要将该文件(sysprebuild.cpp)加入到工程(或者makefile)中,无须使用b2预先编译库就能享用Boost带来的好处。即使将来Boost程序库更新版本,也只需要简单地重新编译工程即可使用新版的功能,而无需耗费大量时间去重新编译链接Boost库。