2016-05-16 18 views
4

これは、ディレクトリ内のすべてのC++ファイルをオブジェクトファイルに変換するという現在の目標で書いたmakeファイルです。私の問題は、常にg ++を実行し、次に他のコマンドを実行することです。最も簡単な修正は常にターゲットディレクトリを使用する前に、mkdirを発行することですmake実行命令の問題

g++ -Iclasses/ -c classes/source/helloworld.cc -o build/release/objs/helloworld.o `pkg-config --cflags --libs gtkmm-3.0` 
mkdir -p build/release/objs 

おかげ

+1

'ビルド/リリース/ objs'のための別の依存関係のターゲットを提供し、' '$(PROGS)の前にあることを置きます。 –

+1

'all 'の規則は次のように言っています:' $(PROGS) 'がすべて最新であることを確認してください。それが終わったら、 'mkdir'を実行すると' all'を作成する作業が完了します。あなたは 'all:objdir $(PROGS)'のようなものが必要です。ここで、 'objdir'のルールは次のようになります:' objdir:; mkdir -p build/release/objs'(セミコロンの代わりに改行とタブを使いますが、実際には1行で表記します)。これは、@πάνταῥεwhatが言ったことのちょうど長いバージョンです。 –

+0

Jonathan Lefflerあなたは私の問題を解決し、makeの仕組みを理解するのに役立つ素晴らしい説明を提供しました。 – Russeree

答えて

1

レシピが後のいずれかの前提条件を実行しているたとえば、再帰が作る使用だから、allを作るときを実行する前に$(PROGS)を通過します。ディレクトリが存在しない限り、彼らが行うことができないため、

build/release/objsは、オブジェクトファイルの前提条件でなければなりません。 dirタイムスタンプが変更された場合は、すべてのオブジェクトファイルをリメイクしたくないので、ディレクトリはorder-only prerequisiteである必要があります。

あなたのパターンルールは、同様に(2を参照)brokenで、あなたは間違ったflag variablesを使用しています。 built-in implicit rule for compilingもリサイクルできます。

CXXFLAGS := $(shell pkg-config --cflags --libs gtkmm-3.0) 
CPPFLAGS := -Iclasses/ 
SRCS  := $(wildcard classes/source/*.cc) 
OBJS  := $(SRCS:classes/source/%.cc=build/release/objs/%.o) 

.PHONY: all 
all: $(OBJS) 

$(OBJS): build/release/objs/%.o: classes/source/%.cc | build/release/objs 
    $(COMPILE.cc) $(OUTPUT_OPTION) $< 

build/release/objs: ; mkdir -p [email protected] 

サイドノート:あなたが唯一のflagsにすべきではないでしょう-libs gtkmm-3.0をコンパイルしているので、リンクするとき、あなたはLIBSを提供しています。

+0

ありがとう、ありがとうございます。 – Russeree

+0

@Russeree質問に答えた場合は、回答を受け入れてください。 – user657267

+0

ありがとうございました。 – Russeree

3

:中

CC=g++ 
CPPFLAGS=`pkg-config --cflags --libs gtkmm-3.0` 
SRCS=$(wildcard classes/source/*.cc) 
PROGS=$(patsubst %.cc,%,$(SRCS)) 
CLASS_HEADERS=classes/ 
all: $(PROGS) 
    mkdir -p build/release/objs 
%: %.cc 
    $(CC) -I$(CLASS_HEADERS) -c $< -o build/release/objs/$(@F).o $(CPPFLAGS) 

結果。 -pオプションを使用している場合、このコマンドを重複して実行することは実際には問題ありません。

%: %.cc 
    mkdir -p build/release/objs 
    $(CC) -I$(CLASS_HEADERS) -c $< -o build/release/objs/$(@F).o $(CPPFLAGS) 

GNU make's -j optionに私の答えで述べたように:それは時々働くかもしれないが、単にあなたの既存のall依存リストの最初の依存関係としてmkdirターゲットを追加することは正しくありません。原則として、これらは任意の順序で実行することができます(mkdirは必ずしも最初ではありません)。依存関係に基づくアプローチを採用したい場合、より複雑な作業を開始する必要があります。

all: do_mkdir 
    $(MAKE) $(progs) 

do_mkdir: 
    mkdir -p build/release/objs 
1

解決策オブジェクトディレクトリのターゲットを作成し、ビルドターゲットの前にそれを置くことができます:ターゲットの

...... 
OBJ_DIR := build/release/objs 

all: create_obj_dir $(PROGS) 

create_obj_dir: 
    mkdir -p $(OBJ_DIR) 

%: %.cc 
    $(CC) -I$(CLASS_HEADERS) -c $< -o $(OBJ_DIR)/$(@F).o $(CPPFLAGS) 
+1

-jを使って複数のmakeスレッドを実行すると、必ずしも動作しません。 –

+0

@ChrisDodd true ... –