2017-04-20 6 views
0

allの私のルールのエコーは適切なものを表示しますが、私がコメントした行にOBJSの定義を移動するとmakefileは動作しません。で、メイクファイルが実行されますが、私はOBJS移動したときに、私は次のエラーを取得するよう:(:=ではなく)=で設定このメイクファイルの変数の奇妙な寿命を教えてください

[email protected]$ make
OBJS = other.o main.o
g++ -Wall other.o main.o -o main
g++: error: other.o: No such file or directory
g++: error: main.o: No such file or directory

#MAKEFILE 

CPP_COMP=g++ 

CFLAGS = -Wall 

CPP_SRC = $(wildcard *.cpp) 

#Define OBJS here and the makefile works. Define OBJS *HERE* it fails as shown below. 
OBJS = $(CPP_SRC:.cpp=.o) 

all: $(OBJS) 
     @echo "OBJS = $(OBJS)" 
     $(CPP_COMP) $(CFLAGS) $(OBJS) -o main 

#*HERE* 
#Why can't I put CPP_SRC and OBJS here? 
#The echo statement above prints out the appropriate value even if I put the variables here. 

%.o: %.cpp 
     $(CPP_COMP) $(CFLAGS) -c $< -o [email protected] 

clean: 
     rm *.o main 

答えて

2

Makefileの変数が評価され、それらが設定されている時に展開されていない、唯一のそれらが使用されるとき。ルール内で使用される変数は、ルールが定義されたときに展開され(ターゲットと前提条件が何であるかを判断するために)展開されますが、アクションが実際にに実行されるまで展開されません。

したがって、OBJS = $(CPP_SRC:.cpp=.o)を設定すると、実際の文字列($など)にはOBJSが設定されます。次に、ルールall: $(OBJS)があると、$(OBJS)が展開され、次に$(CPP_SRC)が展開され、$(wildcard ...コマンドが実行されます。一方、アクション@echo "OBJS = $(OBJS)"は、その文字列を展開せずに記録するだけです。アクションが実際に実行されたとき(Makefile全体が読み込まれた後に実行され、何を実行するかが分かり始めたとき)にのみ、$(OBJS)が展開されます。

OBJSの定義を下に移動するということは、ルールが読み込まれるときに定義されていない(つまり、空の文字列に展開される)ことを意味しますが、アクションの実行時に定義されます。

+1

Spicerは次のように追加します:**期間**。 :-) – Jens

関連する問題