создать шаблон для автоматической генерации зависимостей - PullRequest
0 голосов
/ 12 июня 2018

Я хочу разрешить шаблонным правилам генерировать правильные зависимости заголовка для меня.Я пытался сделать это, но это не удается

Например, если у меня есть файлы foo.cpp, foo.h, bar.cpp, bar.h и foo.h, включая bar.h.с Makefile:

foo_H=foo.h $(bar_H)
bar_H=bar.h

%.o: %.cpp $(%_H)
    $(CPP) $(CPPFLAGS) $< -o $@

, но make не будет обновляться при изменении foo.h или bar.h.

почему это не удается и как это можно исправить?

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

$(%_H) не удалось расширить, потому что, как указано в

https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html

Note that expansion using ‘%’ in pattern rules occurs after any variable or function expansions, which take place when the makefile is read

, поэтому кажется, что использование шаблонов для достижения такой логикитупик

В качестве альтернативы я использовал foreach и include следующим образом:

makedep.mk

$(CUR_OBJ): $(CUR_OBJ:.o=.cpp) $($(CUR_OBJ:.o=_H))
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) $< -o $@

Makefile

foo_H=foo.h $(bar_H)
bar_H=bar.h

SRCS=foo.cpp bar.cpp
OBJS=$(SRCS:.cpp=.o)


$(foreach obj,$(OBJS),$(eval CUR_OBJ:=$(obj)) $(eval include makedep.mk))

, поскольку есть только переменные make и нет сопоставления с шаблоном % все может правильно расширяться

0 голосов
/ 16 июня 2018

Если вы действительно хотите это сделать, вы можете использовать для него вторичное расширение :

foo_H = foo.h $(bar_H)
bar_H = bar.h

.SECONDEXPANSION:
%.o: %.cpp $$($$*_H)
        $(CPP) $(CPPFLAGS) $< -o $@
0 голосов
/ 12 июня 2018

Это не то, как GNU Make работает.

  1. переменная bar_H не определена при назначении foo_H.Так что foo_H будет иметь значение foo.h.
  2. , расширение шаблона не будет работать внутри $(...).Он просто ищет переменную %_H, которая не существует, то есть является пустой.
  3. %< и %@ неверны.Вы, вероятно, намеревались написать $< и $@.
  4. Ваш make-файл нуждается как минимум в одной нецелевой программе.Шаблонного правила недостаточно.
  5. Шаблонное правило не будет использоваться, пока не существуют все зависимости.Здесь это может быть не предназначено.
  6. Ваше шаблонное правило не будет применяться, поскольку оно ищет foo.c, а не foo.cpp.

Намеченное поведение достигнуто

foo.o : foo.h bar.h
bar.o : bar.h

%.o: %.cpp
    $(CPP) $(CPPFLAGS) $< -o $@

Обратите внимание, что зависимости указываются отдельно от исполняемых команд.


Еще одно примечание: если вы хотите избавиться от ада включаемых зависимостей, вы можете захотеть иметьвзгляд на cmake .

...