Ошибка циклической зависимости Makefile

У меня есть make-файл, который компилирует все файлы cpp в папке src. Все файлы cpp зависят от их файлов.h. Так что у меня есть одно правило, чтобы делать все это (я думаю).

Но я хочу удалить main.cpp из этого списка исходных файлов, поскольку у него нет соответствующего заголовочного файла.

У меня есть код, который удаляет основной из списка файлов cpp. Тогда я написал отдельное правило для составления основного. Я думаю, что именно здесь я ошибся.

Вот makefile и ошибка.

CC := g++
CFLAGS := -g -O2
BIN_DIR := bin
BUILD_DIR := build
SRC_DIR := src
TARGET := wavfiletool.exe
MAIN := WavFileTool 

SOURCES := $(wildcard src/*.cpp)
SOURCES := $(filter-out src/$(MAIN).cpp, $(SOURCES))
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)

$(BIN_DIR)/$(TARGET): $(MAIN).o $(OBJECTS) 
    $(CC) $(OBJECTS) $(CFLAGS)  -o $@ 

$(MAIN).o: $(MAIN).cpp
    $(CC) $(CFLAGS) -c $(MAIN).cpp -o $(MAIN).o

$(OBJECTS): $(BUILD_DIR)/%.o : $(SRC_DIR)/%.cpp : $(SRC_DIR)/%.h
    @$(CC) $(CFLAGS) -c $< -o $@

ОШИБКА:

make: Circular WavFileTool <- WavFileTool dependency dropped.

РЕДАКТИРОВАТЬ: Когда я удаляю зависимость $(MAIN).o из целевой строки, ошибка исчезает.

1 ответ

Решение

Круговая зависимость вызвана паразитным пространством после WavFileTool, что приводит к вашим целям для $(BIN_DIR)/$(TARGET) выглядит так

bin/WavFileTool.exe: WavFileTool .o (other .o files)

В следующем правиле WavFileTool в конечном итоге зависит от себя из-за той же проблемы:

WavFileTool .o: WavFileTool .cpp

Однако избавиться от этого места недостаточно, потому что в конце у вас есть недопустимое статическое правило (вы не можете "связать" цели таким образом), а также потому, что вы не правильно указали путь для $(MAIN).o,

Вместо того, чтобы исправлять ваш make-файл, может быть более полезным использовать более стандартное решение, которое вместо этого генерирует свои собственные зависимости:

BIN_DIR   := bin
BUILD_DIR := build
SRC_DIR   := src
TARGET    := WavFileTool.exe

CC       := g++
CPPFLAGS := -MMD -MP
CXXFLAGS := -g -O2

SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
DEPS    := $(wildcard $(BUILD_DIR)/*.d)
RM       = -del $(subst /,\,$1)

.PHONY: clean

$(BIN_DIR)/$(TARGET): $(OBJECTS)
    $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(OBJECTS): $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
    $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(OUTPUT_OPTION) $<

clean: ; $(call RM, $(DEPS) $(OBJECTS))

include $(DEPS)

$(MAKEFILE_LIST): ;
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%

Последняя часть после include отключает переделывание make-файлов и некоторые другие неявные правила, которые могут быть весьма полезны при отладке вашего make-файла с помощью -d в противном случае вам придется пройти через множество ненужных выходных данных.

Другие вопросы по тегам