ソースツリー全体を再度コンパイルしなくても、いつでもプロセスを中断できることはわかっていますmake
。 は、make
ターゲットがまだコンパイルされていない場合、または最後のコンパイル後にソースコードが変更された場合にのみ、ターゲットをコンパイルします。
しかし、 を中断するとmake
、1 つ以上の (同時実行レベルに応じて) 半分準備が整ったバイナリが確実に存在します。 次に を実行したときに、それらはどうなりますか? または、部分的にコンパイルされたバイナリを回避するために、 +make
を押すと現在のターゲットを終了しますか?CtrlC
答え1
make
簡単に言えば、 (おそらくは多数の)ステップがあり、各ステップで複数のファイルを入力として受け取り、1 つのファイルを出力として作成すると考えることができます。
ステップは、「file.c
にコンパイルfile.o
」または「にld
リンクして にmain.o
使用」である可能性があります。を使用して中断すると、現在実行中のステップが終了し、作業中の出力ファイルが削除されます (または削除されるはずです)。通常、「半分準備ができたバイナリ」は残されません。file.o
program
make
CtrlC
を再起動するとmake
、すべての入力ファイルと出力ファイルのタイムスタンプが確認され、次の手順が再実行されます。
- 入力ファイルのタイムスタンプが出力ファイルよりも新しい
- 出力ファイルが存在しません
これは通常、ステップの実行に長い時間がかかる場合 (最近のコンピュータではまれですが、大規模なプログラムのステップは設計ld
時に数分かかることがありました)、停止して再起動すると、そのステップが最初からやり直されることを意味します。make
make
平均値の現実はMakefile
上記の説明よりもかなり複雑ですが、基本は同じです。
答え2
Ctrl+ は実行中のプロセスにCシグナルSIGINT
を送信します。このシグナルはプロセスによってキャッチされます。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
中間ファイルのクリーンアップが行われます。
答え3
何かが停止するとmake
(Ctrl + C、シャットダウン、または失敗したコマンドなど)、すでに完了した作業はそのまま残ります。言い換えると、make
通常どおりに動作します。つまり、まだ実行する必要がある作業を判断し (ファイルが変更されたり、make
処理されなかったりしても問題ないため)、ジョブを続行します。
上記の説明では、関連するMakefile
が依存関係とコマンドを正しく実行するように記述していることが明確に想定されているため、(再)作成する必要があるのはすべて です。