0

非常に単純なMakefileがあり、期待どおりに動作していません。最終的な目標は、毎回適切なファイルを含めて再帰的に呼び出し、含まれているものに固有のビルドを作成することです(すべて同じコードベースを共有するが、ソースファイルの異なる組み合わせを利用するいくつかのプロジェクトをビルドしています)。再帰的な呼び出しを実際に処理したことはないので、明らかな何かが欠けているに違いありません。.mk現在、 Makefileと同じフォルダにあるファイルは1つだけです。これは、このテストの目的のためだけの単純なワンライナーです。最終的には、プロジェクトごとのさまざまな設定が含まれます。

Makefile:

SHELL = /bin/sh

ifdef MYFILE
include $(MYFILE)
PROGRAM = $(basename $(MYFILE))
endif

all: $(wildcard *.mk)

dummy:
        @echo -- Entering dummy stub ... why do I need this?

%.mk: dummy
        @echo Calling $(MAKE) MYFILE=$@ $*
        $(MAKE) MYFILE=$@ $*

$(PROGRAM): objs
        @echo Time to link!

objs:
        @echo Building objs!

test.mk

SOMEVAR = SomeValue

次の2つの問題があります。

問題1

パターンルールから前提条件を削除するdummyと、パターンルールが呼び出されることはありません(恐ろしい「すべてに対して何もする必要がない」エラーが発生します)。%.mkそのダミーの前提条件を必要とせずに、ルールの下でレシピを実行する方法はありますか?

問題2

前述の2つのファイルを考えると、makeは次のことを実行することを期待します。

  1. make [1]が開始し、allルールにヒットします
  2. %.mkmake[1]はパターンルールにジャンプします
  3. make [1]はそれ自体を再帰的に呼び出します(呼び出しは次のようになりますmake MYFILE=test.mk test
  4. make [2]が起動し、test.mkファイルが含まれ、PROGRAM変数が設定されます
  5. make [2]は$(PROGRAM)ルールにジャンプします(そのターゲットで明示的に呼び出されたため)
  6. make [2]はobjsルールにジャンプし、レシピを実行して、チェーンに戻ります

実際には、makeは%.mkパターンルールに固執し、無限ループに入ります。test最初の再帰呼び出し($(PROGRAM)ターゲットに対応する必要があります)を組み込むように明示的に指示したときに、パターンルールをヒットすることを主張している理由がわかりません。ここで何が欠けていますか?

4

1 に答える 1

1

問題0:
これは過剰に設計されています。ここで再帰的なMakeを使用する必要はありません。

問題1: Makeが(ダミーの前提条件なしで)
再構築を試みない理由は、最新であるためです。より良いアプローチは、静的パターンルールに切り替えてPHONYを使用することです。test.mktest.mk

MKS = $(wildcard *.mk)
.PHONY: $(MKS)

$(MKS): %.mk:
    @echo Calling $(MAKE) MYFILE=$@ $*
    $(MAKE) MYFILE=$@ $*

さらに良いアプローチは、実際のファイルの名前を、そのファイルを再構築(または「タッチ」)しないルールのターゲットとして使用しないことです。

問題2:
make [2]で、makefileに。が含まれていますtest.mk。makefileに別のファイルが含まれている場合、Makeは他の処理を行う前にそのファイルの再構築を試みます。そのファイル(存在する)にルールがあり、成功する(実行する)場合、Makeはそれ自体を再呼び出しします。

この設計をゼロから再考する必要があります。詳細に応じて、探している動作を取得する方法はたくさんあります(どのくらいの変数が定義されfoo.mkますか?これらのファイルを手動で移動してビルドを管理しますか?など)。

PSここに頭に浮かぶ1つの恨みがあります。それがあなたのケースに合うかどうかは、詳細に依存します:

makefile:

# includes nothing

%.mk: dummy
        @echo Calling $(MAKE) MYFILE=$@ -f $@ $*
        $(MAKE) MYFILE=$@ -f $@ $*

test.mk:

SOMEVAR = SomeValue
include makefile
于 2012-05-04T16:20:10.007 に答える