.a靜態庫 (archive)
.cc源**(需要編譯預處理)
.hc源**標頭檔案
.ic源**(不需編譯預處理)
.o物件檔案
.s組合語言**
.so動態庫
下面是乙個簡單的「hello, ubuntu」程式的源**:
/* helloubuntu.c */#include int main(int argc,char *argv)
最簡單直接的編譯該**為可執行程式的方法是,將該**儲存為檔案 helloubuntu.c,並執行以下命令:
$ gcc -wall helloubuntu.c編譯器通過檢查命令列中指定的檔案的字尾名可識別其為 c 源**檔案。gcc 預設的動作:編譯源**檔案生成物件檔案(object file),鏈結物件檔案得到可執行程式,刪除物件檔案。由於命令列中未指定可執行程式的檔名,編譯器採用預設的 a.out。在命令列中輸入程式名可使其執行並顯示結果:
$ ./a.out選項 -o 用來指定所生成的可執行程式的檔名。下面的命令生成名為 helloubuntu 的可執行程式:hello, ubuntu
$ gcc -wall helloubuntu.c -o helloubuntu在命令列中輸入程式名將使其執行,如下:
$ ./helloubuntu選項 -c 指示 gcc 編譯源**檔案,但將物件檔案保留在磁碟中並跳過鏈結物件檔案生成可執行檔案這一步。在這種情況下,預設的輸出檔案的檔名同源**檔名一致,只不過字尾換為 .o 。例如:下面的命令將生成名為 helloubuntu.o 的物件檔案:thello, ubuntu
$ gcc -c -wall helloubuntu.c選項 -o 可用來指定生成的物件檔案的檔名。以下命令將產生名為kubuntu.o的物件檔案:
$ gcc -c -wall helloubuntu.c -o kubuntu.o
$ gcc -c -wall ubuntu.c kubuntu.c xubuntu.c即使多個原始碼檔案被編譯,gcc編譯器也會自動進行鏈結操作。例如:下面的**儲存在名為 hellomain.c 的檔案中並呼叫乙個名為 sayhello()的函式:
/* hellomain.c */void sayhello(void);
int main(int argc,char *argv)
以下**儲存在名為 sayhello.c 的檔案中並定義了 sayhello() 函式:
/* sayhello.c */#include void sayhello()
$ gcc -wall hellomain.c sayhello.c -o hello選項 -e 指示編譯器只進行編譯預處理。下面的命令將預處理原始碼檔案 helloubuntu.c 並將結果在標準輸出中列出:
$ gcc -e helloubuntu.c
$ gcc -e helloubuntu.c -o helloubuntu.i選項 -s 指示編譯器生成組合語言**然後結束。下面的命令將由 c 原始碼檔案 helloubuntu.c 生成組合語言檔案 helloubuntu.s:
$ gcc -s helloubuntu.c組合語言的形式依賴於編譯器的目標平台。如果多個原始碼檔案被編譯,每個檔案將分別產生對應的彙編**模組。
靜態庫是編譯器生成的普通的 .o 檔案的集合。鏈結乙個程式時用庫中的物件檔案還是目錄中的物件檔案都是一樣的。靜態庫的另乙個名字叫歸檔檔案(archive),管理這種歸檔檔案的工具叫 ar 。
要構建乙個庫,首先要編譯出庫中需要的物件模組。例如,下面的兩個原始碼檔案為 hellofirst.c 和 hellosecond.c:
/* hellofirst.c */#include void hellofirst()
/* hellosecond.c */
#include void hellosecond()
這兩個原始碼檔案可以用以下命令編譯成物件檔案:
$ gcc -c -wall hellofirst.c hellosecond.c程式 ar 配合引數 -r 可以建立乙個新庫並將物件檔案插入。如果庫不存在的話,引數 -r 將建立乙個新的,並將物件模組新增(如有必要,通過替換)到歸檔檔案中。下面的命令將建立乙個包含本例中兩個物件模組的名為 libhello.a 的靜態庫:
$ ar -r libhello.a hellofirst.o hellosecond.o現在庫已經構建完成可以使用了。下面的程式 twohellos.c 將呼叫該庫中的這兩個函式:
/* twohellos.c */void hellofirst(void);
void hellosecond(void);
int main(int argc,char *argv)
$ gcc -wall twohellos.c libhello.a -o twohellos靜態庫的命名慣例是名字以三個字母 lib 開頭並以後綴 .a 結束。所有的系統庫都採用這種命名慣例,並且它允許通過 -l(ell) 選項來簡寫命令列中的庫名。下面的命令與先前命令的區別僅在於 gcc 期望的找尋該庫的位置不同:
$ gcc -wall twohellos.c -lhello -o twohellos指定完整的路徑名可使編譯器在給定的目錄中尋找庫。庫名可以指定為絕對路徑(比如 /usr/worklibs/libhello.a)或者相對與當前目錄的路徑(比如 ./lib/libhello.a)。選項 -l 不能具有指定路徑的能力,但是它要求編譯器在系統庫目錄下找尋該庫。
共享庫是編譯器以一種特殊的方式生成的物件檔案的集合。物件檔案模組中所有位址(變數引用或函式呼叫)都是相對而不是絕對的,這使得共享模組可以在程式的執行過程中被動態地呼叫和執行。
要構建乙個共享庫,首先要編譯出庫中需要的物件模組。例如:下面是檔名為 shellofirst.c 和 shellosecond.c 的兩個原始碼檔案:
/* shellofirst.c */#include void shellofirst()
/* shellosecond.c */
#include void shellosecond()
要將以上兩個原始碼檔案編譯成物件檔案,可以用下面的命令:
$ gcc -c -wall -fpic shellofirst.c shellosecond.c選項 -c 告訴編譯器只生成 .o 的物件檔案。選項 -fpic 使生成的物件模組採用浮動的(可重定位的)位址。縮微詞 pic 代表「位置無關**」(position independent code)。
下面的 gcc 命令將物件檔案構建成乙個名為 hello.so 的共享庫:
$ gcc -wall -shared shellofirst.o shellosecond.o -o hello.so選項 -o 用來為輸出檔案命名,而檔案字尾名 .so 告訴編譯器將物件檔案鏈結成乙個共享庫。通常情況下,鏈結器定位並使用 main() 函式作為程式的入口,但是本例中輸出模組中沒有這種入口點,為抑制錯誤選項 -shared 是必須的。
編譯器能將字尾為 .c 的檔案識別為 c 語言源**檔案,並知道如何將其編譯成為物件檔案。基於這一點,先前的兩條命令我們可以合併為一條;下面的命令直接將模組編譯並儲存為共享庫:
$ gcc -wall -fpic -shared shellofirst.c shellosecond.c -o hello.so下面的程式,儲存在檔案 stwohellos.c 內,是呼叫共享庫中兩個函式的主程式:
/* stwohellos.c */void shellofirst(void);
void shellosecond(void);
int main(int argc,char *argv)
$ gcc -wall stwohellos.c hello.so -o stwohellos程式 stwohello 已經完成,但要執行它必須讓其能定位到共享庫 hello.so,因為庫中的函式要在程式執行時被載入。
如果環境要求你使用 .c 以外的字尾名來命名你的 c 原始碼檔案,你可以通過 -x 選項來指定其對應的語言以忽略我們的命名規範。例如,下面的命令將從檔案 helloworrld.jxj 編譯 c 語言源**並生成可執行檔案 helloubuntu:
$ gcc -xc helloubuntu.jxj -o helloubuntu通常,在沒有 -x 選項的情況下,任何具有未知字尾名的原始碼檔名都被認為是聯結器可以識別的選項,並在不做任何更改的情況下傳遞給鏈結器。選項 -x 對其後的所有未知字尾的檔案都起作用。例如,下面的命令使 gcc 將 align.zzz 和 types.*** 都作為 c 原始碼檔案來處理:
$ gcc -c -xc align.zzz types.***
步步為營 79 快取
快取cache,一種空間換取時間的技術,適用於經常訪問,不常修改的資料.1 寫入快取 1.1 方法一 cache message ab 1.2 方法二 cache.insert message ab 1.3 其他過載 insert string key,object value,cachedepen...
步步為營 50 事務
說明 比較常用 1 事務的四大特性 1.1 原子性atomicity 乙個事務中包含的多個sql語句,要麼同時成功,要麼同時失敗.1.2 一致性consistency 事務必須使資料庫從從乙個一致性狀態變成另外乙個一致性狀態.銀行轉賬 1.3 隔離性 isolation 各個事務執行互不干擾 鎖 1...
io nio socket步步為營(三)NIO
原理 運用reactor模式 selector是核心 分發器a multiplexor of selectablechannel objects。能檢測任意個註冊過的channel上的事件,並分發事件,內部實現不用考慮,封裝的好處。client沒必要用nio,使用中的client server,需要...