TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

BoostでZlib Filtersを有効にしてビルドする

C++で、gzipの圧縮解凍を標準ストリームで行いたかったので、ライブラリを調べたところ、Boost.IostreamsZlib Filtersを追加することで対応できることがわかった。

しかし、Windowsではデフォルトでは有効になっておらず、「conda install -c conda-forge boost」のビルド済みパッケージにも含まれていない。
そのため、ソースからビルドする必要がある。

この記事では、zlibを有効にいsてビルドする方法について記す。

Windows

boostダウンロード

boostをダウンロードする。
https://www.boost.org/

適当な場所に解凍する(以下、boost_1_75_0をC:\に解凍したとして記述する)。

zlibのソースダウンロード

zlibのソースをダウンロードする。
https://zlib.net/

適当な場所に解凍する(以下、zlib-1.2.11をC:\に解凍したとして記述する)。

boostビルド

b2コマンドの引数「-s ZLIB_SOURCE=」にソースのパスを指定してビルドする。
以下は、staticリンクライブラリをビルドする例。

cd boost_1_75_0
bootstrap
b2 toolset=msvc threading=multi variant=debug,release link=static runtime-link=static address-model=64 --stagedir=stage/x64 -j 8 -s ZLIB_SOURCE="C:\zlib-1.2.11"

なお、Boost.Pythonを有効にするには、ビルド前に「C:\Users\\user-config.jam」に、以下のように記述しておく。

using python : 3.8 : C:\\Users\\kei\\anaconda3\\python ;

マニュアルには、user-config.jamにuse zlibの記述が必要なように書かれているが、必要なかった。

Ubuntu 18.04

Linuxではデフォルトでzlibが有効になっている。

conda install boost

でインストールしたboostで使用できる。
libboost_iostreamsに含まれるので、libboost_zlib相当は必要ない。

コード例
#include <iostream>
#include <fstream>

#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/filter/gzip.hpp>

int main() {
	std::ifstream ifs("a.gz", std::ifstream::binary);
	if (!ifs) return 1;

	boost::iostreams::filtering_streambuf<boost::iostreams::input> filter;
	filter.push(boost::iostreams::gzip_decompressor());
	filter.push(ifs);

	std::istream stream(&filter);
	char buf[256];
	stream.read(buf, sizeof(buf));

	for (size_t i = 0; i < sizeof(buf); ++i) {
		std::cout << std::hex << (unsigned int)(unsigned char)buf[i] << " ";
	}
	std::cout << std::endl;
}
ビルド例
g++ -I$CONDA_PREFIX/include -L$CONDA_PREFIX/lib a.cpp -lboost_iostreams

のようにboost_iostreamsをリンクする。