10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++ Boostライブラリ(filesystem etc.)をWindows用(MinGW用、Visual Studio用)にビルドする

Last updated at Posted at 2016-08-27

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をインストールした環境で試したところすんなりといきました。

  1. Visual Studio 2015をインストール

  2. Boostをダウンロード&展開

  3. Boostのディレクトリで以下のコマンドを実行
    32bit版

    $ bootstrap.bat
    $ b2.exe --address-model=32 --with-filesystem
    

    64bit版

    $ bootstrap.bat
    $ b2.exe --address-model=64 --with-filesystem
    
  4. stage\libにライブラリ完成

MinGWのg++用にビルドしてみる

BoostのfilesystemライブラリをMinGWのg++用にビルドしてみます。
こちらは、Visual Studioのようにすんなりとはいきませんでした。
ネットで検索しましたが、情報が錯綜。以下、こんな感じでうまくいった人がいる、程度の参考にしてください。

  • gcc 5.3.0-2 (MinGW)をインストールする
  • Boost 1.61.0のソースをビルドしてライブラリを作成する

以下のような段階を踏みました。

  1. gccをMinGW Installation ManagerでMinGWのBasicSetupとしてインストール。
  2. .\bootstrap.batでb2.exe(Boost.Build engine)を作成。
  3. b2.exe(Boost.Build engine)でBoostのライブラリをg++でコンパイル&ビルド。

Boostのライブラリをg++でビルドする手順

filesystemライブラリをビルドしてみます。

  1. MinGWのインストール
    MinGWでgccをインストールしておき、インストールしたg++にPATHを通しておきます。
    g++がインストールされるPATHは[MinGW Innstall Dir]/binになります。
    PATHは今回インストールしたg++がPCにインストールされている他のg++よりも先になるように設定してください。
    PATHは空白を含まないディレクトリにしてください。

  2. Boost ver.1.61.0をダウンロード
    http://www.boost.org/users/download/#live
    からboost_1_61_0.zipをダウンロードします。サイズは、約152MBです。

  3. Boostの配置
    ダウンロードしたboost_1_61_0.zipを展開します。
    サイズは、約563MBです。
    他のディレクトリにインストールする場合は空白を含まないディレクトリにしてください。
    今回は以下に展開しました。

    C:\dev\boost\boost_1_61_0

  4. コマンドプロンプトでBoostのディレクトリに移動します。

    $ cd C:\dev\boost\boost_1_61_0

  5. b2.exe(Boost.Build engine)の作成

    $ .\bootstrap.bat
    $ .\bootstrap.bat gcc

  6. コンパイル&ビルド

    $ .\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
      可能な限りすべての組み合わせのビルドが実行されます。

ビルド対象を個々に指定することができます。

  • --toolset
    ビルドを実行するツールセットを指定します。
    例)--toolset=gcc
  • --variant
    • debug
      デバッグ用のビルドを実行します。
    • release
      リリース用のビルドを実行します。
  • --link
    • static
      staticリンク用としてビルドします。
    • shared
      sharedライブラリ用としてビルドします。
  • --threading
    • single
      シングルスレッド用としてビルドします
    • multi
      マルチスレッド用としてビルドします
  • --runtime-link
    • static
      staticなC/C++のランタイムにリンクします。
    • shared
      sharedなC/C++のランタイムにリンクします。

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>
    特定のライブラリをビルド&インストール対象からはずします。
    このオプションを指定しない場合のデフォルト値は全てのライブラリのビルド&インストールです。

参考情報

10
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?