Ich arbeite an einem Makefile für ein C++ - Projekt, das einige Konfigurationen, d. H. Debug, Release und vielleicht ein paar mehr kundenspezifische in der Zukunft unterstützen muss.Makefile Pattern-Regel: Circular Makefile.o <- Makefile Abhängigkeit gelöscht
Derzeit ist meine Namenskonvention für generierte .o-Dateien $(SOURCE_FULLPATH).$(CONFIGURATION).o
. Zum Beispiel erzeugt ABC.cpp
ABC.cpp.debug.o
im Debug-Modus.
Jetzt möchte ich die Musterregel für die Generierung dieser Objektdateien in einer konfigurationsunabhängigen Art und Weise schreiben. Was ich tat war: von jedem XX.o
Dateiname, strippe ich das .debug
oder .release
Suffix von XX
, und verwende den restlichen Teil von XX
als Quelldateiname.
%.o: $$(basename %)
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o [email protected] $<
Mit diesem Trick kann ich die ausführbare Datei korrekt bauen, mit der Ausnahme, dass ich eine Warnmeldung von make erhalten:
make: Circular makefile.o <- makefile dependency dropped.
ich verwirrt bin, weil ich als Ziel nicht makefile
oder makefile.o
Liste oder Abhängigkeit irgendwo in meinem Makefile. Ich habe eine Suche nach SO durchgeführt, aber die meisten Fragen zur Circular-Abhängigkeit beziehen sich auf eine bestimmte Benutzerquelldatei und nicht auf das Makefile selbst. Kann mir jemand helfen zu verstehen, was die zirkuläre Abhängigkeit verursacht und wie man diese Warnmeldung los wird?
Ein Beispielmakefile, das dieses Problem reproduzieren kann, ist unten aufgeführt.
.SECONDEXPANSION:
PROJECT := helloworld
CC := clang++
BUILD_FOLDER := Build
OBJ_FILE_SUFFIX := .o
# Source
CPP_FILES :=\
Source/hello.cpp \
Source/mysqrt.cpp \
INCLUDE_FOLDERS := \
-IInclude
# MMD outputs the dependency files (".d" files). These files will be used by
# this makefile to allow for dependency checking on .h files.
CC_FLAGS += -MMD
EXISTING_OBJ_FILES = $(wildcard $(addsuffix *.o, $(basename $(CPP_FILES))))
##--------------------
## Targets definition
##--------------------
.PHONY:default
default: all
.PHONY:all
all: debug release
.PHONY:debug release
# Add a 'debug'/'release' suffix to the name of the object file
# e.g. hello.cpp -> hello.cpp.debug.o
debug release: OBJ_FILES=$(addsuffix [email protected]$(OBJ_FILE_SUFFIX), $(CPP_FILES))
debug release: $${OBJ_FILES} # Use Secondary Expansion to get the obj names
$(CC) $^ -o $(BUILD_FOLDER)/$(PROJECT)[email protected]
# Strip configuration name from the end of the object file name
%.o: $$(basename %)
$(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o [email protected] $<
## clean: remove executable, all object files, and all dependency files
.PHONY:clean
clean:
-rm -f $(BUILD_FOLDER)/$(PROJECT) $(EXISTING_OBJ_FILES) $(EXISTING_OBJ_FILES:.o=.d)
# Include the dependent files so that in later builds, modified .h files
# will cause all .cpp dependent on them to rebuild
-include $(OBJ_FILES:.o=.d)
Die Ordnerstruktur ist
makefile
Source
- hello.cpp
- mysqrt.cpp
Include
- mysqrt.h
Die vollständige Ausgabe von make debug
ist
make: Circular makefile.o <- makefile dependency dropped.
clang++ -MMD -IInclude -c -o Source/hello.cpp.debug.o Source/hello.cpp
clang++ -MMD -IInclude -c -o Source/mysqrt.cpp.debug.o Source/mysqrt.cpp
clang++ Source/hello.cpp.debug.o Source/mysqrt.cpp.debug.o -o Build/helloworld_debug
Alles, außer für die erste Zeile ist gut.
Ich würde es auch wirklich schätzen, wenn jemand auf mich zeigen kann, wenn es eine schlechte Praxis in meinem Makefile gibt (ich bin immer noch ein Neuling im Makefile). Vielen Dank im Voraus!