Boost 库裁剪及其应用

转载自个人博客:Boost 库裁剪及其应用html


STL 全称“标准模板库(Standard Template Library)”,其实它是一套标准,可能有不一样的实现,它是 C++ 的“标准库”。Boost 则是一个 C++ 库,被称为“C++ 准标准库”。linux

Boost 库涵盖的范围极广,有字符串和文本处理相关子库好比 format 库和 regexp 库,有容器相关子库好比 variant 库(和 Qt 的 QVariant 有得一拼),有迭代器子库好比 tokenizer 库(能够把字符进行 tokenize),还有算法、函数对象和高阶编程相关子库如
functional 库、lambda 库和 signal 库,还有泛型编程、模板编程子库如 call traits、mpl,还有并发编程相关的 thread 库,等等等等。git

Boost 是如此强大,毫无疑问它也很大。Windows 上安装 boost 须要占用 2G+ 的空间,编译配置起来也十分麻烦。github

本文讨论的是如何不配置 boost 库而使用 boost 库。算法

解决方案用一句话说就是:编程

裁剪 boost 库,并在项目中内嵌 boost 源码,使项目脱离对 boost 库的依赖。小程序

一个例子说明 boost 库裁剪的意义

或许你仍是不明白 boost 库裁剪究竟是啥意思,那咱们一块儿来跑一个例子。以个人 cmake-templates 里面的一个 boost 代码为例,源码只有一个 main.cpp,里面只有以下几行:segmentfault

#include <cstdio>
#include <boost/date_time/posix_time/posix_time_types.hpp>

int main( void  )
{
    namespace pt = boost::posix_time;
    pt::ptime now = pt::second_clock::local_time();

    printf( "%s\t->\t%04d-%02d-%02d %02d:%02d:%02d\n"
          , "date '+%Y-%m-%d %H:%M:%S'"
          , (int)now.date().year()
          , (int)now.date().month()
          , (int)now.date().day()
          , (int)now.time_of_day().hours()
          , (int)now.time_of_day().minutes()
          , (int)now.time_of_day().seconds() );

    return 0;
}

程序运行输出大概是:windows

date '+%Y-%m-%d %H:%M:%S'        ->        2016-07-11 19:33:19

这 20 行不到的代码,展现了 Linux 系统下一个经常使用指令 date 输出当前时间的效果(至关于命令行下输入 date '+%Y-%m-%d %H:%M:%S')。bash

若是你的系统配置了 Boost,那就到上面的连接下载源码,进入 boost 文件夹,这里一共有三个文件:一个 main.cpp、一个 CMakeLists.txt,一个 README 说明文档。若是你不知道如何使用 CMake 生成 VS 工程,能够先看我之前写的教程:HOWTO: Win + CMake + Visual Studio 2010 · Issue #1 · district10/cmake-templates

但要运行这个程序并不容易,尤为是在一切都要手工的 Windows 系统上:你必须本身去下载合适的 boost 版本,设定一些环境变量。
在 Linux 下则比较简单,只要三步(先下载源码,并 cd 到源码目录):

sudo apt-get install -y libboost-all-dev cmake
mkdir build && cd build
cmake .. && make && ./BOOST

你不由感慨,为了运行一个 20 行不到的小程序,竟然要手工安装两三个 G 的 boost 库!

这时候 boost 库的裁剪,就显得尤其重要了。咱们不但愿拿到代码的人还要费时间去配置 boost 库,咱们也不但愿本身的代码要十分当心地,才能跑起来。咱们要让本身的代码不论什么状况都能迅速地跑起来!下面咱们来看看刚才那 20 行代码,加上裁剪过的 boost 库源码,一块儿“发行”的效果:district10/bcp-example-1: An exmaple to show how to use bcp.

咱们裁剪后的 boost 库,头文件大概有 3.18 MB,cpp 文件有两个约 11 KB。看上去挺大,可是压缩完其实就 213 KB!拿到这份代码,首先解压 include.zip 到当前文件夹,而后运行 cmake 生成 VS 工程(或者 Linux 上的 makefile 工程),而后编译、运行。彻底不须要再管那烦心的 boost 库的配置了!

我想你必定能把这个程序跑起来的。不管你用什么操做系统,用什么编译器。

运行起来更省心,这就是 boost 库裁剪的意义。

我要怎么裁剪出本身须要的部分?

咱们来深究一下怎么拿到上面那 3.18 MB 的头文件,11 KB 的 cpp 文件。

