1

私のメイクファイル:

CC=cc
INC=-I.
CFLAGS=-g  -DDEBUG -std=gnu99 -DSFHASH -DDOMAIN
LDFLAGS=-ldl
OBJS=*.o
OBJDIR=.obj
BINDIR=.obj
LIBDIR=.obj

%.o: %.c
        $(CC) $(INC) $(CFLAGS) -DSFHASH -o $(OBJDIR)/$@ -c $<


VPATH = .obj
#vpath %.o $(OBJDIR)

hashtest: hashfuncs.o hast.o scanners.o parseargs.o
        $(CC) -rdynamic -o $(BINDIR)/$@ $^ $(LDFLAGS)

clean:
        @rm -f $(OBJDIR)/$(OBJS) $(BINDIR)/hashtest

初めて使用します: make は gcc の入力ファイル パスを書き換えません:

@delphi# make clean
@delphi# make
cc -I. -g  -DDEBUG -std=gnu99 -DSFHASH -DDOMAIN -DSFHASH -o .obj/hashfuncs.o -c hashfuncs.c
cc -I. -g  -DDEBUG -std=gnu99 -DSFHASH -DDOMAIN -DSFHASH -o .obj/hast.o -c hast.c
cc -I. -g  -DDEBUG -std=gnu99 -DSFHASH -DDOMAIN -DSFHASH -o .obj/scanners.o -c scanners.c
cc -I. -g  -DDEBUG -std=gnu99 -DSFHASH -DDOMAIN -DSFHASH -o .obj/parseargs.o -c parseargs.c
cc -rdynamic -o .obj/hashtest hashfuncs.o hast.o scanners.o parseargs.o -ldl
cc: error: hashfuncs.o: No such file or directory
cc: error: hast.o: No such file or directory
cc: error: scanners.o: No such file or directory
cc: error: parseargs.o: No such file or directory
make: *** [hashtest] Error 1

2 回連続で使用すると、次のようになります。

@delphi# make
cc -rdynamic -o .obj/hashtest .obj/hashfuncs.o .obj/hast.o .obj/scanners.o .obj/parseargs.o -ldl
@delphi# 

GNU Make マニュアルには次のように書かれています。

make 変数 VPATH の値は、make が検索するディレクトリのリストを指定します。ほとんどの場合、ディレクトリには、現在のディレクトリにない前提条件ファイルが含まれていると予想されます。ただし、 make は前提条件と *ルールの対象*の両方の検索リストとして VPATH を使用します

VPATH が set-once-at-startup-typeof-variable であるかどうかは理解できますが、そうではありません。実行時に生成されたターゲットの依存関係が適切に検索されているという事実がそうです。

どうしたの?make が gcc の入力ファイル パスを 2 回目だけ正しく書き換えるのはなぜですか?

4

2 に答える 2

2
Subject: Re: (un)expected make behavior while using VPATH
From: mad scientist

<<< %.o: %.c

<<< $(CC) $(INC) $(CFLAGS) -DSFHASH -o $(OBJDIR)/$@ -c $<

これは無効なルールです。これは、私の「makefile のルール」の 1 つに違反しています。

http://make.mad-scientist.net/rules.html

<<< 初めて使用する場合: make は gcc の入力ファイル パスを書き換えません。

<<< 2 回連続で使用すると、次のようになります。

クラシック。気分を悪くしないでください。最初は誰もがそうします。これは、VPATH の設計が間違っていること (または他の機能が必要であること) を指摘している可能性があります。ただし、それは別の会話です。これは役立つかもしれません:

http://make.mad-scientist.net/vpath.html

乾杯!

help-make ml から、スレッドhttp://lists.gnu.org/archive/html/help-make/2012-11/msg00018.html

于 2012-11-14T07:50:52.903 に答える
1

この動作の説明は、GNU Make マニュアルのセクション 3.7 にあります

3.7 make が Makefile を読み取る方法

GNU make は、2 つの異なるフェーズで作業を行います。最初のフェーズでは、すべてのメイクファイル、含まれているメイクファイルなどを読み取り、すべての変数とその値、暗黙的および明示的なルールを内部化し、すべてのターゲットとその前提条件の依存関係グラフを構築します。

第 2 段階では、make はこれらの内部構造を使用して、再構築が必要なターゲットを決定し、再構築に必要なルールを呼び出します。

makeを初めて実行するときは、.objディレクトリ内の前提条件がまだ存在していません。つまり、最初のフェーズで作成された依存関係グラフの一部にはなりません。したがって、これらの前提条件は、作成するルールを実行する第 2 フェーズでは使用されません。hashtestただし、第 2 フェーズで以前に実行されたルールのために、その時点までに存在していたとしてもです。

2 回目の実行make時には、これらの前提条件が存在し、設定によって検出され、依存関係グラフに含まれVPATHます。

VPATHの式は単なる検索パスであり、それ以上のものではないことに注意してください。複数のディレクトリ名をコロンで区切って含めることができます。make最初のフェーズで依存関係グラフを構築する際に、その検索パスで前提条件とターゲットを検索します。その検索リスト内のディレクトリに特定のターゲットが見つかった場合、そのターゲットは既存のファイルとして依存関係グラフに追加されます。

そのターゲットがそのサブディレクトリに存在せず、作成する必要がある場合でも、サブディレクトリをターゲットにmake追加することを期待しているようです。VPATHそれはそれがどのように機能するかではありません-その場合make、複数のディレクトリをどのように処理しVPATHますか?

于 2012-11-13T17:22:25.013 に答える