2014-03-04 98 views
0

我想編譯一個由主C文件和兩個輔助C++文件組成的程序。 Main.c取決於Wrapper.cpp而這取決於Utility.cpp。具體來說,Main.c調用Wrapper.cpp中定義的函數func()可以從命令行編譯,但不能從makefile編譯

有趣的問題是我可以從命令行編譯程序,但是我不能從makefile中這樣做。我得到一個鏈接錯誤「main.o:對func()的引用未定義」。這可能主要是因爲我理解了makefile的概念,但它們可能太複雜了!

下面是我通過命令行編譯如何:

g++ -c Wrapper.cpp Utility.cpp 
gcc -c Main.c Wrapper.cpp 
g++ -o myProg Main.o Wrapper.o Utility.o 

這裏是我的makefile:

# Rules to produce the targets 

all: Main 

Main: Utility.o Main.o Wrapper.o 
     g++ -o myProg Utility.o Main.o Wrapper.o -lstdc++ 

# Rules to produce the object files 

Utility.o: Utility.cpp 
     g++ -c Utility.cpp 

Wrapper.o: Wrapper.cpp Utility.cpp 
     g++ -c Wrapper.cpp Utility.cpp 

Main.o: Main.c Wrapper.cpp 
     gcc -c Main.c Wrapper.cpp 

我知道,我可能會被編譯Utility.cpp和Wrapper.cpp兩次,但我真不不知道如何編寫規則來編譯。有人能給我一些有用的見解。也請不要給我複雜的makefiles,因爲我對他們來說很陌生。

回答

1

您的主要問題是您正在想象源文件依賴於其他源文件。這不是真的。你不需要Utility.cpp的內容來編譯Wrapper.cpp(除非你正在做一些奇怪的事情,例如將源文件加入其他源文件)。

同樣,目標文件僅依賴於它們正在編譯的源文件以及源文件包含的任何標題。

可執行文件依賴於構建程序所需的所有目標文件和庫。

因此,在最簡單的情況下,你會寫(注意你不需要明確的,如果你使用g++-lstd++鏈接:

all: Main 

Main: Utility.o Main.o Wrapper.o 
     g++ -o myProg Utility.o Main.o Wrapper.o 

# Rules to produce the object files 

Utility.o: Utility.cpp 
     g++ -c Utility.cpp 

Wrapper.o: Wrapper.cpp 
     g++ -c Wrapper.cpp 

Main.o: Main.c 
     gcc -c Main.c 

雖然這很容易理解,它確實消除了大部分的。化妝的力量你可以寫此生成的文件以獲得完全相同的結果:。

CXX = g++ 
CC = gcc 

Main: Main.o Utility.o Wrapper.o 

就是這樣,全部完成

+0

非常感謝你對你的反饋。在一個bove簡潔的makefile,如何使用變量CXX和CC? – NewToAndroid

+0

你不需要使用它們。 Make有一些內置的規則,這些規則使用了一些預定義的變量。這個簡潔的makefile利用了這些內置規則,其中一個規則告訴如何從'.cpp'構建'.o',另一個規則告訴如何從'.o'構建一個程序。 (具有相同的前綴名稱)。這些內置規則使用'CXX','CC','CPPFLAGS','CXXFLAGS'等變量。因此,通過設置這些變量,您可以更改規則的工作方式,而無需重新定義規則本身。查看GNU make手冊,或運行'make -pf/dev/null'查看所有規則。 – MadScientist

+0

非常感謝你的非常有用和簡單的makefile。我寫了下面的makefile XX = g ++ CC = gcc CFLAGS = -std = c99 CXXFLAGS = -o myProg all:Main.o Utility.o Wrapper.o ...當我編譯時,我不再得到原始引用未定義的錯誤,所以這很好。但是,不會生成可執行文件,即只生成目標文件並且不鏈接。當我通過命令行將它們鏈接起來時,可執行文件會很快生成。請幫我解決這個問題 – NewToAndroid