庫檔案包含靜態庫檔案和動態庫檔案。
靜態庫就是在鏈結的時候加入到執行**中,成為了**的一部分,所以生成的可執行檔案就比較大,以後和靜態庫沒瓜葛了,自己隨便用了;動態庫是指執行的時候會鏈結到庫檔案,如果沒找到就執行。
先介紹一下預設的庫搜尋路徑,這些預設搜尋路徑是不分動態庫和靜態庫的,都會在前面幾個路徑都找不到的情況來這兒找,所以這個是優先順序最低的。
一般 linux 系統把
/lib
/usr/lib
/usr/local/lib (☆)
作為預設的庫搜尋路徑,所以使用在這三個目錄中的鏈結庫檔案可直接被搜尋到。
這三個路徑有什麼區別?一般用哪個呢?怎麼用呢?很多應用都安裝在/usr/local下面。我們可以看automake工具,定義的預設字首就就是/usr/local。
directory variable default value
prefix /usr/local
exec_prefix $
bindir $/bin
libdir $/lib
…
因為,usr 指 unix system resource,/usr;/usr/bin目錄包含所有的命令、程式庫、文件和其它檔案,我們可以移動到這個目錄下,ls -al看下,都是系統預裝的可執行程式,會隨著系統的公升級而改變,/usr/local/bin目錄是給使用者放置自己的可執行程式,所以我們一般把我們可執行的指令碼檔案放到這個目錄。
使用方法:
方法一:直接拷貝到/usr/local/lib目錄下;
方法二:你可以建立乙個軟連線到/usr/local/lib,這樣就完成了對映,也是可以找到的。但是我想了想,萬一刪除了這個庫檔案呢?那建立的軟連線不就失效了嗎。。所以感覺拷貝靠譜點。
靜態庫的搜尋路徑:
gcc main.c -l. -ltest
就是說把main.c檔案和libtest庫鏈結起來,這裡引數-lpath,直接是連著一起寫的,所以這裡-l.就表示鏈結當前目錄的***檔案,當gcc看到-ltest的時候, 會自動去找去找libtest.a。(不過我個人覺得這種方法不好用,因為現在寫乙個大型專案,是不是都用 cmake了啊,makefile感覺也用的少了吧,不太懂。。以後好回來填坑吧啊)
#方法一:
export ld_library_path=ld_library_path:***x
# ":"是分割路徑的,後面***x表示庫所在的路徑,表示新加了***x搜尋路徑
#缺點,這只是臨時新增,下次開機就沒了~
#方法二:
#首先找到你的配置檔案.bashrc,你可以用locate .bashrc
locate .bashrc
#其次在開啟這個檔案
vim /home/zss/.bashrc
#把剛剛的路徑新增一遍
export ld_library_path=$ld_library_path:***x
#這樣的話,每次開機 ,.bashrc都會執行一遍,所以就又把這個***x路徑給加進去了
使用「ld –verbose」命令檢視gcc的預設鏈結指令碼中search_dir引數,拷貝libsay.so到search_dir指定路徑。
(這種方法我沒用過)
search_dir("=/usr/local/lib/x86_64-linux-gnu"); search_dir("=/lib/x86_64-linux-gnu");
search_dir("=/usr/lib/x86_64-linux-gnu"); search_dir("=/usr/local/lib64");
search_dir("=/lib64"); search_dir("=/usr/lib64"); search_dir("=/usr/local/lib");
search_dir("=/lib"); search_dir("=/usr/lib"); search_dir("=/usr/x86_64-linux-gnu/lib64");
search_dir("=/usr/x86_64-linux-gnu/lib");
動態庫的搜尋路徑:
gcc –wl,-rpath=.
#選項–wl,-rpath 以及 =來指定搜尋路徑
同樣感覺用的比較少,因為自己現在還沒有涉及到動態庫的鏈結,往往都是簡短的**鏈結乙個靜態庫。
這裡可以去參考靜態庫的,一模一樣。
首先開啟這個檔案,跑到檔案最後新增你動態庫的絕對路徑,然後idconfig修改生效都可以了。
題目:錯誤提示找不到動態庫檔案libmymath.so
解決步驟:
cp libmymath.so /usr/lib
export ld_library_path=$ld_library_path:/usr/lib
sudo idconfig
有一點要特別注意,export ld_library_path=...,這個等號是要直接接在path後面的,千萬不能打空格,否者會顯示command not found。還有就是我的疑惑在,既然已經把動態庫拷貝到目錄檔案下,為啥還要在環境變數ld_library_path中新增/usr/lib嗎?這不是多此一舉嗎?後來我想到動態庫的搜尋路徑也是有順序的,既然是動態庫,在執行時期鏈結,肯定是希望越快越好,所以我們再新增到ld_library_path中,讓編譯器能更快的找到。不過這個全域性變數也許會帶來一定危害吧!汗。在下文中提到了。不深究可以不看了 。
引文:
Linux下動態鏈結庫和靜態鏈結庫
第一部分 編譯過程 預處理過程,負責標頭檔案展開,巨集替換,條件編譯的選擇,刪除注釋等工作。gcc e表示進行預處理。編譯過程,負載將預處理生成的檔案,經過詞法分析,語法分析,語義分析及優化後生成彙編檔案。gcc s表示進行編譯。彙編,是將彙編 轉換為機器可執行指令的過程。通過使用gcc c或者as...
Linux下靜態鏈結庫
放置在一起的物件模組的集合,這些物件模組都儲存於乙個存檔檔案中 乙個程序一般分為乙個部分 環境變數,堆疊,空閒記憶體,動態記憶體,可執行程式映像 包括程式本身的執行 還有就是鏈結的靜態庫 共享庫 一般為動態鏈結庫.so檔案 其他記憶體 靜態鏈結庫是在編譯生成可執行檔案是鏈結並裝載複製靜態鏈結庫中自己...
VC預設鏈結庫衝突
在同乙個專案中,所有的原始檔必須鏈結相同的c執行時庫。如果某一檔案用了multithreaded dll版本,而其他檔案用了single threaded或者multithreaded版本的庫,也就是說用了不同的庫,就會導致這個警告的出現。總之,一句話,lib之間有衝突。需要刪除匯入的一些 libs...