2016-01-04 8 views
9

このソリューションにはC#プロジェクトが多数含まれています。それらの間には複雑な依存関係があります。プロジェクトA/B/C、Bの扶養家族、Cの扶養家族B:プロジェクトCで1つのファイルを変更した場合、プロジェクトA、B、Cが一緒に再構築されます。C#はインクリメンタルプロセスをコンパイル/ビルドしていますか?

C++では、buildには2つのプロセス、コンパイルおよびリンクが含まれています。プロジェクトCで1つのファイルを変更すると、ソリューションをビルドし、AとBの関連ファイルがコンパイルされます(他のファイルはコンパイルされず、.objはリンクプロセスで再利用されます)。

javaでは、プロジェクトCの変更されたファイルのみが再コンパイルされ、他のファイルはパッケージ化されて.jarに保存されます。以前の作業出力を再利用します(変更されたファイルの.class)。

つまり、C#は以前の作業出力を再利用しません。 Javaの.classやC++の.objのような中間ファイルはありません。この点では、C#はインクリメンタルビルドプロセスを実行しないと感じています。小さな変更は大きなビルドプロセスを引き起こします。なぜC#が以前の作業出力を使用してビルドプロセスを高速化しないのか分かりません。

C#のコンパイル/ビルドプロセスの理解が正しいかどうかはわかりません。もっと説明するのを助けてくれますか?どうもありがとう。

+0

Windowsバッチファイルを作成すると、すべての依存関係とビルドフォルダを記述して、すべてをシングルショットでビルドすることができます。 – csharpcoder

+3

Eric Lippertは2010年に[How many passes?]というタイトルの記事を書きました。(https://blogs.msdn.microsoft.com/ericlippert/2010/02/04/how-many-passes/):「C#言語宣言が使用の前に発生する必要はありません...ユーザーに与える影響は、ファイルを変更したときに変更されたILのみを再コンパイルする必要はないということです。これを見るもう1つの方法は、C#での再コンパイルの「粒度」はプロジェクトレベルではなく、ファイルレベル " –

+0

ビジュアルスタジオ、ソリューションエクスプローラウィンドウでソリューションを右クリックし、プロジェクト/ソリューションのビルドオーダーを参照してくださいプロジェクトの依存関係も表示されます – Kyle

答えて

8

C#コンパイラが増分し、すべてのプロジェクトA.上のbinフォルダにBとCのファイルをビルド表示されますあなたがそれがないというアイデアがどこにあるのか分かりません。おそらく、ソリューションの複雑さのために、依存関係を正しく理解しておらず、再コンパイルする必要がないと思われるプロジェクトが実際に必要です。

コンパイラの動作を確認するための最良の方法は、単純なダミーのソリューションを作成し、それを周りに再生することです:

セットアップ:

  1. 空のVisual Studio C#のソリューションを作成します。
  2. ABの2つのプロジェクトを追加します。
  3. プロジェクトAでプロジェクトBを参照してください。
  4. BにクラスFooInBを実装し、ABarInAの別のクラスで使用します。

は今、この設定でビットの周りに遊ぶことができます:

  1. ソリューションをコンパイルします。両方のプロジェクトがコンパイルされていることがわかります。
  2. 溶液をもう一度コンパイルします。どちらのプロジェクトもコンパイルされていないことがわかります。どちらも最新です。
  3. BarInAに実装を変更して、もう一度コンパイルしてください。あなた はの1つのプロジェクトがコンパイルされることを確認します。A変更がないので、Bを再度コンパイルする必要はありません。
  4. 実装をFooInBに変更し、最後に1回コンパイルしてください。両方のプロジェクトがコンパイルされていることがわかります。この動作は正しく行われます。ABに依存しますので、Bの変更は必ずAを再コンパイルして、Bの最新バージョンを指していることを確認してください。 C#コンパイラがBの変更がAに影響を及ぼさず、従ってAビルを "最適化"できた場合、各プロジェクトが異なった旧式のアセンブリバージョンを参照する可能性のある悪夢のシナリオである。私は私の知る限り、C#コンパイラのみプロジェクトレベルでインクリメンタルコンパイルを実行する、ということを指摘したいと思います、と述べた

。私は、任意のアセンブリ内のクラスレベルでの増分コンパイルの最適化について認識していません。コンパイラの内部動作をより深く理解している人は、この動作を明確にすることができます。

+0

おそらく、 "建物を最適化する* A *をもう一度最適化する"という意味は、 "建物を最適化する* B *をもう一度"を意味します。別の考え方:この方法を最適化することは、たぶんもう一度コンパイルするよりも、たいていの場合時間がかかります。 –

+0

@StefanSteinegger Woops!ありがとう、それを修正しました。 – InBetween

1

OK ..あなたは実際に正しい軌道に乗っています。ソリューションに3つのプロジェクトがある場合、あるプロジェクトの参照をもう一方のプロジェクトに与えることができます。プロジェクトBをプロジェクトCに依存しているプロジェクトBに依存することを意味します。

プロジェクトをビルドすると、ビルドされたすべてのファイルとdll(ビルド後のイベントから)はそのプロジェクトのbinフォルダになります。

プロジェクトAをビルドすると、プロジェクトCが最初にビルドされます(A-> B-> Cのため)。プロジェクトBは、プロジェクトCのビルドされたコンポーネントを使用し、独自のコンポーネントを作成します。プロジェクトAはBとCのコンポーネントを使用し、独自のコンポーネントを作成します。あなただけのプロジェクトAを構築する場合、参照が正しければこのための

、、、あなたは

+0

このビルドメソッドがスマートではないと感じていますC++では、以前の作業(オブジェクトファイル)は新しいビルドプロセスで再利用されますが、Javaでは、他のファイルやプロジェクトを再構築する必要はありません。私の仕事では、私はいつも何かを変えて再構築し、デバッグします。ビルドにはそれほど時間がかかりませんでしたので、C#はそうだと信じられません。私はそれを理解していないのではないかと疑う。 –

+0

これを更新するには@InBetween私にそれを打つ...良い答え.. :) –

