【问题标题】:MSBuild directory structure limit workaroundsMSBuild 目录结构限制变通办法
【发布时间】:2008-09-26 14:44:51
【问题描述】:

有没有人有办法克服 MSBuild 工具的 260 个字符限制,以便从命令行构建 Visual Studio 项目和解决方案?我正在尝试使用 CruiseControl 使构建自动化(CruiseControl.NET 不是一个选项,所以我试图将其绑定到普通的 ant 脚本中)并且我一直遇到路径长度问题。澄清一下,问题在于解决方案文件中引用的项目路径的长度,因为该工具没有正确折叠路径:(

我也尝试过使用 DevEnv,它有时有效,有时会引发异常,这对于在单独的机器上自动构建并不好。所以请不要建议使用它作为替代品。

最重要的是,通过普通 IDE 使用 Visual Studio 时,项目构建良好。

【问题讨论】:

  • 我注意到,当 vs2008 进行构建时,它似乎运行一组不同的 msbuild 目标,而不是在 cc.net 下执行的简单 msbuild - 也许答案就在其中一个目标中

标签: visual-studio command-line msbuild


【解决方案1】:

这似乎是 MSBuild 的限制。我们遇到了同样的问题,最后,我们不得不缩短路径,因为没有找到任何其他正常工作的解决方案。

【讨论】:

  • 经过几天的努力,这似乎是我必须要求的。值得庆幸的是,正在为这些项目提出一个新的(更短的)路径结构,所以问题应该会消失 :)
  • .Net 框架 (v1.0-v3.5) 的 System.IO 有这个限制,MSBuild 使用的是 .Net。 (目前解决这个问题的唯一方法是在使用路径的任何地方使用 PInvoke。)
  • 谁能确认这在 msbuild 4.0 中没有问题?
  • 似乎 MSBuild 16.0 终于为此添加了一个修复程序,但它似乎需要十多年才能到达那里。 github.com/Microsoft/msbuild/issues/53#issuecomment-459062618
【解决方案2】:

SUBST command 静止图像似乎存在,因此如果 Judah Himango 的解决方案不好,将构建文件夹的根重新映射到驱动器号可能会节省一些字符。

【讨论】:

  • 它们已经被替换到目录结构的最常见根目录 :( 如果路径名不是那么长,它会起作用。
  • 我们正在使用 subst 来构建 Silverlight 工具包,它并不完美,但这个 hack 是一个很好的第一步。 +1 杰森
  • 这可以解决我们的 MSBuild 文件路径问题,至少目前是这样。
【解决方案3】:

我通过调整 CSPROJ 文件解决了类似的问题:

<BaseIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..\..\..\Intermediate\$(AssemblyName)_$(ProjectGuid)\'))</BaseIntermediateOutputPath>

在编译过程中,CSC.EXE 收到的是完整路径而不是相对路径。

感谢 harrydev 提供有关 CSC.EXE 如何使用路径的线索。

【讨论】:

  • 这对于解决 MSB3101:Could not write state file 错误非常有帮助,因为其根本原因是路径太长。此外,您必须扩展路径,因为 MSBuild 只会将您所做的 ..\..\obj 附加到已经太长的路径中。
【解决方案4】:

有两种与构建相关的长路径问题。一种是路径不是很长,但其中有很多“..\”。通常,这些是引用的 HintPath 值。 MSBuild 应将这些路径标准化为低于最大限制,以便它们工作。

另一种路径实在是太长了。对不起,但这些只是行不通。在仔细研究之后,问题在于没有足够的 API 支持长路径。 BCL 团队(见他们的博客)也有类似的问题。只有部分 Win32 API 支持 \?\ 格式。任意的构建工具,可能还有 98% 的应用程序,不这样做;更糟糕的可能会表现得很糟糕(想想所有大小为 MAX_PATH 的缓冲区)。

我们得出的结论是,除非生态系统努力让长路径工作,或者 Windows 想出一些巧妙的方法让它们正常工作(比如短路径损坏?),否则长路径是不可能的MSBuild 支持。如您所见,解决方法包括 subst;但是如果你的树太深了,你唯一的选择就是将它构建成片段,或者缩短文件夹名称。对不起。

丹/MSBuild

【讨论】:

  • 您能否详细说明“..\”是个问题,我们的相对文件路径不是很长。并且即使转换为绝对路径少于 200 个字符,但在 csc.exe 调用中仍然失败。
  • @nietras 我知道你在 8 年前发布了这个;但根本原因是当您使用“..\”时会传递整个路径,例如,如果您的相对路径是“..\obj”但当前工作目录已经超过 260 个字符,那么您已经被淹没了。这就是为什么上面 doomer 的答案(使用 System.IO.Path.GetFullPath)有效的原因,因为它在将其移交并被复用之前将其扩展为绝对路径。希望这对其他人有帮助。
【解决方案5】:

我发现问题在于,当调用 C# 编译器 (csc.exe) 时,它使用项目目录路径 PROJECTDIRECTORY 以及输出路径 OUTPUTPATH,只需将它们附加为:

项目目录+输出路径

但是,如果 OUTPUTPATH 是相对的,即“..\..\Build\ProjectName\AnyCPU_Debug_Bin\”并且项目目录很长,那么总长度会超过 259 个字符,因为路径是:

PROJECTPATH+"..\..\Build\ProjectName\AnyCPU_Debug_Bin\"

而不是绝对路径。

如果 csc.exe 在调用 Win32 函数之前创建一个绝对路径,这将起作用。因为在我们的例子中,绝对路径长度小于 160 个字符。

由于某种原因,从 Visual Studio 对 csc.exe 的调用与 MSBuild 不同,而不是从 Visual Studio 调用。不知道为什么。

在任何情况下,都可以通过更改 PROJECTDIRECTORY 和/或 OUTPUTPATH 路径中的一个或两个来解决问题。

【讨论】:

  • 这就是为什么扩展路径(使用 System.IO.Path.GetFullPath)就像在 doomers 答案中一样,对于很多遇到此问题的人来说都是有效的。
【解决方案6】:

您尝试过 DOS 路径吗?还是 \\?\ 前缀? .NET BCL team blog 有更多信息。

【讨论】:

    【解决方案7】:

    如果路径长度为 260,则有警告解析引用,对于 259 或 261 不会发生此错误。我认为有 msbuild 错误。

    【讨论】:

      【解决方案8】:

      我知道已经有一个公认的答案,但是我在使用 msbuild 时遇到了一个不同的问题,它给了我相同的错误输出,并导致我进行了一次循环的野鹅追逐。所以,对于未来的谷歌人来说,这里是:

      我们有一个调用msbuild 的批处理文件,但由于构建机器可以为多个版本的Visual Studio 构建,每个批处理文件在运行msbuild 之前调用vcvarsall.bat。这有一个令人讨厌的副作用,就是一遍又一遍地完全填满相同的东西。当它填满时,您会收到上述问题中显示的错误:The input line is too long. 一个简单的 Google 搜索可能会让您认为您的路径突然对于msbuild 来说太长了。

      在我的情况下,它就像终止 cmd.exe 的会话并重新启动一样简单,因为这会将环境变量恢复到它们的本机状态。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多