2013-04-17 46 views
1

我有一個基於配置文件生成多個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會自行重啓。

所以這是我們的目標:

  1. 檢查Makefile.inc需要生成(重新)。
  2. 包含它
  3. 在主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生成的依賴文件,並且在我添加代碼生成之前工作正常,所以我不認爲這是一個問題。

回答

2

您需要將all目標移至include之前。 Make始終構建它在makefile中看到的第一個目標,除非您在命令行上提供了特定的目標。由於include出現在任何目標之前,因此Makefile.inc中定義的第一個目標將成爲默認目標,當您運行make這將是將要構建的目標。這就是爲什麼它試圖建立exceptions.o然後停止。如果您明確運行make all,它將按預期工作。

+0

謝謝,修復它。現在似乎很明顯。 –

0

目標文件對源文件 或頭文件的依賴性在哪裏?有一個隱含的規則,應該 拿起依存關係,如果.cpp文件在同一目錄 爲.o,但如果他們不,你必須 提供你自己的,或者使用VPATH(見手冊中的第4.5.1節)。和 您還需要生成包含的依賴關係,請參閱手冊中的 §4.1.4。

+0

GCC生成的所有依賴文件都在原始文件的同一目錄中。例如,client.cpp在同一個目錄下有一個依賴文件client.d。我不認爲依賴文件是問題。如果原始文件編譯,它們會自動生成,並且內容也很好。 –

相關問題