3

私のmakefileの次の断片を考えてみましょう:

gui_backend: $(BUILDDIR)/gui_backend

$(BUILDDIR)/gui_backend: $(BUILDDIR)/gui_backend.o $(BUILDDIR)/config.pb.o
    $(CXX) $(LDFLAGS) -o $@ $^

$(BUILDDIR)/%.o: $(SRCDIR)/%.cc $(SRCDIR)/%.h | $(BUILDDIR)
    $(CXX) $(CXXFLAGS) -c -o $@ $<

$(SRCDIR)/%.pb.cc: $(PROTODIR)/%.proto
    $(PROTOC) $(PROTOOPTIONS) --cpp_out=$(SRCDIR) $<

今私が呼び出すとmake gui_backend、私は得る

make: *** No rule to make target `build/config.pb.o', needed by `build/gui_backend'.

$(BUILDDIR)/%.oここでパターンをピックアップしないのはなぜですか? ルールを追加して明示的に述べると

$(BUILDDIR)/config.pb.o: $(SRCDIR)/config.pb.cc $(SRCDIR)/config.pb.h | $(BUILDDIR)
    $(CXX) $(CXXFLAGS) -c -o $@ $<

うまくいくようです。ただし、メイクファイルはできるだけ簡潔にしたいと考えています。

make を実行すると-d、次のようになります (完全な出力はこちら)。

Considering target file `build/config.pb.o'.
       File `build/config.pb.o' does not exist.
       Looking for an implicit rule for `build/config.pb.o'.
       Trying pattern rule with stem `config.pb'.
       Trying implicit prerequisite `src/config.pb.cc'.
       Trying pattern rule with stem `config.pb'.
       Trying implicit prerequisite `build/config.pb.c'.
       Trying pattern rule with stem `config.pb'.
       Trying implicit prerequisite `build/config.pb.cc'.
       Trying pattern rule with stem `config.pb'.
       [...]
       Trying implicit prerequisite `build/SCCS/s.config.pb.o'.
       Trying pattern rule with stem `config.pb'.
       Trying implicit prerequisite `src/config.pb.cc'.
       Looking for a rule with intermediate file `src/config.pb.cc'.
        Avoiding implicit rule recursion.
        Trying pattern rule with stem `config'.
        Trying implicit prerequisite `src/proto/config.proto'.
        [...]

私は GNU Make 3.81 を実行しています。

make src/config.pb.ccまた、実行してからmake build/config.pb.o手動で実行すると機能することに気付きました。

なぜこれが機能しないのですか?

4

2 に答える 2

1

あなたの例は私には正しいようです。パターン ルールと明示的なルールの唯一の違いは、明示的なルールには順序のみの前提条件がないことです。実行している GNU make のバージョンは何ですか? 注文のみの前提条件をサポートしていますか? そうでない場合、パターン ルールは一致しません。これは、ターゲットを構築する方法を見つけようとしていて|、できないためです。

このような問題に遭遇したときは、実行するのが最も簡単ですmake -d。出力は膨大ですが、非常に啓発的でもあります。構築しようとしているセクションを見つけて、config.pb.oどのパターンを試みているのか、なぜそのパターンを放棄することにしたのかを確認してください。

于 2013-06-19T14:26:41.843 に答える