2

動作しているように見えるこの Makefile がありますが、方法がわかりません:

EXECUTABLE=hello
CC=gcc
OBJS = a.o

all: $(EXECUTABLE)

%.o : %.c
    $(CC) -o $@ -c $<

$(EXECUTABLE): $(OBJS)
    $(CC) -o $@ $<

上の 3 行がローカル定義であることはわかっています。「Make」と入力すると、allターゲットがビルドされます。ここから、私は少し迷っています...私は推測しています:

  1. Makeは$(EXECUTABLE)ラベルを見て、そのビルドコマンドにジャンプします
  2. ラベルが$(OBJS)表示a.oされ、ローカル ディレクトリに存在しないため、パターン マッチング ルールにジャンプします。
  3. a.c生成するルールを見つけて実行するa.o
  4. ここで Make はコマンドに戻り$(EXECUTABLE)、.o ファイルの組み合わせを実行して「hello」プログラムを作成します。

質問:

  1. その流れに対する私の理解は正しいですか?
  2. このファイルの「ラベル」の配置は適切ですか?
  3. これがどのように機能するかについての私の疑いを確認する、私が見逃しているいくつかの GNU ドキュメントはありますか?
4

2 に答える 2

1

あなたの流れは基本的に正しいです。コマンド ラインでターゲットを明示的に渡さない場合、Make はファイルにリストされている最初のターゲットをビルドします。ほとんどのメイクファイルでは、人々はall最初のターゲットとして持っているので、例のように入力するだけmakeでターゲットが自動的にビルドされますall。make が内部的に行うことは、Makefile で定義している依存関係のリストを作成することです。allは に依存し$(EXECUTABLE)ており、 は に依存してい$(OBJS)ます。ターゲットの作成を満たすためには、allその依存関係リストの一番下から始めて、上に向かって作業する必要があります。http://www.gnu.org/software/make/manual/をご覧になりたい場合、make マニュアルは実際には非常に優れています。http://www.gnu.org/software/make/manual/make.html#How-Make-Works

于 2013-03-08T15:15:19.493 に答える
1

少なくとも質問の一部に答えるのに役立つツールを見つけたので、自分自身や他の人の参考のために投稿します。

$(warning <some string>)呼び出しを介して Makefile を「デバッグ」することができます。

したがって、私の例では、次のように使用しました。

all: $(warning All before exe call) $(EXECUTABLE)
    $(warning All warning after call)

%.o : %.c
    $(warning before pattern)
    $(CC) -o $@ -c $<
    $(warning after pattern)

$(EXECUTABLE): $(warning before obj) $(OBJS)
    $(warning after obj)
    $(CC) -o $@ $<

そして、フローを示す出力を得ました:

mike@mike-VirtualBox:~/C$ make
Makefile:6: All before exe call    // started at all
Makefile:14: before obj            // Jumped to EXECUTABLE label
Makefile:10: before pattern        // Jumped to pattern matching
Makefile:10: after pattern
gcc -o a.o -c a.c
Makefile:15: after obj             // back to EXECUTABLE label
Makefile:15: after build           // back to build command
gcc -o hello a.o
Makefile:7: All warning after call

これを使用して、これができることを発見しました:

$(EXECUTABLE): $(warning before obj) $(OBJS)

だがしかし:

$(EXECUTABLE): 
    $(warning before obj) 
    $(OBJS)

Makefileでは空白が重要なので、これは理にかなっています

于 2013-03-08T15:23:25.857 に答える