Linux中gcc編譯器的用法


  在Linux環境下進行開發,gcc是非常重要的編譯工具,所以學習gcc的基本常見用法時非常有必要的。

  一.首先我們先說明下gcc編譯源文件的后綴名類型

  .c為后綴的文件,C語言源代碼文件; 
  .a為后綴的文件,是由目標文件構成的檔案庫文件; 
  .C,.cc或.cxx 為后綴的文件,是C++源代碼文件; 
  .h為后綴的文件,是程序所包含的頭文件; 
  .i 為后綴的文件,是已經預處理過的C源代碼文件; 
  .ii為后綴的文件,是已經預處理過的C++源代碼文件; 
  .m為后綴的文件,是Objective-C源代碼文件; 
  .o為后綴的文件,是編譯后的目標文件; 
  .s為后綴的文件,是匯編語言源代碼文件; 
  .S為后綴的文件,是經過預編譯的匯編語言源代碼文件。 

  

  二.接下來,我們就具體介紹下gcc命令的具體用法了

  gcc的基本命令格式是:gcc [options] [filenames]

其中[options]就是編譯器需要制定的相應選項,filenames就是相關文件的名稱,下面我就介紹下做常用的幾個options

(注意:一定要區分編譯選項里的大小寫,他們時代表不同的含義)

  (1) -c :只是進行編譯而不連接成為可執行文件,編譯器只是由輸入的.c等源代碼文件生成.o為后綴的目標文件,通常用於編譯不包含主程序的子程序文件。

  (2) -o output_filename :確定輸出的文件的名稱為output_filename,如果不給出這個選項,gcc就給出預設的可執行文件a.out。

  (3) -g: 產生符號調試工具(GNU的gdb)所必要的符號信息,要想對源代碼進行調試,我們就必須加入這個選項。

  (4) -O: 對程序進行優化編譯、連接,采用這個選項,整個源代碼會在編譯、連接過程中進行優化處理,這樣產生的可執行文件的執行效率可以提高,但是,編譯、連接的速度就相應地要慢一些。 

  (5) -O2 : 比-O更好的優化編譯、連接,當然整個編譯、連接過程會更慢。 

  (6) -Idirname: 將dirname所指出的目錄加入到程序頭文件目錄列表中,是在預編譯過程中使用的參數。

    C程序中的頭文件包含兩種情況∶  

    a.#include <myinc.h>

    b.#include "myinc.h"

    其中a類時使用的是<>來包含頭文件,b類則使用“”來包含頭文件。他們之間的主要差別是:對於a類,預處理程序源文件在系統預設包含文件目錄(如/usr/include等等)中搜尋相應的文件,而對於b類,源文件則在當前目錄中搜尋頭文件,這個選項的作用是告訴源文件,如果在當前目錄中沒有找到需要的頭文件,就到指定的dirname目錄中去尋找。在程序設計中,如果我們需要的這種包含文件分別分布在不同的目錄中,就需要逐個使用-I選項給出搜索路徑。

  (7) -Ldirname: 將dirname所指出的目錄加入到程序函數鏈接庫文件的目錄列表中,它是在連接過程中使用的參數。在預設狀態下,連接程序ld在系統的預設路徑中(如/usr/lib)尋找所需要的鏈接庫文件。而這個選項告訴連接程序,首先到-L指定的目錄中去尋找,然后再到系統預設路徑中尋找,如果函數庫存放在多個目錄下,就需要依次使用這個選項,給出相應的存放目錄。

  (8) -lname: 程序在連接時,裝載名字為“libname.a”的函數庫,該函數庫位於系統預設的目錄或者由-L選項確定的目錄下。例如,-lm表示連接名為“libm.a”的數學函數庫,

"-lpthread"則表示鏈接線程函數鏈接庫文件。

  (9) -shared:這主要是在生成共享庫文件時使用。

  (10) -Wall : 生成所有警告信息。

  (11) -w : 不生成任何警告信息。

  (12) -S : 生成匯編語言文件。

 

  三.最后,我還想向大家闡明下平時大家都沒怎么注意的一個問題-------gcc是怎么查找源文件中的頭文件和鏈接時所需的鏈接庫文件

  (1) 查找頭文件

    step1:在源文件所在的目錄下進行查找

    step2:在我們在編譯程序用選項“-Idirname”所指的路徑去尋找頭文件。

    step3:查找gcc相關的環境變量所設置的路徑:C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH

    step4:查找gcc內定的目錄:

      /usr/include
      /usr/local/include
      /usr/lib/gcc-lib/i386-linux/2.95.2/include

  (2) 查找動態鏈接庫

    什么時鏈接庫?我再羅嗦一句吧。就像我們C語言中常用的printf函數為例,你們知道printf函數是怎么實現的嗎?其實它是系統把這些函數實現都被做到名為libc.so.6的庫文件中去了,在沒有特別指定時,gcc會到系統默認的搜索路徑”/usr/lib”下進行查找,也就是鏈接到libc.so.6庫函數中去,這樣就能實現函數”printf”了,而這也就是鏈接的作用。其中函數庫又分為靜態函數庫和動態函數庫兩種。靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為”.a”。動態庫與之相反,在編譯鏈接時並沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般后綴名為”.so”,如前面所述的libc.so.6就是動態庫。

    好了,言歸正傳,其實動態鏈接庫的查找過程其實和查找頭文件類似。

    step1: 在選項“-Ldirname”所指定的目錄中查找。

    step2: gcc的環境變量LIBRARY_PATH指定的路徑中查找。

    step3: 在gcc內定的目錄中查找,如 /usr/lib/  /usr/local/lib/

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM