2011-07-05 33 views
1

這個makefile的行爲並不像我期望的那樣。我希望它爲當前目錄和子目錄中的每個.c文件構建.o文件,並將它們放入一個靜態庫中。但是,它會在第一個或第二個文件後停止應用我的$(INCS)。當它試圖構建第二個.o文件時,我在構建行中看不到-I路徑,並且抱怨沒有在其中找到頭文件。名稱已被泛化以簡化事物。我在Windows XP上使用cygwin。我正在使用不在cygwin樹下的ARM交叉編譯器。我基於這個生成文件的回答here。只有大約二十個.c文件,因此以這種方式創建依賴文件的開銷並不大。爲什麼這個makefile不適用於所有對象?

# Project specific options 
CC = my-cross-gcc 
INCS := -I. -Iinc 
INCS += -Imy/inc/path 

CFLAGS := -Wall -fPIC -static -cross-compiler-specific-options 

OUT := bin/libmylib.a 

MKDIR:=mkdir -p 

### Generic C makefile items below: 

# Add .d to Make's recognized suffixes. 
SUFFIXES += .d 

NODEPS:=clean 
#Find all the C files in this directory, recursively 
SOURCES:=$(shell find . -name "*.c") 

#These are the dependency files 
DEPFILES:=$(patsubst %.c,%.d,$(SOURCES)) 
OBJS:= $(patsubst %.c,%.o,$(SOURCES)) 

#Don't create dependencies when we're cleaning, for instance 
ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS)))) 
    -include $(DEPFILES) 
endif 

#This is the rule for creating the dependency files 
%.d: %.c 
    $(CC) $(INCS) $(CFLAGS) -MM -MT '$(patsubst %.c, %.o,$(patsubst %.c,%.o,$<))' $< > [email protected] 

#This rule does the compilation 
%.o: %.c %.d %.h 
    $(CC) $(INCS) $(CFLAGS) -o [email protected] -c $< 

# Now create a static library 
all: $(OBJS) 
    @$(MKDIR) bin 
    ar rcsvq $(OUT) $(OBJS) 

clean: 
    rm -rf $(OBJS) $(OUT) $(DEPFILES) 

爲什麼這個Makefile 申請$(INCS)建立後續.o文件時?我如何解決它?輸出類似於此:

$ make all 
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o firstfile.o -c firstfile.c 
my-cross-gcc -I. -Iinc -Imy/inc/path -<compiler options> -o secondfile.o -c secondfile.c 
my-cross-gcc -<compiler flags> -o thirdfile.o -c thirdfile.c 
thirdfile.c:23:18: fatal error: myinc.h: No such file or directory 
compilation terminated. 

當我去海灣合作委員會一線構築thirdfile.o和使用-I路徑的命令行和類型,目標文件被成功建立。

+0

是否有'firstfile.h'和'secondfile.h'但沒有'thirdfile.h'? –

+1

與你的問題沒有關係,但你似乎沒有在任何地方包括依賴文件,使它們無用。 – interjay

+0

interjay,我似乎已經簡化了我輸入的makefile。我會在上面添加這些行。 – jasper77

回答

3

有在工作中處理的頭文件在這裏兩種不同的機制:

編譯器正試圖從foo.c建立foo.o,並在foo.c遇到#include "foo.h",它去尋找foo.h-I標誌告訴它在哪裏看。如果它被調用沒有標誌,它需要找到foo.h,它會抱怨並死亡。

使正在嘗試構建foo.o,並考慮使用哪個規則時,它將查看先決條件。你的規則的先決條件是foo.c foo.d foo.h,所以它尋找這些先決條件。 它怎麼知道foo.h是哪裏?請注意,其中一個命令中的編譯器標誌是沒用的 - 它不會對此進行任何推導。如果它找不到(並且不知道如何製作)先決條件,它將拒絕該規則並尋找另一個規則,例如對$(INCS)變量一無所知的隱含的%.o規則,並且該引線你到上面描述的問題。

如果是這樣的問題(你可以通過查看頭的位置,做一些實驗檢查),你有兩個選擇:

A)可以使用隱含規則,它的變量。只需將INCS添加到CFLAGS即可獲得您想要的結果。這告訴編譯器要做什麼,但是它仍然讓Make在黑暗中依賴,所以你可能需要再次檢查你的依賴處理是否正確。

B)你可以告訴請在哪裏可以找到頭文件:

vpath %.h inc my/inc/path 

(你可能會注意到,這是多餘的與你INCS變量,冗餘bad--就可以消除這種冗餘,但我敦促你先讓它工作。)

+0

你釘了它。當它到達第三文件時,makefile調用隱式規則。我將INCS添加到CFLAGS,然後不再需要明確的%.o規則,而且它運行得非常好。謝謝。 – jasper77

2

我猜測你有名爲firstfile.h,secondfile.h的文件,但沒有名爲thirdfile.h的文件?

然後,我會假設make不能使用你給它的規則,因爲找不到或建立.h文件。所以它決定使用默認的隱式規則。

+0

這些頭文件確實存在於用-I標誌指定的路徑中。與thirdfile.c不同的是,gcc行省略了-I信息。如果我手動輸入該行,使用-I部分,.o文件可以很好地構建。 – jasper77

1

我可以想象的是,對於「第三文件」,您的depfile文件有些過時或已損壞。也許這已經足夠糟糕了,因爲它會調用其他默認目標。

+0

「編譯器」 - >「製作」 –

+0

謝謝,並且如指出的那樣更正了 –

相關問題