1

次の架空の Makefile があります。

all: SOURCE = $(wildcard src/*.cpp)
unity: SOURCE = $(wildcard unity/*.cpp)

OBJECTS = $(SOURCE:.cpp=.o)

all: prog

unity: prog

prog: $(OBJECTS)
    $(CXX) $(OBJECTS) -o prog

初期ターゲットに基づいて、さまざまなソース ファイル/オブジェクトでコンパイルする必要があります。上記のコンパイラコマンドは適切なファイル名で問題なく呼び出されるため、ターゲット本体よりも依存関係で変数展開がはるかに早く発生するように見えますが、prog 依存関係の $OBJECTS はまだ空であるため、オブジェクトはありません構築されました。

unity フォルダーには、unity ビルドを行うために含まれる他のすべてのソース ファイルと結合されたソース ファイルが含まれています。この Unity ファイルは makefile によって生成されますが、これは省略されており、実際には複数の Unity オブジェクト ファイルである可能性があります。

私のデザインは失われた原因ですか?これを達成するには、再帰的なmakeに頼る必要がありますか?

4

3 に答える 3

1

そんなことはできません。一般に、構築する必要がある複数のターゲットが存在する可能性があるためです。コマンドラインで、または中間目標として。したがって、変数の設定はあいまいになります。このため、ターゲット固有の変数の値は、「ターゲットのコマンド スクリプトのコンテキスト内 (および他のターゲット固有の割り当て) でのみ使用できます」。(ファイル: make.info、ノード: ターゲット固有を参照)

ただし、MAKECMDGOALS 変数を調べることはできます。

于 2012-10-12T23:44:16.563 に答える
1

あなたが直面している問題は、メイクファイルが READ のときに RULES (ターゲットと依存関係リスト) の変数が展開されるのに対して、ターゲットに設定された変数 (上記の $(SOURCES) など) は、ターゲットがトリガーされたときにのみ設定されることです。これは、ターゲット固有の変数が ACTIONS でのみ有用であることを意味します。これは、それらが設定された後に発生する唯一のことだからです。

つまり、make を再帰的に呼び出すことで、必要な効果を得ることができます。

all:
        $(MAKE) SOURCE="$(wildcard src/*.cpp)" prog
unity:
        $(MAKE) SOURCE="$(wildcard unity/*.cpp)" prog

OBJECTS = $(SOURCE:.cpp=.o)

prog: $(OBJECTS)
        $(CXX) $(OBJECTS) -o prog

.PHONY: all unity

しかし、これは私が一般的に推奨するものではありません。

于 2012-10-13T02:49:00.497 に答える
0

$SOURCE を使用して、実行される make ターゲットに応じて別のことを意味することはできません。ここでメイクファイルの解析についてよく理解できます: http://www.gnu.org/software/make/manual/make.html#Reading-Makefiles

あなたの問題では、ソースファイルの種類ごとに個別の変数を定義する必要があります。例えば:

all: SOURCE_ALL = $(wildcard src/*.cpp)
unity: SOURCE_UNITY = $(wildcard unity/*.cpp)

OBJECTS_ALL = $(SOURCE_ALL:.cpp=.o)
OBJECTS_UNITY = $(SOURCE_UNITY:.cpp=.o)
etc ...
于 2012-10-13T00:23:19.307 に答える