23

GCC を使用して依存関係ファイルを生成していますが、ビルド ルールによって出力がサブディレクトリに配置されます。GCC が生成する依存関係ファイルにサブディレクトリのプレフィックスを入れるように GCC に指示する方法はありますか?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
4

7 に答える 7

44

GNU Make と GCC を使用していると仮定しています。まず、依存ファイルのリストを保持する変数を追加します。すべてのソースをリストしたものをすでに持っていると仮定します。

SRCS = \
        main.c \
        foo.c \
        stuff/bar.c

DEPS = $(SRCS:.c=.d)

次に、生成された依存関係を makefile に含めます。

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 が異常終了するのを防ぎます。

于 2010-01-11T23:20:53.320 に答える
21

答えはGCC のマニュアルにあります:-MTフラグを使用してください。

-MT target

依存関係の生成によって発行されるルールのターゲットを変更します。デフォルトでは、CPP はメインの入力ファイルの名前を取得し、ディレクトリ コンポーネントと などのファイル サフィックスを削除.cし、プラットフォームの通常のオブジェクト サフィックスを追加します。結果が目標です。

オプションは、指定した-MT文字列とまったく同じになるようにターゲットを設定します。複数のターゲットが必要な場合は、それらを への 1 つの引数として指定する-MTか、複数の-MTオプションを使用できます。

たとえば-MT '$(objpfx)foo.o'

$(objpfx)foo.o: foo.c
于 2008-09-19T03:27:25.940 に答える
12

Don McCaugheyの答えのこの簡単なバージョンが好きかもしれません:

SRCS = \
    main.c \
    foo.c \
    stuff/bar.c

DEPS = $(SRCS:.c=.d)

ファイルがまだ存在しない場合にエラーを黙らせる接頭辞に-include $(DEPS)注意してください。-.d

依存関係ファイルを生成するための個別のパターン ルールは必要ありません。通常のコンパイル行に-MDorを追加するだけで、ソース ファイルのコンパイルと同時にファイルが生成されます。例えば:-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.
于 2013-06-06T18:06:20.923 に答える
3

DGentry's answer の詳細を説明すると、これは私にとってはうまくいきました:

.depend: $(SOURCES)
    $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend

これは、すべてのソース ファイルの依存関係ルールを含む依存ファイルが 1 つしかない場合にも機能します。

于 2014-06-09T21:52:15.883 に答える
2

わかりました。質問が正しいことを確認するために、test.cを含むものがあり、を含む場所を(生成せに)生成test.hしたいとします。subdir/test.dsubdir/test.osubdir/test.d

subdir/test.o: test.c test.h

それよりも

test.o: test.c test.h

それはあなたが今得ているものです。そうですか?

私はあなたが求めていることを正確に行う簡単な方法を思い付くことができませんでした。ただし、依存関係の生成の改善点を見ると、.oファイルの生成中にファイルを作成する場合.dは、次を使用できます。

gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)

( 、、およびを指定します。)これによりSRC=test.c、subdir/test.oとsubdir/test.dの両方が作成されます。ここには、上記の目的の出力が含まれています。SUBDIR=subdirOBJ=test.osubdir/test.d

于 2008-09-18T22:38:41.063 に答える
0
  1. [GNU] 出力をカレントディレクトリに置かないとmakeが怒る。実際には、ビルド ディレクトリから make を実行し、VPATH make 変数を使用してソース コードを見つける必要があります。コンパイラに嘘をつくと、遅かれ早かれコンパイラは報復します。

  2. オブジェクトと依存関係を他のディレクトリに生成することを主張する場合は、 Emile が回答した-oように、引数を使用する必要があります。

于 2008-09-18T23:10:51.143 に答える
0

これを行うためにGCCに引数がある場合、それが何であるかわかりません。最終的に依存関係の出力をsed<blah>.oにパイプして、 asの出現箇所をすべて書き換えます${OBJDIR}/<blah>.o

于 2008-09-18T21:52:21.863 に答える