[英]Makefile circular dependency with Windows resource files
關於在運行Makefile時( 此處和此處 )刪除循環依賴項有幾個問題,但是,我對為什么會出現它們有些困惑。
例如,我試圖編譯一個包含資源文件的Win32 GUI程序( 來自本教程 )。 這些資源文件通過windres
命令編譯為目標文件,因此可以將它們鏈接到最終的可執行文件( 如此處所述 ):
CC = gcc
CFLAGS = -mwindows
DEPS = resource.h
OBJ = menu_one.o $(patsubst %.rc,%.rc.o,$(wildcard *.rc))
all: menu_one
%.rc.o: %.rc
windres $^ -o $@
%.o: %.c $(DEPS)
$(CC) -c $< -o $@ $(CFLAGS)
menu_one: $(OBJ)
$(CC) $^ -o $@ $(CFLAGS)
命令$(patsubst %.rc,%.rc.o,$(wildcard *.rc))
接收所有以.rc
結尾的資源文件,並在文件上加上.o
擴展名(例如, resource.rc.o
)。
當我運行此命令時,一切似乎都可以正常工作,並且可以正常運行,但是,Make輸出以下內容:
gcc -c menu_one.c -o menu_one.o -mwindows
make: Circular menu_one.rc <- menu_one.rc.o dependency dropped.
windres menu_one.rc -o menu_one.rc.o
gcc menu_one.o menu_one.rc.o -o menu_one -mwindows
因為我在技術上有兩個.o
規則,所以發生這種循環依賴嗎? 換句話說, 如何糾正這種循環依賴性?
我嘗試按照@MadScientist的說法進行操作,但是,這仍然與Make產生了循環依賴關系 。 經過更多谷歌搜索之后,我遇到了下一頁 。 在最底部,有一個標題為“ 循環文件依賴項 ”的部分。 這讓我考慮了Make的輸出:
make: Circular menu_one.rc <- menu_one.rc.o dependency dropped.
看起來rc
后綴正在創建此依賴關系-即使它不是輸出目標文件(即file.rc.o
)的文件擴展名的一部分。 如果將輸出文件后綴更改為.res.o
,則循環依賴關系將完全消失:
...
RESOBJ = $(patsubst %.rc,%.res.o,$(wildcard *.rc))
OBJ = menu_one.o $(RESOBJ)
...
%.res.o: %.rc
windres $^ -o $@
...
如果我想使用前面的后綴.rc.o
,這會引發一個非常類似的問題, 您將如何實現? 可能嗎?
@MadScientist提出的使用任何匹配規則的建議可以完美地解決問題。 現在,這使我可以使用.rc.o
后綴結尾。 請參閱下面的@MadScientist更新后的答案。
一種方法是不以.o
擴展名命名windres
輸出文件。 如果您選擇其他擴展名,則不會有此問題。
另一種方法是對windres
目標使用靜態模式規則 :
RCOBJ := $(patsubst %.rc,%.rc.o,$(wildcard *.rc))
OBJ = menu_one.o $(RCOBJ)
...
$(RCOBJ) : %.rc.o : %.rc
windres $^ -o $@
由於靜態模式規則是創建顯式規則的縮寫,並且不是隱式規則,因此它們不參與搜索,因此make不會產生循環依賴關系。
ETA
好的,我在本地創建了您的示例。 使用make -d
我們可以看看會發生什么:讓需要建立menu_one.rc.o
並找到我們的規則,用的前提menu_one.rc
。 然后,需要查看是否可以重建manu_one.rc
,並找到用於構建可執行文件的通用模式規則:
%: %.o ; ...
此模式匹配與目標menu_one.rc
給人的先決條件menu_one.rc.o
,和你有一個循環。
您需要做的是通知make *.rc
文件是源文件,並且make不應嘗試構建它們。 您可以通過聲明終止規則來執行此操作。 在GNU make手冊中,全面討論了處理任何匹配規則 (僅目標為%
規則,該目標與任何目標均匹配)的復雜性。
添加以下內容以通知使您的.rc
文件處於終端狀態(即,它們不能由其他內容構建):
%.rc:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.