简体   繁体   中英

Makefile circular dependency error

I have a makefile that compiles all the cpp files in the src folder. All of the cpp files are dependent on their .h files. So I have one rule to do all of that (I think).

But I want to remove the main.cpp from that list of source files, since it does not have a corresponding header file.

I have code that removes the main from the list of cpp files. Then I wrote a separate rule for compiling the main. I think this is where I have gone wrong.

Here is the makefile and the error.

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 $@

ERROR:

make: Circular WavFileTool <- WavFileTool dependency dropped.

EDIT: When I remove the $(MAIN).o dependency from the target line, the error goes away.

The circular dependency is caused by a spurious space after WavFileTool , which results in your targets for $(BIN_DIR)/$(TARGET) looking like this

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

In the next rule WavFileTool ends up depending on itself due to the same issue:

WavFileTool .o: WavFileTool .cpp

Getting rid of the space isn't enough however because you have an invalid static rule at the end (you can't "chain" targets like this), and because you haven't correctly specified the path for $(MAIN).o .

Rather than fix your makefile, it might be more useful to use a more standard solution that generates its own dependencies instead:

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.%

The last part after include disables remaking makefiles and some other implicit rules, which can be quite useful when debugging your make file with -d as otherwise you have to wade through a lot of unnecessary output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM