在尝试回答this SO question时,我遇到了一个我无法解释的问题,我很感激您的意见。
设定:
</Project>
标记之前追加xml片段:<Target Name="Build">
<MSBuild Projects="..\Test.sln" Properties="Configuration=Release;Platform=Win32" />
<MSBuild Projects="..\Test.sln" Properties="Configuration=Release;Platform=x64" />
</Target>
Build
目标,每次构建项目时,它都会为Win32和x64平台构建具有Release配置的父解决方案,我希望这个构建能够成功完成,但它只是挂起,即使不应该递归构建BuildInstaller,因为我们只是为Release配置递归构建Test.sln。
我不是在问这是一个好方法还是如何解决它,我只是好奇为什么构建会挂起。将输出窗口详细程度设置为Diagnostic对我没有任何帮助。
我正在使用Visual Studio 2013 Ultimate。
答案 0 :(得分: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和你的安装程序项目之间保持同步的项目列表。