Второе расширение: оценить шаблонное правило перед вызовом функции GNU - PullRequest
1 голос
/ 19 июня 2020

В моем makefile есть правило для каждого объектного файла. Соответствующий исходный файл и скрытый файл зависимостей являются предварительными условиями.

Пример: obj / test / bar.o: src / test / bar. c src / test / .bar .d

Из-за потенциально большого количества объектных файлов я хотел бы обобщить это правило. Моя первая попытка была следующей:

$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)  $(dir $(SRCDIR)/%.$(DEPSEXT)).$(notdir $(SRCDIR)/%.$(DEPSEXT))

с

$(BUILDDIR):=obj
$(SRCDIR):=src
$(OBJEXT):=o
$(SRCEXT):=c
$(DEPXEXT):=d

Проблема в том, что правило шаблона внутри второго предварительного условия оценивает после dir и notdir были применены. Как следствие, вторым предварительным условием для приведенного выше примера будет /src/.test/bar.d вместо /src/test/.bar.d.

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

%.$(OBJEXT): $(shell echo %.$(SRCEXT) | sed -e 's/^[^\/]*/src/') $(shell echo %.$(SRCEXT) |  sed -e 's/^[^\/]*/src/;s/^\(.*\/\)/\1./')

Я использую sed для подстановки строк в объектном файле. Регулярные выражения проверены и верны. Хотя wildcard % виден echo, я не могу передать его в sed. Следовательно, sed получает пустую строку и выдает «неправильный» результат.

Вопросы:

  1. Как мне настроить правило, чтобы оно работало правильно?
  2. Почему echo видит %, но почему невозможно передать его в sed?

1 Ответ

2 голосов
/ 19 июня 2020

Использование функции shell не работает по той же причине, что и использование dir et c. не работает. Обе они являются функциями make, и обе расширяются одинаково, так почему одна из них будет работать, а другая - нет? 1005 * при разборе make-файла . Но шаблонные правила применяются гораздо позже, когда make пытается фактически построить правила. Когда make анализирует make-файл, он абсолютно не знает, до чего будет расширяться %: это расширение не выполняется, пока не будет применено правило. ) работают с буквальным символом %.

Обычно файлы зависимостей помещаются в разные каталоги вместо того, чтобы изменять имя файла, например .deps/foo.d, чтобы избежать проблем такого типа.

Однако вы можете делать все, что хотите, с вторичным расширением следующим образом:

.SECONDEXPANSION:

$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT) $$(dir $(SRCDIR)/$$*.$(DEPSEXT)).$$(notdir $(SRCDIR)/$$*.$(DEPSEXT))
...