2013-04-17 45 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。我不认为依赖文件是问题。如果原始文件编译,它们会自动生成,并且内容也很好。 –

相关问题