简体   繁体   中英

Makefile target always up to date with code generation

I have a script which generates multiple C++ .h and .cpp files, based on a configuration file. This script also generates a file called 'Makefile.inc', and this file contains a variable with the required object filenames, for the generated .cpp files.

Example of a Makefile.inc file (all paths are absolute):

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 , I created the following 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

As you can see, I first include the generated Makefile.inc. Then a variable with all library object files is defined, and this variable makes use of the variable declared in the generated Makefile.inc. After that some variables with compiler flags are declared.

To make use of Makefile remaking , I included a target rule for the generated Makefile.inc, so if the dependency of Makefile.inc (the configuration file) is newer than Makefile.inc, it gets regenerated, and Make will restart itself.

So this is the goal:

  1. Check if Makefile.inc needs to be (re)generated.
  2. Include it
  3. Use the variable inside Makefile.inc in the $LIBOBJS variable in the main Makefile.

And this actually works. If I update the messages.conf file, Make detects that, and will run the python script. It will then restart itself, include the new Makefile.inc, and then proceed with compiling.

But here comes the part that doesn't work: if I don't update the messages.conf file, but only .h or .cpp files which are by default in the $LIBOBJS list, Make will not proceed to compile.

For example, if alter client.cpp and no other files, I get the following error:

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

Well yeah, great you found out that exceptions.o is up to date, but I altered client.cpp, so why don't you start compiling that one? Why does make quit immediatly after seeing that the first target in LIBOBJS is up to date?

Who knows what's causing this, and what could be a solution? Is there maybe a better way to handle code generation with makefiles?

Thanks in advance.

NB: I also use dependency files generated by gcc, and that was working fine before I added the code generation, so I don't think that's a problem.

You need to move the all target to come BEFORE the include . Make always builds the first target it sees in the makefile unless you give a specific target on the command line. Since the include comes before any target, the first target defined in Makefile.inc will be the default target and when you run make that's the one that will be built. That's why it tries to build exceptions.o and then stops. If you run make all explicitly, it will work as you expect.

Where is the dependency for the object files on the source files or the header files? There is an implicit rule which should pick up the dependencies if the .cpp file is in the same directory as the .o , but if they're not, you'll have to provide your own, or use VPATH (see §4.5.1 in the manual). And you also need to generate the dependencies for the includes, see §4.1.4 in the manual.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM