web-dev-qa-db-ja.com

Visual Studioは変更されていないプロジェクトを再構築します

ですから、タイトルが示すように、私は今のところ〜50個のプロジェクトを含むVS2010ソリューションを持っています。何も参照していない「トップレベル」プロジェクトに変更を加えても、VSは50個のプロジェクトすべてを再構築します。アドオンなしでVisual Studio 2010 Ultimateを実行しています。 ILMergeを使用して、すべてのプロジェクトを単一のファイルに統合しています。

下位レベルのdllのタイムスタンプを確認することでこれを確認し、コードが変更されていなくても実際に再構築されることを確認しました。

私はすべての応答とコメントを読みました:

Visual Studio 2008は再構築を続けます

Visual Studioはすべてを構築し続けます

私のソリューションで奇妙なVS2010ビルドグリッチが発生します

C#プロジェクトがVisual Studioで再構築する理由

しかし、それらのほとんどは、ビルド時間を短縮するためのプロジェクトのアンロードに関する提案を提供するだけですが、修正に関して具体的なことは何もありません。私は、VSがこれらの依存プロジェクトを再構築する必要がないのに再構築する必要があると考える理由を解明しようとしています。

「ツール>オプション>プロジェクトとソリューション>ビルドと実行>スタートアッププロジェクトと実行時の依存関係のみをビルドする」をオンにしましたが、効果はありません。

また、8個の(in)direct依存関係のみを持つ「中間レベル」プロジェクトを再構築する場合、ILMergeが呼び出されず、依存プロジェクトが変更されていない場合でも、8個のプロジェクトがすべてビルドされます。

あなたが提供できる洞察力をありがとう。

追加

いくつかの提案をテストするために、新しいWinFormsプロジェクトをゼロから作成しました。次に、そのソリューション内に2つの新しいプロジェクトを作成しました。 2つの「最低レベル」プロジェクトのすべてのコードとリソース(プロジェクトファイルではない)を2つの新しいプロジェクトにコピーしました(エクスプローラーからVisual Studioのプロジェクトにファイルとフォルダーをドロップすることでこれを行いました)。

