1.編譯。對c++而言,通常是檔案獨立編譯--產生獨立的中間目標檔案。這時主要是語義語法檢查,函數與變數的申明的正確性。這需要引入合適的標頭檔,要讓編譯器看到定義。編譯產生的檔案在windows下是.obj檔案,在unix下是.o檔案。
2.串連。串連時,主要是串連函數和全域變數,地址替換和重定位。串連時只關注目標檔案,忽略了源檔案。如果函數未被聲明,通常只是警告一下,可以產生目標檔案。但是如果類型未定義(編譯器無法確定類型大小時),則出錯。
3.庫檔案。每個文字檔得到一個.o檔案。我們使用時必須串連用到的所有.o檔案。這顯然不是一個聰明的做法。怎麼辦?我們可以把很多.o檔案打包成庫檔案。比如說標準c庫,標準c++庫等。打包後的庫檔案在windows下是.lib檔案,在unix下是.a檔案。
// -- 4,5,6,7,8是關於makefile的概貌:http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html#content
4.makefile的編寫
makefile由make解釋程式來執行,makefile的主要規則異常簡單,以冒號區分目標和先決條件,下一行是滿足先決條件時要執行的命令,如下:
target : condition1 ... conditionn
commandline
一個執行個體:
main.o: main.c main.h
gcc -g -o main main.c
如果main.c或main.h有任何一個檔案比main.o新,則執行下面命令的重新編譯。
另一個例子:
clean : (no conditions, clean不是一個檔案,只是一個動作名,沒有先決條件意味著無條件執行)
rm -f main.o
如果我們輸入make clean則執行rm -f main.o
5.make的工作過程
--在目前的目錄下尋找Makefile和makefile檔案。
--解釋執行makefile檔案,對於所依賴的目標檔案,makefile會遞迴它們的依賴性(像一個堆棧的過程)。
--第一個目標檔案當是終極目標,自動執行的時候,它相當於樹的根。如果某些規則不在這棵樹中,則該規則
不會自動執行。比如上面樣本的clean動作(這些動作可以顯示調用)
6.寫出出色的makefile檔案
會寫makefile檔案,並不意味著能寫出一個漂亮的makefile檔案。
makefile中可以申明變數(相當於宏):NAME= ... 引用$(NAME)
使用變數的目的會讓makefile變得很清晰,易於維護。
7.make的自動推導功能
比如看到main.o自動把main.c加入到它的依賴列表。並且gcc -o main.o main.c被推匯出來。
這就是“隱晦規則”,在這裡不詳細討論隱晦規則和偽目標檔案(.PHONY表示)。
8.關於"編程修養":為每一個makefile檔案寫一個clean的偽目標。一般風格是:
clean:
rm object1 ... $(objects)
更為穩健的做法是:
.PHONY : clean
clean :
-rm object1 ... $(objects) //前面加-的原因是:這樣如果執行過程中出錯了,忽略錯誤繼續執行後面的。
// -- 9,10 是關於gcc/g++的概貌
9.gcc/g++簡介:gcc and g++分別是gnu的c & c++編譯器
gcc/g++在執行編譯工作的時候,總共需要4步
1.預先處理,產生.i的檔案 --.i檔案
2.將預先處理後的檔案不轉換成組合語言,組建檔案.s --.s檔案
3.有彙編變為目標代碼(機器代碼)產生.o的檔案 --.o檔案
4.串連目標代碼,產生可執行程式
10.[參數詳解]
-c
只啟用預先處理,編譯,和彙編,也就是他只把程式做成obj檔案
-S
只啟用預先處理和編譯,就是指把檔案編譯成為彙編代碼。
-E
只啟用預先處理,這個不組建檔案,你需要把它重新導向到一個輸出檔案裡
--可以試一下gcc -E hello.c >hello.txt 或者 gcc -E hello.c | more
-o
制定目標名稱,預設的時候,gcc 編譯出來的檔案是a.out,很難聽,如果 你和我有同感,改掉它,哈哈
-ansi
關閉gnu c中與ansi c不相容的特性,啟用ansi c的專有特性(包括禁止一些asm inline typeof關鍵字,以
及UNIX,vax等預先處理宏,
-wall
顯示警告資訊
-fno-asm
此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作關鍵字。
-O0
-O1
-O2
-O3
編譯器的最佳化選項的4個層級,-O0表示沒有最佳化,-O1為預設值,-O3最佳化層級最高
-g
只是編譯器,在編譯的時候,產生調試資訊。
-ggdb
此選項將儘可能的產生gdb的可以使用的調試資訊.
-Ldir
指定編譯的時候,搜尋庫的路徑。比如你自己的庫,可以用它制定目錄,不然編譯器將只在標準庫的目錄
找。這個dir就是目錄的名稱。
-llibrary
指定編譯的時候使用的庫
// -- 11,12 是關於gdb的概貌
11.gdb簡介:Linux包含了一個叫gdb的GNU偵錯工具. gdb是一個用來調試C和C++程式的強力調試器. 它使你能在程式運行時觀察程式的內部結構和記憶體的使用方式. 以下是gdb 所提供的一些功能:
它使你能監視你程式中變數的值. --監視記憶體和寄存器
它使你能設定斷點以使程式在指定的程式碼上停止執行. --斷點調試
它使你能一行行的執行你的代碼. --單步調試
12.gdb基本命令:
file 裝入想要調試的可執行檔.
kill 終止正在調試的程式.
list 列出產生執行檔案的原始碼的一部分. 可以後面加n定位
next 執行一行原始碼但不進入函數內部.
step 執行一行原始碼而且進入函數內部.
run 執行當前被調試的程式
quit 終止gdb
watch 使你能監視一個變數的值而不管它何時被改變. 必須先讓設斷點進入
break 在代碼裡設定斷點, 這將使程式執行到這裡時被掛起.
make 使你能不退出gdb就可以重新產生可執行檔.
shell 使你能不離開gdb就執行UNIX shell命令. exit退出shell模式