簡體   English   中英

Makefile模式規則:循環makefile.o <-刪除了makefile依賴項

[英]Makefile Pattern rule: Circular makefile.o <- makefile dependency dropped

我正在為一個C ++項目制作一個makefile,該文件需要支持一些配置,例如,debug,release和將來可能的一些自定義配置。

目前,我對生成的.o文件的命名約定是$(SOURCE_FULLPATH).$(CONFIGURATION).o 例如, ABC.cpp在調試模式下生成ABC.cpp.debug.o

現在,我想編寫模式規則,以獨立於配置的方式生成那些目標文件。 我所做的是:從每個XX.o文件名,我剝去.debug.release從后綴XX ,並使用剩余部分XX作為源文件名。

%.o: $$(basename %)
    $(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $@ $<

使用此技巧,我可以正確構建可執行文件,但從make收到一條警告消息:

make: Circular makefile.o <- makefile dependency dropped.

我很困惑,因為我沒有在makefile中的任何地方列出makefilemakefile.o作為目標或依賴項。 我在SO上進行了搜索,但是有關循環依賴的大多數問題都在特定的用戶源文件上,而不是在makefile本身上。 誰能幫助我了解導致循環依賴的原因以及如何消除此警告消息

下面列出了可以重現此問題的示例生成文件。

.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 .$@$(OBJ_FILE_SUFFIX), $(CPP_FILES))
debug release: $${OBJ_FILES}    # Use Secondary Expansion to get the obj names
    $(CC) $^ -o $(BUILD_FOLDER)/$(PROJECT)_$@ 

# Strip configuration name from the end of the object file name
%.o: $$(basename %)
    $(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $@ $<

## 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)

文件夾結構為

makefile
Source
- hello.cpp
- mysqrt.cpp
Include
- mysqrt.h

make debug的完整輸出為

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 

除了第一行,其他一切都很好。

如果有人在我的makefile中存在任何不良做法(如果我仍然是makefile中的新手),那么如果有人可以指向我,我也將非常感激。 先感謝您!

GNU Make總是在嘗試進行其他操作之前嘗試更新已讀取的makefile。 如果發現規則和先決條件要求其更新Makefile,則它將這樣做,然后從頭開始-包括嘗試更新Makefile。 請參見3.5如何重新制作Makefile

在您的食譜中:

%.o: $$(basename %)
    $(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $@ $<

您所提供make與制作規則makefile.omakefile

這也是內置配方中規則的逆向

%: %.o
    $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

從單個目標文件生成可執行文件。 因此,您的配方已引入了圓度:

makefile.o <- makefile <- makefile.o

makemakefile本身作為目標時。 通過編寫空規則,可以明確刪除內置的逆規則來抑制圓度:

%: %.o

在makefile中。 然后,您可以在編譯器部分觀察到以下混亂:

$ make makefile.o
clang++   -c -o makefile.o makefile
clang: warning: makefile: 'linker' input unused

如果嘗試創建任何依賴makefile.o目標,也會發生同樣的情況。

可以肯定地假設您將沒有依賴於makefile.o目標。 但是,嘗試從任何現有文件foo編譯foo.o的規則顯然更加需要或需要。 對於您希望捕獲的特定依賴性模式:

foo.cpp.{debug|release}.o: foo.cpp

您最好擁有:

%.o: $$(basename $$(basename %)).cpp
    $(CC) $(CC_FLAGS) $(INCLUDE_FOLDERS) -c -o $@ $<

注意,順便說一句,在GNU Make約定中-由GNU Make的內置規則假定的約定CC表示您的C編譯器,而CXX表示您的C ++編譯器。 同樣,C編譯器的標志表示為CFLAGS ,C ++編譯器的標志表示為CXXFLAGS

用於預處理器的標志表示為CPPFLAGS ,並且-I 路徑選項(即預處理器選項)通常通過CPPFLAGS傳遞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM