博客專欄

        EEPW首頁 > 博客 > Linux動態庫文件搜索路徑

        Linux動態庫文件搜索路徑

        發布人:電子禪石 時間:2019-09-05 來源:工程師 發布文章

        首先回答前面的問題,一共有多少種方法來指定告訴linux共享庫鏈接器ld.so已經編譯好的庫libbase.so的位置呢?答案是一共有五種,它們都可以通知ld.so去哪些地方找下已經編譯好的c語言函數動態庫,它們是:

           1)ELF可執行文件中動態段中DT_RPATH所指定的路徑。即在編譯目標代碼時, 對gcc加入鏈接參數“-Wl,-rpath”指定動態庫搜索路徑,eg:gcc -Wl,-rpath,/home/arc/test,-rpath,/lib/,-rpath,/usr/lib/,-rpath,/usr/local/lib test.c

           2)環境變量LD_LIBRARY_PATH 指定的動態庫搜索路徑

           3)/etc/ld.so.cache中所緩存的動態庫路徑,這個可以通過先修改配置文件/etc/ld.so.conf中指定的動態庫搜索路徑,然后執行ldconfig命令來改變。

           4)默認的動態庫搜索路徑/lib

           5)默認的動態庫搜索路徑/usr/lib

           另外:在嵌入式Linux系統的實際應用中,1和2被經常使用,也有一些相對簡單的的嵌入式系統會采用4或5的路徑來規范動態庫,3在嵌入式系統中使用的比較少, 因為有很多系統根本就不支持ld.so.cache。

           那么,動態鏈接器ld.so在這五種路徑中,是按照什么樣的順序來搜索需要的動態共享庫呢?答案這里先告知就是按照上面的順序來得,即優先級是:1-->2-->3-->4-->5。我們可以寫簡單的程序來證明這個結論。

         

           首先,寫成5個函數,這5個函數名稱都叫pt,但是里面的內容不一樣:

        pt1.c

        #include <stdio.h>

        void pt(){

               printf("1 path on the gcc give \n");

        }

         

        pt2.c 

        #include <stdio.h>

        void pt(){

               printf("2 path on the LD_LIBRARY_PATH \n");

        }

         

        pt3.c 

        #include <stdio.h>

        void pt(){

               printf("3 path on the /etc/ld.so.conf \n");

        }

         

        pt4.c 

        #include <stdio.h>

        void pt(){

               printf("4 path on the /lib \n");

        }

         

        pt5.c 

        #include <stdio.h>

        void pt(){

               printf("5 path on the /usr/lib \n");

        }

         

           然后,分別編譯這5個函數,然后將它們分別移到上面5種情況對應的5個不同目錄下:

        gcc -fPIC -c pt1.c -o pt.o

        gcc -shared pt.o -o libpt.so

        mv libpt.so /tmp/st/1/

         

        gcc -fPIC -c pt2.c -o pt.o

        gcc -shared pt.o -o libpt.so

        mv libpt.so /tmp/st/2/

         

        gcc -fPIC -c pt3.c -o pt.o

        gcc -shared pt.o -o libpt.so

        mv libpt.so /tmp/st/3/

         

        gcc -fPIC -c pt4.c -o pt.o

        gcc -shared pt.o -o libpt.so

        mv libpt.so /lib/

         

        gcc -fPIC -c pt5.c -o pt.o

        gcc -shared pt.o -o libpt.so

        mv libpt.so /usr/lib/

         

           再次,編寫一個main函數m,讓它來調用函數pt:

        m.c

        #include <stdio.h>

         

         

        int main(){

               printf("start....\n");

               pt();

               printf("......end\n");

               return 0;

        }

         

           最后,準備環境,讓ld都知道這5個路徑:

        (a) 往/etc/ld.so.conf總增加一行,內容:/tmp/st/3,然后執行 ldconfig 命令

        (b) export LD_LIBRARY_PATH=/tmp/st/2

        另外3中路徑,ld都可以得到,請接著看下面。

           之后測試:

        gcc m.c -o m1 -L/tmp/st/1 -lpt -Wl,-rpath,/tmp/st/1

        ./m1

        start....

        1 path on the gcc give

        ......end

        這里在可執行文件中動態段中DT_RPATH所指定的路徑,因此需要在編譯m.c的時候就指定路徑,由于其他路徑都也告訴了ld,很明顯,此種方法優先級最高了。

         

        gcc m.c -o m -L/tmp/st/1 -lpt

        ./m

        start....

        2 path on the LD_LIBRARY_PATH

        ......end

        這里很顯然調用了LD_LIBRARY_PATH指定了路徑中的共享庫,因此此種情況優先級第二。

         

        mv /tmp/st/2/libpt.so /tmp/st/2/libpt2.so

        /m

        start....

        3 path on the /etc/ld.so.conf

        ......end

        這里是調用了/etc/ld.so.cache中所緩存的動態庫路徑中的共享庫,因此此種情況優先級第三。

         

        mv /tmp/st/3/libpt.so /tmp/st/3/libpt3.so

        ./m

        start....

        4 path on the /lib

        ......end

        這里是調用/lib中的共享庫,優先級第四。

         

        rm /lib/libpt.so

        ./m

        start....

        5 path on the /usr/lib

        ......end

        這里是調用/lib中的共享庫,優先級第五。

         

           故證明這五種路徑指定方法的優先級是1-->2-->3-->4-->5!


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞:

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 山东| 象山县| 灵丘县| 光山县| 墨玉县| 绵竹市| 左云县| 郴州市| 疏附县| 丰台区| 满城县| 时尚| 郑州市| 孝感市| 邓州市| 阿鲁科尔沁旗| 新化县| 天门市| 利津县| 磐石市| 英吉沙县| 三穗县| 晴隆县| 烟台市| 塔城市| 永兴县| 普兰店市| 翁牛特旗| 科尔| 襄樊市| 喀喇| 明溪县| 辽宁省| 龙川县| 平泉县| 全南县| 增城市| 丰顺县| 贵南县| 健康| 朔州市|