別の出力ディレクトリに対する GCC 依存関係の生成
-
01-07-2019 - |
質問
GCC を使用して依存関係ファイルを生成していますが、ビルド ルールにより出力がサブディレクトリに置かれます。GCC が生成する依存関係ファイルにサブディレクトリのプレフィックスを入れるように GCC に指示する方法はありますか?
gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
解決
答えは、 GCCマニュアル:使用 -MT
フラグ。
-MT target
依存関係の生成によって発行されるルールのターゲットを変更します。デフォルトでは、CPP はメイン入力ファイルの名前を取得し、ディレクトリ コンポーネントとファイル サフィックス(
.c
, 、そしてプラットフォームの通常のオブジェクトサフィックスを追加します。結果が目標です。アン
-MT
オプションは、指定した文字列と正確にターゲットを設定します。複数のターゲットが必要な場合は、それらを単一の引数として指定できます。-MT
, 、または複数を使用します-MT
オプション。例えば、
-MT '$(objpfx)foo.o'
与えるかもしれない$(objpfx)foo.o: foo.c
他のヒント
GNU Make と GCC を使用していると仮定します。まず、依存関係ファイルのリストを保持する変数を追加します。すべてのソースをリストしたものをすでに持っていると仮定します。
SRCS = \
main.c \
foo.c \
stuff/bar.c
DEPS = $(SRCS:.c=.d)
次に、生成された依存関係をメイクファイルに含めます。
include $(DEPS)
次に、このパターン ルールを追加します。
# automatically generate dependency rules
%.d : %.c
$(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"
# -MF write the generated dependency rule to a file
# -MG assume missing headers will be generated and don't stop with an error
# -MM generate dependency rule for prerequisite, skipping system headers
# -MP add phony target for each header to prevent errors when header is missing
# -MT add a target to the generated dependency
「$@」がターゲット(:の左側にあるもの)です。)、「$<」が前提条件です ( の右側にあるもの:)。式「$(<:.c=.o)」は、拡張子 .c を .o に置き換えます。
ここでのコツは、-MT を 2 回追加して 2 つのターゲットを含むルールを生成することです。これにより、.o ファイルと .d ファイルの両方がソース ファイルとそのヘッダーに依存するようになります。そうすることで、対応する .c または .h ファイルが変更されるたびに、依存関係ファイルが自動的に再生成されます。
-MG および -MP オプションを使用すると、ヘッダー ファイルが見つからない場合に make が異常終了するのを防ぐことができます。
この簡潔なバージョンが気に入っていただけるかもしれません ドン・マッコーイの答え:
SRCS = \
main.c \
foo.c \
stuff/bar.c
DEPS = $(SRCS:.c=.d)
追加 -include $(DEPS)
に注意してください -
プレフィックス。 .d
ファイルはまだ存在しません。
依存関係ファイルを生成するために別のパターン ルールを作成する必要はありません。単に追加するだけです -MD
または -MMD
通常のコンパイル行に追加し、 .d
ファイルはソース ファイルのコンパイルと同時に生成されます。例えば:
%.o: %.c
gcc $(INCLUDE) -MMD -c $< -o $@
# -MD can be used to generate a dependency output file as a side-effect of the compilation process.
詳細について Dジェントリーさんの答え, 、これは私にとってはうまくいきました:
.depend: $(SOURCES)
$(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend
これは、すべてのソース ファイルの依存関係ルールを含む依存関係ファイルが 1 つだけある場合にも機能します。
OK、質問が正しいかどうかを確認するために:持っていると思います test.c
これには以下が含まれます test.h
, 、そしてあなたは生成したい subdir/test.d
(その間 ない 生成する subdir/test.o
) どこ subdir/test.d
含まれています
subdir/test.o: test.c test.h
それよりも
test.o: test.c test.h
それが今あなたが得るものです。そうですか?
あなたが求めていることを正確に実行する簡単な方法を思いつきませんでした。しかし、見てみると、 依存関係生成の改善, を作成したい場合は、 .d
.o ファイルを生成するときに、次のものを使用できます。
gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)
(与えられた SRC=test.c
, SUBDIR=subdir
, 、 そして OBJ=test.o
.) これにより、subdir/test.o と subdir/test.d の両方が作成されます。 subdir/test.d
上記のような目的の出力が含まれています。
GCC に対してこれを行うべきという議論があるとすれば、それが何なのか私にはわかりません。最終的に依存関係の出力をパイプすることになります。 セド すべての出現箇所を書き換える <blah>.o
として ${OBJDIR}/<blah>.o
.
[GNU] 出力を現在のディレクトリに置かないと、make は怒ります。実際には、ビルド ディレクトリから make を実行し、VPATH make 変数を使用してソース コードを見つける必要があります。コンパイラに嘘をつくと、遅かれ早かれ復讐されるでしょう。
オブジェクトと依存関係を他のディレクトリに生成したい場合は、
-o
引数として エミールが答えた.