我有一个较大的C ++项目,源文件组织在多个文件夹中(在文件系统上)。
在其中两个文件夹中,我有同名文件。 e.g。
\MyProject\foo\Blurp.cpp
\MyProject\foo\File.cpp
\MyProject\bar\File.cpp
\MyProject\bar\Knoll.cpp
该项目是跨平台的,我在linux和OSX上使用autoconf,但必须在W32上使用MSVC(由于我在W32上使用的一些第三方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建议的解决方案 - 为每个文件设置对象目录 - 这在理论上确实有效,但出于实际原因我想避免使用)
答案 0 :(得分:13)
也许您可以设置项目范围内的对象文件名' (Configurtion Properties-> C / C ++ - >输出文件)到
$(IntDir)%(RelativeDir)
使用源文件的相对源文件夹。请注意%
,但如果源文件位于项目目录之外,包含..\
答案 1 :(得分:9)
您可以为冲突的一个(或两个)文件设置文件特定的项目设置,并将“对象文件名”属性设置为:
$(InputDir)\$(IntDir)\
只需右键单击文件名而不是项目名称,即可设置该文件的属性。
例如,如果您为\MyProject\foo\File.cpp
执行此操作,则该源文件的目标文件将转到\MyProject\foo\Release\File.obj
,因此它不会与\MyProject\bar\File.cpp
的目标文件冲突。< / p>
这样做的缺点是它可能会使编译器输出混乱你的源代码树(但希望不会太多),而且 - 更糟糕的是 - 文件特定的项目设置往往会被遗忘/隐藏,因为它们不是完全在IDE中调用。如果有时候你(或其他人)需要改变一些东西,那么为什么构建对于特定文件的行为如此奇怪,直到有人用它旋转了半天,直到它突然发现它为止,这可能是一个谜。上。
我个人更喜欢项目范围的$(InputDir)\$(IntDir)\
设置会导致目标文件转到相对于源文件的目录,但它实际上并不能很好地作为项目级别设置。在这种情况下,VS仍然只设置输出目录一次,它最终相对于列表中的第一个源文件。然后链接器会对它应该在哪里查找目标文件感到困惑。
答案 2 :(得分:0)
使用
$(IntDir)%(Directory)
作为“目标文件路径”。
%(Directory)
包含文件的绝对路径,没有卷,也没有文件名本身。该解决方案至少应在VS 2019中运行,并且可以直接应用于项目。