29

我有一个包含 100 多个项目(C++、托管 C++、C#)的大型解决方案,其中许多项目相互依赖。

我有一个 TeamCity 服务器,我想在那里构建这个解决方案。

当我在 VisualStudio 中构建解决方案时,一切正常,但使用 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,这不是真的。

4

4 回答 4

30

请参阅Visual Studio 博客中的使用 MSBuild.exe 时解决方案构建顺序不正确:

遵循这个原则:根本不要使用解决方案文件中表达的依赖关系!更好地在具有依赖关系的文件中表达依赖关系:改为在项目中放置项目引用。在我们的示例中,这将是从 B 到 C 的项目引用。

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

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

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

我也可以通过删除解决方案文件中的依赖项来进行整理——删除现在不需要的行——你的 GUID 会有所不同,但使用 VS 对话框,它会完成这项工作......

于 2012-08-14T12:53:48.087 回答
9

当我尝试构建一个依赖于 .Net Core 项目输出的 .Net 标准项目时,上面的解决方案对我来说不太适用。我必须添加一个额外的“SkipGetTargetFrameworkProperties”才能获得在 VS2017 和 MSBuild 中构建的解决方案。

<ProjectReference Include="foo.csproj">
    <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    <SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>
于 2019-02-08T08:56:40.363 回答
8

我有一个很像这样的问题。它通过在成功构建整个解决方案之前需要两次构建来体现在解决方案中。

事实证明,我不小心添加了一个Reference而不是ProjectReference(在 .sln 文件中查找),这意味着 VS/MSBuild 将需要并查找引用的库文件,但完全不知道如何构建它如果它不见了。最终,构建过程将与引用的库一起进入项目,构建它并使其可用于下一次构建尝试。

根据您的依赖关系树和 MS 工具链的特定情绪,这可能会出现零星错误,因此是一个需要调试的婊子。

短版:确保对解决方案中项目的引用被列为ProjectReference而不仅仅是Reference通过在解决方案选项卡上添加引用而不是浏览和选择 DLL 文件来执行此操作。

于 2016-04-27T06:36:04.423 回答
0

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

于 2021-07-02T19:42:08.147 回答