我有一個基於配置文件生成多個C++ .h和.cpp文件的腳本。該腳本還生成一個名爲「Makefile.inc」的文件,該文件包含一個具有所需對象文件名的變量,用於生成的.cpp文件。一個Makefile.inc文件的Makefile目標始終是代碼生成的最新版本
實施例(所有路徑都是絕對值):
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
Using the answer in this question as 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 [email protected] $^ $(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的改造,我包括爲產生Makefile.inc的目標規則,所以如果Makefile.inc(配置文件)的相關性比Makefile.inc更新時,它會再生, Make會自行重啓。
所以這是我們的目標:
- 檢查Makefile.inc需要生成(重新)。
- 包含它
- 在主Makefile的$ LIBOBJS變量中使用Makefile.inc中的變量。
而這實際上工作。如果我更新messages.conf文件,Make檢測到並會運行python腳本。然後它會重新啓動,包含新的Makefile.inc,然後繼續編譯。
但是這裏來不工作的一部分:如果我不更新messages.conf文件,但只有被默認在$ LIBOBJS清單的.h或.cpp文件,讓不會繼續編譯。
例如,如果ALTER client.cpp並沒有其他的文件,我得到以下錯誤:
make: `atlarge/exceptions.o' is up to date.
好耶,偉大的你發現exceptions.o是最新的,但我改變的客戶端.cpp,那麼你爲什麼不開始編譯那個?爲什麼在看到LIBOBJS中的第一個目標是最新的之後馬上退出?
誰知道是什麼原因造成的,什麼是解決方案?是否有更好的方法來處理使用makefile的代碼生成?
在此先感謝。
注意:我也使用由gcc生成的依賴文件,並且在我添加代碼生成之前工作正常,所以我不認爲這是一個問題。
謝謝,修復它。現在似乎很明顯。 –