linux編譯靜態
你說的靜態庫和動態庫吧?編譯速度沒有太大的區別,在實際運行時,靜態庫運行較快,而動態庫內地函數由於在實際使用到時才載入到內存,所以運行較慢。動態庫的好處是只要保持介面不變,就可以在程序運行時進行動態庫的切換。
『貳』 Linux下的靜態鏈接庫和動態鏈接庫有什麼區別
學習Linux動態鏈接庫是一個繞不開的話題。動態鏈接庫與靜態鏈接庫之間存在著顯著的區別。靜態鏈接庫在編譯鏈接時,將庫文件的代碼全部加入到可執行文件中,生成的文件較大,但運行時無需庫文件。靜態庫後綴名為.a。相反,動態鏈接庫在程序運行時才被載入內存,節省了資源,並解決了靜態庫在更新、部署和發布時的麻煩。動態庫的後綴名為.so,gcc/g++在編譯時默認使用動態庫。
通過生成動態庫的步驟,可以了解如何將多個文件編譯成一個動態庫。創建一個頭文件和三個.cpp文件,然後將這幾個文件編譯成動態庫libdynamic.so。通過命令行參數,-shared和-fPIC選項來生成動態鏈接庫。在調用動態鏈接庫時,使用鏈接命令來創建可執行文件,參數-L和-ldynamic用於查找庫文件。
在測試鏈接時,可能會遇到ld提示找不到庫文件的問題。解決方法之一是編輯/etc/ld.so.conf文件,添加庫文件所在目錄,並通過ldconfig更新緩存文件。靜態庫的編譯過程同樣重要,通過ar命令創建靜態庫文件,並使用nm命令查看文件內容。
動態鏈接庫的優點在於進程間的資源共享,可以避免重復載入相同庫函數,大大節省了系統的內存資源。C的標准庫就是動態鏈接庫,使得系統中所有運行的程序共享同一代碼段。在編寫程序時,可以選擇何時鏈接動態鏈接庫函數,根據需求進行載入,從而節省系統資源。
動態鏈接庫在程序運行過程中根據需要載入特定功能,避免了一次性載入所有可能用到的函數,降低了內存佔用。例如,在處理不同文件類型時,只在確定文件類型後才載入相應的讀寫函數,避免了未使用的函數佔用內存。
總之,動態鏈接庫和靜態鏈接庫在編譯和運行時具有不同的特點和優勢。選擇何時使用動態鏈接庫取決於具體應用需求和資源優化目標。理解兩者之間的區別有助於更有效地利用資源,提高程序性能。
『叄』 linux動態庫和靜態庫的區別
靜態庫:這類庫的名字一般是libxxx.a,xxx為庫的名字。利用靜態函數庫編譯成的文件比較大,因為整個函數庫的所有數據都會被整合進目標代碼中,他的優點就顯而易見了,即編譯後的執行程序不需要外部的函數庫支持,因為所有使用的函數都已經被編譯進去了。當然這也會成為他的缺點,因為如果靜態函數庫改變了,那麼你的程序必須重新編譯。
動態庫:這類庫的名字一般是libxxx.M.N.so,同樣的xxx為庫的名字,M是庫的主版本號,N是庫的副版本號。當然也可以不要版本號,但名字必須有。相對於靜態函數庫,動態函數庫在編譯的時候並沒有被編譯進目標代碼中,你的程序執行到相關函數時才調用該函數庫里的相應函數,因此動態函數庫所產生的可執行文件比較小。由於函數庫沒有被整合進你的程序,而是程序運行時動態的申請並調用,所以程序的運行環境中必須提供相應的庫。動態函數庫的改變並不影響你的程序,所以動態函數庫的升級比較方便。linux系統有幾個重要的目錄存放相應的函數庫,如/lib /usr/lib。
當要使用靜態的程序庫時,連接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記指明當程序執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連接的預設操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。
『肆』 linux靜態庫和共享庫的區別
linux下的庫有兩種:靜態庫和共享庫(動態庫)。二者的不同點在於代碼被載入的時刻不同。
靜態庫在程序編譯時會被連接到目標代碼中,目標程序運行時將不再需要該動態庫,移植方便,體積較大,但是浪費空間和資源,因為所有相關的對象文件與牽涉到的庫被鏈接合成一個可執行文件。
動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行時才被載入,因此體積較小,可以實現進程間的資源共享,甚至可以真正做到鏈接載入完全由程序員在程序代碼中控制,另外將一些程序的升級變得簡單,但是在程序運行時需要動態庫存在。
『伍』 linux 靜態庫和動態庫編譯的區別
Linux庫有動態與靜態兩種,動態通常用.so為後綴,靜態用.a為後綴。例如:libhello.so libhello.a
為了在同一系統中使用不同版本的庫,可以在庫文件名後加上版本號為後綴,例如: libhello.so.1.0,由於程序連接默認以.so為文件後綴名。所以為了使用這些庫,通常使用建立符號連接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so
動態庫和靜態庫的區別:
當要使用靜態的程序庫時,連接器會找出程序所需的函數,然後將它們拷貝到執行文件,由於這種拷貝是完整的,所以一旦連接成功,靜態程序庫也就不再需要了。然而,對動態庫而言,就不是這樣。動態庫會在執行程序內留下一個標記『指明當程序執行時,首先必須載入這個庫。由於動態庫節省空間,linux下進行連接的預設操作是首先連接動態庫,也就是說,如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連接。
兩種庫的編譯產生方法:
第一步要把源代碼編繹成目標代碼。以下面的代碼hello.c為例,生成hello庫:
/* hello.c */
#include
void sayhello()
{
printf("hello,world\n");
}
用gcc編繹該文件,在編繹時可以使用任何全法的編繹參數,例如-g加入調試代碼等:
gcc -c hello.c -o hello.o
1.連接成靜態庫
連接成靜態庫使用ar命令,其實ar是archive的意思
$ar cqs libhello.a hello.o
2.連接成動態庫
生成動態庫用gcc來完成,由於可能存在多個版本,因此通常指定版本號:
$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
另外再建立兩個符號連接:
$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so
這樣一個libhello的動態連接庫就生成了。最重要的是傳gcc -shared 參數使其生成是動態庫而不是普通執行程序。
-Wl 表示後面的參數也就是-soname,libhello.so.1直接傳給連接器ld進行處理。實際上,每一個庫都有一個soname,當連接器發現它正在查找的程序庫中有這樣一個名稱,連接器便會將soname嵌入連結中的二進制文件內,而不是它正在運行的實際文件名,在程序執行期間,程序會查找擁有 soname名字的文件,%B
『陸』 linux下使用nm指令查看靜態庫/動態庫編譯內容
在Linux環境下,當你遇到鏈接庫問題時,深入理解庫的編譯內容變得尤為重要。這時,nm指令就成為一個有效的工具,幫助我們揭示靜態庫和動態庫內的編譯細節。
首先,對於靜態庫,我們可以使用命令
nm -g libname.a
執行後,如圖所示,它會列出靜態庫中的全局變數和函數介面,讓你清晰地看到庫的內部結構。
而對於動態庫,其查看方式為
nm -g libname.so
同樣會顯示出動態庫的編譯內容,包括函數和符號,這對於定位和修復與庫相關的bug時非常有用。
因此,在鏈接第三方庫或處理bug時,記得利用nm指令來記錄和分析庫的編譯內容,它能提供寶貴的線索和信息。