Linux環境:C編程基礎操作

gcc安裝

Ubuntu:

sudo apt-get install gcc

Centos:

sudo yum install gcc

確認是否安裝成功

gcc -v

gcc基礎編譯命令

通過gcc編譯命令可以生成後綴名.i的預處理文件,.s的彙編文件,.o的目標文件,.a/.so的庫文件和可執行文件
Linux中的C程序源碼編譯成可執行程序,可能需要依賴多個庫文件。可以把這些依賴的庫文件當作源碼文件的一部分。

常用gcc命令參數
-c 後接編譯源文件名
-o 後接產生的目標文件
-g 表示在目標文件中產生調試信息,使得目標文件可以用於 gdb 調試
-D<宏定義> 編譯時將宏定義參數傳入進去
-Wall 打開所有類型的警告

生成可執行文件的方式

  1. 若干源碼文件 直接編譯生成可執行文件
    格式:gcc [源碼文件名] -o [可執行文件名]
    eg.
    	gcc c1.c c2.c -o test.exe
    
  2. 源碼文件生成目標文件,目標文件和依賴的庫文件(可以省略)一起鏈接生成可執行文件
    格式:
    gcc -c [源碼文件名] -o [目標文件名]
    gcc -o [可執行文件] [源碼文件] -[庫文件]
    	gcc -c c1.c -o c1.o
    	gcc -c c2.c -o c2.o
    	gcc -o test.exe c1.o c2.o
    
  3. 源碼文件生成預處理文件,預處理文件生成彙編文件,彙編文件生成目標文件,目標文件鏈接成可執行文件
    	gcc -E  main.c -o main.i
     	gcc -S  main.i -o main.s
      	gcc -c  main.s -o main.o
    	gcc -o  main.exe main.o
    

gcc進階命令:靜態庫與動態庫文件的生成

  1. 靜態庫文件生成
    靜態庫生成較爲簡單,庫文件在鏈接時直接注入源碼文件,生成的可執行文件移植性好,運行時不依賴靜態庫文件,方便部署,但是不利於升級,每次升級後需要重新生成可執行文件
    生成流程:

    1. gcc編譯命令生成目標文件 gcc -c add.c -o add.o
    2. ar命令對目標文件(可以是多個)打包生成庫文件 crsv爲參數,其中csv是修飾符可以省略 ar crsv libadd.a add.o
    3. 庫文件放入默認庫文件路徑/lib/usr/lib mv libadd.a /lib
    4. 編譯生成可執行文件,注意庫文件名gcc -o main.exe main.c -ladd

其中,只有第二步需要記憶,其他均爲常規操作。

  1. 動態庫文件生成
    動態庫生成稍微複雜,庫文件在鏈接時不注入源碼文件,生成的可執行文件運行時需要依賴動態庫文件,移植性差,不便於部署在其他機器,但是升級方便,只需要更新庫文件。
    生成流程:

  2. 動態編譯生成目標文件 gcc -fPIC -Wall -c add.c

  3. 目標文件生成動態庫文件 gcc -shared -o libadd.so add.o

  4. 庫文件放入默認庫文件路徑/lib/usr/lib mv libadd.so /lib

  5. 編譯生成可執行文件,注意庫文件名gcc -o main.exe main.c -ladd
    需要注意的是第一步和第二步也可以合成一步gcc -fPIC -Wall -shared -o libadd.so add.c

批量編譯:Makefile簡介

通過編寫Makefile文件可以實現批量編譯操作

