文章目錄
- 可以用參數-D在命令列設定宏(macro),並且可以設定宏的值
- g++可以將.o對象檔案連結成程式
- 如果想連結其他庫檔案,則用參數-I
- 連結器預設在/lib和/usr/lib檔案夾下面尋找系統標準庫。
- 如果想從其他的檔案夾下面尋找要連結的庫,則從參數-L指定
- Makefile如下:
- 首先是編譯目標(target),緊接著是一個冒號:,然後是完成目標所需的依賴(dependencies)
- 規則行必須以Tab鍵開頭
- $(CFLAGS)是make變數,變數可以再Makefile中定義,也可以在命令列定義
- 啟動GDB
- 命令run加參數可運行程式
- 命令where可以查看Stack
- 用up命令可以彈出運行棧
- 用print命令可以查看變數值
- 用next命令執行下一條語句
- 用step命令可以進入一個函數
1、用GCC編譯1.1、建立源檔案
#include <stdio.h> #include “reciprocal.hpp” int main (int argc, char **argv) { int i; i = atoi (argv[1]); printf (“The reciprocal of %d is %g\n”, i, reciprocal (i)); return 0; } |
- (reciprocal.cpp) C++ 源檔案 - reciprocal.cpp
#include <cassert> #include “reciprocal.hpp” double reciprocal (int i) { // I should be non-zero. assert (i != 0); return 1.0/i; } |
- (reciprocal.hpp) 標頭檔 - reciprocal.hpp
#ifdef __cplusplus extern “C” { #endif extern double reciprocal (int i); #ifdef __cplusplus } #endif |
1.2、編譯源檔案
- 參數-I指定搜尋標頭檔的位置。
- 預設情況下,GCC在當前檔案夾及標準庫的標頭檔所在的檔案夾來搜尋標頭檔。
% g++ -c -I ../include reciprocal.cpp |
- 可以用參數-D在命令列設定宏(macro),並且可以設定宏的值
對於如下程式definemacro.c:
#include "stdio.h" #include "stdlib.h" int main(int argc, char** argv){ int i = 3; #ifdef CHANGEVALUE i = 4; #endif printf("i = %d\n", i); printf("PT = %f\n", PI); } |
如果編譯時間命令列為gcc definemacro.c,會報‘PI’ undeclared錯誤。
如果編譯時間命令列為gcc -D PI=3.14 definemacro.c,則輸出如下:
i = 3
PT = 3.140000
如果編譯時間命令列為gcc -D PI=3.14 -D CHANGEVALUE definemacro.c,則輸出如下:
i = 4
PT = 3.140000
% g++ -c -O2 reciprocal.cpp |
1.3、連結化物件檔案
% g++ -o reciprocal main.o reciprocal.o |
例如欲連結庫libpam.a,則用如下命令列,編譯器會自動加上首碼lib和尾碼.a
% g++ -o reciprocal main.o reciprocal.o –lpam |
- 連結器預設在/lib和/usr/lib檔案夾下面尋找系統標準庫。
- 如果想從其他的檔案夾下面尋找要連結的庫,則從參數-L指定
% g++ -o reciprocal main.o reciprocal.o -L/usr/local/lib/pam –lpam |
2、用Make自動編譯
reciprocal: main.o reciprocal.o g++ $(CFLAGS) -o reciprocal main.o reciprocal.o main.o: main.c reciprocal.hpp gcc $(CFLAGS) -c main.c reciprocal.o: reciprocal.cpp reciprocal.hpp g++ $(CFLAGS) -c reciprocal.cpp clean: rm -f *.o reciprocal |
- 首先是編譯目標(target),緊接著是一個冒號:,然後是完成目標所需的依賴(dependencies)
- 下一行是完成編譯目標的規則
- 規則行必須以Tab鍵開頭
- $(CFLAGS)是make變數,變數可以再Makefile中定義,也可以在命令列定義
% make CFLAGS=-O2 gcc -O2 -c main.c g++ -O2 -c reciprocal.cpp g++ -O2 -o reciprocal main.o reciprocal.o |
3、用GDB調試3.1、帶調試資訊編譯
- 如果要在編譯時間帶調試資訊,則在編譯時間命令列用-g參數
% make CFLAGS=-g gcc -g -c main.c g++ -g -c reciprocal.cpp g++ -g -o reciprocal main.o reciprocal.o |
3.2、運行GDB
(gdb) run Starting program: reciprocal |
(gdb) where #0 __strtol_internal (nptr=0x0, endptr=0x0, base=10, group=0) at strtol.c:287 #1 0x40096fb6 in atoi (nptr=0x0) at ../stdlib/stdlib.h:251 #2 0x804863e in main (argc=1, argv=0xbffff5e4) at main.c:8 |
(gdb) up 2 #2 0x804863e in main (argc=1, argv=0xbffff5e4) at main.c:8 8 i = atoi (argv[1]); |
(gdb) print argv[1] $2 = 0x0 |
(gdb) break main Breakpoint 1 at 0x804862e: file main.c, line 8. |
(gdb) next 9 printf (“The reciprocal of %d is %g\n”, i, reciprocal (i)); |
(gdb) step reciprocal (i=7) at reciprocal.cpp:6 6 assert (i != 0); |