編譯過程

GCC和程序編譯過程

GCC是linux下面的編譯器,最初名稱是GNU C Compiler (GCC) ,後面逐漸可以編譯各種語言,因此GNU Compiler Collection (GCC)。

他是自由軟件大神Richard Stallman發起的。目前GCC系列在win和unix環境都可以使用,win中可以使用mingw或者cygwin

 

使用GCC,就要知道它的各種編譯選項,而在這之前我們首先要知道程序的編譯過程:

 

預處理,一般是包含頭文件,展開宏定義等,生成.i格式輸出文件

編譯,將預處理後的文件編譯生成彙編代碼

彙編,將彙編代碼生成機器碼

鏈接,將多個不同的目標文件以及動態庫和靜態庫路徑鏈接生成最終的可執行文件

對於一個簡單的文件,上面的流程gcc命令如下:

程序的運行過程:

    預處理->編譯->彙編->鏈接

    預處理                       gcc -E hello.c -o hello.i

    編譯,生成彙編代碼    gcc -S hello.i -o hello.s 

    彙編,生成.o彙編文件 gcc -c hello.s -o hello.o

    鏈接生成可執行文件  gcc hello.o -o hello

 

GCC的其他常用選項包括如下:

gcc選項:

 -o 輸出可執行文件

 -c 編譯生成目標文件

 -g 輸出調試信息

 -O2 編譯器優化級別  1-3

 -Wall 警告選項 輸出警告信息

 -l 緊接着鏈接庫 lpthread

 -L 指定鏈接庫的路徑

 -I 頭文件路徑

 -shared 編譯成動態鏈接庫

 

注意-c只是生成目標文件,而-o直接回生成可執行文件

頭文件與鏈接庫文件

在編譯程序的時候,我們通常需要關注的是頭文件以及鏈接庫文件

頭文件.h開頭,一般會有各種函數和結構的聲明,庫文件包括動態鏈接庫與靜態鏈接庫,linux下分別是.so 和 .a

Makefile的作用和介紹

其實GCC編譯器完全可以滿足編譯C以及CPP程序的需求,那麼爲什麼還需要makefile呢。

Makefile的作用是將GCC編譯的過程規則化,包括編譯順序,依賴關係,第二次進行增量編譯,編譯後的一些相關操作等。

Makefile會定義一對規則和依賴關係,規則定義如下:

 名稱: 依賴項1  依賴項2 .....

  [tab] 一系列命令

一些選項和宏定義:

  # 註釋

  \ 換行

  macro宏定義

  CC 表示編譯器的名稱

  CFLAGS表示編譯器選項

  LDLIBS表示鏈接庫選項

  $@ 代指目標文件

  $<第一個依賴文件

  $^所有依賴文件

  $?所有的比目標文件更新的依賴文件

  $+和$^類似,但是可以包含重複

  VPATH = src include 從src 和 include中尋找依賴項

  vpath %.c src 從src找.c文件

  vpath %.h include 從include找.h文件

  %.o:%.c   #%表示文件匹配

 

  相關examples:

   #(1) 

   .c.o:                    # .c.o:表示所有的.o都與其對應的.c依賴

            gcc -c $<    # 表示編譯所有的.c依賴項

   

   #(2)

    #main依賴於 mytool1 和 mytools2

    main:main.o mytools1.o mytools2.o

    gcc -o $@ $^

   .c.o:

    gcc -c $< -l.;

 

   #(3)

      LINK_TARGET = test_me.exe

 

 

   OBJS =  \

     Test1.o \

     Test2.o \

     Main.o

   

   REBUILDABLES = $(OBJS) $(LINK_TARGET)

 

 

   clean : 

      rm -f $(REBUILDABLES)

      echo Clean done

 

 

    all : $(LINK_TARGET)

      echo All done

 

 

   $(LINK_TARGET) : $(OBJS)

        g++ -g -o $@ $^

 

 

   %.o : %.cpp

        g++ -g -o $@ -c $<

 

 

   Main.o : Main.h Test1.h Test2.h

   Test1.o : Test1.h Test2.h

   Test2.o : Test2.h

 

 

   # %.dep : %.cpp

   #   g++ -M $(FLAGS) $< > $@

   # include $(OBJS:.o=.dep)

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