• 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'

    (完)

  • 相关阅读:
    DataTable 中各种计算(笔记)
    超级强悍开源图表控件ZedGraph,请高手指教数据绑定问题!!!
    ArcGIS Engine 9.3项目迁移到ArcGIS Engine 10 报错的解决方案
    c# ,vb.net代码相互转换
    ArcGIS扩展开发(一)为 ArcGIS Desktop建立Addin插件
    设计
    正则表达式
    JSON入门
    关于Unity中资源导入
    关于Unity中的ShaderLab
  • 原文地址:https://www.cnblogs.com/gaowengang/p/12631924.html
Copyright © 2020-2023  润新知