1

構成ファイルに基づいて、複数の C++ .h および .cpp ファイルを生成するスクリプトがあります。このスクリプトは、'Makefile.inc' というファイルも生成します。このファイルには、生成された .cpp ファイルに必要なオブジェクト ファイル名を含む変数が含まれています。

Makefile.inc ファイルの例 (すべてのパスは絶対パスです):

MESSAGE_OBJS = \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/error-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-request-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/challenge-response-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/login-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/get-game-list-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/game-list-response-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/join-game-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/connect-to-game-message.o \
    /scratch/openttd/software/AtLargePlatform/branches/lucas/libatlarge/atlarge/messages/leave-game-message.o 

この質問の回答を base として使用して、次の Makefile を作成しました。

# Include the generated makefile for messages.
# This includes a variable with all message targets
include atlarge/messages/Makefile.inc

# Create a variable with all source targets
LIBOBJS = \
    atlarge/exceptions.o \
    atlarge/message-factory.o \
    atlarge/envelope.o \
    atlarge/client.o \
    atlarge/user.o \
    atlarge/atlarge-protocol.o \
    atlarge/atlarge-gameserver.o \
    $(MESSAGE_OBJS)


CXXFLAGS += -W -Wall -I. -g -O3 -MD \
    `pkg-config jansson --cflags` \
    `libgcrypt-config --cflags` \
    `pkg-config glib-2.0 --cflags` \
    -fPIC -DDEBUG -DENABLE_LOGGING

PREFIX = /usr/local

# TODO use pkg-config for jansson
LDLIBS += -lm -ljansson -latlarge-util `libgcrypt-config --libs` `pkg-config glib-2.0 --libs` 
LDFLAGS += -shared -L/usr/local/lib

# Include automatically generated dependencies
-include $(LIBOBJS:.o=.d)

all: libatlarge.so

# If the message Makefile doesn't exist yet, generate it
atlarge/messages/Makefile.inc: atlarge/messages/messages.conf
    python ../common/messagegen.py -o ./atlarge/messages/ atlarge/messages/messages.conf

libatlarge.so: $(LIBOBJS)
    $(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)

clean:
    @rm -f *.o
    @rm -f atlarge/*.o
    @rm -f atlarge/messages/*.o
    @rm -f atlarge/messages/*.cpp
    @rm -f atlarge/messages/*.h
    @rm -f atlarge/messages/Makefile.inc
    @rm -f atlarge/*.d
    @rm -f atlarge/messages/*.d
    @rm -f *.d
    @rm -f ../common/*.d
    @rm -f ../common/*.o
    @rm -f *.a
    @rm -f *.so
    @rm -f tags

install: libatlarge.so
    @install -m 0644 $^ $(PREFIX)/lib
    @install -m 0755 -d $(PREFIX)/include/atlarge
    @install -m 0755 -d $(PREFIX)/include/atlarge/messages
    @install -m 0644 -D atlarge/*.h $(PREFIX)/include/atlarge
    @install -m 0644 -D atlarge/messages/*.h $(PREFIX)/include/atlarge/messages
    @ldconfig
    @echo "Installed"


.PHONY: all clean install splint messages

ご覧のとおり、まず、生成された Makefile.inc を含めます。次に、すべてのライブラリ オブジェクト ファイルを含む変数が定義され、この変数は、生成された Makefile.inc で宣言された変数を使用します。その後、コンパイラ フラグを持ついくつかの変数が宣言されます。

Makefile remakeを利用するために、生成された Makefile.inc のターゲット ルールを含めたので、Makefile.inc (構成ファイル) の依存関係が Makefile.inc よりも新しい場合、再生成され、Make は自動的に再起動します。

これが目標です:

  1. Makefile.inc を (再) 生成する必要があるかどうかを確認します。
  2. 含める
  3. メイン Makefile の $LIBOBJS 変数で Makefile.inc 内の変数を使用します。

そして、これは実際に機能します。messages.conf ファイルを更新すると、Make がそれを検出し、python スクリプトを実行します。その後、それ自体を再起動し、新しい Makefile.inc を含めて、コンパイルを続行します。

しかし、ここで動作しない部分があります。messages.conf ファイルを更新せず、デフォルトで $LIBOBJS リストにある .h または .cpp ファイルのみを更新すると、Make はコンパイルを続行しません。

たとえば、client.cpp を変更し、他のファイルを変更しない場合、次のエラーが発生します。

make: `atlarge/exceptions.o' is up to date.

そうですね、exceptions.o が最新であることがわかりましたが、client.cpp を変更したので、それをコンパイルしてみませんか? LIBOBJS の最初のターゲットが最新であることを確認した後、make がすぐに終了するのはなぜですか?

何が原因で、何が解決策になるのか誰が知っていますか? メイクファイルでコード生成を処理するより良い方法はありますか?

前もって感謝します。

注: gcc によって生成された依存関係ファイルも使用していますが、コード生成を追加する前は問題なく動作していたので、問題はないと思います。

4

2 に答える 2

2

allの前にターゲットを移動する必要がありincludeます。コマンド ラインで特定のターゲットを指定しない限り、Make は常に、makefile で最初に検出したターゲットをビルドします。はどのターゲットよりも前に来るため、includeで定義された最初のターゲットMakefile.incがデフォルトのターゲットになり、実行するmakeとそれがビルドされます。そのため、ビルドしようとしてexceptions.o停止します。明示的に実行するmake allと、期待どおりに動作します。

于 2013-04-17T11:47:56.143 に答える