makefileは別のターゲットを実行します


122

私はこのような構造のメイクファイルを持っています:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

「make all」を実行する前に、ターミナルで一貫して「make clean」に続けて「clear」を実行していることに気付きました。厄介なC ++コンパイルエラーを試す前に、クリーンな端末を用意するのが好きです。だから私は3番目のターゲットを追加しようとしました:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

これは機能しますが、makeの2番目のインスタンスが実行されます(私は信じています)。makeの2番目のインスタンスを実行せずに同じ機能を取得する正しい方法はありますか?

回答:


171

実際、あなたは正しいです。それはmakeの別のインスタンスを実行します。可能な解決策は次のとおりです。

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

呼び出すmake freshと、最初にcleanターゲットが取得され、次にclearscreenwhichが実行されclear、最後にallwhichがジョブを実行します。

8月4日編集

makeの-jオプションを使用した並列ビルドの場合はどうなりますか?順序を修正する方法があります。makeマニュアルのセクション4.2から:

ただし、これらのルールのいずれかが実行された場合にターゲットを強制的に更新せずに、起動するルールに特定の順序を課したい場合があります。その場合、注文のみの前提条件を定義します。注文のみの前提条件を指定するには、前提条件リストにパイプ記号(|)を配置します。パイプ記号の左側にある前提条件はすべて正常です。右側の前提条件は注文のみです:ターゲット:通常の前提条件| 注文のみの前提条件

もちろん、通常の前提条件セクションは空でもかまいません。また、同じターゲットに対して複数行の前提条件を宣言することもできます。それらは適切に追加されます。同じファイルを通常の前提条件と注文のみの前提条件の両方として宣言すると、通常の前提条件が優先されます(これらは注文のみの前提条件の動作の厳密なスーパーセットであるため)。

したがって、makefileは次のようになります。

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

12月5日編集

タスク内の各コマンドは次のようになりますので、複数のmakefileのインスタンスを実行するには大したことではありませんサブシェルをとにかく。ただし、call関数を使用して再利用可能なメソッドを作成できます

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")

6
@ sas4740:基本的に、以降のすべて.PHONY : は常に実行されるキーワードとして扱われますが、偽のターゲットはファイルを対象としています。
Dacav

「注文のみの前提条件」は条件付きですか?目標のために私は最初のT0 succedsをt1を実行して、両方succedsはT3で、いくつかのタスクを実行する場合にのみ場合にのみよりも、T0を行いたいT2
fantastory

1
@fantastory、いや、彼らは独立していると思いますt2依存しt0t1そしてt3。あなたがこれを必要とする場合、あなたは置くべき t3で必要とされるt2t1で必要とされるt3t0で必要とされますt1。これは、3つの異なるルールを意味します。ただし、これを確認する必要があります。100%よくわかりません。
Dacav 2015年

3
「注文のみの前提条件は、」独立している
fantastory

2
「すべて」の前に「クリーン」が実行される保証がどこにあるのかわかりませんか?あなたがそれらを正しく置くという事実| それらは順序どおりに実行されません。順序のみの依存関係は、そのような操作の後でターゲットが必ずしも更新されないことを意味します。依存要素の順序とは関係ありません...または?
CygnusX1 2016年

6

make all「新しい」ターゲットから行を削除した場合:

fresh :
    rm -f *.o $(EXEC)
    clear

次のmake fresh allように実行されるコマンドを実行するだけです。make fresh; make allです。

これをmakeの2番目のインスタンスと考える人もいますが、これは確かにmakeのサブインスタンス(make内のmake)ではなく、これが結果として発生したようです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.