目標を2つの単語に設定する

目標を2つの単語に設定する

Makefileを使ってコンパイルしています。きれいパスワード。私のクリーンファイルには、次の形式のファイル名が*.iclあります.icl

$(EXE): % : %.icl | copy
    $(CLM) $(CLM_LIBS) $(CLM_INC) $(CLM_OPTS) $@ -o $@

それでは、バイナリを実行できるルールを追加したいと思います。最近はよくあります。

make some_module && ./some_module

上記のルールに従ってモジュールを実行する make ターゲットが欲しい。しかし、モジュール名自体はすでに別々のコンパイル対象なので、そのままにしたいと思います。私が望むのはmake run some_module、呼び出し可能で上記の規則に従って実行できる2つの単語を持つターゲットです./some_module

複数の単語を含むターゲットを作成できますか?

私は次の規則を作成しようとしました(今は依然として依存関係がありません)。

run $(EXE):
    ./$@

実行すると、make run some_module多くのレシピが「上書き」と「無視」され、最終的に./run存在しなくなります。

Makefile:24: warning: overriding recipe for target 'tut7_2_2'
Makefile:21: warning: ignoring old recipe for target 'tut7_2_2'
Makefile:24: warning: overriding recipe for target 'support_check'
Makefile:21: warning: ignoring old recipe for target 'support_check'
[...]
Makefile:24: warning: overriding recipe for target 'drawingframe'
Makefile:21: warning: ignoring old recipe for target 'drawingframe'
./run
/bin/bash: ./run: No such file or directory
Makefile:24: recipe for target 'run' failed
make: *** [run] Error 127

答え1

あなたは使用することができます$(MAKECMDターゲット)runコマンドラインで指定された他のターゲットの中で最後に強制します。以下の例は、Cleanがわからないので、Cで書かれています。

EXE = a b c

%: %.c
    $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)

all: $(EXE)

clean:
    rm -f $(EXE)

run: $(filter-out run, $(MAKECMDGOALS))
    @for i in $^; do ./$$i; done

.PHONY: all clean run

make run program常に不要な出力を生成するため、少しぎこちないように見えますprogram is up to date

$ cat a.c
#include <stdio.h>
int main(int argc, char **argv) { printf("This is %s\n", argv[0]); return 0; }
$ cp a.c b.c
$ cp a.c c.c

$ make run a b
cc  -o a a.c
cc  -o b b.c
This is ./a
This is ./b
make: 'a' is up to date.
make: 'b' is up to date.

make program runそのような出力がなければ、英語のようにもっと自然になるかもしれません。

$ make c run
cc  -o c c.c
This is ./c

答え2

あなたはできます調査するMAKECMDGOALS他の目標を設定している間に1つの目標の存在を検出します。%: %.icl実行が target の存在を検出するようにするかrunruntarget と呼ばれる実行ファイルを target 確認するようにしてください。複数の実行可能ファイルをターゲットに渡す場合、最初のメソッドを使用すると各ファイルがビルドの直後に実行され、2番目のメソッドを使用するとすべての実行が最後に実行されます。

このアプローチの欠点は、他の機能とうまく拡張できないことです。たとえば、複数の実行可能ファイルを持つターゲットを依存関係として定義すると、ターゲットを持つrunメソッドは機能しません。

EXE = foo bar experimental
released: foo bar
run: $(filter $(EXE), $(MAKECMDGOALS))
        set -e; for x in $^; do ./$x; done

ここではmake released run何も実行されません。

このような状況で私が一般的にすることは、各実行可能ファイルの「実行」ターゲットを定義することです。これにより、各目標を単一の単語で表現できることが大きな利点です。シンプルで他の機能を損なうことはありません。

$(EXE): %.run: %
        ./$(@:.run=)
all.run: $(EXE:=.run)

make {foo,bar}.runfoo次に、ビルドしてテストしたい、またはビルドしてbar実行make all.runするには実行します。

関連情報