氟塑料離心泵www.buybeng.com

          jquery教程http://www.software8.co/wzjs/jquery/

          #LINUX#通過編譯鏈接,卻運行時找不到.so文件

          我們知道在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?
          int plus(int a, int b)  
          {  
              return a + b;  
          }  
          編譯成動態鏈接庫
          gcc plus.c -o libfoo.so -shared -fPIC
          產生動態鏈接庫libfoo.so
          另外寫一個main.c文件
          view plaincopy to clipboardprint?
          #include <stdio.h>  
          #include <stdlib.h>  
            
          int main(int argc, char *argv[])  
          {  
              int sum = plus(3, 5);  
              printf("%d\n", sum);  
            
              return 0;  
          }  
          現在開始思考如何存放libfoo.so位置?
          開始,我們先將libfoo.so存放在當前目錄中,進行編譯和鏈接
          gcc main.c -o output -lfoo //-lfoo告訴gcc,我們需要動態鏈接foo庫。
          出現以下提示:
          baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ls
          libfoo.so  main.c  plus.c
          baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ gcc main.c -o main -lfoo
          /usr/bin/ld: cannot find -lfoo
          collect2: 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 -lfoo
          baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ls
          libfoo.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
          嗚嗚,遇到開始提到的問題了.
          //http://www.software8.co/wzjs/czxt/1733.html
          那我們怎么看輸出到可執行文件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_PATH
          baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ls
          libfoo.so  main  main.c  plus.c
          baiyang@baiyang-Lenovo-G450:~/workspace/test_so$ ./main
          8
          成功運行,用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 NEED
          NEEDED libfoo.so
          NEEDED libc.so.6
          VERNEED 0x08048354
          VERNEEDNUM 0x00000001
          熟練掌握它們,會對系統跟進一步的認識,加油吧.

          posted on 2012-12-15 10:00 你爸是李剛 閱讀(241) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年12月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          導航

          統計

          常用鏈接

          留言簿

          隨筆檔案

          文章檔案

          技術網站

          行業網站

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          站長網 氟塑料離心泵 注塑機 液晶廣告機
          主站蜘蛛池模板: 大同县| 东乡县| 仙居县| 兴业县| 拉孜县| 望奎县| 泰来县| 台前县| 达尔| 扬中市| 安溪县| 郸城县| 隆子县| 泊头市| 荔浦县| 保靖县| 凤凰县| 平顶山市| 中江县| 仁化县| 衡山县| 仙桃市| 松江区| 凤山市| 雷山县| 富民县| 友谊县| 景谷| 鱼台县| 大宁县| 田林县| 克山县| 谷城县| 温泉县| 连云港市| 驻马店市| 田阳县| 建始县| 江永县| 亚东县| 仪陇县|