MSBuild构建顺序

35

我有一个包含100多个项目(C ++,Managed C ++,C#)且它们之间相互依赖的大型解决方案。

我有一个TeamCity服务器,并希望在那里构建此解决方案。

在Visual Studio中构建解决方案时一切正常,但是在TeamCity中却出现了CS0006错误。 我知道这是为什么 - TeamCity使用MSBuild 4来构建解决方案,但是MSBuild 4存在已知错误 - 它会忽略构建顺序并按照自己想要的顺序构建解决方案中的项目。 由于这种行为,如果您具有:

Project A
Project B which has reference to A

MSBuild可以按以下顺序构建这些项目:

1. B
2. A

最简单的解决方案是设置 BuildProjectReferences=true(默认值),这样所有引用的项目都会自动构建。但我不能使用这种方法,因为并非所有引用的项目都在此解决方案中,而且我无法从另一个解决方案构建项目。

这里有另一种解决此问题的方法 - 使用 ConfigurationManager 并禁用所有不应该构建的项目,但它只在 VisualStudio 中有效 - MSBuild 会忽略它并构建所有引用的项目。

问题是恢复构建顺序,可以在 VisualStudio 中的窗口 ProjectBuildOrder 中查看它,但如果我直接从控制台使用 MSBuild,则不正确。


这是一个非常泛泛的问题,你能更具体一些吗?它能在Visual Studio中构建吗? - Ritch Melton
1
不,我使用JetBrains TeamCity服务器,它使用MSBuild。如果我从VisualStudio运行构建,一切都很好。 - igofed
你能具体说明一下要修复什么吗?你是想修复预构建事件还是在禁用项目引用时修复构建? - seva titov
我熟悉TeamCity。你在配置中引用了解决方案文件吗?实际的构建错误是什么?看起来你假定了某种“已知问题”,但据我所知,所有这些东西基本上都可以正常工作,除非你正在做一些奇怪的事情。100个项目并不可怕,我曾经有过在CI下构建大约350个项目的经验。 - Ritch Melton
我更新了问题并尝试更具体。 - igofed
显示剩余5条评论
4个回答

35

请参考The Visual Studio Blog的文章“使用MSBuild.exe时构建顺序不正确”,遵循以下原则:完全不要在解决方案文件中使用表达的依赖项!最好在具有依赖项的文件中表达依赖关系:在项目中放置一个项目引用,而不是在解决方案中。在我们的示例中,这将是从B到C的项目引用。

您可能以前没有这样做,因为您不想引用项目引用的目标,仅仅是为了排序构建。但是,在4.0中,您可以创建一个仅用于排序构建而不添加引用的项目引用。它看起来像这样——请注意元数据元素,所有这些都在<ItemGroup>标记内,当然:

<ProjectReference Include="foo.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>

请注意,您必须使用文本编辑器添加子元素。Visual Studio可以添加项目引用,但不提供此元数据的UI界面。

我可以通过从解决方案文件中删除依赖项来进行整理,也可以删除现在不必要的行,例如这样——您的GUID将是不同的,但使用VS对话框即可完成操作...


4
除非这些项目针对相同的框架,否则它们无法正常工作 :( - bradgonesurfing

12

当我试图构建一个依赖于 .Net Core 项目输出的 .Net Standard 项目时,上面的解决方案对我并不完全适用。我必须添加额外的 "SkipGetTargetFrameworkProperties" 才能让该解决方案在 VS2017 和 MSBuild 中成功构建。

<ProjectReference Include="foo.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>

这个 MSBuild "bug" 在 VisualStudio 2019 中仍然存在。我也遇到了同样的问题,一个 .Net Standard 项目的 pre-build script 依赖于一个 .Net Core WebAPI 项目。一开始我想在 sln 中只设置构建顺序,但是 MSBuild 忽略了这个设置。您提供的解决方案解决了这个问题,谢谢! - Balázs Somorjai

8
我曾经遇到过类似的问题。在解决方案中,需要构建两次才能成功构建整个解决方案。
事实证明,我不小心添加了一个引用(在.sln文件中查找此内容),而不是项目引用,这意味着VS/MSBuild将需要并查找引用的库文件,但如果缺少该文件,则完全不知道如何构建它。最终,构建过程会转到具有引用库的项目,并对其进行构建,使其可用于下一次构建尝试。
根据依赖关系树和MS工具链的特定心情,这可能会出现为间歇性错误,并因此难以调试。
简短版:确保解决方案中项目的引用被列为“ProjectReference”,而不仅是“Reference”。通过在“解决方案”选项卡上添加引用,而不是浏览并选择DLL文件来完成此操作。

太棒了。花了3天时间才弄清楚这个问题。你有任何想法是什么导致引用被添加为引用而不是项目引用吗?如果有一个工具可以找到所有这些情况就太好了。 - russelrillema
在我的情况下,这是在项目文件而不是解决方案文件中。 - russelrillema

0

上述内容对我没有帮助。我使用的解决方案是构建sln几次,在第一次运行时传递/t:1stproject.csproj,然后/t:2ndproject,最后在没有/t的情况下构建sln以完成其余部分的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接