Учтите это:
OBJS = $(notdir $(shell find $(SRCDIR) | grep .o))
%: %.cc $(OBJS)
$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $^
Когда установлен SRCDIR
, он может найти некоторые объектные файлы (кстати, я не знаю, почему вы используете grep
здесь вместо простого добавления -name \*.o
к команде find
: grep
глючит, так как он также будет соответствовать файлам, таким как foo.ohno
.
Предположим, он находит объектный файл /my/path/to/src/foo.o
. notdir
выполняется на этом, а OBJS
установлен на foo.o
.
Это означает, что шаблон становится:
%: %.cc foo.o
$(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) -o $@ $^
Теперь make хочет найти шаблонное правило, которое будет соответствовать. Это правило не будет соответствовать этому правилу, поскольку, хотя шаблоны %
и %.cc
совпадают, другой предпосылки foo.o
не существует (ее нет в локальном каталоге). В результате этот шаблон игнорируется, и make будет продолжать искать другой шаблон. Он найдет встроенный шаблон, который соответствует, и именно поэтому вы получите результат, который вы делаете.
В случае, когда объектные файлы не найдены (неправильная команда find
), переменная OBJS
пуста, поэтому правило шаблона соответствует.
Если вы удалите notdir
, это должно сработать, но я не знаю, почему вы добавили его, так что, возможно, что-то еще является проблемой.
Другие примечания:
- Вы всегда должны явно использовать
$(MAKE)
или ${MAKE}
при вызове рекурсивного make, и никогда не make
или какую-либо другую переменную.
- Как правило, вы должны использовать
:=
при вызове shell
или других более медленных функций.
- Возможно, было бы проще понять, что происходит, если вы использовали явное правило, а не шаблонное правило для построения тестовой программы: тогда вы получите ошибку типа no rule для сборки foo.o