Условная зависимость с make / gmake - PullRequest
3 голосов
/ 05 февраля 2010

Есть ли способ заставить make / gmake воздействовать на условные зависимости?

У меня есть это правило:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CPPC) -c $(FLAGS_DEV) $< -o $@

В общем случае каждый файл .cpp имеет соответствующий файл .h; Однако есть несколько исключений. Есть ли способ добиться "зависеть от этого, если он существует" с помощью gmake? В противном случае, есть ли лучшая практика для этого типа установки?

Спасибо заранее; Ура!

Обновление: Я использую GCC

Ответы [ 3 ]

3 голосов
/ 05 февраля 2010

Лучший способ сделать это - на самом деле определить зависимости файлов cpp с помощью gcc -MM и включить их в make-файл.

SRCS = main.cpp other.cpp
DEPS = $(SRCS:%.cpp=$(DEP_DIR)/%.P)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
  $(CPPC) -c $(FLAGS_DEV) $< -o $@

$(DEP_DIR)/%.P: $(SRC_DIR)/%.cpp
  $(CPPC) -MM $(FLAGS_DEV) -MT $(OBJ_DIR)/$*.o -MP -MF $@ $<

-include $(DEPS)
3 голосов
/ 05 февраля 2010

Этого можно добиться с помощью разумного использования шаблонных правил в вашем make-файле благодаря двум функциям сопоставления шаблонных правил gmake. Во-первых, gmake пытается сопоставить шаблоны в порядке их объявления; во-вторых, шаблон соответствует тогда и только тогда, когда все предварительные требования в шаблоне могут быть выполнены (либо они уже существуют в виде файлов, либо существует правило для их создания). Итак, если вы напишите свой make-файл так:

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
        $(CPPC) -c $(FLAGS_DEV) $< -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
        $(CPPC) -c $(FLAGS_DEV) $< -o $@

gmake будет соответствовать первому шаблону для тех файлов, которые имеют соответствующий .h файл, и второму - для тех, у которых его нет. Конечно, современные проверки также будут работать так, как ожидается (например, «foo.o» будет считаться устаревшим, если «foo.h» существует и новее).

Возможно, вы захотите использовать другую переменную, чтобы устранить избыточность между этими двумя правилами; например:

COMPILE=$(CPPC) -c $(FLAGS_DEV) $< -o $@
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/%.h
        $(COMPILE)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
        $(COMPILE)
0 голосов
/ 05 февраля 2010

Гораздо более надежным решением было бы позволить gcc сгенерировать зависимости для вас. Если вы создаете правило для генерации (например) .d файлов, содержащих сгенерированные зависимости, вам не нужно беспокоиться о том, существует ли файл .h для любого данного файла .cpp, и вы автоматически получаете правильные зависимости для каждого .cpp файл для любых .h файлов, от которых он зависит.

1008 * Е.Г. *

DEPFILES=$(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.d,$(wildcard $(SRC_DIR)/*.cpp))

$(OBJ_DIR)/%.d: $(SRC_DIR)/%.cpp
    g++ -MF $@ -MM -MT $@ -MT $(basename $@).o %<

include $(DEPFILES)

Обратите внимание, что я делаю цели .d и .o правила make, используя опцию -MT, так что зависимости корректно переделываются после любых изменений любой из текущих зависимостей.

...