Проект VisualStudio с несколькими исходными файлами с тем же именем?

У меня есть довольно большой проект на С++, с исходными файлами, организованными в нескольких папках (в файловой системе).

в двух из этих папок, у меня есть файлы с тем же именем. например.

\MyProject\foo\Blurp.cpp
\MyProject\foo\File.cpp
\MyProject\bar\File.cpp
\MyProject\bar\Knoll.cpp

проект является кросс-платформой, и я использую autoconf для linux и OSX, но мне нужно использовать MSVC на W32 (из-за некоторых сторонних библиотек С++, которые я использую для W32 и несовместимости бинарного интерфейса С++ для компиляторов)

на стороне MSVC, проект организован также в несколько "Фильтров" (эти виртуальные папки) (с именами, примерно соответствующими каталогам, в которых живут файлы), поэтому я могу их отличить.

теперь проблема в том, что когда я строю проект, MSVC помещает объектные файлы в один плоский каталог, и я получаю:

\MyProject\Release\Blurp.obj
\MyProject\Release\File.obj
\MyProject\Release\Knoll.obj

как видно, существует только один File.obj, поэтому отсутствует один двоичный объект. очевидно, компоновщик жалуется, поскольку он не может найти классы/функции/... определенные в этом отсутствующем объектном файле.

есть ли способ сообщить MSVC о создании объектных файлов с уникальным именем в зависимости от каталогов (или фильтров), в которых находятся эти файлы?

Я представляю себе что-то вроде:

\MyProject\Release\foo\Blurp.obj
\MyProject\Release\foo\File.obj
\MyProject\Release\bar\File.obj
\MyProject\Release\bar\Knoll.obj

или

\MyProject\Release\foo-Blurp.obj
...

или что угодно. все другие системы сборки, которые я знаю (CMake, autotools), могут обрабатывать несколько файлов с тем же именем.

этот вопрос похож на 3729515, но в настоящее время я придерживаюсь VS2008. (решение, предлагаемое для VS2008 - для установки Object-Directory для каждого файла, о котором идет речь, - это то, что действительно работает теоретически, но которое я бы хотел избежать по практическим соображениям)

Ответ 1

Вы можете установить параметр проекта для конкретного файла (или обоих) файлов, которые конфликтуют, и установить для свойства "Имя файла объекта":

$(InputDir)\$(IntDir)\

Просто щелкните имя файла вместо имени проекта, чтобы установить свойство только для этого файла.

Например, если вы сделаете это для \MyProject\foo\File.cpp, то объектный файл для этого исходного файла перейдет к \MyProject\foo\Release\File.obj, чтобы он не конфликтует с объектным файлом для \MyProject\bar\File.cpp.

Недостатки этого в том, что он может помешать вашему исходному дереву с выходами компилятора (но, надеюсь, их не так уж много), и, что еще хуже, параметры проекта, зависящие от файла, как правило, забываются/скрыты, поскольку они не вызывается в среде IDE. Если когда-нибудь по дороге вам (или кому-то еще) нужно что-то изменить, может быть довольно загадочной мысль о том, почему сборка действует так странно для определенных файлов, пока кто-то не закручивается с ней на полдня, пока не наступит вопрос о том, что происходит на.

Я лично предпочел бы, чтобы общесистемный параметр $(InputDir)\$(IntDir)\ заставлял файлы объектов обращаться к каталогам по отношению к исходному файлу, но на самом деле он совсем не работает как настройка уровня проекта. В этом случае VS по-прежнему только устанавливает выходной каталог один раз и заканчивается тем, что он относится к первому исходному файлу в списке. Тогда компоновщик путается о том, где он должен искать объектные файлы.

Ответ 2

Возможно, вы можете установить широкоэкранное имя объекта объекта (свойства Configurtion- > C/С++ → Output Files) на

$(IntDir)%(RelativeDir)

который использует относительную исходную папку исходных файлов. Обратите внимание на %, но это становится уродливым, если исходные файлы находятся вне каталога вашего проекта, содержащего ..\