Makefile target всегда в курсе генерации кода

У меня есть скрипт, который генерирует несколько файлов 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 перезапустится сам.

Так что это цель:

  1. Проверьте, нужно ли (пере) генерировать Makefile.inc.
  2. Включите это
  3. Используйте переменную внутри Makefile.inc в переменной $ LIBOBJS в главном Makefile.

И это на самом деле работает. Если я обновлю файл 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, и до того, как я добавил генерацию кода, все работало нормально, так что я не думаю, что это проблема.

1

Решение

Вам нужно переместить all цель приехать до include, Make всегда создает первую цель, которую видит в make-файле, если вы не указали конкретную цель в командной строке. Так как include предшествует любой цели, первая цель определена в Makefile.inc будет целью по умолчанию и при запуске make это тот, который будет построен. Вот почему он пытается построить exceptions.o а затем останавливается. Если вы бежите make all явно, это будет работать, как вы ожидаете.

2

Другие решения

Где находится зависимость для объектных файлов от исходных файлов
или файлы заголовков? Там является неявное правило, которое должно
подобрать зависимости, если .cpp файл в том же
каталог как .o, но если это не так, вам придется
предоставьте свой или используйте VPATH (см. §4.5.1 в руководстве). А также
вам также нужно сгенерировать зависимости для включений, см.
§4.1.4 в руководстве.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector