c++ - 对于某些生成的项目,msbuild 将文件名解释为中文字符,而不是其他项目

标签 c++ visual-studio-2012 msbuild

我一直在为我们的软件堆栈开发跨平台构建系统。具体来说,我正在开发构建系统的 Windows 组件。

我们有许多项目,每个项目都有一个手工编码的 .vcxproj。有些项目相互依赖,有些则依赖于 Qt。

我的 .vcxproj 文件在我迄今为止尝试过的五个项目中的三个工作正常,但在另外两个项目上却以一种非常有趣的方式失败了:

project\dir> msbuild /p:Configuration=Release /p:PropertyA=C:\path\to\project\root\ /p:Platform=x64 obj\project.vcxproj
Microsoft (R) Build Engine version 4.0.30319.17929
[Microsoft .NET Framework, version 4.0.30319.18047]
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 16.07.2013 11:13:43.
Project "C:\path\to\project\root\obj\project.vcxproj" on node 1 (default targets).
PrepareForBuild:
  Creating directory "C:\path\to\project\root\obj\x64_Int\Release_DLL_Int\".
InitializeBuildStatus:
  Creating "C:\path\to\project\root\obj\x64_Int\Release_DLL_Int\project.unsuccessfulbuild" because "AlwaysCreate" was specified.
ClCompile:
  C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\AMD64\CL.exe /c /I"include path A" /I"include path B" /Zi /nologo /W3 /WX- /sdl /O2 /Oi /D NDEBUG /D _CRT_SECURE_NO_WARNINGS /D QT_CORE_LIB /D _WINDLL /D _MBCS /Gm- /EHsc /MD /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fo"C:\path\to\project\root\obj\x64_Int\Release_DLL_Int\\" /Fd"C:\path\to\project\root\obj\x64\\project.pdb" /Gd /TP /errorReport:queue
          /nologo

        src\main\cpp\source_a.cpp src\main\cpp\source_b.cpp src\main\cpp\source_c.cpp ...
  ????????????????????????????????????
c1xx : fatal error C1083: Cannot open source file: '????????????????????????????????????': No such file or directory [C:\path\to\project\root\obj\project.vcxproj]
  ????????????????????????????????
c1xx : fatal error C1083: Cannot open source file: '????????????????????????????????': No such file or directory [C:\path\to\project\root\obj\project.vcxproj]
...

对于每个源文件使用这些问号字符串之一,源文件路径中的每个字符一个问号。

这是在命令行上,但如果我在 Visual Studio (2012) 中打开项目,我可以看到字符的真实含义:

error C1083: Cannot open source file: '猀爀挀尀洀愀椀渀尀挀瀀瀀尀...⸀挀瀀瀀': No such file or directory
error C1083: Cannot open source file: '猀爀挀尀洀愀椀渀尀挀瀀瀀尀...⸀挀瀀瀀': No such file or directory
...

(抱歉,我省略了真实的文件名。)

文件名中的每个字符都已[一致]替换为中文字符。罗马字和汉字的关系是1:1替换的,即\ -> cpp -> 挀瀀瀀.

我已经用详细的诊断信息运行了 msbuild,但在这些错误消息之前的 12000 多行输出中,没有一个地方有中文字符——它在失败之前多次正确列出了源文件。

通过历史悠久的调试技术“随机注释掉一些东西”,我发现如果我手动编辑以某些方式失败的 vcxproj 文件,问题就会消失,但链接会失败,因为我已经注释掉了库路径或源文件。

在两个失败的项目中,删除 4-6 个源文件(随机地,尽管注释掉相同的四个文件总是有效或无效)将修复它。 在依赖 Qt 的版本中,删除 $(Q​​T5DIR)/include/QtCore 的路径可以解决问题,但由于找不到 Qt 而无法链接。

源文件都是 ASCII 编码的,并且在删除后解决问题的文件中似乎没有任何一致的格式。

我已经在三台不同的计算机上尝试过此操作,其中两台 Windows 7 计算机和一台 8.1 预览版。它在 8.1 上运行良好,但在两台 Win 7 计算机上都失败。

它似乎与项目中的文件数量无关,因为其中一个工作项目的文件数量远远多于任何一个非工作项目。

这似乎不是一个依赖问题,因为只有一个非工作依赖于 Qt,并且工作和非工作之间的共性似乎排除了项目间依赖。

我意识到这很明显,任何微软大师都知道发生了什么吗?

问题 1:我做错了什么?什么可能导致这种行为?

问题 2:关于如何继续追踪问题,有什么想法吗?

更新:

  • 如果我单独运行 ClCompile 行,它实际上会尝试编译所有内容,但找不到标准库。我认为这意味着在这种情况下不会发生这个问题。
  • 我在这里找到了我认为的解决方法:c1xx : fatal error C1083: Cannot open source file - with some Chinese or Javanese但我仍然希望有人能给出真正的解决方案。为什么会出现这种情况?为什么删除 .vcxproj 中看似随机的部分可以解决此问题?是否有编码检测启发式方法误解了我的路径?

最佳答案

我猜测存在文本格式错误。反斜杠的值为 U+005C,其转换为的字符的值为 U+5C00 (根据 http://www.scarfboy.com/coding/unicode-tool?s=U%2B5C00 )。同样的问题也适用于 cpp 中的“c”,我确信“p”也是如此。

我不太熟悉 MSVC 支持的文本编码,但我会首先查看编码并确保它们都是相同的,然后查看任何可能错误地转换文件的内容,例如程序它认为它是在 ANSI 文件而不是扩展编码上运行的。您可能会丢失一个字节,或者您的宽字符的字节顺序可能会翻转。

关于c++ - 对于某些生成的项目,msbuild 将文件名解释为中文字符,而不是其他项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17682278/

相关文章:

visual-studio - 如果我不是企业,如何获得 Visual Studio Express Desktop 2012 的产品 key ?

msbuild - 如何将 PropertyGroup/ItemGroup 中可变数量的项目传递给 msbuild 脚本

asp.net - 在构建服务器上不使用 Visual Studio 构建 ASP.NET 4.5

c++ - 程序不询问预期值的数量

c++ - 在 C++ 中声明接口(interface)并使用多重继承实现接口(interface)

c++ - 保存和打开文件对话框

c - 制作链接列表

c# - Visual Studio 中的 "Treat all warnings as errors except..."

c++ - "if else"是否被视为单个语句?

python - 交叉连接两个 vector 的元素以产生第三个 vector