Ошибка файла Makefile, правило не найдено, но правило присутствует - PullRequest
0 голосов
/ 02 января 2019

Этот Makefile

CC = gcc

INC_PATH = -I../common/

SOURCEDIR := ./
SOURCES := $(wildcard $(SOURCEDIR)/*.c)
OBJDIR :=./obj
OBJECTS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.o, $(SOURCES))
DEPENDS := $(patsubst $(SOURCEDIR)/%.c,$(OBJDIR)/%.d, $(SOURCES))

COMMONDIR     := ../common
SOURCESCOMMON := $(wildcard $(COMMONDIR)/*.c)
OBJDIRCOMMON  := $(COMMONDIR)/obj
OBJECTSCOMMON := $(patsubst $(COMMONDIR)/%.c,$(OBJDIRCOMMON)/%.o, $(SOURCESCOMMON))
DEPENDSCOMMON := $(patsubst $(COMMONDIR)/%.c,$(OBJDIRCOMMON)/%.d, $(SOURCESCOMMON))

# ADD MORE WARNINGS!
WARNING := -Wall -Wextra

# OBJS_LOC is in current working directory,
EXECUTABLE := ../server
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean

# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: $(EXECUTABLE)

clean:
    $(RM) $(OBJECTS) $(DEPENDS) $(EXECUTABLE)

# Linking the executable from the object files
# $^   # "src.c src.h" (all prerequisites)
$(EXECUTABLE): $(OBJECTSCOMMON) $(OBJECTS)
    $(CC) $(WARNING) $^ -o $@

-include $(DEPENDS) $(DEPENDSCOMMON)

$(OBJDIR):
    mkdir -p $(OBJDIR)

$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
    $(CC) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@

$(OBJDIRCOMMON):
    mkdir -p $(OBJDIRCOMMON)

$(OBJDIRCOMMON)/%.o: $(SOURCESCOMMON)/%.c | $(OBJDIRCOMMON)
    $(CC) $(WARNING) -MMD -MP -c $< -o $@

генерирует ошибку:

 make[1]: *** No rule to make target '../common/obj/utilities.o', needed by '../server'.  Stop.

Основное правило, генерирующее правило, имеет в качестве входных данных $(OBJECTSCOMMON) со ссылкой на файл объектов *.o, содержащийся в каталоге OBJDIRCOMMON. Правило для генерации этих объектов не имеет явной цели, но оно:

$(OBJDIRCOMMON)/%.o: $(SOURCESCOMMON)/%.c | $(OBJDIRCOMMON)
    $(CC) $(WARNING) -MMD -MP -c $< -o $@

и я думаю, что это вызывает ошибку. Я ожидал, что определение OBJECTSCOMMON := $(patsubst $(COMMONDIR)/%.c,$(OBJDIRCOMMON)/%.o, $(SOURCESCOMMON)) сделало правило и действительным для генерации $()

Однако аналогичное правило используется для генерации $(OBJECTS) в том же Makefile, и оно работает:

$(OBJDIR)/%.o: $(SOURCEDIR)/%.c Makefile | $(OBJDIR)
    $(CC) $(WARNING) -MMD -MP -c $(INC_PATH) $< -o $@

Так почему разное поведение между правилами?

1 Ответ

0 голосов
/ 02 января 2019

$(SOURCESCOMMON)/%.c расширяется до $(wildcard $(COMMONDIR)/*.c)/%.c, поэтому шаблон будет содержать что-то вроде ../common/utilities.c/%.c (возможно, с другим именем файла).Этот файл не существует, поэтому правило шаблона игнорируется.

В другом правиле используется $(SOURCEDIR), поэтому у него нет этой проблемы.

...