0


0

再帰make Q .:他のターゲットの*後*の汎用ターゲット?

再帰的なメイクは悪とみなされることなどを知っています。 とにかく我慢してください。

GNU makeを使用して比較的大きなプロジェクトを管理します。GNUmakeは、make includeを頻繁に使用して、個々のmakeファイルをシンプルに保ちます。 他のターゲットの後に実行されるターゲットを追加したいと思います。 より正確には、問題は次のとおりです。

次のようなMakefileがあります。

 PROJ_SRC = a.cpp b.cpp
 PROJ_LIB = ab

 PROJ_SUBDIRS  = x/ y/ z/
 PROJ_EXAMPLES = example/

最初にサブディレクトリx、y、zでmakeを呼び出してから、PWD自体でlibをビルドし、次に 'example’サブディレクトリに移動して、そのlibを使用してサンプルをビルドします。

例のビットを除くすべてが正常に機能していますが、その最後のビットのクリーンなソリューションに頭を包むことはできません。 私が試したものは次のとおりです。

 # works ok for the target 'all', but nothing else
 all: subdirs ... $(PROJ_OBJ) $(PROJ_LIB_FULL) ... $(PROJ_EXAMPLES)

 # ugly, needs to be adde on all targets, and runs into examples
 # repeatedly if multiple targets get invoked.
 full_lib:: $(PROJ_LIB_FULL)
 $(PROJ_LIB_FULL):: subdirs
   $(CXX) ...
 ifdef PROJ_EXAMPLES
   $(MAKE) -C $(PROJ_EXAMPLES)
 endif

 # this does not make sense, as it builds the lib even on 'make clean' etc
 $(PROJ_EXAMPLES):: full_lib

それを一般化する方法についてのアイデアはありますか?

PS .:上記のスニペットが完全な構文ではない場合は申し訳ありません-それらは単に問題を説明することになっています…​

1 Answer


3


ディレクトリを「作成」するための高度なトリックがあります。たとえば、サブディレクトリでMakeを不必要に実行する必要はありません。 しかし、それがなくてもかなりきれいなソリューションを得ることができます。

$(PROJ_LIB): $(PROJ_SUBDIRS)
  $(CXX) ...

$(PROJ_EXAMPLES): $(PROJ_LIB)
  $(MAKE) -C [email protected]

.PHONY: clean
clean: TARG=clean
clean: $(PROJ_SUBDIRS)
  $(MAKE) -C $(PROJ_EXAMPLES) [email protected]

.PHONY: $(PROJ_SUBDIRS)
$(PROJ_SUBDIRS):
  $(MAKE) -C [email protected] $(TARG)

また、クリーニング時にライブラリのビルドを回避するというトリックが気に入らない場合は、常にライブラリのビルドを呼び出すmakedirを `example /`にすることができます。 結局のところ、その依存関係は実際には `example`に属します。

編集:

`example / Makefile`にlibの依存関係を処理させたい場合は、それによって物事が単純化されます。 再帰的なターゲットをかなりきれいにまとめることができます:

$(PROJ_LIB): $(PROJ_SUBDIRS)
  $(CXX) ...

RECURSIVES = clean distclean veryclean squeakyclean
.PHONY: $(RECURSIVES)

$(RECURSIVES): [email protected]

ALL_SUBDIRS = $(PROJ_SUBDIRS) $(PROJ_EXAMPLES)

# Maybe you want them all to recurse into the same directories:
$(RECURSIVES): $(ALL_SUBDIRS)

#...or maybe not:
clean veryclean squeakyclean: $(ALL_SUBDIRS)
distclean: $(PROJ_EXAMPLES)

# This part does the recursion:
.PHONY: $(ALL_SUBDIRS)
$(ALL_SUBDIRS)
  $(MAKE) -C [email protected] $(TARG)

# And you still have to define the top-level rules:

clean:
  rm ...

# Maybe nothing to do at this level for distclean

veryclean:
  rm ... and ...

squeakyclean:
  rm *