Итак, глядя на вывод, оператор $ (info INCLUDE_PATH: $ (INCLUDE_PATH)) в начале файла в основном разрешается нормально, но внутри переменной задачи $ (INCLUDE_PATH) не разрешается.
Нет, это совсем не так.Как заметил @GM в комментариях, у вас есть два разных правила шаблона для построения объектных файлов в $(BINDIR)
, и они отличаются в зависимости от того, ссылаются ли их рецепты на $(INCLUDE_PATH)
.Вывод, который вы представляете, соответствует первому, а не второму.И это именно то, что я ожидал бы , потому что шаблон предварительных условий во втором правиле */%.c
, не соответствует фактически используемому предварительному условию main.c
, чье имяне содержит /
символа.
Для вашего примера makefile вы можете заменить оба $(BINDIR)/%.o
правила этим правилом ...
$(BINDIR)/%.o : %.c
$(CC) -c -I$(INCLUDE_PATH) $(CFLAGS) -o $@ $< $(LIBS)
..., чтобы решить проблему, но на самом деле это плохая форма по нескольким причинам.Прежде всего, в самом make-файле должно быть указано как минимум значение по умолчанию INCLUDE_PATH
, особенно если оно относится к другой части того же проекта.Во-вторых, было бы более логично собирать директивы -I
(и -D
, -U
и, возможно, некоторые другие) в переменную с именем CPPFLAGS
и использовать , что , в ваших правилах сборки:
CPPFLAGS = -I$(INCLUDE_PATH)
$(BINDIR)/%.o : %.c
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LIBS)
Полученное правило очень похоже на встроенное правило make
для построения объектного файла из одного соответствующего исходного файла.
В общем, я небольшой поклонник создания объектов в другом каталоге, чем их соответствующие источники, поскольку это идет вразрез с зерном, и, следовательно, требует больше усилий для настройки и является гораздо более сложным.Является ли ваш реальный проект большим или маленьким, я действительно не понимаю, насколько эти усилия оправданы.Если вам нужны сборки из исходного кода, то пройдите весь путь и используйте VPATH .