1

ビルド ユニット 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 へのコピーを処理すると仮定します)

  1. LIB/src のヘッダファイルの 1 つに変更を加えると、make はルール「%.a %.h:」を実行しないのはなぜですか?
  2. 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 をさらに一般化する方法についてのヒントを大歓迎します。

4

2 に答える 2

0

質問 1 について: LIB_HEADERS 定義を上に移動し、ルールを
%.a %.h: $(LIB_HEADERS)に変更する必要があるかもしれません。

于 2013-09-17T15:32:36.287 に答える
0

申し訳ありませんが、あなたのビルド システムは怪物です。再帰的な Make を贅沢に使用して、洗練された依存関係を処理しようとしています。再帰的な Make には用途がありますが、その欠点の 1 つは、依存関係を処理する Make のネイティブ機能が無効になることです。このシステムの作成者が Make の仕組みや適切な makefile がどのようなものであるべきかを本当に理解していなかったことを示す他の問題があります。

%.a %.h:ヘッダー ファイルを変更したときにMake がこのルールを実行しない理由LIB/src/は、このルールに依存関係がなく、存在しないヘッダー ファイルに依存するものがこの makefile にないためです。それが意味をなさない場合は、Make ルールがどのように機能するかを理解していません。

これらのルール:

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

1 つのルールに組み合わせることができます。

ONE TWO: % : %/lib/libLIB.a $(addprefix %/include/,$(notdir $(LIB_HEADERS)))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

しかし、これをしないでください。代わりに、 と を排除ONE/include/TWO/include/ます。それらは頭痛の種でしかないからです。次に、ここでのルールは

ONE TWO: % : %/lib/libLIB.a $(LIB_HEADERS)
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

および のメイクファイルはONE/TWO/を参照できますLIB/src/

于 2013-09-17T16:34:10.227 に答える