Проблема не с расширением $<
в рецепте. Проблема заключается в расширении $@
в списке предварительных требований.
Автоматические переменные, такие как $@
, определяются только в рецепте, но не в списках целей или предварительных требований. Это выделено в разделе Руководство по GNU Make для автоматических переменных :
Распространенной ошибкой является попытка использовать $@
в списке предварительных условий; это не сработает.
Тот факт, что hello.c
на самом деле отсутствует в списке предварительных условий, не мешает вам вызывать make hello
. Это просто означает, что make hello
всегда будет вызывать компилятор, даже если hello.c
не был изменен. Но это означает, что $<
будет таким же пустым, как и вычисленный список предварительных условий.
В GNU make есть функция, позволяющая вам выполнить второе расширение предварительных условий; это объясняется в руководстве. Но более простое решение - просто не полагаться на $@
в списке обязательных компонентов. Если вы пытаетесь создать свой собственный общий рецепт компиляции C, используйте шаблонное правило для целей объектного файла (.o
). Для конечного исполняемого файла перечислите все предварительные условия для конечного исполняемого файла (который почти наверняка будет состоять из нескольких файлов).
Обычно это делается с использованием отдельной переменной с именами, такими как SRCS
и OBJS
(или SOURCES
и OBJECTS
, если вы не против печатать гласные). Обычно вы создаете предварительные условия для объектных файлов для конечного исполняемого файла (который будет являться операцией связи), поскольку каждый отдельный исходный файл будет иметь свои собственные предварительные условия заголовка.