我有一个包含100多个项目的大型解决方案(C ++,Managed 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 中看到,如果我直接从Console使用MSBuild,则不是这样。
答案 0 :(得分:22)
请参阅Visual Studio博客上的Incorrect solution build ordering when using MSBuild.exe:
遵循以下原则:不要使用解决方案文件中表达的依赖关系!最好在具有依赖关系的文件中表达依赖关系:将项目引用放在项目中。在我们的示例中,这将是从B到C的项目引用。
之前您可能没有这样做,因为您不想引用项目引用的目标,而只是命令构建。但是,在4.0中,您可以创建仅在不添加引用的情况下对构建进行排序的项目引用。它看起来像这样 - 注意元数据元素,当然这一切都在
<ItemGroup>
标签内:<ProjectReference Include="foo.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> </ProjectReference>
请注意,您必须使用文本编辑器添加子元素 - Visual Studio可以添加项目引用,但不会公开此元数据的UI。
我可以通过删除解决方案文件中的依赖项来整理 - 删除现在这样不必要的行 - 你的GUID会有所不同,但是使用VS对话框就能完成这个工作......
答案 1 :(得分:6)
我有一个像这样的问题。它通过在成功构建整个解决方案之前需要两个构建来体现在解决方案中。
事实证明,我不小心添加了参考而不是 ProjectReference (在.sln文件中查找),这意味着VS / MSBuild需要和查找引用的库文件,但如果缺少如何构建它,则完全不知道。最终,构建过程将通过引用的库到达项目,构建它并使其可用于下一次构建尝试。
根据您的依赖关系树和MS工具链的特定情绪,这可能会出现偶发错误,因此成为调试的婊子。
简短版:确保对解决方案内项目的引用列为 ProjectReference ,而不仅仅是参考。通过在 Solution 选项卡上添加引用而不是浏览和选择DLL文件来执行此操作。
答案 2 :(得分:1)
在尝试构建依赖于.Net Core项目输出的.Net Standard项目时,上述解决方案对我而言不太有效。为了获得要在VS2017和MSBuild中构建的解决方案,我必须添加一个额外的“ SkipGetTargetFrameworkProperties”。
<ProjectReference Include="foo.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>
答案 3 :(得分:0)
上面提到的一切都对我没有帮助。我使用的解决方案是多次构建 sln,在第一次运行时传递 /t:1stproject.csproj,然后是 /t:2ndproject,最后是没有 /t 的 sln 以完成其余的解决方案。