2013-07-10 52 views
0

我有一組[文件名] .c格式的文件,其中一些#包括一個關聯的[名稱] .h文件。如果[name] .c或[name] .h被修改,我想要一個makefile目標來重新構建[name] .o。我試過了:如何使Makefile目標取決於只存在的文件?

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h 
     #Implementation of target omitted 

但是,對於沒有關聯.h文件的.c文件,請在上述規則上投訴。我嘗試過:

$(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h) 
     #Implementation of target omitted 

這會生成,但修改.h文件不會觸發重建。有沒有什麼原因,我不能用這種方式%?

注:我試圖避免使用makedeps.pl或makefile生成的解決方案(因爲我實際上沒有處理.c或.h文件)。

回答

1

您的嘗試將無法正常工作,因爲作爲目標或先決條件列表一部分出現的變量和函數會在讀入生成文件時立即擴展。此時,顯然,無法知道%可能擴展到後來,當make試圖找出如何構建目標時,所以它實際上擴展了字符串<srcdir>/%.h,其中大概沒有。

答案之一是前提條件移動到一個單獨的規則:

$(OBJDIR)/foo.o : $(wildcard $(SRCDIR)/foo.h) 
$(OBJDIR)/bar.o : $(wildcard $(SRCDIR)/bar.h) 
$(OBJDIR)/baz.o : $(wildcard $(SRCDIR)/baz.h) 

如果你不希望有寫這篇文章時,你可以使用eval來爲你做它:假設你有一個列出目標文件的變量:

OBJECTS = foo.o bar.o baz.o 

$(foreach O,$(OBJECTS),$(eval $(OBJDIR)/$O : $(wildcard $(SRCDIR)/$(O:.o=.h)))) 

(這可能不完全正確)。

或者,您可以啓用.SECONDEXPANSION寫:

.SECONDEXPANSION: 
$(OBJDIR)/%.o : $(SRCDIR)/%.c $$(wildcard $(SRCDIR)/%.h) 
     #Implementation of target omitted 

(注意額外的$逃避通配符功能)。

+0

謝謝,使用.SECONDEXPANSION工作。 –

相關問題