2016-12-10 3 views
0

は私のメイクです:ライン9と10でメイクファイルが期待どおりに動作しないのはなぜですか?ここで

SHELL = /bin/sh 
CC=g++ 
CFLAGS=-I. 
DEPS = settings.h 
OBJ = settings.o tomato.o 
EXDIR = $(ROOT_TOMATO)/bin 
OBJDIR = $(ROOT_TOMATO)/obj 

$(OBJDIR)/%.o: %.cpp $(DEPS) 
    $(CC) -c -o [email protected] $< 

$(EXDIR)/tomato: $(OBJ) 
    $(CC) -o [email protected] $^ $(CFLAGS) 

clean: 
    rm -f a.out *.o 

all: tomato 

、私はそれがオブジェクトファイルを作成し、OBJDIRでそれらを置くために取得しようとしているが、それは代わりにカレントディレクトリにOBJファイルを置き、ROOT_TOMATO/src:

$(OBJDIR)/%.o: %.cpp $(DEPS) 
    $(CC) -c -o [email protected] $< 

なぜ機能していないのかわかりません。おそらくもっと良い方法があるかもしれませんが、私はこの特定のケースで私のコードがなぜ機能しないのかを知りたいのです。

側の注意点として、メイクファイルが別のmakefileによって呼び出される:

あなたが $(EXDIR)/tomatoため

$(EXDIR)/tomato: $(OBJ) 

前提条件が、$(OBJDIR)/settings.o$(OBJDIR)/tomato.oではなく、単なるsettings.otomato.o言い

#Main makefile for project 

#Get root compile directory 
ROOT_TOMATO = $(shell pwd) 
export ROOT_TOMATO 

All: 
    $(MAKE) -C src 
+1

9行目と10行目に問題がある場合は、質問をする前に、makefileからEXDIRについて何かを削除する必要があります。あなたの例は最小限ではありません。あなたのメイクファイルには、あなたの質問には関係のないたくさんのゴミもあります。 -1の質問です。 – user31264

答えて

3

OBJで定義したとおりです。したがって、パターンルールはそれらを構築するためには使用されず、settings.otomato.oを構築する暗黙のルールに戻ってしまいます。

あなたは代わりに使用することができ

$(EXDIR)/tomato: $(OBJ:%=$(OBJDIR)/%) 

...またはそれを得る-行くからこれらのパスが含まれていることをそうOBJを設定します。

cleanルールにも同様の問題があるため、実際のオブジェクトパスを含む変数を使用することは賢明であることに注意してください。 $(EXDIR)/tomatoの前提条件とcleanレシピの両方で使用できます。

また、内部Makefileのデフォルトルールはallではなく、$(EXDIR)/tomatoであることに注意してください。これは特定のターゲットの最初のルールです。これは良いことです。 allルールは、その前提条件が$(EXDIR)/tomatoではなく、ルールがないため、tomatoであるため、意図したとおりに機能しません。私はあなたがそれを修正し、ある時点で上部にallルールを移動したいと思うだろうと思う。

+0

ありがとうございます。あなたの答えは実際に働いた。 – user3273814

0

Makeは、 'keep it simple'という言葉がであり、偉大なアドバイスです。単純なことが単純な言語です。難しいものはラインノイズのように見えます。

メイクは、実行可能なビルドプロセスドキュメントの一種であることを忘れないでください。可読性は良いことです。

私はある

CXX=g++ 
OBJ=settings.o tomato.o 
TARGET=tomato 

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


# default target 
$(TARGET): $(OBJ) 
    $(CXX) -o $(TARGET) $(OBJ) $(CFLAGS) 

tomato.o: settings.h 
settings.o: settings.h 

clean: 
    rm $(TARGET) *.o 

ようなものとしてあなたのMakefileを書き換えたい:

  1. それは、C++コンパイラのマクロとしてCXXを使用し、CコンパイラのCCを残すために、従来のです - ルールを読んでいる誰もが正しい結論にジャンプするよう促します。
  2. %.o: %cppルールは単純にしておいてください。だから、現在のディレクトリにたくさんの*.oファイルがあります。大したことです!それらをMercurial/Git無視ファイルに入れて移動してください。 を別のディレクトリに入れ、@Wintermuteはそれを行う方法を示していますが、句読点が必要であり、実際にはそれほど多くはありません。
  3. $(VAR:sub=result)構成をどのように使用する必要はないことに注目してください。便利ですが、あまりにも多すぎると結果がすぐに判読できなくなります。
  4. %のルールに依存関係を置くことを嫌う。これらのモジュールを個別に表現すると(tomato.osettings.oの依存関係のように)、これらのモジュールには何もないと書いてあります。はすべてがきれいに見えます。

自動的すべてを行い、複雑なmakefileが(...ああ、私から弟をそれを取る)先延ばしの素晴らしい方法です。

+1

これはすべて良いアドバイスかもしれませんが、オブジェクトファイルを別のディレクトリに置く方法であった、質問された質問には関係がありません。 – MadScientist

関連する問題