递归构建解决方案时构建过程挂起

Posted

技术标签:

【中文标题】递归构建解决方案时构建过程挂起【英文标题】:Build process hangs when recursively building solution 【发布时间】:2015-02-24 21:13:32 【问题描述】:

在尝试回答 this SO question 时,我遇到了一个我无法解释的问题,希望您能提供意见。

设置:

    拥有由多个 C++ 项目 (Test.sln) 组成的解决方案, 向您的解决方案添加一个全新的项目 (BuildInstaller.vcxproj), 在文本编辑器中打开 BuildInstaller.vcxproj 并在关闭 </Project> 标签之前附加以下 xml 片段:
<Target Name="Build">
  <MSBuild Projects="..\Test.sln" Properties="Configuration=Release;Platform=Win32" />
  <MSBuild Projects="..\Test.sln" Properties="Configuration=Release;Platform=x64" />
</Target>
    以上代码会覆盖 BuildInstaller 项目的默认 Build 目标,并且每次构建项目时,它都会使用 Win32 和 x64 平台的发布配置构建其父解决方案, 为防止无限递归,请在 Visual Studio 中打开配置管理器并取消选中 BuildInstaller 项目的“构建”复选框,以查看所有 Debug/Release 和 Win32/x64 组合, 然后,仍然在配置管理器中,创建一个新配置,例如您应该取消选中所有其他项目的 Build 复选框并仅选中 BuildInstaller 的安装程序, 现在为安装程序配置构建您的解决方案。

我希望这个构建能够成功完成,但它只是挂起,即使不应该递归构建 BuildInstaller,因为我们只为发布配置递归构建 Test.sln。

我不是在问这是否是一个好方法或如何解决它,我只是好奇为什么构建会挂起。将输出窗口详细程度设置为诊断对我没有帮助。

我正在使用 Visual Studio 2013 Ultimate。

【问题讨论】:

【参考方案1】:

MSBuild 对项目中的递归具有内部保护。通常,如果在构建图中发现任何类型的循环依赖项,您的构建将失败并出现错误 MSB4006。也就是说,如果我猜测可能导致挂起的原因,并且如果它与递归有关,我会倾向于 .sln 文件。原因是 MSBuild 处理 .sln 文件的方式非常奇特。每当遇到 .sln 文件时,它都会将其转换为实际 MSBuild 引擎可以理解的中间表示。该中间表示没有任何类似于项目文件的标识符,因此如果 .sln 在循环中,循环依赖检测逻辑可能无法正常工作。

要解决您的特定问题,有几种方法。最简单的方法是从 Test.sln 中删除 BuildInstaller.vcxproj。二是修改BuildInstaller.vcxproj如下:

首先,创建一个 ItemGroup,填充解决方案中的所有项目:

<ItemGroup>
    <AllMyProjects Include="..\Proj1\Proj1.vcxproj" />
    <AllMyProjects Include="..\Proj2\Proj2.vcxproj" />
    ...
    <!-- DO NOT ADD BuildInstaller project to prevent recursion!!! -->
</ItemGroup>

然后为每个配置构建项目:

<Target Name="Build">
    <MSBuild Projects="@AllMyProjects" Properties="Configuration=Release;Platform=Win32" />
    <MSBuild Projects="@AllMyProjects" Properties="Configuration=Release;Platform=x64" />
</Target>

第二种方法的缺点是您必须记住在 .sln 和您的安装程序项目之间保持同步的项目列表。

【讨论】:

评论:如果我为发布配置启用构建BuildInstaller.vcxproj,那么构建最终会出现“循环依赖”错误,这是预期的,但在安装程序配置的情况下挂起的构建仍然是对我来说很神秘。至于解决方法——这正是我在linked SO thread 中建议做的,唯一的区别是我将BuildInstaller.vcxproj 转换为简单的BuildInstaller.msbuild 脚​​本。所以我很高兴我的方法没有那么坏:)如果没有人很快解释得更好,我会接受答案。 仅供参考,我仍然不知道为什么会这样。令人惊讶的是,如果我从命令行而不是 IDE 构建解决方案,一切正常,我的意思是 msbuild Test.sln /p:Configuration:Installer 如果您想了解问题的根源,您应该将此错误报告给 Microsoft,因为只有 MS VS 团队能够调查并修复问题。较小的独立重现文件将帮助您引起他们的注意,如果您提到仅在 IDE 中可见的问题,它会缩小小组的跟进范围。 你读懂了我的想法,我做到了here,请随意投票:)

以上是关于递归构建解决方案时构建过程挂起的主要内容,如果未能解决你的问题,请参考以下文章

VS2013 在编译时挂起

Xcode 6:构建挂起并且 Interface Builder Cocoa Touch Tool 开始分配所有 RAM

项目构建失败时,Android Studio 挂起/冻结

十六 递归

dom构建渲染过程

初识webpack