web-dev-qa-db-ja.com

コンパイルを続行するにはどうすればよいですか?

ソースツリー全体を再コンパイルしなくても、いつでもmakeプロセスを中断できることはわかっています。私が知っているように、makeは、まだコンパイルされていない場合、または最後のコンパイル後にソースコードが変更されている場合にのみ、ターゲットをコンパイルします。
しかし、makeを中断すると、1つ以上の(同時実行レベルに応じて)ハーフレディバイナリが確実に存在します。次にmakeを実行したときに、それらはどうなりますか?それとも私が押すと現在のターゲットを終了しますか Ctrl+C 部分的にコンパイルされたバイナリを回避するには?

11
psimon

簡単に言えば、makeは(おそらく大きな)ステップ数を持っていると考えることができます。各ステップでは、多数のファイルを入力として受け取り、1つのファイルを出力として作成します。

ステップは「コンパイルfile.cからfile.o "または" ldを使用してリンクmain.oおよびfile.o into program "。makeを CtrlCの場合、現在実行中のステップが終了し、作業中の出力ファイルが削除されます(または削除されます)。通常、「ハーフレディバイナリ」は残りません。

makeを再起動すると、すべての入力ファイルと出力ファイルのタイムスタンプが確認され、次の手順が再実行されます。

  • 入力ファイルのタイムスタンプが出力ファイルよりも新しい
  • 出力ファイルが存在しません

これは一般に、ステップの実行に長い時間がかかる場合(最近のコンピューターではまれですが、ldが設計されている場合、大規模プログラムのmakeステップは簡単に数分かかる可能性があります)、停止しますmakeを再起動すると、最初からそのステップが開始されます。

平均Makefileの現実は、上記の説明よりもかなり複雑ですが、基本は同じです。

12
Greg Hewgill

Ctrl+CSIGINTを実行中のプロセスに送信します。このシグナルはプロセスによってキャッチできます。 makeソースコードでは、_commands.c_でこの信号のトラップを見つけることができます。

_  /* If we got a signal that means the user
     wanted to kill make, remove pending targets.  */

  if (sig == SIGTERM || sig == SIGINT

  ... remove childrens ...

  /* Delete any non-precious intermediate files that were made.  */

  remove_intermediates (1);
_

remove_intermediates()makeのクリーンアップ関数です。ここでの定義を参照してください:

_/* Remove all nonprecious intermediate files.
   If SIG is nonzero, this was caused by a fatal signal,
   meaning that a different message will be printed, and
   the message will go to stderr rather than stdout.  */
_

そして後で見る関数では、それらは効果的に削除されます:

_status = unlink (f->name);
_

結論:通常、makeを使用してコンパイルを中断することを恐れないでください。キャッチできないシグナル(_SIGKILL, SIGSEGV, SIGSTOP_)でない場合は、中間ファイルのクリーンアップを行います。

8
chaos

何かがmakeを停止した場合(ctrl-C、シャットダウン、または失敗したコマンドであっても)、すでに実行された作業は残ります。言い換えると、makeはいつものように動作します。ファイルを変更したり、makeでファイルを処理する必要がなかったりするために、まだ何が必要かを判断し、ジョブ。

上記の説明は、関連するMakefilesが正しく実行するための依存関係とコマンドを説明していることを明確に想定しているため、(再)作成する必要があるのはすべてです。

1
vonbrand