5

これは私のメイクファイルです:

all: first second

second:
    @echo "==Building second=="

first:
    @echo "==Building first=="

という名前のディレクトリがある場合second、同じ名前のルールはメイクファイルによって完全に無視されます。それがなければ、すべてが正常に進みます。

secondこれは、フォルダーがその中の Makefile であるかどうかに関係なく発生することに注意してください。

プロジェクトを整理しているときに、この問題に取り組みました。一般的な Makefile を作成して、各ディレクトリで Makefile を呼び出すことを考えました。そのため、ルールがフォルダーと同じ名前を持つのは当然のことのように思えます。

解決策は簡単です: Makefile 内のルール名を変更します...しかし、この動作はかなり奇妙に思えます: これに関するアイデア/洞察、および別の可能な解決策はありますか?

Ubuntu 12.04.2 LTS の下で、Bash 4.2.25 内で GNU Make 3.81 を使用しています。

4

3 に答える 3

7

ルールが実行されない理由を探しているだけなら、それは簡単です: make はターゲットを構築しようとします。ターゲットは、(デフォルトでは) ファイルシステム内のアーティファクトの存在によって表されます。アーティファクトがファイルであるかディレクトリであるか (または、理論的にはその他のもの) を作成することは重要ではありません。

make がファイルを古くて更新が必要であると見なす (したがって、make がターゲットに関連付けられたレシピを実行する) には、2 つのことのうち少なくとも 1 つが真でなければなりません。ファイルまたはディレクトリ) は存在できないか、存在する場合は、その最終変更時刻が少なくとも 1 つの前提条件よりも古い必要があります。

あなたの状況ではsecond、存在するため、再構築の最初の要件が満たされていないため、前提条件がないため、2 番目の要件が満たされていないため、ターゲットは期限切れであるとは見なされず、レシピは呼び出されません。

bobbogo が示唆するように、ターゲットを.PHONY. Make は、ターゲットがファイルシステムのアーティファクトを表しているのではなく、ビルドを編成するために使用される makefile の単なる偽のターゲットであることを理解します。

于 2013-05-01T13:28:37.310 に答える
0

あなたの問題文を正しく理解している場合、あなたは を呼び出しているのではなく、 を呼び出していechoます$(MAKE) -Csecond。Miller のRecursive Make Considered Harmfulを読む時が来ました! これらは従来のメーカーに固有の問題ではありませんが、従来のメーカーでそれを改善するのは難しく、不器用です.

このため、makeppが作成されました。ほぼ同じメイクファイルを使用できますが、再帰を指定する必要はありません。ターゲット ディレクトリに makefile がある場合、それらは通常、同じプロセスに自動的に読み込まれます。または、ターゲットが別のディレクトリに生成される場合は、どの makefile をロードするかを makepp に指示する必要があります。いずれにせよ、1 つのプロセスがすべての (自動的に検出された!) 依存関係の概要を持っています。

makeppには他にもたくさんあります。GNU make でできることのほとんどすべてを実行する以外に、もっと便利なことがたくさんあります。また、Perl プログラミングを使用して makefile を拡張することもできます。

于 2013-05-01T15:56:04.083 に答える