web-dev-qa-db-ja.com

MSBuildのビルド順序

100を超えるプロジェクト(C++、マネージC++、C#)を含む大規模なソリューションがあり、それらの多くは相互に依存しています。

TeamCityサーバーがあり、そこでこのソリューションを構築したいと思います。

VisualStudioでソリューションを構築すると、すべてうまくいきますが、TeamCityではCS0006エラーが発生します。その理由はわかっています-TeamCityはMSBuild4を使用してソリューションをビルドしますが、MSBuild 4には既知のバグがあります-ビルドの順序を無視し、必要な順序でソリューションからプロジェクトをビルドします。あなたが持っている場合、この振る舞いのために:

Project A
Project B which has reference to A

MSBuildは、次の順序でこれらのプロジェクトをビルドできます。

1. B
2. A

最も簡単な解決策は、BuildProjectReferences = true(デフォルト)を設定することです。参照されているすべてのプロジェクトが自動的にビルドされます。ただし、このソリューションで参照されているプロジェクトがすべてではなく、別のソリューションからプロジェクトをビルドできないため、このアプローチを使用することはできません。

この問題の別の修正がありますConfigurationManagerを使用して、ビルドすべきではないすべてのプロジェクトを無効にしますが、VisualStudioでのみ機能します-MSBuildはそれを無視し、参照されているすべてのプロジェクトをビルドします。

問題は、VisualStudioのウィンドウに表示されるビルド順序を復元することですProjectBuildOrderこれは、コンソールから直接MSBuildを使用する場合には当てはまりません。

24
igofed

Visual Studioブログの MSBuild.exe使用時のソリューションビルドの順序が正しくない を参照してください。

この原則に従ってください:ソリューションファイルで表現された依存関係をまったく使用しないでください!依存関係のあるファイルで依存関係を表現することをお勧めします。代わりに、プロジェクトにプロジェクト参照を配置します。この例では、それはBからCへのプロジェクト参照になります。

プロジェクト参照のターゲットを参照したくなく、単にビルドを注文したため、これまでにこれを行ったことがない場合があります。ただし、4.0では、参照を追加せずにビルドのみを注文するプロジェクト参照を作成できます。次のようになります。メタデータ要素に注意してください。もちろん、これはすべて<ItemGroup>タグ内にあります。

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

テキストエディターで子要素を追加する必要があることに注意してください— Visual Studioはプロジェクト参照を追加できますが、このメタデータのUIは公開しません。

ソリューションファイルの依存関係も削除することで片付けることができます-このような不要な行を削除します-あなたのGUIDは異なりますが、VSダイアログを使用してそれが仕事をします。 ..

25
Alexeyss

私はこのような問題を抱えていました。ソリューション全体を正常にビルドする前に2つのビルドを要求することにより、ソリューションに現れました。

結局のところ、ProjectReferenceではなくReferenceを誤って追加してしまいました(.slnファイルでこれを探してください)。つまり、VS/MSBuildは、参照されているライブラリファイルを必要とし、検索しますが、ファイルが見つからない場合、howを完全に認識していません。最終的に、ビルドプロセスは、参照されたライブラリを使用してプロジェクトに到達し、ライブラリをビルドして、次のビルド試行で使用できるようにします。

依存関係ツリーとMSツールチェーンの特定のムードによっては、これは散発的なエラーとして表示される可能性があるため、デバッグするのが難しい場合があります。

ショートバージョン:ソリューション内のプロジェクトへの参照が参照だけでなくProjectReferenceとしてリストされていることを確認してください。これを行うには、DLLファイルを参照して選択する代わりに、Solutionタブに参照を追加します。

6
Saustrup

上記のソリューションは、.NetCoreプロジェクトからの出力に依存する.NetStandardプロジェクトをビルドしようとしたときにうまく機能しませんでした。ソリューションをVS2017とMSBuildでビルドするには、「SkipGetTargetFrameworkProperties」を追加する必要がありました。

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