2011-11-15 18 views
2

私は再帰的であるように元々設計された(またはそうでない場合もある)古いビルドを書き直しに取り組んでいます。冒頭には、より現代的で表現力豊かで強力なもの(例えば、scons)に移行する日が来るでしょう。しかし、その日は今ではありません。メイクファイルの依存性中毒の扱い

私はこの作業の一環として、ジェネリック変数/マクロ&ターゲット/レシピをいくつかの簡潔なルールファイルに統合して、プライマリビルドの一部として組み込みます。ビルドの各サブセクションは、小さなmakefileを使用してターゲット&の依存関係を追加し、これらのサブメイクファイルに変数を追加する方法はほとんどありません。トップレベルのmakefileはすべてのmakefileをインクルードし、すべてが依存関係ツリーに寄与できるようにします。

私は、人がmakefileを変更する際に適切な判断を下すとは確信していません。

CFLAGS = initial cflags 
all: A.so 
%.so %.o: 
    @echo "${@}: ${CFLAGS} : ${filter 5.o,${^}} ${filter %.c,${^}" 

%.c : 
    true 

%.o : %.c 
A.so : B.so a1.o a2.o a3.o 
B.so : b1.o b2.o b3.o 
A.so : CFLAGS += flags specific to building A.so 

私はその一例をコピー台無しにしなかった場合、状況はこれです:私は心配程度だものの例としてA.soB.soにリンクする、とA.soのオブジェクトがあることを特別なフラグを必要とします建てられた;ただし、B.soBのオブジェクトはCFLAGSに変更を継承します。

より一般的なターゲットの再利用を促進するために、わずかに異なるフラグを必要とするオブジェクトに対してCFLAGSを特に変更する程度であっても、すべてのオブジェクトファイルでなくても大部分をビルドする単一のターゲット(心配するターゲット/レシピが1つしかない場合は、デバッグが簡単になります)。

このビルドを再構築した後、私は誰かがこのような何か愚かなことをしないと自信がありません。私がそれを再検討するつもりがなければ、ピアレビューに合格する可能性があります。場合は、

% : CFLAGS += some naive attempt at altering CFLAGS for a specific purpose 

しかし:誰かが、その後でそれを更新しない限り、依存関係の中毒を防止するであろう

% : CFLAGS = initial cflags 

...:

私はこのような何かを行うためのアイデアを中心に蹴ってきました1000個のターゲット(非常に控えめな見積もり)があり、変数に約1kのメモリが割り当てられていると、約1MBのオーバヘッドが発生し、レシピを使って作業するときにCFLAGSの値を検索するのにかかる時間に大きな影響を与える可能性がありますgmakeはもちろん)。

つまり、私の質問は次のようなものです:メイクファイルの依存性中毒を防ぐには、何が良い/良い方法ですか?私が概説したよりも優れた戦略はありますか?そこに誰もが上記のようにスコープ変数の道を行くことにしようとした場合


編集

は、私は最初は全く明らかではなかったニュアンスに走りました。変数は:=を使用して作成され

% : INCLUDES := 
# ... 
SOMEVAR := /some/path 
% : INCLUDES += -I${SOMEVAR} 
... 
SOMEVAR := 

それだけで=を使用した場合、対象のレシピがINCLUDESを評価されるまで、それは評価を遅らせる一方で、:=の右側にあるすべてのものは、すぐに評価されるべきです。

しかし、SOMEVARは、目標レシピが評価されるときに何も評価されません。あなたが定義を変更した場合:

% : INCLUDES := whatever 
# ... 
SOMEVAR := /some/path 
% : INCLUDES := ${INCLUDES} -I${SOMEVAR} 
... 
SOMEVAR := 

...それはSOMEVARではなく、評価を遅らせるすぐに評価されるように強制的にではなく、グローバルな定義に、その前にスコープ定義にINCLUDES評価しません。

$(flavor ...)INCLUDESsimple、および$(origin ...)戻りfileであると言います。これは、:=または+=を使用するかどうかに関係なく発生します。

つまり、スコープ付き変数で+=を使用すると、スコープ付き変数の定義のみが使用されます。それはグローバルを見ません。 :=を使用すると、グローバルのみが使用されます。明らかに構築されたオブジェクトに、現在構築されたアーカイブの名前が反映されません

A.so_CFLAGS = flags specific to building A.so 
%.so %.o: 
    @echo "${@}: ${CFLAGS} ${[email protected]_CFLAGS} : ${filter %.o,${^}} ${filter %.c,${^}}" 

:あなたがあなたのファイル名に特殊記号を控える場合

答えて

1

、あなたは変数名置換を有するターゲット固有の変数を選択することができますそのライブラリのために、しかし、私はこれが望ましいかどうかわからない。

このアプローチには、実際にはCFLAGSを無効にすることができないなど、明らかに欠点があります。しかし、automakeが同じ問題を解決し、愚かなテキスト置換に頼っていることを考えると、多くの人がすでにここで素晴らしい解決策を見つけることに失敗したと思います。

automakeを再エンジニアリングする代わりに使用することをお勧めします。

+0

+1 automake発言のために+1;私は命名の事で完全に売られているわけではありませんが、それはひどい考えでもありません。 –

関連する問題