Xilinx Zynq 环境交叉编译 Thrift 记录

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/_toolchains/ (推荐)

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'

(完)

原文地址:https://www.cnblogs.com/gaowengang/p/12631924.html