#LINUX#通過編譯連結,卻運行時找不到.so檔案

來源:互聯網
上載者:User

我們知道在linux下,.so檔案相當與windows上的dll檔案,即動態連結程式庫。

動態連結程式庫是為了減少發布程式的大小,可以將具有相同功能的code放在動態連結程式庫中,隨應用程式一起發布。而對於應用程式來說,只需要知道其介面就可以,在運行時動態載入代碼到記憶體中,與其相反的是靜態連結庫。

在接手一個項目的代碼後,因為此代碼需要很多第三方庫,所以,在本機安裝這些第三方庫之後,我也成功的通過了編譯與連結階段,產生了可以執行的代碼。

可是在啟動並執行時候,出現了以下的錯誤提示:

baiyang@baiyang-Lenovo-G450:~/Desktop$ ./test_cal_features./test_cal_features: error while loading shared libraries: libCGAL.so.5: cannot open shared object file: No such file or directory

這裡涉及幾個問題:
1.為何能通過編譯與連結,卻不能運行?
2.我明明將libCGAL.so.5,安裝到了/usr/local/lib下啊,既然能通過編譯與連結,應該能找到啊?
3.執行./test_cal_features時,到底發生了什麼事?
4.linux下,應用程式如何對.so進行搜尋?

但本質問題,就是linux下gcc搜尋路徑設定問題.

好,今天就一一來回答以上到問題。

開始一個新的例子

plus.c 檔案

view plaincopy to clipboardprint?
  1. int plus(int a, int b)  
  2. {  
  3.     return a + b;  
  4. }  

編譯成動態連結程式庫

gcc plus.c -o libfoo.so -shared -fPIC

產生動態連結程式庫libfoo.so
另外寫一個main.c檔案

view plaincopy to clipboardprint?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     int sum = plus(3, 5);  
  7.     printf("%d\n", sum);  
  8.   
  9.     return 0;  
  10. }  
現在開始思考如何存放libfoo.so位置?

開始,我們先將libfoo.so存放在目前的目錄中,進行編譯和連結

gcc main.c -o output -lfoo //-lfoo告訴gcc,我們需要動態連結foo庫。

出現以下提示:

baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ lslibfoo.so  main.c  plus.cbaiyang@baiyang-Lenovo-G450:~/workspace/test_so$ gcc main.c -o main -lfoo/usr/bin/ld: cannot find -lfoocollect2: ld returned 1 exit status

也就是說,gcc不能找到foo庫,那麼我們如果顯示的指示gcc如何搜尋foo呢,我們可以修改LIBRARY_PATH值

baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ export LIBRARY_PATH="."baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ gcc main.c -o main -lfoobaiyang@baiyang-Lenovo-G450:~/workspace/test_so$ lslibfoo.so  main  main.c  plus.c

恭喜,成功找到了.
那好,如果此時我們運行代碼

baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ./main./main: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory

嗚嗚,遇到開始提到的問題了.
那我們怎麼看輸出到可執行檔main怎麼讀取libfoo.so呢,在運行過程中到底讀的什麼檔案呢?
我們可以用strace命令查看到底有什麼訊號發生

strace ./main

你會發現,它搜尋到路徑是

/lib/i386-linux-gnu,/usr/lib等路徑目錄下

也就說,是因為沒有搜尋目前的目錄,我們可以通過修改以下命令進行修改

baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ export LD_LIBRARY_PATH=".":$LD_LIBRARY_PATHbaiyang@baiyang-Lenovo-G450:~/workspace/test_so$ lslibfoo.so  main  main.c  plus.cbaiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ./main8

成功運行,用strace查看存在這一句open(“./libfoo.so”, O_RDONLY|O_CLOEXEC) = 3
故,現在搜尋了目前的目錄。
總結一下,前面提到過的幾個環境變數:

  • LIBRARY_PATH 該環境變數可設定為一個或多個目錄名字列表,串連 程式會搜尋該目錄,以尋找特殊串連程式檔案,和由 -l (字母 l )命令列選項指定名字的庫。由 -L 命令列選項指定的目錄在環境變 量的前面,首先被尋找。也見 COMPILER_PATH 。
  • LD_LIBRARY_PATH 該環境變數不會影響編譯器,但程式啟動並執行時 候會有影響。變數指定一個目錄列表,程式會尋找該列表定位共用庫。 只有當未在編譯器的目錄中找到共用庫的時候,執行程式必須設定該變數。
那麼在預設到情況下,如何進行搜尋呢?

動態庫的搜尋路徑搜尋的先後順序是:

  • 1 編譯目標代碼時指定的動態庫搜尋路徑,LIBRARY_PATH【編譯階段】;
  • 2 在運行時,環境變數LD_LIBRARY_PATH指定的動態庫搜尋路徑【運行階段】;
  • 3 設定檔/etc/ld.so.conf中指定的動態庫搜尋路徑【編譯階段】;
  • 4 預設的動態庫搜尋路徑/lib【編譯階段】;
  • 5 預設的動態庫搜尋路徑/usr/lib【編譯階段】。
對二進位檔案進行處理
  • strace
  • gdb
  • objdump
  • nm
以上工具,都可以讓你查看二進位檔案到底幹了什麼,比如,我們用objdump可以查看可執行檔需要什麼連結庫
baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ objdump -x main | grep NEEDNEEDED libfoo.soNEEDED libc.so.6VERNEED 0x08048354VERNEEDNUM 0x00000001

熟練掌握它們,會對系統跟進一步的認識,加油吧.

額外資料
  • 詳細講解gcc如何對標頭檔和連結庫進行搜尋;
  • strace

 

-----------------打造高品質的文章 更多關注 把酒泯恩仇---------------

為了打造高品質的文章,請  推薦  一下吧。。。。謝謝了,請關注我後續的文章,會更精彩哦

請關注sina微博:http://weibo.com/baiyang26

把酒泯恩仇官方部落格:http://www.ibaiyang.org 【推薦用google reader訂閱】

把酒泯恩仇官方豆瓣:http://www.douban.com/people/baiyang26/

如果您想轉載本部落格,請註明出處

如果您對本文有意見或者建議,歡迎留言

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.