Boost.Buildでは同名のオブジェクトファイルに対して1つルールしか許されない

次のエラーが出て、ハマったので残す。

現象

error: Name clash for '<pbin/gcc-5.4.0/debug>interpreter.o'
error: 
error: Tried to build the target twice, with property sets having 
error: these incompatible properties:
error: 
error:     -  none
error:     -  <include>/root <linkflags>-pthread
error: 
error: Please make sure to have consistent requirements for these 
error: properties everywhere in your project, especially for install
error: targets.

使っていたJamfileは次の通り(抜粋)。

exe main
        :
        main.cpp
        interpreter.cpp
        parser.cpp
        ;

unit-test interpreter_test
        :
        interpreter.cpp
        interpreter_test.cpp
        /gtestgmock
        :
        <include>/root/
        <linkflags>-pthread
        ;

原因

何が原因かというと、interpreter.cppがexe, unit-test両方で使われているが、unit-testの方でだけ

        <include>/root/
        <linkflags>-pthread

が指定されていることだった。Boost.Buildからするとinterpreter.oを作る時のビルドオプションがexeとunit-testとで一貫していないため、どっちを採用したらいいかわからんということらしい。

対策

結局、次の2通りの対策がある。

1) 同名のオブジェクトファイルに対しては常に同じビルドオプションを使う

obj a-obj : a.cpp : <include>/usr/local/include ;
exe a : a-obj ;
exe b : a-obj ;

2) オブジェクトファイル名を変えて異なるビルドオプションを使う

obj a_obj : a.cpp : <include>/usr/local/include ;
obj b_obj : a.cpp ;
exe a : a_obj ;
exe b : b_obj ;

参考

この問題がまさにBoost.BuildのFAQにあがっていたので、詳細はこちらを参照。 https://boostorg.github.io/build/manual/develop/index.html#bbv2.faq.duplicate

Boost.BuildのJamfileでboostライブラリをリンクする方法

たったそれだけなんだが、ググってもなかなかやり方がわからなかったので、書き残す。

コンパイルしたいmain.cpp

#include <boost/program_options.hpp>

int main(int ac, char* av[])
{
    namespace po = boost::program_options;

    // (略)

    return 0;
}

方法1

リンクするライブラリをフルパスで直に書く。

Jamroot.jam

exe main : main.cpp /usr/lib/i386-linux-gnu/libboost_program_options.so ;

方法2

リンクするライブラリをlibルールとして書く。

Jamroot.jam

lib boost_po : : <name>boost_program_options ;

exe main : main.cpp boost_po ;

方法3

リンクするライブラリをlibルールに書き、project全体でリンクさせる。

Jamroot.jam

lib boost_po : : <name>boost_program_options ;

project 
    : requirements
        <library>boost_po
        ;

exe main : main.cpp ;

参考

Boost.Build tutorial

http://www.boost.org/build/doc/html/bbv2/tasks/libraries.html

http://www.boost.org/build/doc/html/index.html

Boost.Build の簡単な使い方 (TDDしてみる)