0

私は GNU を使用しています。ここでは、次のようなさまざまなタイプのビルドに対して、別の を呼び出すmakeトップ レベルがあります。makefilemakefile

LIST_OF_TYPES: 32 64 ...

tgt-name: deps
          $(foreach i,$(LIST_OF_TYPES), \
            $(MAKE) -f $(MY_MAKEFILE) ARCH=$i mylib;)

などのより高いj係数で実行すると-j100、ビルドの1つが失敗しますが、戻り値はまだ0そうです。ビルドが本当に機能したかどうかわかりません! foreachコンストラクトの使用方法に問題はありますか? それとも、問題を引き起こしているjのは単に高いですか?foreach

4

2 に答える 2

1

あなたがリストした最上位のメイクファイルは安全です-j(ただし、最適ではありません)。の展開後$(foreach...)make実質的に以下が表示されます。

tgt-name: deps
    $(MAKE) -f $(MY_MAKEFILE) ARCH=32 mylib; $(MAKE) -f $(MY_MAKEFILE) ARCH=64 mylib; ...

これらのサブ make の 1 つが失敗した場合 (の誤った処理が原因で-j)、その失敗は最上位の make に報告されません。次のようなものを使用する必要があります。

tgt-name: deps
    $(MAKE) -f $(MY_MAKEFILE) ARCH=32 mylib && $(MAKE) -f $(MY_MAKEFILE) ARCH=64 mylib && ... && :

&&、前のコマンドが失敗した場合にエラーですぐに終了するように bash に指示します。(:最後の は bash ビルトインで、正常終了を発行するだけです。これにより、 の記述が簡単になります$(foreach ...)。)


編集:

もちろん、これに対する適切な方法は、シェルでのシリアル処理ではなく、make依存関係を使用することです。次のようなものを確認したい:

tgt-name: # default target

.PHONY: target-32
target-32: deps
    $(MAKE) -f ${MY_MAKEFILE} arch=32 mylib

.PHONY: target-64
target-64: deps
    $(MAKE) -f ${MY_MAKEFILE} arch=64 mylib

# etc. etc.

tgt-name: target-32 target-64
    @echo $@ Success

これは-j安全です。アンダー-j メイクは全てtarget-% 同時に行います。良い。(この場合、あなたは安全$MY_MAKEFILEではないように見えますが-j(いたずらです!))ボイラープレートを置き換えるいくつかのマクロ:

LIST_OF_TYPES := 32 64 ...
LIST_OF_TARGETS := $(add-prefix,target-,${LIST_OF_TYPES})

tgt-name: # default target

.PHONY: ${LIST_OF_TARGETS}
${LIST_OF_TARGETS}: target-%: deps # Static Pattern Rule will (conveniently) set $*
    $(MAKE) -f ${MY_MAKEFILE} arch=$* mylib

tgt-name: ${LIST_OF_TARGETS}
    @echo $@ Success

PS私はあなたがtgt-nameとしてマークするべきだと思う.PHONY

于 2013-01-15T17:13:29.123 に答える
0

私はこの種の使用を見たことがありませんforeachが、それはあなたのために働くようです。通常、bashforループを使用します

tgt-name: deps
    for i in $(LIST_OF_TYPES); do $(MAKE) -f $(MY_MAKEFILE) ARCH=$$i mylib; done

ただし、これは問題ではありません。どちらの場合もmake、AFAICSが順番に実行されるためです。

ライブラリを構築するため、2つのオブジェクトが同時にアーカイブに挿入される可能性があります。これが発生すると、アーカイブが破損する可能性があります。

すべての並列実行と同様に、ジョブまたはスレッドを作成する場合でも、共有リソース(この場合はアーカイブ)を保護する必要があります。ライブラリビルドの最後にオブジェクトを追加するか、何らかのロック(例man lockfileなど)で挿入を保護する必要があります。

もちろん、他の問題があるかもしれません。共有リソース(オブジェクトファイル、アーカイブなど)への同時アクセスまたは不完全に定義された依存関係に注意してください。

更新

foreach問題ないようです。LIST_OF_TYPES単一のタイプ(例:32のみ)に設定してから、を実行しmake -j100 mylibます。問題が単一のアーカイブの構築にある場合、1つのタイプだけでも失敗します。

でテストすることもできますmake ARCH=32 -j100 mylib。これも問題を示しているはずです。

于 2012-12-29T12:53:45.053 に答える