2016-11-13 4 views
1

私は小さなプロジェクトを構築し、それを掃除するためのルールを含むMakefileを持っています。たとえば:Makefileで 'build'と 'clean'の 'rebuild'ルールを作るには?

CC:=gcc 
LD:=gcc 
SOURCES:=$(wildcard src/*.c) 
OBJS:=$(SOURCES:src/%.c=build/%.o) 
TARGET:=bin/program 

all: $(TARGET) 

$(TARGET): $(OBJS) 
    @mkdir -p bin 
    $(LD) $+ -o [email protected] 

build/%.o: src/%.c 
    @mkdir -p build 
    $(CC) $+ -c -o [email protected] 

clean: 
    rm -rf $(OBJS) 
    rm -rf $(TARGET) 
    rmdir bin 
    rmdir build 

.PHONY: clean all 

私は今、そのためにcleanallを実行することになり、ルールrebuildの作成に興味があります。私は正しい順序をいかに適切に達成しているかわかりません。


私が見た解決策は私の知るところでは間違っています。

rebuild: clean all 
.PHONY: rebuild 

実際に依存関係が表示される順番に実行されるという保証はないため、当然間違っています。 allcleanより前に実行されます。

注文のみの依存関係を示唆する回答があります。

rebuild: | clean all 
.PHONY: rebuild 

私の知る限り、これは問題を解決しません。 a: | b cと言う場合、abcに依存しますが、bまたはcを入力した場合は、強制的にaルールを実行するわけではありません。それはとの関係がありません。は依存関係です。私は今見

唯一のオプションは、私は本当にそのような単純な何かを行うための新しいメイクのインスタンスを起動避けたい

rebuild : clean 
    make build 

を持つことで、メイクの新しいインスタンスを起動しています!


私はいくつかreasearchを行った。私は同様の質問を見たことがあるが、は正しいと答えた答え。私のknolwedgeには、ターゲットを.PHONYにするか、注文のみの依存関係を使用することは解決策ではありません。 (それが有効になって並列処理-jなし、である)シリアルを実行しているときに

rebuild: clean all 

allclean前にビルドすることができること:

答えて

6

まず、それはルールでというのは本当ではありません。 Makeはmakefileにリストされている順番で前提条件を作成します(レシピを含むルールは特別なケースがありますが、ここでは関係ありません)。並列ビルドを使用すると、makeは依存関係ツリーを同じ順序でまだ歩いていますが、ルールは並行して構築されるため、同じ順序で開始されない可能性があります。

しかし、このルールは他の理由(ディレクトリキャッシングなど)には適していません。)

私はあなたがこれを行うには、再帰的なメーク呼び出しを使用することをお勧め:

.PHONY: rebuild 
rebuild: 
     $(MAKE) clean 
     $(MAKE) all 
1

再帰せずにそれを行うための方法があります。価格は、冗長性の少量です:

.PHONY: rebuild 
$(TARGET) rebuild: $(OBJS) 
    @mkdir -p bin 
    $(LD) $+ -o $(TARGET) # note that I have replaced [email protected] with $(TARGET) 

rebuild: | clean 
2

あなたは目標がrebuildあるとき、条件付きcleanall間の依存関係を追加するMAKECMDGOALSを使用することができます。このような何か:

ifeq (rebuild,$(findstring rebuild,${MAKECMDGOALS})) 
all: clean 
rebuild: all 
endif 

今それを行うには、他の些細な、安全な方法があるとき、私は本当にメイクファイルでこれを行うことの利点が表示されていない(ちょうど「make clean && make allは」より良い選択肢かもしれません)

関連する問題