0. 本文使用的環境
Ubuntu 18.04,Vivado 2018.2
目的是:交叉編譯 Thrift 0.13.0 到 arm 環境(從而實現:在 FPGA arm 環境下跑 Thrift C server,在外部 PC 機上跑 Thrift Python client。從而達到 Python 遠程調用 C 函數的目的)。
Vivado 自帶交叉編譯工具,也可以在如下地址下載,
https://www.linaro.org/downloads/
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain
https://mirrors.tuna.tsinghua.edu.cn/armbian-releases/_toolchain/ (推薦)
1. Xilinx 的工具集
Xilinx Vivado 安裝好之后 (安裝時要勾選 SDK 套件),例如我將其安裝在 /opt 目錄下,則其環境配置文件為 /opt/Xilinx/SDK/2018.2/settings64.sh,一般來說,使用交叉編譯環境前,需要 source 這個文件。打開這個文件,它指向 /opt/Xilinx/SDK/2018.2/.settings64-SDK_Core_Tools.sh,打開指向的文件,內容為,
############################################################## # Copyright (c) 1986-2020 Xilinx, Inc. All rights reserved. # ############################################################## if [ -n "${PATH}" ]; then export PATH=/opt/Xilinx/SDK/2018.2/bin:/opt/Xilinx/SDK/2018.2/gnu/microblaze/lin/bin:/opt/Xilinx/SDK/2018.2/gnu/arm/lin/bin:/opt/Xilinx/SDK/2018.2/gnu/microblaze/linux_toolchain/lin64_le/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-none-eabi/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-linux/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-none/bin:/opt/Xilinx/SDK/2018.2/gnu/armr5/lin/gcc-arm-none-eabi/bin:/opt/Xilinx/SDK/2018.2/tps/lnx64/cmake-3.3.2/bin:$PATH else export PATH=/opt/Xilinx/SDK/2018.2/bin:/opt/Xilinx/SDK/2018.2/gnu/microblaze/lin/bin:/opt/Xilinx/SDK/2018.2/gnu/arm/lin/bin:/opt/Xilinx/SDK/2018.2/gnu/microblaze/linux_toolchain/lin64_le/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-none-eabi/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-linux/bin:/opt/Xilinx/SDK/2018.2/gnu/aarch64/lin/aarch64-none/bin:/opt/Xilinx/SDK/2018.2/gnu/armr5/lin/gcc-arm-none-eabi/bin:/opt/Xilinx/SDK/2018.2/tps/lnx64/cmake-3.3.2/bin fi
因為我開發 Zynq-7000 系列下的程序 (armv7, aarch32),所以要使用上述高亮路徑指向的編譯器及附帶工具。為方便起見,將其添加到 .bashrc (最好給當前用戶 和 root 用戶都添加,后面會解釋給 root 用戶添加的原因),
# for Xilinx SDK corss compile env target for Zynq-7000 devices export PATH=$PATH:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin
添加好之后,source 這個文件,就能看到可以使用的 arm 工具集,如下,
$ arm # tab tab arm2hpdl arm-linux-gnueabihf-g++ arm-linux-gnueabihf-gcov-tool arm-linux-gnueabihf-ranlib arm-linux-gnueabihf-addr2line arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gdb arm-linux-gnueabihf-readelf arm-linux-gnueabihf-ar arm-linux-gnueabihf-gcc-7.2.1 arm-linux-gnueabihf-gprof arm-linux-gnueabihf-size arm-linux-gnueabihf-as arm-linux-gnueabihf-gcc-ar arm-linux-gnueabihf-ld arm-linux-gnueabihf-strings arm-linux-gnueabihf-c++ arm-linux-gnueabihf-gcc-nm arm-linux-gnueabihf-ld.bfd arm-linux-gnueabihf-strip arm-linux-gnueabihf-c++filt arm-linux-gnueabihf-gcc-ranlib arm-linux-gnueabihf-nm arm-linux-gnueabihf-cpp arm-linux-gnueabihf-gcov arm-linux-gnueabihf-objcopy arm-linux-gnueabihf-elfedit arm-linux-gnueabihf-gcov-dump arm-linux-gnueabihf-objdump
arm 編譯器,有它自己的默認搜索路徑,它不會主動識別系統搜索路徑例如 /usr/include,/usr/local/include 等。查看它的搜索路徑,
# -v: verbose
# -E: only preprocess
# -: input & output is stdin & stdout
$ echo 'main(){}' | arm-linux-gnueabihf-gcc -v -E -
輸出內容為,
$ echo 'main(){}' | arm-linux-gnueabihf-gcc -v -E - Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc Target: arm-linux-gnueabihf Configured with: /proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/snapshots//gcc-linaro-7.2-2017.11-rc1/configure SHELL=/bin/sh --with-bugurl=https://bugs.linaro.org --with-mpc=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libstdcxx-pch --disable-libmudflap --with-cloog=no --with-ppl=no --with-isl=no --disable-nls --enable-c99 --enable-gnu-indirect-function --disable-multilib --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=arm --disable-multilib --enable-multiarch CFLAGS=-O2 CXXFLAGS=-O2 --disable-silent-rules --enable-libquadmath --enable-libg2c --enable-symvers=gnu --enable-libstdcxx-pch --enable-libssp --disable-libmudflap --enable-checking=release --enable-cheaders=c_global --enable-poison-system-directories --enable-clocale=generic --enable-shared --enable-threads=posix --disable-multilib --enable-c99 --without-local-prefix --enable-lto --disable-bootstrap --with-linker-hash-style=gnu --with-ppl=no --with-cloog=no --without-isl --enable-nls --enable-__cxa_atexit --with-build-sysroot=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-plugins --enable-linker-build-id --enable-long-long --enable-shared --with-sysroot=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-languages=c,c++,lto --enable-checking=yes --disable-bootstrap --with-bugurl=https://bugs.linaro.org --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu Thread model: posix gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11-rc1) COLLECT_GCC_OPTIONS='-v' '-E' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-marm' '-mtls-dialect=gnu' /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../libexec/gcc/arm-linux-gnueabihf/7.2.1/cc1 -E -quiet -v -imultilib . -imultiarch arm-linux-gnueabihf -iprefix /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/ -isysroot /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc - -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3-d16 -marm -mtls-dialect=gnu ignoring duplicate directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/7.2.1/include" ignoring nonexistent directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/usr/local/include/arm-linux-gnueabihf" ignoring nonexistent directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/usr/local/include" ignoring duplicate directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/7.2.1/include-fixed" ignoring duplicate directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/include" ignoring nonexistent directory "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/usr/include/arm-linux-gnueabihf" #include "..." search starts here: #include <...> search starts here: /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/include /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/include-fixed /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/include /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/usr/include End of search list. # 1 "<stdin>" # 1 "<built-in>" # 1 "<command-line>" # 31 "<command-line>" # 1 "/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include/stdc-predef.h" 1 3 4 # 32 "<command-line>" 2 # 1 "<stdin>" main(){} COMPILER_PATH=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../libexec/gcc/arm-linux-gnueabihf/7.2.1/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../libexec/gcc/arm-linux-gnueabihf/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../libexec/gcc/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/bin/ LIBRARY_PATH=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/lib/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/lib/:/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../arm-linux-gnueabihf/libc/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-E' '-march=armv7-a' '-mtune=cortex-a9' '-mfloat-abi=hard' '-mfpu=vfpv3-d16' '-marm' '-mtls-dialect=gnu'
注意,為方便起見,將需要使用的庫文件編譯安裝在上述高亮目錄下,即 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr
2. 交叉編譯 glib 庫
交叉編譯一個庫,首先要對這個庫依賴的所有庫進行交叉編譯。glib 依賴 pcre, libffi, zlib,我這里使用,
pcre-8.38.tar.bz2 , https://sourceforge.net/projects/pcre/files/pcre/8.38/
libffi-3.2.1.tar.gz,ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz
zlib-1.2.11.tar.gz,http://www.zlib.net/
(1) 交叉編譯 pcre
編譯前,首先打開 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/lib/libstdc++.la,做如下更改,
# Directory that this library needs to be installed in: # libdir='/proj/esdt_sdk/gnu_abe/ABE/builds/lin/arm/arm-linux/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/lib' libdir='/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/lib'
否則編譯時會有如下 warning,很明顯上述文件的路徑是個虛擬路徑(Xilinx 為什么要這么設置,具體原因目前不明)
libtool: warning: library '/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/7.2.1/../../../../arm-linux-gnueabihf/lib/libstdc++.la' was moved.
解開壓縮包,配置,編譯,安裝,
$ tar --bzip2 -xf pcre-8.38.tar.bz2 $ cd pcre-8.38/ $ su # 建議切換到 root 用戶進行編譯,因為普通用戶,使用 sudo make install 時,會觸發一個子 shell,在這個子 shell 中不能識別 arm 工具集 # ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --host=arm-linux-gnueabihf # make # make install
這樣,編譯后的頭文件,庫文件,可執行文件,會依次安裝在 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr 下的 include, lib, bin 中。
(2) 交叉編譯 libffi
$ tar --gzip -xf libffi-3.2.1.tar.gz $ cd libffi-3.2.1/ $ su # ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --host=arm-linux-gnueabihf # make # make install
注意:libffi 有點特殊,它會將頭文件安裝在 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/lib/libffi-3.2.1/include ,所以必須在默認頭文件搜索路徑 /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include 下給它建立鏈接,
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include$ sudo ln -fs ../lib/libffi-3.2.1/include/ffi.h ./ffi.h /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include$ sudo ln -fs ../lib/libffi-3.2.1/include/ffitarget.h ./ffitarget.h
(3) 交叉編譯 zlib
$ tar --gzip -xf zlib-1.2.11.tar.gz $ cd zlib-1.2.11/ $ su # export CC=arm-linux-gnueabihf-gcc # 注意,zlib 比較特殊,它不能識別 --host, CC 這樣的配置指令,所以使用 export 臨時設置一下環境 # ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr # make # make install
(4) 交叉編譯 glib
$ tar --xz -xf glib-2.56.4.tar.xz $ cd glib-2.56.4/
在源代碼目錄下創建一個 .cache 文件,姑且命名為 arm-linux-gnueabihf.cache,填入以下內容,
glib_cv_stack_grows=no
glib_cv_uscore=no
原因在於 ./configure 生成 Makefile,會運行一些測試,但交叉編譯情況下,在 build 機器上,有些測試不能運行,所以會導致 configure 不通過的問題,如下,(當然,這里的 .cache 文件添加的內容,還有待思量,需要進一步研究 TODO)
... configure: error: cannot run test program while cross compiling See `config.log' for more details
另外,glib 還依賴於 libmount 模塊,此模塊和系統掛載文件分析相關,詳情見:https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.21/libmount-docs/index.html,(我配置時直接把它 disable 掉了,這塊也有待思量)
# (Optional) 查看可用配置選項
# ./configure --help
# 注意,默認情況下,不會生成靜態鏈接庫,而編譯 thrift 靜態鏈接 server 時,需要靜態 glib 庫,所以這里要加上 --enable-static=yes
# ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --host=arm-linux-gnueabihf --cache-file=arm-linux-gnueabihf.cache --enable-libmount=no --enable-static=yes # make # make install
3. 交叉編譯 Boost
$ tar --bzip2 -xf boost_1_70_0.tar.bz2 $ cd boost_1_70_0 $ ./bootstrap.sh --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr
修改生成的 project-config.jam 文件,
... if ! gcc in [ feature.values <toolset> ] { # using gcc ; using gcc : : /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc ; } ...
編譯並安裝,
$ sudo ./b2 install
4. 交叉編譯 libevent
獲取源碼包 http://libevent.org/
$ tar --gzip -xf libevent-2.1.11-stable.tar.gz $ cd libevent-2.1.11-stable/ $ su # ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --host=arm-linux-gnueabihf # make # make install
5. 交叉編譯 openssl
獲取源碼包 https://www.openssl.org/
(openssl 沒有使用標准的 automake,查看 INSTALL 了解詳細配置選項)
$ tar --gzip -xf openssl-1.1.1f.tar.gz $ cd openssl-1.1.1f $ su # ./config no-asm --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --cross-compile-prefix=arm-linux-gnueabihf-
打開 config 后生成的 Makefile 文件,刪除里面的 -m64 選項 (arm-linux-gnueabihf-gcc 不能識別這個選項,目前還沒找到方法配置它,只能暴力刪除)
再編譯,安裝,
# make # make install
6. 交叉編譯 thrift
獲取源碼包 http://thrift.apache.org/
$ tar --gzip -xf thrift-0.13.0.tar.gz $ cd thrift-0.13.0 $ su
打開 configure.ac,注釋掉以下內容(root cause 是,交叉編譯情況下,交叉編譯工具安裝在非標准路徑,或者是交叉編譯工具根本沒有類似工具,導致無法完成 configure.ac 中的一些測試,詳見:https://nerdland.net/unstumping-the-internet/malloc-has-not-been-declared/
)
# AC_FUNC_MALLOC
# AC_FUNC_REALLOC
這樣就可以解決編譯過程中的這個錯誤,
...
/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/include/c++/7.2.1/cstdlib:145:11: error: ‘::malloc’ has not been declared using ::malloc; ^~~~~~ /opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/include/c++/7.2.1/cstdlib:158:11: error: ‘::realloc’ has not been declared using ::realloc; ^~~~~~~
因為經過前述步驟,glibc 也沒有安裝在標准目錄,而如果 build 環境已經安裝有 libglib2.0-dev,則 thrift 配置時會指向 build 環境的 glib 庫 (因為 build 環境的 pkg-config 會檢測到在默認安裝路徑有 glib,但這個不是我們要用的,我們要用交叉編譯的 glib 庫),所以設置臨時環境變量如下, (注意: petalinux 2018.2 要求安裝 libglib2.0-dev:i386,不能用 libglib2.0-dev,但是 i386 版本安裝后, pkg-config --cflags 不能檢測到 glib 已經安裝了,所以也要手動指定 GLB_LIBS 和 GOBJECT_LIBS)
# export GLIB_CFLAGS='-I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include/glib-2.0 -I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/lib/glib-2.0/include' # export GOBJECT_CFLAGS='-I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include/glib-2.0 -I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/lib/glib-2.0/include'
# export GLIB_LIBS='-lglib-2.0'
# export GOBJECT_LIBS='-lgobject-2.0 -lglib-2.0'
繼續配置,
./bootstrap.sh
# 僅在 ARM 服務器端保留對 C,C++,Python 的支持 ./configure --prefix=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --host=arm-linux-gnueabihf --with-boost=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --with-libevent=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --with-zlib=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr --with-openssl=/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr CPPFLAGS="-I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include -I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/include/glib-2.0 -I/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/lib/glib-2.0/include" LDFLAGS="-L/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/arm-linux-gnueabihf/libc/usr/lib" --with-as3=no --with-qt5=no --with-csharp=no --with-java=no --with-erlang=no --with-nodejs=no --with-nodets=no --with-lua=no --with-perl=no --with-php=no --with-php_extension=no --with-py3=no --with-dart=no --with-ruby=no --with-haskell=no --with-go=no --with-swift=no --with-rs=no --with-cl=no --with-haxe=no --with-dotnetcore=no --with-d=no --enable-tests=no
再分別打開文件 ./lib/c_glib/src/thrift/config.h 和 ./lib/cpp/src/thrift/config.h,進行如下修改,(root cause 也是交叉編譯環境下,configure.ac 的部分測試不能成功執行,導致一些宏沒有設對)
/* Possible value for SIGNED_RIGHT_SHIFT_IS */ /* #undef ARITHMETIC_RIGHT_SHIFT */ #define SIGNED_RIGHT_SHIFT_IS 1 #define ARITHMETIC_RIGHT_SHIFT 1
這樣就可以解決編譯過程中的這個錯誤,
...
./src/thrift/protocol/TCompactProtocol.tcc:34:3: error: #error "Unable to determine the behavior of a signed right shift" # error "Unable to determine the behavior of a signed right shift"
編譯,
# make
編譯完成后,進行 test 的時候,又出現了 error,(這是當然,arm 環境下的結果肯定不能再 X86 環境下運行,但是我配置時設置了 --enable-tests=no,不知道為什么這里還進入了測試,有待進一步研究),但是編譯已經完成了,已經生成我們需要的結果了,測試錯誤暫且忽略,
...
Making all in test make[4]: Entering directory '/home/peterpan/Downloads/thrift-0.13.0/lib/c_glib/test' /home/peterpan/Downloads/thrift-0.13.0/compiler/cpp/thrift --gen c_glib ContainerTest.thrift /bin/bash: /home/peterpan/Downloads/thrift-0.13.0/compiler/cpp/thrift: cannot execute binary file: Exec format error Makefile:1774: recipe for target 'gen-c_glib/t_test_container_test_types.c' failed make[4]: *** [gen-c_glib/t_test_container_test_types.c] Error 126
...
安裝,
# make install
安裝末尾又報出同樣的測試錯誤,可以忽略它,這是安裝完成后的測試,原因同上述 error 一樣,
... make[3]: Entering directory '/home/peterpan/Downloads/thrift-0.13.0/lib/c_glib/test' /home/peterpan/Downloads/thrift-0.13.0/compiler/cpp/thrift --gen c_glib ContainerTest.thrift /bin/bash: /home/peterpan/Downloads/thrift-0.13.0/compiler/cpp/thrift: cannot execute binary file: Exec format error Makefile:1774: recipe for target 'gen-c_glib/t_test_container_test_types.c' failed ...
總結:
因為一般情況下,源碼發布的軟件包,大部分都適配主流操作系統 Linux,UNIX,OS X,Windows 等,即編譯環境,不管是基於 automake 的configure.ac, Makefile.am 或者是基於經典 make 的 Makefile,已經適配好了,所以一般直接 $ ./configure && make && sudo make install 即可。
但對交叉編譯來說,不適配,例如 configure.ac 中的一些測試不能做,導致生成的 Makefile 有問題,所以編譯過程中會有各種報錯,這時就要仔細檢查 configure.ac 和 Makefile.am,把一些不必要的測試去掉,交叉編譯就坑在這里了,而且涉及的工具較多如 automake,autotools 的用法, 經典 make 的 shell 用法。
X. 常用 ./configure 編譯選項,直接在命令行跟在 ./configure 后面(當然也可以在 Makefile.am 中進行設置 AM_...)
CC : c 編譯器,例如 CC=arm-linux-gnueabihf-gcc CXX : c++ 編譯器,例如 CXX=arm-linux-gnueabihf-g++ CFLAGS : c 編譯器選項,例如 CFLAGS='-g -O0' CXXFLAGS : c++ 編譯器選項,例如 CXXFLAGS='-O3 -std=c++11' CPPFLAGS : c 和 c++ 預處理選項,指定頭文件路徑的地方,例如 CPPFLAGS='-I/usr/local/arm-linux-gnueabihf/include -I/usr/local/include -I/usr/include' LDFLAGS : c 和 c++ 鏈接選項,指令庫文件路徑的地方,例如 LDFLAGS='-L/usr/local/arm-linux-gnueabihf/lib -L/usr/local/lib -L/usr/lib'
(完)