Boost.Test コンパイル時間の短縮

Boost.Testのコンパイル時間の短縮方法


Boost.Testは便利なフレームワークですが、いかんせんコンパイル時間がかなり悪化します。

例えば以下のコードをclang++でコンパイルした場合のコンパイル時間は自分の環境でおおよそ2秒弱です

#include <iostream>
#include <boost/format.hpp>

using namespace std;

int max(int a, int b) {
  return a > b ? a : b;
}

int main() {
  int a = -2, b = 3;
  cout << boost::format("max(%d, %d) = %d\n") % a % b % max(a, b);
  
  return 0;
}

これが、Boost.Test向けに以下のコードに変更してコンパイルすると、コンパイル時間は20秒以上に増加します。さすがにこれは厳しいです。開発効率にも大きな影響を及ぼしそうです

#include <iostream>
#include <boost/format.hpp>

#define BOOST_TEST_MODULE test_max
#include <boost/test/included/unit_test.hpp>

using namespace std;

int max(int a, int b) {
  return a > b ? a : b;
}

BOOST_AUTO_TEST_CASE(test_max) {
  BOOST_TEST(max(-2, 3) == 3);
}

このスレッドによるとコンパイルに時間がかかる要因は<boost/test/included/unit_test.hpp>のインクルード部分とのことなので、この部分を分離したソース (ex. boost_test_main.cc)を準備して.oファイルまでコンパイルしておきます。そして実際のテストコードでは上記の代わりに<boost/test/unit_test.hpp>をインクルードします。

boost_test_main.cc
#define BOOST_TEST_MODULE test_main
#include <boost/test/included/unit_test.hpp>
boost_test_max.cc
#include <iostream>
#include <boost/format.hpp>

#include <boost/test/unit_test.hpp>  // 違いはここだけ

using namespace std;

int max(int a, int b) {
  return a > b ? a : b;
}

BOOST_AUTO_TEST_CASE(test_max) {
  BOOST_TEST(max(-2, 3) == 3);
}

boost_test_main.ccはほぼ変更することはないため、一度のコンパイルでよく、boost_test_max.ccのコンパイルとリンクはほぼもとのプログラムと同程度の時間となりました。

% clang++ -O2 boost_test_main.cc -c -o boost_test_main.o  # これは時間がかかるが一度のみ
% clang++ -O2 boost_test_max.cc boost_test_main.o -o boost_test_max # こちらは高速

おすすめ