2009-06-10 5 views
8

私は、nタプルリストを使用してクリーンアップできるMakefileをたくさん書いていることがわかりました。しかし、私はこれを正しく(そしてきれいに)行う方法を見つけることができません。これまで私は$(シェル...)trsed、またはそうでなければMakefile以外の標準を使って思いつきました。例えばMakefilesでリストを反復する?

、私はこれを行うにはしたいと思います:

XYZs = \ 
    dog.c pull_tail bark \ 
    duck.c chase  quack \ 
    cow.c tip  moo 

all: 
    @- $(foreach X Y Z,$(XYZs), \ 
     $(CC) $X -o bully/$Y ; \ 
     ln bully/$Y sounds/$Z ; \ 
    ) 

はMakefileの中でのnタプルのリストを反復処理するための良い方法はありますか?ありがとう!

答えて

10

メークファイルは基本的に本質的に宣言的なものなので、make自体が自分が望むものを提供するとは思わない。しかし、いくつかの文字列の値を特定のターゲットに関連付けることを望んでいるように見えるので、GNU makeのTarget specific variable valuesの機能に興味があるかもしれません。これは、マニュアルからの抜粋です:

ターゲット固有の変数の1つの以上の特別な機能があります:あなたは、変数値は、すべての依存関係のために効果 でもあることをターゲット固有の変数、 を定義する ときこのターゲット (ただし、これらの依存関係は、 を独自のターゲット固有の 変数値で上書きしない限り)。したがって、たとえば、このような 声明:

prog : CFLAGS = -g

prog : prog.o foo.o bar.o

progためのコマンドで-gに スクリプトをCFLAGSを設定しますが、それはまた コマンドで-gCFLAGSを設定しますprog.o、foo.o、 およびbar.oを作成するスクリプト と、依存関係を作成するコマンド・スクリプト があります。

まだ読んでいないのなら、GNU makeマニュアルはかなり良いです。

編集:あなたがあなたのコメントでは約尋ねた何をすべきか:

dog: ANIMAL=dog.c BULLY=pull_tail SOUND=bark 

使用:

dog: ANIMAL=dog.c 
dog: BULLY=pull_tail 
dog: SOUND=bark 
+0

涼しく、途中にあるかもしれません!これを行うための構文はありますか? 犬:ANIMAL = dog.c BULLY =プルテールSOUND =樹皮 – Dylan

+0

+1、とても素敵です。 –

+2

問題は、makeが宣言的ではなく、この頻繁に必要なパターンの宣言構文を提供していないことです。 – reinierpost

0

あなたは後方にそれをやっています。

あなたはスクリプトのようにmakeを扱っています。そうではなく、与えられたXをYを作成する方法に関する一連の規則です。そして、makeエンジンは、その結果を得るために何が起こる必要があるかを把握します。

上記の例では、実際に生成手順にスクリプトを使用する必要があります。おそらくそれをmakeから呼び出すのですが、CCの内容を処理させてください。

+4

これは、最初にそこにいる理由がなく、とにかく$(foreach)で回避できるmakeの限界です。 – reinierpost

2

私が知っていることはありませんが、それはあなたが強制的に命令言語を実行しようとしているからです。GNUで

あなたはおそらくのような何かをしたいと思いますあなたのためのリンクを処理するために、.cファイルのデフォルトのルールを再定義し、まだ

pull_tail : SOUND=bark 
pull_tail : dog.c 
     $(CC) $< -o $^ 
     ln [email protected] $(SOUND) 

chase : SOUND=quack 
chase : duck.c 
     $(CC) $< -o $^ 
     ln [email protected] $(SOUND) 

... 

またはより良いのが、あなたの名前の奇妙な構造(プログラム名にはソース名との字句関係はありません)、それは難しくなります。

あなたが手編集があまりなく迅速にこれを再構築することができるようにしたいものを、あなたはおそらくデータからのmakefile framgmentを再生成し、作るGNUのinclude機能を使用するスクリプトを書きたい場合は...

5

私はforeachのGNU Makeマニュアルをチェックしたいと思います。ここでは私が別のプロジェクトで使ったいくつかのランダムな切り取りです...例は不完全ですが、多分あなたにいくつかのアイデアを与えるでしょうか?私はより多くの時間を持っている場合、私はあなたがoに各cファイルをコンパイルすると同じ拡張子を持つファイルの集合のデフォルトのルールを使用することができます...後で

REMAKE_PROGS:= dog duck cow 

XYZs = \ 
    dog.c pull_tail bark \ 
    duck.c chase  quack \ 
    cow.c tip  moo 

$(foreach src, $(XYZs), $(eval $MAKE $(src)) 

$(REMAKE_PROGS): 
     @echo "\n# === [email protected] linking\n" 
     $(call compile,[email protected],$([email protected]),$(CXX),$(MPICXX),$(LDFLAGS) $(LIBS) $(SYSLIBS) $(OTHER_LIB) $(EXTRA_LD_FLAGS)) 
     @echo "\n# --- [email protected] compiled\n" 

define compile 
    @mkdir -p $(dir $(1)) 
    $(if ${ANNOUNCE},@echo "\n# +++ ${MAKECMDGOALS} compiling\n" $(eval ANNOUNCE=)) 
    $(call compiler,$(1),NOMPI,$(3),$(4)) 
    $(eval MY_FLAGS=$(FLAGS_$(1)) $(5)) 
    $(if $(filter %xlf %xlf90,$(COMPILER_$(1))),$(eval MY_FLAGS:=$(MY_FLAGS:-D%=-WF,-D%))) 
    $(strip $(COMPILER_$(1)) $(2) $(MY_FLAGS) -o $(1)) 
endef 
+0

私はforeach-call-makeではなくforeach-eval-callを使用していますが、これはちょっと醜いものです。 http://www.gnu.org/software/automake/manual/make/Eval-Function.html#Eval-Function – reinierpost

0

これをクリーンアップするかもしれません。もちろん、特別なファイル拡張子に制限されるわけではありません。 .c一連のファイルをコンパイルするために、あなたはこのようにそれを行うことができます:

OBJS = foo.o bar.o baz.o 
OUT = myprog 

all: $(OBJS) 
     $(SILENT) echo "LD [email protected]" 
     $(SILENT) $(CPP) -o $(OUT) $^ $(LDFLAGS) 

%.o: %.c 
     $(SILENT) echo "CC $<" 
     $(SILENT) $(CC) $(CCOPTS) -o [email protected] -c $< 
+0

「現在の$(OBJ)値」を使用する必要があるときに問題が発生します。パターンルール。 GNU makeはそのための宣言的な構文を提供していないし、$(foreach)は醜い(しかし完璧に機能する)回避策である。 – reinierpost

6

感謝のヒントを - いくつかのハッキングの後、私はこれは私が望んでいたものよりだと思う:

XYZs = \ 
    dog.c:pull_tail:bark \ 
    duck.c:chase:quack \ 
    cow.c:tip:moo 

all: 
    @- $(foreach XYZ,$(XYZs), \ 
     $(eval X = $(word 1,$(subst :, ,$(XYZ)))) \ 
     $(eval Y = $(word 2,$(subst :, ,$(XYZ)))) \ 
     $(eval Z = $(word 3,$(subst :, ,$(XYZ)))) \ 
     \ 
     $(CC) $X -o bully/$Y ; \ 
     ln bully/$Y sounds/$Z ; \ 
    ) 

缶誰もっとうまくいく?