glib wpa_supplicant Unix上庫編譯錯誤解決與總結


編譯Linux下的庫是一件痛苦的事情,這里主要闡述glib和wpa_supplicant庫的編譯,因各自的依賴關系,另外一些庫要事先編譯。glib依賴libffi和zlib,而wpa_supplicant依賴dbus和openssl。

總結下交叉編譯幾個常見的邏輯:
1. 指定CC為交叉編譯器
2. 指定--prefix,如果不指定,會將宿主機PC上相應的庫給覆蓋了,如果是系統關鍵的庫文件,那就會造成系統啟動失敗。解決辦法只有一個一個找到被覆蓋的文件,再從一台好的PC機上拷貝回來。注意這里要找到被修改的文件不是那么容易,也許只有看文件的修改日期,另要找到一台相同系統的機器也不是那么簡單的。
3. 編譯依賴其他庫的package的時候(這里就是glib,它依賴libffi和zlib),要將依賴庫的lib和include路徑指定清楚,讓編譯器能夠找到這些文件,如果頭文件include找不到的話,那就會編譯出錯,報not found file or directory之類的錯誤;如果是庫文件lib找不到的話,那就會在ld鏈接的時候出錯,報undefined function之類的錯誤。
4. pkg-config和PKG_CONFIG_PATH的使用,網上已經有很詳細的介紹了,這里不再細數。只是說明盡量用pkgconfig方式來指定依賴庫和頭文件的路徑,在*.pc文件里面已經有很詳細的定義,就不用在configure或者make的時候指定一串串長長的CFLAGS,LDFLAGS,-I,-L。
5. 在定義CFLAGS或者LDFLAGS的時候,盡量不要指定PC系統的目錄,像/usr/lib,/usr/include之類。因為系統一般都是x86的庫,如果被交叉編譯的庫鏈接的話會報錯。


編譯歷程:
1. 需定義LIBFFI_LIBS, LIBFFI_CFLAGS, ZLIB_LIBS和ZLIB_CFLAGS這幾個宏,否則會出現一下的錯誤。

make[4]: Entering directory `/home/joe/Downloads/glib-2.32.4/gobject'
CCLD   gobject-query
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_pointer'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_float'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_void'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint64'
./.libs/libgobject-2.0.so: undefined reference to `ffi_prep_cif'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint32'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_double'
./.libs/libgobject-2.0.so: undefined reference to `ffi_call'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_sint32'
./.libs/libgobject-2.0.so: undefined reference to `ffi_type_uint64'
collect2: ld returned 1 exit status
make[4]: *** [gobject-query] Error 1
make[4]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject'
make[3]: *** [all-recursive] Error 1
make[3]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/home/joe/Downloads/glib-2.32.4/gobject'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/joe/Downloads/glib-2.32.4'
make: *** [all] Error 2
 
        

2. 需編譯安裝libffi,否則會出現一下的錯誤:
configure: error: Package requirements (libffi >= 3.0.0) were not met:
No package 'libffi' found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

3. 將PC上編譯出來的glib-compile-schemas拷貝到交叉編譯的glib代碼目錄下面,否則會提示找不到glib-compile-schemas的錯誤:
./configure: glib-compile-schemas not found
這個問題挺奇怪,既然要編譯glib,竟然還要先在PC上編譯一個glib,然后編第二次使用第一次邊出來的bin文件。 http://www.spinics.net/lists/gtk/msg17208.html這個patch在這里做一個記錄。

4. 定義linux-arm.cache文件作為參數--cache-file的值,手工指定:不能為交叉編譯檢查glib_cv_stack_grow, 應為交叉編譯在PC上,不在板子里。類似其他一些值寫進去,否則會有類似下面的錯誤:
checking for growing stack pointer...configure: error: cannot run test program while cross compiling
修改內容如下:
echo ac_cv_type_long_long=yes>$ARCH-linux.cache
echo glib_cv_stack_grows=no>>$ARCH-linux.cache
echo glib_cv_uscore=no>>$ARCH-linux.cache
echo ac_cv_func_posix_getpwuid_r=yes>>$ARCH-linux.cache

5. 在CFLAGS中指定-Wl,-rpath $(DESTDIR)/../obj/external/glib/gmodule/.libs/,否則會出現找不到gmodule.so的庫文件的錯誤:
gmodule.so not found
glib編譯過程中會引用先前編譯出來的庫文件,然而竟然沒有找到,find了一下發現在make install之前這個庫的位置,故而用-Wl -rpath在指定。

6. 編譯openssl需要定義no-asm和shared,去掉-m64,否則會出現編譯匯編失敗和編譯器不識別-m64的錯誤。

7. 編譯wpa_supplicant需要禁止掉nl80211的編譯,否則會提示錯誤:
netlink/genl/genl.h: No such file or directory
如果指定系統/usr/include目錄給CFLAGS,以提示genl.h的位置,這個問題是沒有了,會出現其他問題,提示__asm__錯誤,原來定義/usr/include之后,有些頭文件就到這個目錄下去找,也就是找x86的頭文件,這和arm的不兼容,故出現問題。也就是上面描述的總結5。

總結:
有時候編譯UNIX庫並沒有想象中的那么簡單,configure&make&make install永遠不會是所有的過程,不同PC不同編譯器會碰到不同的問題,在此做記錄,與大家共勉。



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM