交叉編譯的時候不能使用本地(i686機器,即pc機器,研發機器)機器上的庫,但是在做編譯鏈結的時候預設的是使用本地庫,即/usr/lib,/lib兩個目錄。因此,在交叉編譯的時候,要採取一些方法使得在編譯鏈結的時候找到需要的庫。
首先,要知道:編譯的時候只需要頭文件,真正實際的庫文件在鏈結的時候用到。 (這是我的理解,假如有不對的地方,敬請網上各位大俠指教) 然後,講講如何在交叉編譯鏈結的時候找到需要的庫。
(1)、交叉編譯時候直接使用-l和-i引數指定搜尋非標準的庫文件和頭文件的路徑。例如:
arm-linux-gcc test.c -l/usr/local/arm/2.95.3/arm-linux/lib -i/usr/local/arm/2.95.3/arm-linux/include
(2)、使用ld.so.conf文件,將用到的庫所在文件目錄新增到此文件中,然後使用ldconfig命令重新整理快取。
(3)、使用如下命令:
$ export ld_library_path=$ld_library_path:/usr/local/arm/2.95.3/arm-linux-lib
參見《ld.so.conf 文件和pkg_config_path變數》這篇文章。
通過環境變數ld_library_path指定動態庫搜尋路徑(!)。
通過設定環境變數ld_library_path也可以指定動態庫搜尋路徑。當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號":"分隔。
不過ld_library_path的設定作用是全域性的,過多的使用可能會影響到其他應用程式的執行,所以多用在除錯。(ld_library_path的缺陷和使用準則,可以參考《why ld_library_path is bad》 )。通常情況下推薦還是使用gcc的-r或-rpath選項來在編譯時就指定庫的查詢路徑,並且該庫的路徑資訊儲存在可執行檔案中,執行時它會直接到該路 徑查詢庫,避免了使用ld_library_path環境變數查詢。
(4)、交叉編譯時使用軟體的configure引數。例如我編譯minigui-1.3.3,使用如下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux \
cflags=-i/usr/local/arm/2.95.3/arm-linux/include \
ldflags=-l/usr/local/arm/2.95.3/arm-linux/lib \
--prefix=/usr/local/arm/2.95.3/arm-linux \
--enable-lite \
--disable-galqvfb \
--disable-qvfbial \
--disable-vbfsupport \
--disable-ttfsupport \
--disable-type1support \
--disable-imegb2312py \
--enable-extfullgif \
--enable-extskin \
--disable-videoqvfb \
--disable-videoecoslcd
這裡我配置了cflags和ldflags引數,這樣一來,我就不用去修改每個makefile裡-l和-i引數了,也不用再去配置ld_library_path或改寫ld.so.conf文件了。
linux下動態庫使用小結
1. 靜態庫和動態庫的基本概念
靜態庫,是在可執行程式連線時就已經加入到執行碼中,在物理上成為執行程式的一部分;使用靜態庫編譯的程式執行時無需該庫檔案支援,**都可以用,但是生成的可執行檔案較大。動態庫,是在可執行程式啟動時載入到執行程式中,可以被多個可執行程式共享使用。使用動態庫編譯生成的程式相對較小,但執行時需要庫檔案支援,如果機器裡沒有這些庫檔案就不能執行。
2. 如何使用動態庫
如何程式在連線時使用了共享庫,就必須在執行的時候能夠找到共享庫的位置。linux的可執行程式在執行的時候預設是先搜尋/lib和/usr/lib這兩個目錄,然後按照/etc/ld.so.conf裡面的配置搜尋絕對路徑。同時,linux也提供了環境變數ld_library_path供使用者選擇使用,使用者可以通過設定它來查詢除預設路徑之外的其他路徑,如查詢/work/lib路徑,你可以在/etc/rc.d/rc.local或其他系統啟動後即可執行到的指令碼新增如下語句:ld_library_path =/work/lib:$(ld_library_path)。並且ld_library_path路徑優先於系統預設路徑之前查詢(詳細參考《使用ld_library_path》)。
不過ld_library_path的設定作用是全域性的,過多的使用可能會影響到其他應用程式的執行,所以多用在除錯。(ld_library_path的缺陷和使用準則,可以參考《why ld_library_path is bad》 )。通常情況下推薦還是使用gcc的-r或-rpath選項來在編譯時就指定庫的查詢路徑,並且該庫的路徑資訊儲存在可執行檔案中,執行時它會直接到該路徑查詢庫,避免了使用ld_library_path環境變數查詢。
3.庫的鏈結時路徑和執行時路徑
現代聯結器在處理動態庫時將鏈結時路徑(link-time path)和執行時路徑(run-time path)分開,使用者可以通過-l指定連線時庫的路徑,通過-r(或-rpath)指定程式執行時庫的路徑,大大提高了庫應用的靈活性。比如我們做嵌入式移植時#arm-linux-gcc $(cflags) –o target –l/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉編譯好的zlib庫),將target編譯好後我們只要把zlib庫拷貝到開發板的系統預設路徑下即可。或者通過-rpath(或-r )、ld_library_path指定查詢路徑。
小問題:
1.編譯時的-l選項是否影響ld_library_path的值?
舉乙個例項:
當前資料夾結構如下:
test.c tools/
tool下有tool.c tool.h my_err.h 以及由此生成的libtool.so
tool下編譯生成庫檔案
gcc -wall -g -shared -o tool.so tool.c
在當前資料夾引用:
gcc -wall -g –o test.c -ltools -ltool
編譯不報錯,但是執行載入的時候就出現cannot open shared object file。
如果將該庫檔案拷貝到/usr/lib下就沒有錯誤,正常執行。
說明編譯時的-l選項並不影響環境變數ld_library_path,-l只是指定了程式編譯連線時庫的路徑,並不影響程式執行時庫的路徑,系統還是會到預設路徑下查詢該程式所需要的庫。
交叉編譯時候如何配置連線庫的搜尋路徑
交叉編譯的時候不能使用本地 i686機器,即pc機器,研發機器 機器上的庫,但是在做編譯鏈結的時候預設的是使用本地庫,即 usr lib,lib兩個目錄。因此,在交叉編譯的時候,要採取一些方法使得在編譯鏈結的時候找到需要的庫。首先,要知道 編譯的時候只需要頭文件,真正實際的庫文件在鏈結的時候用到。這...
boost庫的交叉編譯
1.首先執行boost解壓目錄下的 bootstrap.sh 2.修改生成的project config.jam檔案 修改 using gcc opt poky linux gcc sysroot opt poky 2.4.2 sysroots aarch64 poky linux 注 1.gcc ...
帶WiringPi庫的交叉編譯如何處理
帶wiringpi庫的交叉編譯如何進行 1.正常我們先要交叉編譯wiringpi庫,編譯出的庫適合樹莓派,這時候交叉編譯可執行程式的試試,鏈結庫的格式也是正確的。2.通過 i l來指定 因為鏈結的庫的格式不對,是宿主機的平台,出現以下錯誤 arm linux gnueabihf gcc demo2....