Visual Studioで単一のプロジェクト内に同名のソース・ファイルが含まれていてもビルドが通るようにする方法
以下のコードはVisual Studio 2013のデフォルト設定ではエラーとなる。
// ./a/func.hpp void func_a(); // ./b/func.hpp void func_b(); // ./a/func.cpp #include <iostream> #include "func_a.hpp" void func_a() { cout << "a" << endl; } // ./b/func.cpp #include <iostream> #include "func_b.hpp" void func_b() { cout << "b" << endl; } // ./main.cpp #include "./a/func.hpp" #include "./b/func.hpp" int main() { func_a(); func_b(); return 0; }
原因は、./a/func.cpp
と./b/func.cpp
から生成される.obj
ファイルが競合するためである。Visual Studio側の挙動については、以下の記事が詳しい。
Visual Studio 2008では同名のソースファイルを扱うことが出来ない件 - How to disappear completely
http://d.hatena.ne.jp/heisseswasser/20110602/1307014324
結論から先に書きますと、Visual Studio 2008では同名のソースがプロジェクトに含まれていると、どれかコンパイルされるかはファイルの更新日時に依存するようです。
...
一番古いファイルがビルドの対象となるようです。
また、上記の記事からリンクされている記事に、以下のような記述がある。
同名.cppファイルの自動解決は出来ないのか
https://social.msdn.microsoft.com/Forums/ja-JP/3c4e0904-d0ff-4f72-b619-6703f87e03f0/cpp?forum=vcexpressja
②ほかの設定法がある(たとえばプロジェクト→プロパティ→C/C++→出力ファイルに入れるべき適切なマクロが存在する)
以下のように設定することで、生成される.obj
ファイルが競合せず、ビルドが通るようになる。
- ソリューションエクスプローラーからプロジェクトを選択
プロジェクト(p)
->プロパティ(p)
->構成プロパティ
->C/C++
->出力ファイル
を開くASM リストの場所
及びオブジェクト ファイル名
を$(IntDir)
から$(IntDir)%(RelativeDir)
に変更する
上記のようにすることで、Visual Studioが各.cpp
ファイルをコンパイルする過程で、先にコンパイルされたファイルが後でコンパイルされたファイルに上書きされる事が無くなる。各.cpp
ファイルから生成される.obj
ファイルは、元の.cpp
ファイルの相対パスを保持したディレクトリに出力される。
デフォルト設定では、相対パスを無視して、ファイル名のみ保持するため、各.cpp
ファイルをコンパイルする過程で、ファイル名が衝突すると先にコンパイルされたファイルが後でコンパイルされたファイルに上書きされてしまう。