1. 程式人生 > 其它 >Linux C/C++開發環境和編譯除錯(一)

Linux C/C++開發環境和編譯除錯(一)

Linux C/C++開發環境和編譯除錯(一)

1.安裝相應的軟體

1.1 編譯器/偵錯程式

sudo:切換到root並執行某命令

sudo apt get:更新軟體包的來源

安裝編譯器和偵錯程式:

sudo apt install build-essential gab

使用如下命令來確認軟體版本和是否安裝成功:

gcc --version
g++ --version
gdb --version

1.2安裝CMake

root@ziggy-virtual-machine:~# apt install cmake

GCC 編譯器

gcc:C語言

g++:C++

2.1 編譯過程

編譯過程分為四步:

  1. 預處理,生程.i檔案

    g++ -E test.cpp -o test.i
    
  2. 編譯生成組合語言檔案

    g++ -S test.i -o test.s
    
  3. 彙編,將原始碼比那一為機器語言的目的碼

    g++ -c test.s -o test.o
    
  4. 連線

    #產生可執行檔案並指定檔名
    g++ test.o -o test
    

    編寫簡單的輸出字串的test.cpp檔案

    #使用g++ test.cpp -o test即可生成可執行檔案test
    

2.2 編譯引數

g++編譯引數

-g:如果想要使用gdb除錯,就必須使用-g產生可以被偵錯程式使用的除錯資訊
g++ -g test.cpp -o test#帶除錯資訊的test

-O[n]#優化原始碼,n:0-3
g++ test.cpp -O2 -o test

#-l , -L指定庫檔案|指定庫檔案路徑
-l用於指定程式要連結的庫,-l緊跟庫名
能夠用-l直接連線的庫:/lib,/usr/lib,/usr/local/lib中的庫
g++ -lglog test.cpp

-L #指定庫檔案所在的目錄名(如果庫檔案不在三個目錄中)
#連線test2庫,在/root/test下有libtest2.so
g++ -L/root/test -ltest2 test.cpp

-I#指定標頭檔案搜尋目錄,如果在當前目錄則使用-I.
g++ -I/myinclude test.cpp

-wall#列印gcc警告資訊
-w#關閉警告資訊

-std=c++11#設定編譯標準
g++ -std=c++11 test.cpp

-D#定義巨集

2.3 例子

使用tree命令,檢視建立好的檔案目錄結構

swap.cpp需要swap.h,但是swap.h並不在swap.cpp所在的目錄中,main和其他兩個檔案也不在同一級目錄

#可以將main.cpp和swap.cpp一同編譯,但是由於swap.cpp用到了swap.h
g++ main.cpp src/swap.cpp -Iinclude
g++ main.cpp src/swap.cpp -Iinclude -o swap
g++ main.cpp src/swap.cpp -Iinclude -o swap -Wall

2.4 生成庫檔案並編譯

將2.3中的swap.cpp生成為靜態庫

#進入/src
#首先生成swap.o檔案
g++ swap.cpp -c -I../include
#其次生成靜態庫libswap.a
root@ziggy-virtual-machine:~/GCC_test/src# ar rs libSwap.a swap.o
ar: 正在建立 libSwap.a
root@ziggy-virtual-machine:~/GCC_test/src# ls
libSwap.a  swap.cpp  swap.o

#將main.cpp連線靜態庫
 g++ main.cpp -lSwap -Lsrc -Iinclude -o static_main

生成動態庫

g++ swap.cpp -U../include -fPIC -shared -o libSwap.so
#相當於:
gcc swap.cpp -I../include -c -fPIC
gcc -shared -o libSwap.sp swap.o
#生成可執行檔案:
g++ main.cpp -Iinclude -Lsrc -lSwap -o sharemain

靜態庫和動態庫的區別:
靜態庫直接將libSwap.a包裝進來

動態庫是在執行時再將動態庫檔案引入

靜態庫生成的可執行檔案>動態庫

動態庫的可執行檔案執行時,如果動態庫不在預設搜尋路徑下,則需要指定搜尋路徑

LD_LIBRARY_PATH=src ./sharemain

動態庫和靜態庫在同一目錄下時優先使用動態庫

3. gdb除錯

#常用命令
$(gdb)next(n)   # 單步除錯(逐過程,函式直接執行)
$(gdb)step(s) # 單步除錯(逐語句:跳入自定義函式內部執行)
$(gdb)info(i) # 檢視函式內部區域性變數的數值
$(gdb)finish # 結束當前函式,返回到函式呼叫點
$(gdb)continue(c) # 繼續執行
$(gdb)print(p) # 列印值及地址
$(gdb)quit(q) # 退出gdb
$(gdb)break+num(b) # 在第num行設定斷點
$(gdb)$(gdb)help(h) # 檢視命令幫助,具體命令查詢在gdb中輸入help + 命令delete breakpoints num(d) # 刪除第num個斷點

按回車執行上一次的命令

3.2 除錯例子

#include <iostream>
using namespace std;
int main(int argc,char **argv)
{
    int N = 100;
    int sum = 0;
    int i = 1;
    
    while (i <= N)
   {
        sum = sum + i;
        i = i + 1;
   }
    cout << "sum = " << sum << endl;
    cout << "The program is over."   << endl;
    
    return 0;
}