3

あなたは正しいです。

プロジェクトAがプロジェクトBに依存する場合、依存プロジェクトBの変更は、プロジェクトAの再コンパイルを必要とします。

プロジェクトBがプロジェクトCに依存する場合、プロジェクトBの変更はプロジェクトCの再コンパイルを行いません。

Javaでは、1つのクラス/ファイルが1つの.classファイルにコンパイルされます。そのため、1つのファイルが変更されたときに、プロジェクト全体が再コンパイルされることはありません。

配布前に、これらの.classファイルが結合されて.jarになります。単一の.classファイルが変更された場合は、.jar全体を再アセンブリする必要があります。

.NETでプロジェクトをすぐにアセンブリ(.dllまたは.exe)にコンパイルすると、単一のファイルが変更されるため、アセンブリ全体の再コンパイルが必要になります。

.jar(または.apkのような依存関係)を使用してアプリケーションを実行/デバッグするJava環境でも同じ動作が見られます。 .jar全体も開発中に必要です。また、1つのファイルが変更されたときにプロジェクト全体が再コンパイルされます。

いつでもソリューションの外にプロジェクトを配置できます。そして、作成する.dllの参照のみを追加してください。これにより、コンパイル時間が最小限に抑えられます。

+0

ありがとう。 Javaは、変更されたファイルを次に.jarに再コンパイルします。以前の作業出力を再利用します(変更されたファイルの.class)。 C#は以前の作業出力を再利用しません。 Javaの.classやC++の.objのような中間ファイルはありません。したがって、この時点では、C#はインクリメンタルなビルドプロセスを行わないと感じています。なぜC#が以前の作業出力を使用してビルドプロセスを高速化しないのか分かりません。 –

+0

私の経験では、Javaスタジオ(Androidスタジオを使用)はC#(Visual Studioを使用)より時間がかかります。私のVisual Studioプロジェクトは、Javaプロジェクトほど大きなオーダーです。 Javaでの私の最初の経験は、「​​これは永遠に続く:私の設定に何が間違っているか」 – GvS

1

私は多くのプロジェクトとさらに多くのプロジェクト間の参照を含むソリューションを持っています。

私は、プロジェクトABCを持っていると言うことができます。

  • ABC
  • Bは、Windowsフォームとreffers C
  • Cがグレードってこんなモンとデータベース・ロジックが含まれている含まれていreffers私のメインのデスクトップexeファイルです。

私の主な問題は、Bはコンパイルに約45秒かかります。今度は、私だけCにコードの小さな行を変更しましょう、コンパイラがCをコンパイルしますと、私はほとんどが非常に高速なコンパイルC内のコードを変更するので、その後、それは私が常にコンパイルするBを待つ必要がA よりBを、コンパイルします。

私はredgateから.NET Daemonを発見しました。これはビルドプロセスを変更するツールで、公開APIがCから変更された場合にのみBを再構築します。これはビルドプロセスに大きな影響を与える可能性があります。 https://www.red-gate.com/products/dotnet-development/dotnet-demon/

をビジュアル:私はしかし、私はちょうど見て、彼らはもうそれを販売していない...それは私の個人的な経験に基づいて日を超える建物費やした時間の約80%を節約し、

を言うだろうStudio 2015はMicrosoftの新しいRoslynコンパイラ、 を導入し、.NET Demonを冗長化すると考えています。

私はまだVisual Studio 2013にいますが、ビルドプロセスの最初の観察とNETビルドに関するその他の回答は、Roslynを使用したVisual Studio 2015ではもう真実ではないと思います。たぶんdotnet-deamonビルドのように動作します。

私の新しいプロジェクトではIOCのコンテナを使用していますが、すべてのプロジェクトはプロジェクト間の参照があまりなく、メインプロジェクトに組み込まれています。これにより、ほぼすべてが並行してビルドできるため、ビルドプロセスが改善されます。

+0

ありがとうございます。私はあなたと同じ問題があります。私はVS2015を試してみます。 –

+0

私が助けてくれれば教えてください。私は2015年に移行する予定です。しかし、もし.NET Deamonがなくなるならば、VS 2015が同様の改善をしない限り、これは欠点になります。 –

0

すべてのバージョンのC#(MSBuildは実際には)非依存プロジェクトの増分コンパイルをサポートしています。

VS2003でC#をサポートするインクリメンタルコンパイルwithin projects。この機能を最新のC#バージョンに移行するには、uservoice suggestionがあります。

0

私はJenkins MSBuildプラグインでテストしましたが、インクリメンタルビルドは期待通りに機能し、変更されたプロジェクトだけが再コンパイルされます。

私が望むのは、インクリメンタルデプロイを行うことです。これらの変更/再コンパイルされたdllだけをデプロイすることです。今、どのように効率的に再コンパイルされたDLLを見つけることができますか?

関連する問題