2015-11-19 30 views
4

我有一個項目,其中包含許多源文件在不同的文件夾位置。出於某種原因,我的Makefile可以執行下列操作之一,但不能兩者都在同一時間(這是我真正想要的): -MAKE:編譯所有文件一次並生成目標文件到不同的目錄

1)編譯所有文件到一個單獨的目錄

2)執行編譯一次,gcc只需要調用一次,因爲這大大減少了編譯時間。

這是一個代碼段工程實現選項1: -

INCLDDIRS := "The needed include directories" 
CFLAGS = "some c flags" 
C_SOURCE = "Many many source files in different directories" 
C_SOURCE_NAMES = $(notdir $(C_SOURCE)) 
OBJECT_DIRECTORY = ObjDir 
C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_NAMES:.c=.o)) 

all: $(OBJECT_DIRECTORY) $(C_OBJECTS) 

$(OBJECT_DIRECTORY): 
    mkdir ObjDir 

$(OBJECT_DIRECTORY)/%.o:%.c 
    $(CC) $(CFLAGS) $(INCLDDIRS) -c -o [email protected] $< 

出於某種原因,上述的單獨編譯每個C源文件並生成對象文件(即GCC被稱爲對於所有源文件) 。這不是我想要的。然而,至少所有生成的文件都位於ObjDir

,這是代碼片段,致力於實現選項2: -

INCLDDIRS := "The needed iclude directories" 
CFLAGS = "some c flags" 
C_SOURCE = "Many many source files in different directories" 
C_SOURCE_NAMES = $(notdir $(C_SOURCE)) 
OBJECT_DIRECTORY = ObjDir 
C_OBJECTS = $(OBJECT_DIRECTORY)/*.o 

all: $(OBJECT_DIRECTORY) $(C_OBJECTS) 

$(OBJECT_DIRECTORY): 
    mkdir ObjDir 

$(C_OBJECTS): (C_SOURCE) 
    $(CC) $(CFLAGS) $(INCLDDIRS) -c $(C_SOURCE) 

對於上面的代碼中,所有文件都編譯一次(即GCC是隻調用一次),但目標文件是在與Makefile相同的位置生成的,而不是單獨的目錄。我不想在生成這些文件後生成這些文件,因爲這不是更清潔的解決方案。

我的問題是: 我有什麼,這樣一旦和目標文件生成到一個單獨的目錄進行編譯做我的Makefile?

+0

我認爲你可以在每個目錄中使用單獨的Makefile,並使用「main」生成文件中的$(MAKE)來運行其他文件。 –

+1

第一個makefile是正確的,但不是你想要的。第二隻是不正確的。 –

回答

3

你想要的makefile文件看起來像這樣。

INCLDDIRS := "The needed include directories" 
CFLAGS = "some c flags" 
C_SOURCE = "Many many source files in different directories" 
C_SOURCE_NAMES = $(notdir $(C_SOURCE)) 
OBJECT_DIRECTORY = ObjDir 
BINARY := your_binary 

all: $(BINARY) 

$(OBJECT_DIRECTORY): 
     mkdir [email protected] 

$(OBJECT_DIRECTORY/$(BINARY): $(C_SOURCE) | $(OBJECT_DIRECTORY) 
     $(CC) $(CFLAGS) $(INCLDDIRS) -o [email protected] $^ 

它採用order-only prerequisite的輸出目錄(所以一定要知道首先創建它,但不能指望它在引起重建)。

它將源文件列爲輸出二進制文件的先決條件,並在編譯行中全部使用它們。

與此生成的文件的主要問題,並與你的目標,是一個改變任何源文件會導致源文件從頭重新編譯。就漸進式工作而言,這是相當低效的。 (這就是爲什麼默認的想法是使用中間目標文件,你用一些乾淨的速度交換一下增量速度。)

你的第二個makefile不能正常工作的原因是,在一個乾淨的目錄中,C_OBJECTS變量沒有價值。您的通配符$(OBJECT_DIRECTORY)/*.o什麼都不匹配。

那說,這是也是不正確的,因爲它上市源文件爲對象文件,該文件是不正確的先決條件。

+0

感謝您提供豐富的答案。 – StRiDeR

相關問題