1. 程式人生 > >交叉編譯幾種常見的報錯

交叉編譯幾種常見的報錯

由於是第一次交叉編譯,不知道會出現什麼問題,思路就是先把gcc和ld都改成arm的,然後遇到什麼問題在解決什麼問題,以下過程都是在這個思路下進行。

1.指定arm的編譯器和聯結器:

只是把gcc改為arm-none-linux-gnueabi-gcc,ld改為arm-none-linux-gnueabi-ld,其他的都沒有修改。出現以下錯誤:

arm-none-linux-gnueabi-ld: warning: library search path "/usr/local/lib" is unsafe for cross-compilation 
arm-none-linux-gnueabi-ld: skipping incompatible /usr/local/lib/libfreetype.so when searching for -lfreetype 
arm-none-linux-gnueabi-ld: skipping incompatible /usr/local/lib/libfreetype.a when searching for -lfreetype 
arm-none-linux-gnueabi-ld: cannot find -lfreetype

分析原因是:連結的這些庫檔案都是在PC編譯器下編譯出來的,現在把它們和用arm-none-linux-gnueabi-gcc編譯出來的檔案做連結,當然會出錯。

解決方法:這些庫重新用arm-gcc重新編譯生成相應的庫。

下面使用是重新編譯庫檔案的過程:

重新編譯freetype

根據交叉編譯的文件,我建立了一個資料夾/usr/local/arm-linux來存放編譯後的庫檔案。執行:

./configure –host=arm-none-linux-gnueabi –prefix=/usr/local/arm-linux

注意:host的引數應該是交叉編譯環境的字首。

另外,freetype自動生成的include資料夾有點小問題,編譯完成後的include目錄結構是/include/ft2build.h和

/include/freetype2/freetype/***.h如果直接使用會出現標頭檔案找不到的問題,這裡涉及到freetype的一個小技巧:使用freetype時只需要包含ft2build.h這一個標頭檔案即可,因為ft2build.h裡面會自動包含其他需要的標頭檔案。而ft2build.h中的包含其他標頭檔案的路徑是/freetype/***.h,顯然找不到相應的標頭檔案。我們把freetype2中的freetype檔案整個拷貝到include目錄下,然後把freetype2刪除即可。

原目錄結構:

…/include/freetype2/freetype/***.h

…/include/ft2build.h

修改以後是:

…/include/freetype/***.h

…/include/ft2build.h

如果安裝完成後直接就是後面這個目錄結構就不用修改了。或者在編譯時直接使用-I再加一個頭檔案的目錄。

-I/…/include/freetype2

使用arm編譯器和使用pc上的編譯器編譯過程差不多,需要注意的是我們需要重新指定路徑以免把原來的庫檔案覆蓋掉。

2.在編譯時出現這種錯誤:

解決上面的問題之後,再次編譯,出現以下錯誤:

/usr/local/arm-2009q1/bin/../arm-none-linux-gnueabi/libc/usr/include/sys/types.h:62: error: conflicting types for ‘dev_t’ 
/usr/local/arm-2009q1/bin/../arm-none-linux-gnueabi/libc/usr/include/linux/types.h:13: error: previous declaration of ‘dev_t’ was here

開始以為是編譯器自動尋找types.h檔案然後自動包含進來了,後來所有的都標頭檔案刪除,然後每加一個頭檔案進來就編譯看看是否出現錯誤,後來發現這個我的交叉編譯器對於某些標頭檔案的使用順序有要求。例如:

#include <fcntl.h>

#include <linux/fb.h>

#include <linux/fb.h>

#include <fcntl.h>

第一種編譯沒有問題,第二種會出現上面的錯誤。而這兩種寫法在PC的gcc上都沒有錯誤。

我的交叉編譯器版本:gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)

感覺這個問題是由於pc上的gcc和交叉編譯使用的gcc的行為不同才導致的。

3.連結時這樣的錯誤:

arm-none-linux-gnueabi-ld main.o es_run_file.o es_fbctl.o es_time.o es_sql.o es_fbio.o es_dao.o es_utf8.o es_copy.o es_font.o -o main  -L/usr/local/arm-linux/lib -lfreetype -lpthread -lsqlite3 -lncurses 
arm-none-linux-gnueabi-ld: warning: cannot find entry symbol _start; defaulting to 00009050 
es_copy.o: In function `file_exist’: 
/root/work/es_copy.c:32: undefined reference to `stat’

最後一個錯誤是找不到stat,我把es_copy.c檔案單獨拿出來修改以後編譯:

arm-none-linux-gnueabi-gcc es_copy.c

沒有錯誤。把Makefile裡的聯結器也改成arm-none-linux-gnueabi-gcc,以上兩個問題都消失了。這個問題在gcc和arm-none-linux-gnueabi-gcc這兩種編譯器中都存在,應該連結時ld的引數設定不對,具體怎樣設定還是沒有找到。

總結:交叉編譯的一般過程

1.交叉編譯並安裝使用到的共享庫。

2.交叉編譯源程式。

3.除錯