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 文件一塊兒編譯二進制,也能夠)。
相關文章
相關標籤/搜索