天天看點

gcc學習(二)[第二版]

1、概要

在使用C語言和其他語言進行程式設計的時候,我們需要頭檔案來提供對常數的定義和對系統及庫函數調用的聲明。

庫檔案是一些預先編譯好的函數集合,那些函數都是按照可重用原則編寫的。它們通常由一組互相關聯的用來完成某項常見工作的函數構成。比如用來處理螢幕顯示情況的函數(ncurses庫)和資料庫通路例程(dbm庫)等。

2、使用庫的優點:

1)子產品化開發

2)可重用性

3)可維護性

3、頭檔案與庫檔案的位置

/usr/include及其子目錄底下的include檔案夾

/usr/local/include及其子目錄底下的include檔案夾 

/usr/lib

/usr/local/lib

/lib

gcc學習(二)[第二版]

4、使用外部庫【-i選項】

編譯:

gcc -Wall calc.c -o calc -lm

#-lm表示要連結libm.so或者libm.a庫檔案

gcc學習(二)[第二版]

靜态庫(.a):程式在編譯連結的時候把庫的代碼連結到可執行檔案中。程式運作的時候将不再需要靜态庫,靜态庫占用磁盤空間較大。

共享庫(.so/.sa):程式在運作的時候才去連結共享庫的代碼,多個程式可共享使用庫的代碼。[最近的Linux[CentOS 6.4]版本在/usr以及/lib目錄下已經找不到.a檔案的蹤影了]

gcc學習(二)[第二版]

2、共享庫的優點:

一個與共享庫連結的可執行檔案僅僅包含它用到的函數入口位址的一個表,而不是外部函數所在目标檔案的整個機器碼

在可執行檔案開始運作以前,外部函數的機器碼由作業系統從磁盤上的該共享庫中複制到記憶體中,這個過程稱為動态連結(dynamic linking)

共享庫可以在多個程式間共享,是以動态連結使得可執行檔案更小,節省了磁盤空間。作業系統采用虛拟記憶體機制允許實體記憶體中的一份共享庫被要用到該庫的所有程序共用,節省了記憶體和磁盤空間。

-可以簡單的認為将多個.o檔案打包到一起,就生成了靜态庫

1)gcc -c hello_fn.c

#同gcc -Wall -c hello_fn.c -o hello_fn.o

2)ar rcs libhello.a hello_fn.o search.o

#arar是gnu歸檔工具,rcs表示(replace and create),相當于将将.o檔案打包成為.a檔案,并且.o檔案可以有多個

gcc學習(二)[第二版]

3)gcc -Wall main.c libhello.a -o main

#将各個子產品編譯,連結生成可執行檔案【方式一】

4)gcc -Wall -L. main.c -o main -lhello

#-L.表示在目前目錄搜尋庫檔案,-lhello[省略的lib],此時即使删除靜态庫libhello.a也可運作main檔案【方式二】

gcc學習(二)[第二版]

1)從左到右搜尋-I -L指定的目錄。

2)由環境變量指定的目錄

可以定義C_INCLUDE_PATH/CPP_INCLUDE_PATH(頭檔案搜尋路徑)、LIBRARY_PATH(庫檔案搜尋路徑)儲存在~/.bash_profile中,另在Ubuntu系統中,也可以将這些定義存放在~/.bashrc中

gcc學習(二)[第二版]

3)由系統指定的目錄:/usr/include,/usr/lib等

gcc -shared -fPIC hello_fn.o -o hello_fn.so

說明:

1)shared表示生成共享庫

2)-fPIC表示生成位置無關碼(Position Independent Code)

3)庫的命名規則:libXXX.so[.版本号]

gcc學習(二)[第二版]

1)gcc main.o -o main –L. -lhello

#該指令與使用靜态庫的指令相同,但是,在共享庫與靜态庫共存的情況下,優先使用共享庫

l:連結共享庫,隻要庫名即可(去掉lib以及版本号)

L:連結庫所在的路徑.

2)運作共享庫

法1)拷貝.so檔案到系統共享庫路徑下,一般指/usr/lib

法2)在~/.bash_profile檔案中,配置LD_LIBRARY_PATH變量

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

. ~/.bash_profile

法3)配置/etc/ld.so.conf,配置完成後調用ldconfig更新ld.so.cache

3)ldd指令:用于檢視程式運作時需要加載的共享庫

gcc學習(二)[第二版]