ビルド ユニット ONE と TWO -> ビルド ユニット LIB の依存関係を処理するためのメイクファイルを作成しています。
「ビルド ユニット」とは、ディレクトリ src、lib、include、および bin を含むディレクトリと、src のソース コードをコンパイルするための makefile を意味します。ライブラリは「lib」に配置され、ライブラリ ヘッダー ファイルは「include」に配置されます。コンパイルされたバイナリは「bin」に配置されます。ビルド ユニットは、「make」、「make all」、「make lint」、および「make clean」を受け入れます。
LIB のヘッダー ファイルに変更が加えられると、この makefile はそれを検出し、コンパイルする前に新しいバージョンの LIB を再コンパイル + インストール (.a+.h ファイルを 1 つと 2 つにコピー) するためのものです。
.PHONY: ONE TWO CLEAN LINT
ALL: ONE TWO
%.a %.h:
@echo ---------- Compiling LIB ----------
@cd LIB && gmake.exe LIB
LIB_HEADERS := $(wildcard LIB/src/*.h)
ONE: ONE/lib/libLIB.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
@echo ---------- Compiling $@ ----------
@cd $@ && gmake.exe
TWO: TWO/lib/libLIB.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
@echo ---------- Compiling $@ ----------
@cd $@ && gmake.exe
CLEAN LINT:
@cd ONE && gmake.exe $@
@cd TWO && gmake.exe $@
@cd LIB && gmake.exe $@
(LIB の makefile が ONE と TWO へのコピーを処理すると仮定します)
- LIB/src のヘッダファイルの 1 つに変更を加えると、make はルール「%.a %.h:」を実行しないのはなぜですか?
ONE と TWO を 1 つのルールに一般化するにはどうすればよいですか? 私はこれを行いたいです(ただし、少なくともこの方法では、ターゲットを依存関係で使用することはできません):
ONE TWO: $@/lib/libLIB.a $(subst LIB/src/,$@/include/,$(LIB_HEADERS)) @echo ---------- Compiling $@ ---------- @cd $@ && gmake.exe
アップデート:
一歩下がって、有向非循環グラフを描き、特定の種類のすべてのファイルではなく、単一のファイルの観点から考えることで、解決策を見つけました。
完全を期すために、(あまりエレガントではない)ソリューションを次に示します。
.PHONY: ONE TWO CLEAN LINT
ALL: ONE TWO
LIB_HEADERS := $(sort $(subst name.h,,$(wildcard LIB/src/*.h)))
# ------------------------------------------------------------
ONE/include/%.h: LIB/src/%.h
@echo Copying $< to $@
@mkdir ONE\\include 2> NUL || :)
@copy $(subst /,\,$<) ONE\\include\\ 1> NUL
TWO/include/%.h: LIB/src/%.h
@echo Copying $< to $@
@mkdir TWO\\include 2> NUL || :)
@copy $(subst /,\,$<) TWO\\include\\ 1> NUL
# ------------------------------------------------------------
ONE/lib/liblib.a: LIB/bin/liblib.a
@echo Copying $< to $@
@mkdir ONE\\lib 2> NUL || :)
@copy $(subst /,\,$<) ONE\\lib\\ 1> NUL
TWO/lib/liblib.a: LIB/bin/liblib.a
@echo Copying $< to $@
@mkdir TWO\\lib 2> NUL || :)
# Windows-equivalent of touch (discarding any output to stdout):
@copy $(subst /,\,$<) TWO\\lib\\ 1> NUL
# ------------------------------------------------------------
LIB/bin/liblib.a: $(LIB_HEADERS) $(wildcard LIB/src/*.cpp)
@echo ---------- Looking for changes to liblib ----------
@cd LIB && gmake.exe LIB
@copy /b $(subst /,\,$@) +,, 1> NUL || :)
# ------------------------------------------------------------
ONE: ONE/lib/liblib.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
@echo ---------- Compiling ONE ----------
@cd ONE && gmake.exe
TWO: TWO/lib/liblib.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
@echo ---------- Compiling TWO ----------
@cd TWO && gmake.exe
# ------------------------------------------------------------
CLEAN LINT:
@cd ONE && gmake.exe $@
@cd TWO && gmake.exe $@
@cd LIB && gmake.exe $@
ONE と TWO をさらに一般化する方法についてのヒントを大歓迎します。