Ошибка циклической зависимости 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
в противном случае вам придется пройти через множество ненужных выходных данных.