linux 編譯代碼__linux

來源:互聯網
上載者:User

轉自: http://www.iteye.com/topic/240578

GNU編譯器集     GNU編譯器集(其前身為GNU C編譯器)誕生於1987年。當時Richard Stallman(GNU項目的創辦人)想要建立一個編譯器,它可以滿足他定義的“自由軟體”概念,並可用來編譯GNU項目發布的其他軟體。GNU C編譯器迅速在自由軟體社區中流行開來,而且以其健壯性和可移植性而聞名。它已成為許多整合開發工具的基礎,被世界各地的發行商應用在Linux和其他動作系統之上。
    GCC已不再是主要針對GNU項目自身的軟體的小型C語言編譯器了。如今,它已支援了許多不同的語言,包括C、C++、Ada、Fortran、Objective C,甚至還有Java。事實上,現代Linux系統除了可以自豪地炫耀那些由GNU工具直接支援的語言以外,它還支援大量其他語言。日益流行的指令碼語言Perl、Python和Ruby,以及正在不斷髮展的mono 可移植C#實現的確有助於沖淡人們對Linux編程的傳統看法,但這完全是另外一個問題了。

Linux核心和許多其他自由軟體以及開放源碼應用程式都是用C語言編寫並使用GCC編譯的。

1. 編譯單個源檔案

為了進行測試,你可以建立“Hello World”程式:

C代碼   #include <stdio.h>   #include <stdlib.h>      int main(int argc, char **argv)   {           printf("Hello world!\n");           exit(0);   }  


使用如下命令編譯並測試這個代碼:
引用 # gcc -o hello hello.c
# ./hello
Hello wordl!

在預設情況下產生的可執行程式名為a.out,但你通常可以通過gcc的“-o”選項來指定自己的可執行程式名稱。

2. 編譯多個源檔案

源檔案message.c包含一個簡單的訊息列印函數:
C代碼   #include <stdio.h>      void goodbye_world(void)   {           printf("Goodbye, world!\n");   }  

使用gcc的“-c”標記來編譯支援庫代碼:
引用 # gcc -c message.c

這一過程的輸出結果是一個名為message.o的檔案,它包含適合串連到一個較大程式的已編譯目標代碼。

建立一個簡單的樣本程式,它包含一個調用goodbye_world的main函數

C代碼   #include <stdlib.h>      void goodbye_world(void):      int main(int argc, char **argv)   {           goodbye_world();           exit(0);   }  

使用GCC編譯這個程式:
引用 # gcc -c main.c

現在有了兩個目標檔案:message.o和main.o。它們包含能夠被Linux執行的目標代碼。要從這個目標代碼建立Linux可執行程式,需要再一次調用GCC來執行串連階段的工作:
引用 # gcc -o goodbye message.o main.o

運行編譯結果:
引用 # ./goodbye
Goodbye, world!

前面這些單獨的步驟也可以簡化為一個命令,這是因為GCC對如何將多個源檔案編譯為一個可執行程式有內建的規則。
引用 # gcc -o goodbye message.c main.c
# ./goodbye
Goodbye, world!

3. 使用外部函數庫
GCC常常與包含標準常式的外部軟體庫結合使用,幾乎每一個Linux應用程式都依賴於由GNU C函數庫GLIBC。
應用外部函數庫的例子:
C代碼   #include <stdio.h>   #include <stdlib.h>   #include <math.h>      #define MAX_INPUT 25      int main(int agrc, char **argv)   {           char input[MAX_INPUT];           double angle;              printf("Give me an angle (in radians) ==>");           if(!fgets(input, MAX_INPUT, stdin)){                   perror("an error occurred.\n");           }           angle = strtod(input, NULL);              printf("sin(%e) = %e\n", angle, sin(angle));              return 0;   }   編譯命令:
引用 # gcc -o trig -lm trig.c

GCC的"-lm"選項,它告訴GCC查看系統提供的數學庫(libm)。因為Linux和UNIX的系統函數庫通常以"lib"為首碼,所以我們假設它存在。真正的函數庫位置隨系統的不同而不同,但它一般會位於目錄/lib或/usr/lib中,在這些目錄中還有數以百計的其他必需的系統函數庫。

4. 共用函數庫與靜態函數庫

Linux系統上的函數庫分為兩種不同的類型:共用的和靜態

靜態函數庫:每次當應用程式和靜態串連的函數庫一起編譯時間,任何引用的庫函數中的代碼都會被直接包含進最終的二進位程式。

共用函數庫:包含每個庫函數的單一全域版本,它在所有應用程式之間共用。這一過程背後所涉及的機制相當複雜,但主要依靠的是現代電腦的虛擬記憶體能力,它允許包含庫函數的實體記憶體安全地在多個獨立使用者程式之間共用。

使用共用函數庫不僅減少了檔案的容量和Linux應用程式在記憶體中覆蓋的地區,而且它還提高了系統的安全性。一個被許多不同程式同時調用的共用函數庫很可能會駐留在記憶體中,以在需要使用它時被立即使用,而不是位於磁碟的交換分區中。這有助於進一步減少一些大型Linux應用程式的裝載時間。

將上面的message.c作為共用庫函數使用的例子:

引用 # gcc -fPIC -c message.c
“PIC”命令列標記告訴GCC產生的代碼不要包含對函數和變數具體記憶體位置的引用,這是因為現在還無法知道使用該訊息代碼的應用程式會將它串連到哪一段記憶體位址空間。這樣編譯輸出的檔案message.o可以被用於建立共用函數庫,我們只需使用gcc的“-shared”標記即可:
引用 # gcc -shared -o libmessage.so message.o

將上面的mian.c使用共用庫函數ligmessage.so編譯:
引用 # gcc -o goodbye -lmessage -L. message.o “-lmessage”標記來告訴GCC在串連階段引用共用函數庫libmessage.so。“-L.”標記告訴GCC函數庫可能位於目前的目錄中,否則GNU的連接器會尋找標準系統函數庫目錄,在本例的情況下,就找不到可用的函數庫了。

此時運行編譯好的goodbye會提示找不到共用函數庫:
引用 #./goodbye
./goodbye: error while loading shared libraries: libmessage.so: cannot open shared object file: No such file or directory

可以使用命令ldd來發現一個特定應用程式需要使用的函數庫。ldd搜尋標準系統函數庫路徑並顯示一個特定程式使用的函數庫版本。
引用 #ldd goodbye
        linux-gate.so.1 =>  (0x00493000)
        libmessage.so => not found
        libc.so.6 => /lib/libc.so.6 (0x0097c000)
        /lib/ld-linux.so.2 (0x0095a000)

庫檔案libmessage.so不能在任何一個標準搜尋路徑中找到,而且系統提供的設定檔/etc/ld.so.conf也沒有包含一個額外的條目來指定包含該庫檔案的目錄。

需要設定一個環境變數LD_LIBRARY_PATH來制定額外的共用函數庫搜尋路徑,
引用 # export LD_LIBRARY_PATH=`pwd`
# ldd goodbye
        linux-gate.so.1 =>  (0x002ce000)
        libmessage.so => /tmp/cpro/libmessage.so (0x00b0f000)
        libc.so.6 => /lib/libc.so.6 (0x0097c000)
        /lib/ld-linux.so.2 (0x0095a000) 運行程式
引用 # ./goodbye
Goodbye, world!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.