0

「大きな」C プロジェクトをビルドするために使用するメイクファイルのセットがあります。現在、C++ プロジェクトでいくつかを再利用しようとしていますが、理解できないこの頭痛に遭遇しました。

メイクファイルはこんな感じ

SOURCES = \
elements/blue.cpp

# Dont edit anything below here

VPATH = $(addprefix $(SOURCE_DIR)/, $(dir $(SOURCES)))

CXXFLAGS = $(OPT_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -D_LINUX -DNDEBUG -pipe
DCXXFLAGS = $(DEBUG_FLAGS) -MMD -MF $(BUILD_DIR)/$*.d -v -D_LINUX -D_DEBUG -pipe

OBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Release/%.o, $(notdir $(SOURCES)))
DOBJECTS := $(patsubst %.cpp, $(BUILD_DIR)/Debug/%.o, $(notdir $(SOURCES)))

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp
    +@[ -d $(dir $@) ] || mkdir -p $(dir $@)
    $(CPP) $(INCLUDE) $(CXXFLAGS) $(DEFINES) -o $@ -c $<

少し複雑ですが、C で行うことは、SOURCES で定義されたすべての %.c ファイルをビルドし、オブジェクト ファイルを BUILD_DIR に配置することです。c ではうまく機能しますが、cpp ファイルでは機能しません。私は得る

make: *** No rule to make target `blue.cpp', needed by `build/Release/blue.o'.  Stop.

VPATH がまったく機能していないようです。私は試した

vpath %.cpp src/elements

しかし、それもうまくいきません。

驚くべきことに、blue.cpp の名前を blue.c に変更し、makefile を編集して %.c の使用法に戻しても問題なくコンパイルされます。

私はここで夢中になっていますか?

4

3 に答える 3

3

あなたの例から、C++ファイルをコンパイルするためにアクティブ化されているMakefileルールがないように見えます。多分あなた%は間違って拡大していますか?

試す

$(OBJECTS): %.o: %.cpp
    ...

そして、必要に応じて、ルール部分で宛先を指定します$(basename ..)

blue.cMakeにはCファイルをコンパイルするためのデフォルトのルールが組み込まれているため、Cで機能します。--no-builtin-rulesこのオプションを指定してMakeを実行すると、blue.cファイルも機能しなくなると思われます。

ドキュメントから、

Cプログラムのコンパイルは、$(CC) -c $(CPPFLAGS) $(CFLAGS)'. Compiling C++ programs n.o is made automatically from n.cc, n.cpp, or n.C with a command of the form$(CXX)-c $(CPPFLAGS)$(CXXFLAGS)'の形式のコマンドを使用してncから自動的に行われます。.cc' for C++ source files instead of接尾辞.C'を使用することをお勧めします。

デフォルトのC++ルールがありますが、別のルールまたは不正な変数が原因で、機能しない可能性があります。確実にするために、ルールを明示的に作成することをお勧めします。

次のようなルールが必要です。

%.o: %.cpp
    $(CPP) $(CPP_OPTS) -c -o $@ $<

ソースからオブジェクトファイルをコンパイルするには、次のようにします。

executable: $(OBJECTS)
    ... compile objects into final blob ...

ある形式のオブジェクトが%.o依存関係をトリガーする場所。または、Autotools/Autoconfを使用してMakefileを作成します。これは、C++ファイルをオブジェクトのディレクトリにビルドするだけの私が書いた例です。

SOURCES=$(wildcard path/to/src/*.cpp)
OBJECTS=$(SOURCES: .cpp=.o)
CC=g++

final: $(OBJECTS)
    mv $(OBJECTS) /path/to/build_dir

%.o: %.cpp:
    g++ -c -o $@ $<

決して完全な例ではありませんが、あなたはその考えを理解します。ルールではfinal、オブジェクトファイルをコピーしますが、ここで何でも実行するか-o、特定の場所にビルドファイルを配置するオプションを変更できます。

于 2010-01-25T23:12:41.687 に答える
3

本当に VPATH が必要ですか? 私は過去にトラブルしかありませんでした。実際、VPATH は拡張機能に依存していることを覚えているようで、それは Aiden の理論に適合します。私のメイクファイルでは、ソース ディレクトリの SDIR を明示的に指定しています。

SDIR = ./somewhere
... 
$(ODIR)/%.o: $(SDIR)/%.cpp 
    $(CC) -c $(INC) -o $@ $< $(CFLAGS) 

.

編集: VPATH の使用に慣れている場合は、vpath ディレクティブの使用を調査する必要があります (大文字と小文字の違いに注意してください)。例えば:

vpath %.cpp foo:bar

foo および bar ディレクトリで .cpp ファイルを探します。しかし、私が言ったように、私はこれを使用するのに問題がありました.

于 2010-01-25T23:43:00.760 に答える
0

わかりました、私はここでそれを理解しました、そしてそれはバグの大きな混乱です。

さらに実験を重ねた後、make-bugs リストにバグを投稿し、何が起こっているのかを正確に伝えるためにデバッグ出力をオンにしました。解決策にたどり着いたので、以前にこれを行うべきだったことが判明しました。

私はhttp://mad-scientist.net/make/autodep.htmlから開発された自動依存関係生成スキームを使用していますが、驚くべきことに、make を壊していました。この回線でトラブルが発生しました

-include $(patsubst %.c, $(BUILD_DIR)/%.d, $(notdir $(SOURCES)))

私はそれを %.cpp に変更しませんでした。何らかの理由で blue.cpp をインクルードしようとすると、解決しようとしたときに vpath を使用して make が検索しなくなりました。

$(OBJECTS): $(BUILD_DIR)/Release/%.o: %.cpp

したがって、解決策は、メイクファイルを正しく移植することでした。

于 2010-01-26T15:08:06.780 に答える