Clang でプリコンパイル済みヘッダーを使う

Clnag でプリコンパイル済みヘッダーを使ってみたので覚書。

[プリコンパイル済みヘッダーを生成]

まず、プリコンパイルしたヘッダーファイルを用意します。

// header.h
// とりあえず、重そうな標準ライブラリを列挙
#include <iostream>
#include <vector>
#include <map>
#include <regex>
#include <tuple>
#include <regex>
#include <string>
#include <type_traits>
#include <functional>
#include <memory>
#include <sstream>
#include <algorithm>
#include <thread>

あとは普通にコンパイルするようにしてプリコンパイル済みヘッダーを生成します。

$ clang++ -std=c++1z -x c++-header header.h -o header.h.pch

これにより header.h.pch というプリコンパイル済みヘッダーが生成されます。 コンパイルオプションは -std=c++1z みたいに通常のコンパイルと同じように指定できます。 同様に Boost などの任意のインクルードパスを設定したい場合は -I を使用します。

$ clang++ -std=c++1z -I/path/to/boost_1_61_0 -x c++-header header.h -o header.h.pch

[プリコンパイル済みヘッダーを使う]

生成したプリコンパイル済みヘッダーは次ように -include とヘッダーファイルを指定して使用します。

$ clang++ -std=c++1z -include header.h main.cpp -o main

また、プリコンパイル済みヘッダーを直接指定することも出来ます。

$ clang++ -std=c++1z -include-pch header.h.pch main.cpp -o main

[プリコンパイル済みヘッダーを使うときの注意]

-std= の指定がプリコンパイル時とコンパイル時で異なるとエラーになるので注意してください。

$ clang++ -std=c++1y -include-pch header.h.pch main.cpp -o main
error: C++1z was enabled in PCH file but is currently disabled
1 error generated.

[パフォーマンスの違い]

$ time clang++ -std=c++1z -include-pch header.h.pch main.cpp -o main

real    0m0.159s
user    0m0.116s
sys 0m0.037s
$ time clang++ -std=c++1z main.cpp -o main

real    0m0.916s
user    0m0.847s
sys 0m0.054s

こんな感じでコンパイル時間が約 1/7 ぐらいになりました。
便利そう。

[参照]