首先,下载 Boost 库源码,你能够去 官网,也能够用个人备份:http://whudoc.qiniudn.com/2016/boost_1_58_0_headers_sources.7z(37.6 MB)。咱们只须要官方 release 的源码里的 boostlibs 文件夹下的东西,因此我建议你下载个人备份。由于它真的小不少,下载起来也很快。并且里面还打包了用于提取 boost 源码的工具 bcp1

而后,解压下载到的压缩包,进入源码文件夹,新建一个文件夹,好比叫 output,而后在当前窗口打开命令行,输入 ./bcp.exe boost/date_time/posix_time/posix_time_types.hpp output,这里 "./bcp.exe" 是咱们的裁剪工具,"boost/date_time/posix_time/posix_time_types.hpp" 是咱们本身项目中用到的 boost 头文件,若是有多个头文件,用空格隔开,把它们都敲进命令行。2最后的 "output" 是输出文件夹。

在 cmake 里,这个过程大概是 1)在源码根目录新建 include 文件夹,在根目录的 CMakeLists.txt 加上 include_directories( ${CMAKE_SOURCE_DIR} );2)新建 libs 文件夹,把裁剪出来的 cpp 文件放到这个文件下的 MiniBoost 文件加下,而后参考 district10/bcp-example-1/libs 写好 CMakeLists 文件,再到根目录的 CMakeLists 文件加上 add_subdirectory( libs);3)将裁剪出来的 miniboost 连接到咱们的二进制:target_link_libraries( ${PROJECT_NAME} MiniBoost )

你能够仔细对比看看连接系统安装的 Boost 库和使用自带的裁剪后的 Boost 库(我把它称为 MiniBoost)二者的区别和联系,再一次,咱们源码连接贴在这里:

哦对,一个须要注意的地方是,提取出来的头文件里,boost/config/auto_link.hpp 里的内容最好删掉,否则在 Windows 平台上,boost 会尝试自动连接。因此我一般把这个文件内容清空。

更多的实践

上面那只是一个很小的例子。下面是裁剪 boost 库的实际应用,这里我举两个有意思的例子。

第一个叫 kaguya,是一个 lua 脚本语言的 C++ 绑定。这个库颇有意思的是,若是你的编译器支持 C++11 的几个特定特性,它是不依赖于 boost 库的(但依赖了 lua 库);若是你的编译器对 C++11 特性支持得不够,它就用 boost 库来作补充。

我 fork 了这个 repo,先给它把 lua 源码打包了进去,这样你就不用安装、编译、配置 lua 也能运行 kaguya 了,又把 boost 库打包内嵌进去,这样,你也没必要要本身配置 boost 库,或者使用一个支持 C++11 的编译器了(对于 windows 系统来讲,也就是你用 VS2010,VS2013 就能够,没必要要安装 VS2015)。

这是个人 fork 的 standalone 分支:4ker/kaguya at standalone。相信你必定能很快把它跑起来。

第二个叫 bcp,就是咱们用来裁剪 boost 的工具。Boost 源码里有 bcp 这个工具的源码,可是编译起来真是巨麻烦!官方的源码在这里 boostorg/bcp: Boost.org bcp module,你试试能跑起来吗?

这是我修改后的源码:district10/cmake-bcp: Build Boost bcp via CMake/CMakeLists.txt,很容易就能运行起来。里面有说明文档(其实就是先 cmakemake)和一些其余说明。

用 bcp 来生成一个单独的(standalone)bcp 源码,生成 bcp。是否是和编译器 “自举” 的概念不谋而合?~


refs and see also


  1. 打包里包含一个 Windows x64 二进制 bcp.exe,一个 Linux x64 二进制 bcp_standalone_linux,若是你的系统是 32 位,或者是别的操做系统什么的。你就要本身去编译 bcp 二进制。源码在 [district10/cmake-bcp: Build Boost bcp
  2. 我建议你写一个脚本文件。很快,output 文件夹下出现了 boost 文件夹和 libs 文件夹。前者是提取出来的头文件,后者是出来的 cpp 文件。把这些文件集成到本身的项目中就能够了。集成进来后,咱们的源码应当能 include 那些提取出来的头文件,咱们的二进制应当可以连接那些提取出来的 cpp 文件生成的库文件(或者和咱们的 cpp 文件一块儿编译二进制,也能够)。
相关文章
相关标签/搜索