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