Boostとは
BoostとはC++のライブラリです。
C++の次の標準機能を実装検討の実験場になっていて、Boostで検討された機能がC++の標準機能に取り込まれます。沢山の機能がC++11, C++14に取り入れられ、現在は、C++17の機能の実装検討をしています。
また、複数のプラットフォーム、複数のコンパイラで動作するようになっているため、Boostのライブラリを使うことで、複数のプラットフォームで動作するプログラムを作ることができます。
Boostのライブラリを利用したプログラムは、以下のメリットがあります。
- C++で標準化されていないライブラリを使うことができる。
- プログラムを次世代のC++標準に移植するのが容易。
- プログラムを異なるプラットフォームに移植するのが容易。
- プラットフォーム依存を処理する
#ifdef
が減りテストが容易。
大部分は、ヘッダーオンリーで利用することができますが、一部分はビルドが必要です。
Boost ver.1.61.0では以下のようになっています。
- ライブラリ全体:108
- ヘッダオンリーなライブラリ:83
- ビルドするライブラリ:25
ビルドするライブラリ一覧
ライブラリ名 | C++11 | 備考 |
---|---|---|
atomic | ○ | |
chrono | ○ |
BOOST_CHRONO_HEADER_ONLY をdefineすればヘッダオンリーで使用可能 |
container | △ | |
context | ||
coroutine | ||
date_time | posix timeのみを使用する場合は、BOOST_DATE_TIME_NO_LIB をdefineすればヘッダオンリーで使用可能 |
|
exception | △ | |
filesystem | 時刻処理が入らなければ、Chronoは不要。 | |
graph | GraphMLを使用しなければヘッダオンリー | |
iostreams | ||
locale | ||
log | ||
math | △ | |
program_options | ||
python | ||
random | ○ |
random_device を使用しない場合、ヘッダオンリーで使用可能。 |
regex | ○ | |
serialization | ||
signals | ||
system | ||
test | ||
thread | ○ | |
timer | ||
type_erasure | ||
wave |
Boostライブラリのいくつかは、C++11, C++14に取り込まれています。C++11, C++14をサポートしたコンパイラを使っている場合は、C++標準の利用を選択してください。
Boost → C++11 の対応をまとめたサイト
http://boostjp.github.io/tips/cxx11-boost-mapping.html
C++17 filesystem
-
標準化
C++17では、ファイル/ディレクトリ操作に関する標準化作業を進めています。
https://isocpp.org/files/papers/P0218r1.html -
機能
主要な機能は以下のようになっています。- ファイルのコピー
- ファイルの削除
- ファイルの移動/ファイル名の変更
- ファイルが存在するかを調べる
- ファイルサイズを取得する
- ファイルの最終更新日時を取得する
- パスのファイル名を取得する
- パスの拡張子を取得する
- パスの拡張子を変更する
- ディレクトリを作成する
- ディレクトリ内のファイルを列挙する
- ディレクトリ内のすべてのファイルを再帰的に列挙する
- エラーハンドリング
-
利用方法
C++17でfilesystemが標準化されると次のように使えるようになります。#include <filesystem> namespace fs = std::filesystem;
-
実装状況
実装状況は以下のようになっています。-
Boost
Boost Filesystem Libraryが2003年~提供されています。
ライブラリのビルドが必要です。
プログラムで使用する際は、以下のようにします。#include <boost/filesystem.hpp> namespace fs = boost::filesystem;
歴史が長く、先行検討されていた一部のAPIには廃止になったものがあります。
過去のプログラムのコンパイルが通らない場合は、こちらが参考になります。
http://www.boost.org/doc/libs/1_61_0/libs/filesystem/doc/deprecated.html -
Microsoft
Visual C++ 2015から正式提供されています。
プログラムで使用する際は、以下のようにします。#include <filesystem> namespace fs = std::experimental::filesystem::v1;
Windowsのルートパス、文字列、ディレクトリ属性は、Posix標準とは異なります。
相違点は、こちらで解説されています。
https://msdn.microsoft.com/ja-jp/library/hh874694.aspx -
libstdc++
gcc-5.3から提供されています。
libstdc++fs.a
に含まれているため、-lstdc++fs
オプションを指定してg++でビルドします。
libstdc++はPOSIXベースの機能のみサポートしているため、Windowsファイルシステムでは基本的な部分のみ動作します。プログラムで使用する際は、以下のようにします。
#include <experimental/filesystem> namespace fs = std::experimental::filesystem::v1
リファレンスマニュアルは以下で公開されています。
-
-
サンプルプログラム
Boost 1.61.0 と Visual C++ 2015 でディレクトリ内のファイル名を出力してみます。Boost 1.61.0 のプログラム
boost.cpp#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const string directory = "dir"; fs::path p(directory); for (fs::directory_iterator next(p), end; next != end; ++next) { cout << next->path() << endl; } }
Visual C++ 2015 のプログラム
msvc.cpp#include <iostream> #include <filesystem> namespace fs = std::experimental::filesystem::v1; int main() { const string directory = "dir"; fs::path p(directory); for (fs::directory_iterator next(p), end; next != end; ++next) { cout << next->path() << endl; } }
includeとnamespaceは異なりますが、プログラムは共通です。
fs::path p(directory);
の部分では、pathクラスのインスタンスを
インスタンス名("文字列")
で作成しています。
directory_iteratorは、次のようになります。- 引数なしのコンストラクタ
イテレータを終端にセットしたインスタンスを生成します。 - 引数のあるコンストラクタ
引数で与えられたディレクトリにイテレータをセットします。 - 次の要素
++
オペレータで次の要素にイテレータを移動させます。
for文の
++
オペレータでイテレータを順次移動させ、イテレータが終端に達するまで処理を続けます。
- 引数なしのコンストラクタ
-
エラー出力の比較
Boost 1.61.0 と Visual C++ 2015 のfilesystemのエラー出力を比べてみます。
存在しないファイルのサイズを取得しようとしてみます。Boost 1.61.0 のプログラム
boost.cpp#include <iostream> #include <boost/filesystem.hpp> namespace fs = boost::filesystem; int main() { const fs::path file("abc.txt"); // 存在しないファイル try { fs::file_size(file); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
Boost 1.61.0 のエラー出力
boost::filesystem::file_size: 指定されたファイルが見つかりません。: "abc.txt"
Visual C++ 2015 のプログラム
msvc.cpp#include <iostream> #include <filesystem> namespace fs = std::experimental::filesystem::v1; int main() { const fs::path file("abc.txt"); // 存在しないファイル try { fs::file_size(file); } catch (fs::filesystem_error& ex) { std::cout << ex.what() << std::endl; throw; } }
Visual C++ 2015 のエラー出力
file_size(p): invalid argument: operation not permitted
歴史の差でしょうか、Boostのほうが分かりやすいエラーメッセージになっていました。
Visual Studio用にビルドしてみる
BoostのfilesystemライブラリをVisual Studio用にビルドしてみます。
Visual Studioをインストールした環境で試したところすんなりといきました。
-
Visual Studio 2015をインストール
-
Boostをダウンロード&展開
-
Boostのディレクトリで以下のコマンドを実行
32bit版$ bootstrap.bat $ b2.exe --address-model=32 --with-filesystem
64bit版
$ bootstrap.bat $ b2.exe --address-model=64 --with-filesystem
-
stage\lib
にライブラリ完成
MinGWのg++用にビルドしてみる
BoostのfilesystemライブラリをMinGWのg++用にビルドしてみます。
こちらは、Visual Studioのようにすんなりとはいきませんでした。
ネットで検索しましたが、情報が錯綜。以下、こんな感じでうまくいった人がいる、程度の参考にしてください。
- gcc 5.3.0-2 (MinGW)をインストールする
- Boost 1.61.0のソースをビルドしてライブラリを作成する
以下のような段階を踏みました。
- gccをMinGW Installation ManagerでMinGWのBasicSetupとしてインストール。
- .\bootstrap.batでb2.exe(Boost.Build engine)を作成。
- b2.exe(Boost.Build engine)でBoostのライブラリをg++でコンパイル&ビルド。
Boostのライブラリをg++でビルドする手順
filesystemライブラリをビルドしてみます。
-
MinGWのインストール
MinGWでgccをインストールしておき、インストールしたg++にPATHを通しておきます。
g++がインストールされるPATHは[MinGW Innstall Dir]/bin
になります。
PATHは今回インストールしたg++がPCにインストールされている他のg++よりも先になるように設定してください。
PATHは空白を含まないディレクトリにしてください。 -
Boost ver.1.61.0をダウンロード
http://www.boost.org/users/download/#live
からboost_1_61_0.zip
をダウンロードします。サイズは、約152MBです。 -
Boostの配置
ダウンロードしたboost_1_61_0.zip
を展開します。
サイズは、約563MBです。
他のディレクトリにインストールする場合は空白を含まないディレクトリにしてください。
今回は以下に展開しました。C:\dev\boost\boost_1_61_0
-
コマンドプロンプトでBoostのディレクトリに移動します。
$ cd C:\dev\boost\boost_1_61_0
-
b2.exe(Boost.Build engine)の作成
$ .\bootstrap.bat
$ .\bootstrap.bat gcc -
コンパイル&ビルド
$ .\b2.exe toolset=gcc --with-filesystem
コンパイル&ビルドが実行され、filesystemライブラリが
stage\lib
ディレクトリに生成されます。オプションを指定していないためデフォルト値が適用され設定は下記のようになっています。- gcc-mingw-5.3.0
- debug, release
- staticリンク
- マルチスレッド
ライブラリを
--with
で指定しないと、長時間のビルド、ファイルのコピーが始まり、以下がstage\lib
ディレクトリに生成されます。
atomic, chrono, container, context, coroutine, date_time, exception, filesystem, graph, iostreams, locale, log, math, program_options, python, random, regex, serialization, signals, system, test, thread, timer, type_erasure, wave
b2.exe(Boost.Build engine)のビルドオプション
ビルドの組み合わせを指定することができます。
- --build-type
- minimal
Windowsではデバッグ用とリリース用のstaticリンク用&マルチスレッド用のライブラリが生成されます。
--build-type
の指定を省略したときのデフォルト値です。 - complete
可能な限りすべての組み合わせのビルドが実行されます。
- minimal
ビルド対象を個々に指定することができます。
- --toolset
ビルドを実行するツールセットを指定します。
例)--toolset=gcc - --variant
- debug
デバッグ用のビルドを実行します。 - release
リリース用のビルドを実行します。
- debug
- --link
- static
staticリンク用としてビルドします。 - shared
sharedライブラリ用としてビルドします。
- static
- --threading
- single
シングルスレッド用としてビルドします - multi
マルチスレッド用としてビルドします
- single
- --runtime-link
- static
staticなC/C++のランタイムにリンクします。 - shared
sharedなC/C++のランタイムにリンクします。
- static
b2.exe(Boost.Build engine)のinstallオプション
- --prefix=<PREFIX>
アーキテクチャ非依存なファイルをインストールするディレクトリを指定します。
Windowsのデフォルト値:C:\Boost
Linuxのデフォルト値:/usr/local - --exec-prefix=<EPREFIX>
アーキテクチャ依存のファイルをインストールするディレクトリを指定します。
デフォルト値:<PREFIX> - --libdir=<DIR>
ここのライブラリがインストールされます。
デフォルト値:<EPREFIX>/lib - --includedir=<HDRDIR>
ここのヘッダーがインストールされます。
デフォルト値:<PREFIX>/include
b2.exe(Boost.Build engine)のstageオプション
- --stagedir=<STAGEDIR>
ライブラリをインストールするディレクトリを指定します。
デフォルト値:./stage
b2.exe(Boost.Build engine)の並列実行オプション
- -j [Num]
[Num]に並列実行させる数を指定します。
b2.exe(Boost.Build engine)の32bit/64bitオプション
- address-model=[N bit]
[N bit]に32または64を指定します。
b2.exe(Boost.Build engine)のその他オプション
- --with-<library>
特定のライブラリのみをビルド&インストールします。
複数のライブラリを指定したい場合は、--with-filesystem --with-system
のように列挙します。
このオプションを指定しない場合のデフォルト値は全てのライブラリのビルド&インストールです。 - --without-<library>
特定のライブラリをビルド&インストール対象からはずします。
このオプションを指定しない場合のデフォルト値は全てのライブラリのビルド&インストールです。
参考情報
- BoostのConfiguration
http://www.boost.org/build/doc/html/bbv2/overview/configuration.html - Boostとgccやmsvcの連携
http://www.boost.org/build/doc/html/bbv2/reference/tools.html - Boost日本語情報サイト
http://boostjp.github.io/howtobuild.html