21

ソースファイルとオブジェクトファイルを分離してMakefileを書き込もうとしていますが、これを実現するための適切な方法がわからないようです。私には2つの方法がありますが、誰かがこれを行うための「正しい」方法を指摘できることを望んでいます。

私のプロジェクトは、これらと同じレベルのMakefileを含むフォルダーにsrc分割されています。obj

最初の方法では、ワイルドカード関数を使用してソースファイルを検索し、srcテキスト置換を使用して対応するオブジェクトファイルを決定します。

SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)

prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(patsubst src/,obj/,$(OBJ))

%.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  

これは機能しているようですが、実行するたびにmake progすべてのオブジェクトファイルが再コンパイルされます。OBJ変数はすべてのオブジェクトの前にある必要があります。src/そうしないと、「ターゲットを作成するルールがありません」というメッセージが表示されます。prog プラス面として、ターゲットのpatsubstを使用して、オブジェクトファイルを簡単に指定できます。

2番目の方法も同様ですが、OBJ変数にvpathとテキスト置換を使用します。

 vpath = %.cpp src
 vpath = %.o obj

 SRC = $(wildcard src/*.cpp)
 OBJ = $(subst src/,,$(SRC:.cpp=.o))
 POBJ = $(patsubst src/,obj/$(SRC:.cpp=.o))

 prog: $(OBJ)
       $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) -o prog $(POBJ)

 %.o: %.cpp
     $(CC) $(CFLAGS) -c $< -o $(COMPILE)/$(@F)  

POJBこれにより、オブジェクトファイルの再コンパイルは不要になりますが、ターゲットに別の変数を追加する必要がありますprog(basedirがないとオブジェクトファイルだけでpatsubstを実行できないため)。

どちらの方法も機能し、それぞれに利点がありますが、どちらが「正しい」アプローチであり、どちらでもない場合、このタイプの建物を実現するための適切な方法は何ですか。

4

1 に答える 1

26

あなたの最初の例はほとんどそこにあります:

SRC = $(wildcard src/*.cpp)
OBJ = $(patsubst src/%.cpp, obj/%.o, $(SRC))

prog: $(OBJ)
  $(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) $(OBJ) -o prog 

obj/%.o: src/%.cpp
  $(CC) $(CFLAGS) -c $< -o $@
于 2012-12-25T06:46:34.380 に答える