一番下のプロジェクト、それを呼び出してみましょう[〜#〜] b [〜#〜]、他のプロジェクトを参照していません。次のプロジェクト[〜#〜] a [〜#〜]、参照[〜#〜] b [〜#〜]のみ。したがって、必要な.NETおよび外部アセンブリ参照をプロジェクトに追加すると、ソリューションがビルドされます。

その後、新しいWinFormプロジェクト参照[〜#〜] a [〜#〜]を取得し、フルビルドを行いました。したがって、参照チェーンは次のとおりです。

WinForm-> [〜#〜] a [〜#〜]-> [〜#〜] b [〜#〜]

その後、WinFormonlyを変更し、標準ビルド(F6)を実行しました。前と同様に、Visual Studioは3つのプロジェクトすべてを再構築しました。

プロジェクトのソースファイルを体系的に削除した後[〜#〜] b [〜#〜]Resources.Designer.csおよびResources.resxを削除すると(それらのリソースの.Properties.Resourcesオブジェクトを使用したコード)WinFormの変更は、ソリューション全体を再構築することはなく、WinFormのみを再構築します。

Resources.resxResources.Designer.csをプロジェクトに追加し直す[〜#〜] b [〜#〜](ただし、参照されたコードはコメントアウトされたままなので、何も使用されていません。リソース)は、完全なビルド動作を再導入します。

リソースファイルが破損しているかどうかを確認するために、それらを再度削除してから(プロジェクトプロパティ->リソースを使用して)新しいファイルを作成し、以前と同じリソース(単一のExcelファイル)を再度追加しました。このセットアップでは、完全な再構築が引き続き発生します。

次に、単一のリソースを削除しましたが、プロジェクトにリソースファイルを残しました[〜#〜] b [〜#〜]。リソースが追加されていなくても、リソースファイルがプロジェクトに残っている場合でも、完全な(不要な)再構築が発生します。

(.NET 3.5)プロジェクトにリソースファイルを追加するだけで、Visual Studio 2010は常にそのプロジェクトを再構築するようです。これはバグですか、それとも意図した/予期された動作ですか?

どうもありがとう!

65
Matt Klein

私はこれが修正だとは思わないが、私の状況に合った回避策だ...

私はもともとResourcesセクションを含む50個のうち5個のプロジェクトがありました。これらのプロジェクトは常に再構築されるため、依存していたものもすべて再構築されます。これらの5つのプロジェクトの1つは、他のプロジェクトの48が参照する「ベース」レベルのライブラリでした。したがって、私のプロジェクトの96%は、必要なくても毎回再構築されます。

私の回避策は、依存性注入、インターフェース、および専用の「リソース」プロジェクトを使用することでした。これらの5つのプロジェクトが独自のResourcesオブジェクトを参照する代わりに、各プロジェクトに必要なリソースを提供するインターフェースを作成しました。次に、これらのリソースを必要とするクラスでは、コンストラクターでの作成中にインターフェースを渡す必要があります(コンストラクター注入)。

次に、通常のような実際のリソースセクションを含む別の「リソース」プロジェクトを作成しました。このプロジェクトには、リソース自体と、インターフェースを介してそれらのリソースを提供するために必要な各インターフェースのクラスのみが含まれていました。このプロジェクトは、リソース依存関係を持つ他のすべてのプロジェクトを参照し、プロジェクトに必要なインターフェースを実装します。

最後に、何も参照しなかった(およびexeが実際に作成され、コンポジションのルートが存在する)「トップレベル」プロジェクトで、「リソース」プロジェクトを参照し、DIを接続して、先に進みました。

つまり、毎回2つのプロジェクト(「リソース」と「トップレベル」)のみが再構築され、部分的なビルド(Shift-F6)を行うと、それらはまったく再構築されません。

繰り返しますが、大した問題ではありませんが、ビルドに約3分かかるたびに48のプロジェクトがビルドされるため、不必要なリビルドで1日30〜90分を失いました。リファクタリングには少し時間がかかりましたが、良い投資だったと思います。

これは簡略図です。混乱を減らすため、Main.exeからProj1およびProj2への依存関係は表示されていないことに注意してください。

Diagram of solution

この設計では、Resourcesセクションに依存関係がないため、完全な再構築をトリガーすることなくProj1またはProj2のビルドを実行できます。 Main実装について知っているのはResourcesだけです。

17
Matt Klein

[ツール]-[オプション]を開き、ツリーで[プロジェクトとソリューション]-[ビルドと実行]を選択し、[MSBuildプロジェクトビルド出力の詳細]を[診断]に設定します。これにより、プロジェクトをビルドする理由、つまり.

プロジェクト「ReferencedProject」は最新ではありません。プロジェクトアイテム「c:\ some.xml」の「出力ディレクトリにコピー」属性が「常にコピー」に設定されています。

または

プロジェクト「MyProject」は最新ではありません。入力ファイル「c:\ ReferencedProject.dll」は、出力ファイル「c:\ MyProject.pdb」の後に変更されます。

この場合の修正は、新しい場合にのみsome.xmlをコピーすることです。

ビルド前後のイベントもビルドをトリガーできます。

117
user3285954

これは、プロジェクトに実際に存在しないファイルがある場合に発生します。
プロジェクトはファイルが変更されたかどうかを判断できないため(ファイルが存在しないため)、再構築されます。

プロジェクト内のすべてのファイルを見て、近くに展開可能な矢印がないファイルを検索します。

16
Yochai Timmer

VS 2015でも同じ問題が発生しました。

私にとってトリックは何でしたか:

  1. あるプロジェクトは、他のプロジェクトビンにあるコピー自体を参照していました(魔法、はい)。この種の問題は、(ビルドオプションで)診断ビルド出力に切り替えてから、プロジェクト階層の最上位からプロジェクトを1つずつビルドしようとすると見つかります。参照。
  2. すべてのプロジェクトのすべての「常にコピー」ファイルを「新しい場合にコピー」に変更しました。基本的に、すべての.csprojファイルで<CopyToOutputDirectory>Always</CopyToOutputDirectory>から<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  3. 次に、このPowerShellスクリプトに関する this の記事で説明されているように、NTFSトンネリングを無効にしました。

New-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "MaximumTunnelEntries" -Value 0 -PropertyType "DWord"

その後、再構築が必要になりましたが、今のところ機能しているようです。

9
Michael Logutov

私の場合、犯人は参照されたdllの「ローカルにコピー」設定がtrueに設定され、「出力ディレクトリにコピー」設定がファイルを常にコピーに設定することでした。

4
I-A-N

MSBuildチームは、ビルドの増分問題の調査に関するドキュメントをここで収集しています: https://github.com/Microsoft/MSBuild/wiki/Rebuilding%20when%20nothing%20changed

1
Kirill Osenkov

私はこれと同じ問題を抱えていたため、独自の出力ディレクトリにあるdllへのローカル参照のコピーを持ついくつかのプロジェクトに関連していることが判明しました。

これを見つけるための鍵は、ビルド出力用に診断出力を設定することでしたが、ログで何を探すべきかを知ることでもありました。検索:「最新ではない」がキーでした。

1
Ademund

ビルドログの詳細度を上げることで見つけるのに苦労したもう1つの原因がようやく見つかりました。

場合によっては、MSBuildはvc120.pdbは出力フォルダーにあり、このファイルが存在しない場合は、プロジェクト全体が再構築されます。これは、デバッグシンボル生成を無効にしている場合でも発生します

ここでの回避策は、デバッグシンボルを有効にしてこのファイルを生成し、PDBファイルを削除せずにwithout設定を無効にします。

1
Mehrdad

このカテゴリのビルドの問題では、MSBuildの出力の詳細度を「診断」に設定することが実際に必要な最初のステップです。ほとんどの場合、再構築の理由が説明されていれば対処できますが、MSBuildは一部のファイルが変更されてコピーする必要があると誤って主張することがあります。

その場合は、NTFSトンネリングを無効にするか、出力フォルダーを新しい場所に複製する必要があります。 ここではより多くの言葉で。

0
Ofek Shilon

私の場合(C#、C++/CLI、およびネイティブC++ソリューションの混合)、何も変更されていなくても、一部のC++プロジェクトが再リンクされていました。私は何が起こっているのかを解明しようとして何年も費やしました。結局、PDB出力パス(オプション/ Fd)がフォルダー設定$(IntDir)を処理できないという「コマンドライン」オプションから解決しました。私はそれを削除しました-空の値はデフォルトを正しく行います-そして私の問題はなくなりました。

0
user11657883

あなたの観察に基づくと、明らかではない方法で他のプロジェクトへの依存関係を表現しているプロジェクトがあるようです。孤立した依存関係は、UIに表示されずにプロジェクトファイルに残る可能性があります。テキストエディターで開いた後、動作に問題のあるプロジェクトファイルを確認しましたか?ソリューションビルドの依存関係を確認しましたか?

何も見つけられない場合は、プロジェクトの1つをゼロから再作成して、新しいプロジェクトで同じ問題が発生するかどうかを確認してください。クリーンなプロジェクトが正しくビルドされると、不要な依存関係がどこかで表現されていることがわかります。私の知る限り、これらはプロジェクトファイルまたはソリューションファイルに存在する必要があります。ただし、メイクファイルまたはその他の異常なビルドステップが必要です。

0
Owen Wengerd

VS2010は常にソリューションを再構築しますか?

この問題は、プロジェクトファイルの変更、ソリューションのクリーニング、すべてのbinフォルダーの手動削除、Visual Studioの再起動、すべての再構築によって解決されます。

0
Ryan Byrne

Visual Studio 2015から2017にアップグレードするときにVisual Studioでプロジェクトを再構築する問題が発生しました。同様の問題が発生する可能性がある人のために、この回答を追加します。

私の場合、問題は、ソリューション内のすべてのプロジェクトが同じ中間出力パス(obj)を持っていることでした。 GeneratedInternalTypeHelper.csファイルは、XAMLを含むすべてのプロジェクトによって生成されます。 Visual Studio 2015まで、ビルドプロセスは明らかにこのファイルのファイル日付をチェックしなかったため、問題は発生しませんでした。 VS2017では、このファイルのファイルの日付がチェックされ、ビルドプロセスの後半のプロジェクトが(同じコンテンツで)上書きするため、以前のプロジェクトが再ビルドされ、後のビルドが再トリガーされ、無限に再起動されます。

この場合の解決策は、すべてのプロジェクトが異なる中間出力ディレクトリを持つようにすることです。これにより、問題はなくなります。

0
Flash

頻繁に発生する別の問題は、ソリューション内の一部のアイテムに将来の修正スタンプがある場合です。これは、時計を進めてから時計を正しい時刻に設定した場合に発生する可能性があります。 Linuxのインストール中にこれが発生しました。

この場合、git bashを使用してすべてのファイルに再帰的にアクセスできます(はい、Windowsの場合):

find . -exec touch {} \;
0
Mikhail

私はあなたと同じ問題を抱えていました。いくつかの削除されたファイルから来ていることがわかりました。プロジェクトからファイルを削除すると、問題はなくなりました。よろしく。

0
PhonPanom