1. 程式人生 > >嵌入式編譯時 ld: cannot find -lxxx 和 ld:skipping incompatible

嵌入式編譯時 ld: cannot find -lxxx 和 ld:skipping incompatible

編譯原始碼時報錯:

/opt/toolchains/uclibc-crosstools-gcc-4.2.3-3/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.3/../../../../mips-linux-uclibc/bin/ld: cannot find -lrvsip

原來是radv沒有編譯,librvsip.a也沒有生成。

cd radv

make

make install

此時librvsip.a以生成,其他的一切貌似很正常。

再次編譯總的原始碼時仍然出錯:

/opt/toolchains/uclibc-crosstools-gcc-4.2.3-3/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.3/../../../../mips-linux-uclibc/bin/ld:skipping incompatible
...

/opt/toolchains/uclibc-crosstools-gcc-4.2.3-3/usr/bin/../lib/gcc/mips-linux-uclibc/4.2.3/../../../../mips-linux-uclibc/bin/ld: cannot find -lrvsip

仔細分析我的操作和出錯提示,真相大白於天下:

此嵌入式系統cpu 的arch 是mips,而我 "cd radv; make; make install" 時預設的gcc 是系統系統自帶的X86的gcc,與crosstools gcc對應的mips-linux-gcc 顯然不同,在連結的時候,mips-linux-ld 還是回檢查ld的物件(這裡是librvsip.a

啦)的arch格式啦,ld:skipping incompatible 就是不相容,連線失敗,故還是回報錯 ld: cannot find -lxxx(這裡是lrvsip)。

另外有的網友不是這樣的情況,有的是32bit CPU 與 64bit CPU的區別。

總之,每一種不同架構的CPU都會對應不同的GCC 工具鏈。

建議:

在單獨模組移植編譯的時候,常常並不指定具體的嵌入式crosstools gcc, Makefile 中的 CC 是從上級Makefile中繼承來的,這樣單獨編譯可能會沒有問題。但一旦在其他模組中連結了此模組的生成的binary檔案,比如生成的庫,自然就會出現連結錯誤。在修改Makefile的時候往往回加上install、clean等偽目標,install偽目標

中執行的install或cp命令 一定要與clean偽目標執行的rm命令高度一致,更不可遺漏,clean的時候一定要clean掉install的binary檔案。

另外,很多情況下使用共享庫時並不是一帆風順,比如執行程式的時候報類似下面的錯誤:

error while loading shared libraries: xxx.so.xx: cannot open shared object file: No such file or directory

一般的做法是:

I. 在/etc/ld.so.conf 或 /etc/ld.so.conf.d/xxx.conf( 比如本人的Fedora 10 ) 下 加 /usr/local/lib(比如本人裝的 libpcap.so.1.3.0 在此目錄)

II. root 許可權下執行 ldconfig -v  使之馬上生效,會有很多顯示,如果不是root許可權最後則會報錯:

/sbin/ldconfig: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
從這裡可以看出,其原理是產生cache檔案,loading shared libraries 的時候從cache中快速查詢相應的目錄和共享庫(比如libpcap.so)。

//todo