Linux中的兩種共享代碼方式靜態庫和動態庫
1.共享代碼
隨著軟件開發的發展,人們發現很多應用的代碼是相同的,也就是說這些代碼可以被共享,因此,人們提出了靜態庫和動態庫兩種方案來解決代碼共享的問題。
2.靜態庫
靜態庫,顧名思義,它是靜態的,也就是說它不會被動態編譯,它只會靜態編譯,節省了編譯時間,提高了編譯速度。同一份靜態庫,可以被多個程序進行編譯,也就實現了代碼的復用共享。
3.動態庫
動態庫,就是程序應用啟動的時候,動態加載的,因為它一般是在系統運行的時候就已經運行的動態庫,因此其它應用可以直接使用它,并且同一個動態庫可以被多個應用共享使用,在系統中對于一個動態庫只會存在一份,這大大節省了內存空間,大大提升了系統的性能。
在linux系統中,動態庫一般以.so形式命名,表示share object。
很多時候,你很難知道一個應用需要哪些動態庫,不過我們有個工具ldd可以幫助你查看一個應用需要哪些動態庫。
如果一些動態庫沒有找到的話,程序就無法正常運行,這也是你會看到很多程序啟動的時候提示缺少xx.so的原因。
如果你的程序需要xx.so動態庫,而系統路徑中沒有它的話,你可以通過LD_LIBRARY_PATH 將你需要的動態庫添加到系統路徑中。
查看一個文件使用了什么連接器可以使用file命令,一般程序都會使用/lib64/ld-linux-x86-64.so.2這個文件,而這個文件其實會指向一個ld-2.xx.so文件。
4.動態加載器ld.so
在linux系統中,動態庫都是通過ld.so來進行管理的,它首先會根據應用的編譯信息查找相對或者絕對路徑來查找動態庫,然后就會通過環境變量LD_LIBRARY_PATH來查找動態庫,最后它會根據/etc/ld.so.cache緩存來查找動態庫。
因此,當我們像系統中添加一個動態庫的時候我們有兩種方式,一種是直接放入到/usr/lib64文件夾里面,不過這需要你有root權限,第二種就是通過LD_LIBRARY_PATH配置我們的動態庫路徑。
5.程序引入動態庫
在程序編譯的時候,我們可以通過指定編譯參數來引入動態庫。
例如,當我們使用gcc來進行編譯的時候,我們可以通過-l來表示鏈接庫名稱,通過-Ldir來指定動態庫路徑。 當我們使用g++來進行編譯的時候,-L可以用來指定動態庫的路徑,進行程序動態庫的鏈接。
6.總結
人們為了減少冗余代碼,提出了共享庫的概念,在鏈接的時候和程序一同打包成一個可執行文件的這個庫就是靜態庫,反之,在鏈接的時候不將動態庫打包進可執行文件,只是標記運行需要此共享庫,這就是動態庫。
靜態庫是同程序一同打包的,因此它不需要環境的依賴,而動態庫是程序執行時候需要引用的,因此它對環境有依賴,這也是為什么很多依賴動態庫的文件執行的時候報錯缺少動態庫的原因,那是操作系統缺少對應的動態庫導致的。
靜態庫增大了程序的體積,同時多個程序對相同靜態庫的鏈接也占用了大量的內存,因此,才有了動態庫的出現,可以說兩者都是為了解決代碼共享復用的問題,而且兩者是相輔相成的關系。