У меня есть скрипт, который генерирует несколько файлов 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
Используя ответ в этом вопросе в качестве базы, Я создал следующий 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, Я включил целевое правило для сгенерированного Makefile.inc, поэтому, если зависимость Makefile.inc (файл конфигурации) новее, чем Makefile.inc, он будет восстановлен, и Make перезапустится сам.
Так что это цель:
И это на самом деле работает. Если я обновлю файл messages.conf, Make обнаружит это и запустит скрипт python. Затем он перезапустится, включит новый Makefile.inc и продолжит компиляцию.
Но здесь идет часть, которая не работает: если я не обновите файл messages.conf, но только файлы .h или .cpp, которые по умолчанию находятся в списке $ LIBOBJS, Make не продолжит компиляцию.
Например, если alter client.cpp и других файлов нет, я получаю следующую ошибку:
make: `atlarge/exceptions.o' is up to date.
Хорошо, да, здорово, что вы узнали, что exceptions.o обновлен, но я изменил client.cpp, так почему бы вам не начать его компилировать? Почему make немедленно завершает работу, увидев, что первая цель в LIBOBJS обновлена?
Кто знает, что вызывает это, и что может быть решением? Может быть, есть лучший способ для обработки кода с make-файлами?
Заранее спасибо.
NB: Я также использую файлы зависимостей, сгенерированные gcc, и до того, как я добавил генерацию кода, все работало нормально, так что я не думаю, что это проблема.
Вам нужно переместить all
цель приехать до include
, Make всегда создает первую цель, которую видит в make-файле, если вы не указали конкретную цель в командной строке. Так как include
предшествует любой цели, первая цель определена в Makefile.inc
будет целью по умолчанию и при запуске make
это тот, который будет построен. Вот почему он пытается построить exceptions.o
а затем останавливается. Если вы бежите make all
явно, это будет работать, как вы ожидаете.
Где находится зависимость для объектных файлов от исходных файлов
или файлы заголовков? Там является неявное правило, которое должно
подобрать зависимости, если .cpp
файл в том же
каталог как .o
, но если это не так, вам придется
предоставьте свой или используйте VPATH (см. §4.5.1 в руководстве). А также
вам также нужно сгенерировать зависимости для включений, см.
§4.1.4 в руководстве.