原理:每次編譯過程使用的命令大體相同,不同的只有文件名,所以可以使用變量名替換掉文件名,從而實現自動化編譯。不同的文件之間存在依賴關係,所以採用自頂(可執行文件)向下(源碼文件)的遞歸過程。
Makefile的語法規則:

  1. 變量命名 :Makefile實際上是採用不同字符串對命令進行替換實現的,所以變量均爲字符串格式。爲了與命令區別,變量使用時需要加小括號並使用$進行標識$(變量名)

    • 直接賦值定義:變量名:= 字符串
    • 遞歸式定義 : 變量名 = 字符串(變量名)類似多個指針指向一個地址
  2. 函數:

    • 查找函數$(wildcard *.c),wildcard是函數名,後跟一個參數,作用是將符合該參數規則的文件名當作一列字符串輸出,各個文件名之間會隔開。*.c會找到當前目錄下的所有.c文件名並輸出
    • 字符串替換函數$(patsubst 匹配規則1,匹配規則2,源字符串列表)將源字符串列表中符合匹配規則1的字符串 進行替換 使其符合匹配規則2。Makefile中的通配符爲%

    示例OC=$(patsubst %.c,%.o,$(wildcard *.*))含義是將當前目錄下所有有後綴名的文件中的.c文件名拿出來,並把.c替換成.o,然後將這一串字符串賦值給變量OC

  3. 規則
    主要用到 :

    • $@代表當前規則下的目標文件\
    • $^代表當前規則的所有依賴文件
    • 所有的.o文件會自動依賴同名的.c文件
    • 一系列的預定義變量
      通過上述規則,即可編寫通用的makefile文件,針對特殊需求只需要修改對應變量即可

以下爲簡單的通用Makefile文件示例

生成可執行文件的Makefile文件

   EXE:=test.exe                                                                                                                                                                              
   #編譯後得到的可執行文件的名字
   
   CC:=gcc
   #選擇的C編譯器 可以根據需要改動
   
   CFLAGS:=-Wall -g
   #gcc編譯參數 顯示所有警告信息 可調試 可以根據需要改動
   
  LIBSO:=
  #庫依賴文件 可以根據需要添加
  
  OC := $(patsubst %.c, %.o, $(wildcard *.c))
  #目標文件列表 用來生成可執行文件
  
  $(EXE):$(OC)
      $(CC) $(CFLAGS) -o $@ $^
  
  .PHONY : clean rebuild
  clean:
      rm -f $(EXE) $(OC)
  rebuild:
      clean $(EXE)

生成靜態庫文件的Makefile文件

# 庫文件名, lib*.a
TARGET  := libtest.a

# 編譯器選擇
CC      := gcc

#打包程序選擇
AR      = ar

#gcc編譯參數 顯示所有警告信息 可調試 可以根據需要改動
CFLAGS:=-Wall -g

#依賴的庫文件
LIBS    :=

# 自動查找當前目錄所有 .c 文件,並將目標定義爲同名 .o 文件

SOURCE  := $(wildcard *.c)

OBJS    := $(patsubst %.c,%.o,$(SOURCE))

 
$(TARGET) : $(OBJS) 

#生成靜態庫文件
    $(AR) crvs $(TARGET) $(OBJS)

#移動到/lib中
    mv $(TARGET) /lib

.PHONY : clean delete rebuild

clean :
#刪除中間文件
    rm -rf *.o
#刪除庫文件
delete:
	rm  /lib/$(TARGET)
#重新生成庫文件
rebuild:
	clean $(TARGET)


生成動態庫文件的Makefile文件

# 庫文件名, lib*.so
TARGET  := libtest.so

# 編譯器選擇
CC      := gcc

#gcc生成動態庫文件的編譯參數
CFLAGS:= -g -Wall -fPIC -shared -o

#依賴的庫文件
LIBS    :=

# 自動查找當前目錄所有 .c 文件

SOURCE  := $(wildcard *.c)

$(TARGET) : $(OBJS) 
	$(TARGET) $(CFLAGS) $(TARFET) $(SOURCE) 

#移動到/lib中
    mv $(TARGET) /lib

.PHONY : clean delete rebuild

clean :
#刪除中間文件
    rm -rf *.o
#刪除庫文件
delete:
	rm  /lib/$(TARGET)
#重新生成庫文件
rebuild:
	clean $(TARGET)

gcc調試命令gdb

如果在gcc編譯程序時加入了-g參數,則可以使用gdb命令對可執行文件進行調試
gdb -q 可執行文件名
#-q參數可以消除gdb啓動時輸出的無用的版本信息等
常用gdb命令:
l:查看代碼
b : 打斷點
info b:查看所有斷點
tb :打臨時斷點
r :運行
bt:查看函數堆棧調用信息
delete:刪除斷點
n:下一步,遇到函數直接執行不進入
s:下一步,遇到函數進入
disable:使某個斷點失效
enble:啓用某個斷點
c:繼續運行
p:打印命令,可以用來打印變量
q:退出

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