2012-10-17 82 views
8

我想構建一個應用程序,並且有多個模塊存儲在多個目錄中。我決定遵循this的想法,即在每個目錄中都有一個makefile,然後合併它。但是 - 作爲一名初學者程序員 - 我仍然不知道該怎麼做。首先,這樣的「部分」製作文件將如何看起來像。它們不能具有主函數,因爲每個二進制文件只能有一個,儘管當我嘗試編譯它時,gcc抱怨未定義的對main的引用。其次,我不知道如何將所有這些模塊放在一起看起來像。多個目錄中的Makefiles

我將不勝感激任何幫助,但請儘量保持您的答案簡單。 Makefiles對我來說仍然是一種黑魔法。

+0

[Makefile與源文件在不同的目錄中]可能的副本(http://stackoverflow.com/questions/1139271/makefiles-with-source-files-in-different-directories) –

回答

25

在你可以用makefile做任何事情之前,你必須知道如何在沒有makefile的情況下做到這一點。

由於您使用的是gcc,我會假定您的源代碼是C++。

你還沒有告訴我們你的目錄結構是什麼樣子,所以我假設你在兩個目錄中有三個源文件:primary/main.cc,other/foo.ccother/bar.cc。 (我們可以在稍後處理類似foo.h的頭文件。)並且您想構建myApp

STEP 1:做手工

要在一個命令做到這一點,您可以使用:

gcc -Wall primary/main.cc other/foo.cc other/bar.cc -o myApp 

這將編譯三個源文件和二進制對象鏈接在一起成可執行文件myApp

STEP 2:做這捆柴(不要嘗試,直到你可以得到前面的步驟,完美地工作)

而是用一個命令建立的,你可以採取一箇中間步驟,編譯源文件轉換成二進制對象文件:

gcc -Wall -c primary/main.cc -o primary/main.o 
gcc -Wall -c other/foo.cc -o other/foo.o 
gcc -Wall -c other/bar.cc -o other/bar.o 

這將產生alpha/main.obeta/foo.obeta/bar.o。編譯器不會抱怨foobar缺少main()函數,因爲目標文件不需要一個。 然後物體連接在一起成一個可執行文件:

gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp 

第3步:做本地(不要嘗試,直到你可以得到前面的步驟,完美地工作。)

就像前面的步驟,但我們的行爲primary/other/

cd primary 
gcc -Wall -c main.cc -o main.o 
cd ../other 
gcc -Wall -c foo.cc -o foo.o 
gcc -Wall -c bar.cc -o bar.o 
cd .. 
gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp 

步驟四:使用一個Makefile(在你完成上一步操作之前,不要嘗試這樣做。)

我們可以使用makefile執行STEP 1,但這並不是必須的。寫一個makefile到primary(即primary/makefile)是這樣的:

main.o: 
    gcc -Wall -c main.cc -o main.o 

(在fromt gcc...的空白是一個TAB)

現在試試這個:

cd primary 
make 
cd ../other 
gcc -Wall -c foo.cc -o foo.o 
gcc -Wall -c bar.cc -o bar.o 
cd .. 
gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp 

STEP 5:使用一些Makefile文件(別試試這個,直到你可以完成上一步工作。)

寫一個other/makefile

both: foo.o bar.o 

foo.o: 
    gcc -Wall -c foo.cc -o foo.o 

bar.o: 
    gcc -Wall -c bar.cc -o bar.o 

,並在頂級目錄下,你正在構建myApp一個makefile:

myApp: 
    gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp 

現在試試這個:

cd primary 
make 
cd ../other 
make 
cd .. 
make 

STEP 6:使用一個Makefile文件調用其他(不要嘗試這個,直到你可以完成上一步工作。)

編輯頂層Makefile:

myApp: 
    cd primary; make 
    cd other; make 
    gcc -Wall primary/main.o other/foo.o other/bar.o -o myApp 

現在試試:

make 

如果所有這些工作,你有什麼是原油,但有效 makefile文件系統。當你準備好關閉訓練輪時,可能會有很多改進。

編輯:

如果有一個子目錄(如other/)許多源文件,你不希望在保持手工頂層Makefile列表,有幾種方法來處理它。這是一個:

OTHER_SOURCES := $(wildcard other/*.cc) 

OTHER_OBJECTS := $(OTHER_SOURCES:.cc=.o) 

myApp: 
    cd primary; make 
    cd other; make 
    gcc -Wall primary/main.o $(OTHER_OBJECTS) -o myApp 

但是,你應該讓這些makefiles工作和理解他們,然後再嘗試更多的精簡。

+0

感謝您的優秀教程!如果我在每個模塊目錄中有非常多的文件,該怎麼辦?如果寫下第六步的最後一行,會非常煩人。有沒有解決方法?就像將所有.o文件合併到一個目錄中,或者在makefile中告訴獲取給定目錄中的所有.o文件一樣? – yauser

+0

您也可以使用'-C'來(在makefile內部)更改目錄並讀取該目錄中的makefile。 – Aif

+0

@Aif:是的,我使用'-C',但我試圖保持原始的東西。正如我所說,許多改進都是可能的。 (我聽說'-C'實際上不符合POSIX標準......) – Beta