g++多文件編譯,並實現makefile

  上文g++基本知識彙總介紹簡單的g++編譯器的用法,只是針對沒有依賴關係的單個文件的操作,當我們有多個文件需要編譯的時候,是如何工作的呢?下面以簡單的實例進行介紹,然後把實例以MakeFile文件實現,並對MakeFile文件進行簡單介紹。



     準備工作,下面是需要的簡單實例文件及代碼:

  main.cxx  

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat main.cxx</span>
<span style="font-family:Courier New,monospace;">#include <iostream></span>
<span style="font-family:Courier New,monospace;">#include "printf1.hxx"</span>
<span style="font-family:Courier New,monospace;">#include "printf2.hxx"</span>
<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c main.cxx</span>

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c  printf1.cxx</span>

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c printf2.cxx</span>
<span style="font-family:Courier New,monospace;">
int main(){ printf1(); printf2();}</span>
<span style="font-family:Courier New,monospace;">printf1.hxx</span>
<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat printf1.hxx</span>
<span style="font-family:Courier New,monospace;">#ifndef _PRINTF_1_H_</span>
<span style="font-family:Courier New,monospace;">#define _PRINTF_1_H_</span>

<span style="font-family:Courier New,monospace;">void printf1();</span>

<span style="font-family:Courier New,monospace;">#endif</span>
<span style="font-family:Courier New,monospace;">printf1.cxx</span>
<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat printf1.cxx</span>
<span style="font-family:Courier New,monospace;">#include "printf1.hxx"</span>
<span style="font-family:Courier New,monospace;">#include <iostream></span>

<span style="font-family:Courier New,monospace;">using namespace std;</span>

<span style="font-family:Courier New,monospace;">void printf1()</span>
<span style="font-family:Courier New,monospace;">{</span>
<span style="font-family:Courier New,monospace;">        cout<<"printf1"<<endl;</span>
<span style="font-family:Courier New,monospace;">}</span>
<span style="font-family:Courier New,monospace;">printf2.hxx</span>
<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat printf2.hxx</span>
<span style="font-family:Courier New,monospace;">#ifndef _PRINTF_2_H_</span>
<span style="font-family:Courier New,monospace;">#define _PRINTF_2_H_</span>

<span style="font-family:Courier New,monospace;">void printf2();</span>

<span style="font-family:Courier New,monospace;">#endif</span>
<span style="font-family:Courier New,monospace;">printf2.cxx</span>
<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat printf2.cxx</span>
<span style="font-family:Courier New,monospace;">#include "printf2.hxx"</span>
<span style="font-family:Courier New,monospace;">#include <iostream></span>

<span style="font-family:Courier New,monospace;">using namespace std;</span>

<span style="font-family:Courier New,monospace;">void printf2()</span>
<span style="font-family:Courier New,monospace;">{</span>
<span style="font-family:Courier New,monospace;">        cout<<"printf2"<<endl;</span>
<span style="font-family:Courier New,monospace;">}</span>
共計<span style="font-family:Courier New,monospace;">5</span>個文件,<span style="font-family:Courier New,monospace;">3</span>個<span style="font-family:Courier New,monospace;">cxx</span>文件,<span style="font-family:Courier New,monospace;">2</span>個<span style="font-family:Courier New,monospace;">hxx</span>頭文件

1、手動多文件編譯

先分別直接彙編(編譯)爲.o文件

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c main.cxx</span>

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c printf1.cxx</span>

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ -c printf2.cxx</span>

②鏈接階段

如果直接執行

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ main.cxx -o main</span>
<span style="font-family:Courier New,monospace;">/tmp/cc9LFDvP.o:main.cxx:(.text+0xc): undefined reference to `printf1()'</span>
<span style="font-family:Courier New,monospace;">/tmp/cc9LFDvP.o:main.cxx:(.text+0x11): undefined reference to `printf2()'</span>
<span style="font-family:Courier New,monospace;">collect2: ld </span>返回<span style="font-family:Courier New,monospace;"> 1</span>
出現上邊錯誤,原因是編譯器找不到<span style="font-family:Courier New,monospace;">printf1()</span>和<span style="font-family:Courier New,monospace;">printf2()</span>的定義。

所以需要將3obj文件鏈接到一個文件上:

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ g++ main.cxx printf1.cxx printf2.cxx -o main</span>

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ ./main</span>
<span style="font-family:Courier New,monospace;">printf1</span>
<span style="font-family:Courier New,monospace;">printf2</span>
並輸出結果。

這樣就能解決多文件編譯問題,但是一般情況下,一個項目下的文件比較多,如果這樣輸入,比較費勁,所以就需要把編譯過程寫進一個MakeFile文件中

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ cat makefile</span>
<span style="font-family:Courier New,monospace;">cc=g++</span>
<span style="font-family:Courier New,monospace;">exe=main</span>
<span style="font-family:Courier New,monospace;">obj=main.o printf1.o printf2.o</span>

<span style="font-family:Courier New,monospace;">$(exe):$(obj)</span>
<span style="font-family:Courier New,monospace;">        $(cc) -o $(exe) $(obj)</span>
<span style="font-family:Courier New,monospace;">main.o:main.cxx</span>
<span style="font-family:Courier New,monospace;">        $(cc) -c main.cxx</span>
<span style="font-family:Courier New,monospace;">printf1.o:printf1.cxx</span>
<span style="font-family:Courier New,monospace;">        $(cc) -c printf1.cxx</span>
<span style="font-family:Courier New,monospace;">printf2.o:printf2.cxx</span>
<span style="font-family:Courier New,monospace;">        $(cc) -c printf2.cxx</span>
<span style="font-family:Courier New,monospace;">clean:</span>
<span style="font-family:Courier New,monospace;">        rm -rf *.o main</span>
其中
<span style="font-family:Courier New,monospace;">cc=g++</span>
<span style="font-family:Courier New,monospace;">exe=main</span>
<span style="font-family:Courier New,monospace;">obj=main.o printf1.o printf2.o</span>
爲變量的定義,<span style="font-family:Courier New,monospace;">$(...)</span>作爲引用,可以分析一下,是不是和上文中單個操作效果一樣?

執行過程:

<span style="font-family:Courier New,monospace;">Administrator@72cec870236147e /home/liujl/mytest</span>
<span style="font-family:Courier New,monospace;">$ make</span>
<span style="font-family:Courier New,monospace;">g++ -c main.cxx</span>
<span style="font-family:Courier New,monospace;">g++ -c printf1.cxx</span>
<span style="font-family:Courier New,monospace;">g++ -c printf2.cxx</span>
<span style="font-family:Courier New,monospace;">g++ -o main main.o printf1.o printf2.o</span>





makefile可以參考:

1ASimple Makefile Tutorial

2中文makefile教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章