13

我有一个较大的 C++ 项目,源文件组织在多个文件夹中(在文件系统上)。

在其中两个文件夹中,我有同名的文件。例如

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

该项目是跨平台的,我在 linux 和 OSX 上使用 autoconf,但必须在 W32 上使用 MSVC(由于我在 W32 上使用的一些第 3 方 C++ 库以及跨编译器的 C++ 二进制接口不兼容)

在 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 建议的解决方案 - 为每个有问题的文件设置对象目录 - 在理论上确实有效,但出于实际原因我想避免)

4

3 回答 3

18

也许您可以将项目范围的“对象文件名”(配置属性->C/C++->输出文件)设置为

$(IntDir)%(RelativeDir)

它使用源文件的相对源文件夹。注意%, 但是如果你的源文件位于你的项目目录之外,这会变得很难看,包含..\

于 2014-04-08T11:54:08.457 回答
11

您可以为冲突的一个(或两个)文件设置特定于文件的项目设置,并将“对象文件名”属性设置为:

$(InputDir)\$(IntDir)\

只需右键单击文件名而不是项目名称即可仅为该文件设置属性。

例如,如果您这样做,\MyProject\foo\File.cpp则该源文件的目标文件将转到,\MyProject\foo\Release\File.obj因此它不会与\MyProject\bar\File.cpp.

这样做的缺点是它可能会使您的源代码树与编译器输出混淆(但希望不会太多),而且 - 更糟糕的是 - 特定于文件的项目设置往往会被遗忘/隐藏,因为它们没有被调用IDE。如果某个时候你(或其他人)需要改变一些东西,那么为什么构建对于特定文件的行为如此奇怪,直到有人用它搞砸了半天,直到他们明白发生了什么,这可能是一个谜在。

我个人更喜欢项目范围的设置$(InputDir)\$(IntDir)\会导致目标文件转到相对于源文件的目录,但实际上它作为项目级别设置根本无法正常工作。在那种情况下,VS 仍然只设置一次输出目录,它最终相对于列表中的第一个源文件。然后链接器对它应该在哪里查找目标文件感到困惑。

于 2013-01-17T07:01:00.000 回答
0

采用

$(IntDir)%(Directory)

作为“对象文件路径”。

%(Directory)包含没有卷和文件名本身的文件的绝对路径。该解决方案至少应该在 VS 2019 中工作,并且可以直接应用于项目。

于 2019-12-09T19:39:37.707 回答